Add support for listing loaded modules, modprobe, rmmod
authorAndy Grover <andy@groveronline.com>
Tue, 13 Mar 2012 06:16:35 +0000 (23:16 -0700)
committerAndy Grover <andy@groveronline.com>
Tue, 13 Mar 2012 06:16:35 +0000 (23:16 -0700)
And other misc. cleanups and changes.

Signed-off-by: Andy Grover <andy@groveronline.com>
libkmod.c
setup.py

index 7b4e82feb46852ca5681663dd973f23a3063776d..b3096200839ed2131d2fee6be98d1724c64300bb 100644 (file)
--- a/libkmod.c
+++ b/libkmod.c
@@ -23,9 +23,9 @@ typedef struct {
     struct kmod_ctx *ctx;
 } kmodobject;
 
-static PyTypeObject KmodType;
+static PyTypeObject KmodObjType;
 
-static PyObject *LibKmodError;
+static PyObject *KmodError;
 
 
 /* ----------------------------------------------------------------------
@@ -43,10 +43,12 @@ libkmod_init(PyObject *self, PyObject *args, PyObject *kwds)
 
     kmod->ctx = kmod_new(mod_dir, NULL);
     if (!kmod->ctx) {
-        PyErr_SetFromErrno(PyExc_OSError);
+        PyErr_SetString(KmodError, "Could not initialize");
         return -1;
     }
 
+    kmod_load_resources(kmod->ctx);
+
     return 0;
 }
 
@@ -55,6 +57,8 @@ libkmod_dealloc(PyObject *self)
 {
     kmodobject *kmod = (kmodobject *)self;
 
+    kmod_unload_resources(kmod->ctx);
+
     /* if already closed, don't reclose it */
     if (kmod->ctx != NULL){
            kmod_unref(kmod->ctx);
@@ -69,57 +73,168 @@ libkmod_library_get_version(kmodobject *self)
     return Py_BuildValue("s", "whatup dude v1.234");
 }
 
+static PyObject *
+libkmod_kmod_loaded_modules(PyObject *self, PyObject *unused_args)
+{
+    kmodobject *kmod = (kmodobject *)self;
+    struct kmod_list *list, *itr;
+    int err;
+
+    err = kmod_module_new_from_loaded(kmod->ctx, &list);
+    if (err < 0) {
+        PyErr_SetString(KmodError, "Could not get loaded modules");
+        return NULL;
+    }
+
+    PyObject *pylist = PyList_New(0);
+
+    kmod_list_foreach(itr, list) {
+        struct kmod_module *mod = kmod_module_get_module(itr);
+        const char *name = kmod_module_get_name(mod);
+        long size = kmod_module_get_size(mod);
+
+       PyObject *entry = Py_BuildValue("(sl)", name, size);
+
+       PyList_Append(pylist, entry);
+
+       Py_DECREF(entry);
+        kmod_module_unref(mod);
+    }
+    kmod_module_unref_list(list);
+
+    return pylist;
+}
+
+static PyObject *
+libkmod_kmod_modprobe(PyObject *self, PyObject *args)
+{
+    kmodobject *kmod = (kmodobject *)self;
+    struct kmod_list *list = NULL, *itr;
+    struct kmod_module *mod;
+    char *alias_name;
+    unsigned int flags = KMOD_PROBE_APPLY_BLACKLIST;
+    int err;
+
+    if (!PyArg_ParseTuple(args, "s", &alias_name))
+       return NULL;
+
+    err = kmod_module_new_from_lookup(kmod->ctx, alias_name, &list);
+    if (err < 0) {
+        PyErr_SetString(KmodError, "Could not modprobe");
+        return NULL;
+    }
+
+    kmod_list_foreach(itr, list) {
+        mod = kmod_module_get_module(itr);
+
+       err = kmod_module_probe_insert_module(mod, flags,
+           NULL, NULL, NULL, NULL);
+
+       if (err < 0) {
+               if (err == -EEXIST) {
+                       PyErr_SetString(KmodError, "Module already loaded");
+                       goto err;
+               } else {
+                       PyErr_SetString(KmodError, "Could not load module");
+                       goto err;
+               }
+       }
+
+        kmod_module_unref(mod);
+    }
+    kmod_module_unref_list(list);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+
+err:
+    kmod_module_unref(mod);
+    kmod_module_unref_list(list);
+    return NULL;
+}
+
+static PyObject *
+libkmod_kmod_rmmod(PyObject *self, PyObject *args)
+{
+    kmodobject *kmod = (kmodobject *)self;
+    struct kmod_module *mod;
+    char *module_name;
+    int err;
+
+    if (!PyArg_ParseTuple(args, "s", &module_name))
+       return NULL;
+
+    err = kmod_module_new_from_name(kmod->ctx, module_name, &mod);
+    if (err < 0) {
+        PyErr_SetString(KmodError, "Could  get module");
+        return NULL;
+    }
+
+    err = kmod_module_remove_module(mod, 0);
+    if (err < 0) {
+           PyErr_SetString(KmodError, "Could not remove module");
+           kmod_module_unref(mod);
+           return NULL;
+    }
+    kmod_module_unref(mod);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
 /* ----------------------------------------------------------------------
  * Method tables and other bureaucracy
  */
 
 static PyMethodDef Libkmod_methods[] = {
-    /* LVM methods */
     { "getVersion",          (PyCFunction)libkmod_library_get_version, METH_NOARGS },
     { NULL,             NULL}           /* sentinel */
 };
 
+static PyMethodDef kmodobj_methods[] = {
+    { "loaded_modules", libkmod_kmod_loaded_modules, METH_NOARGS },
+    { "modprobe", libkmod_kmod_modprobe, METH_VARARGS },
+    { "rmmod", libkmod_kmod_rmmod, METH_VARARGS },
+    { NULL,             NULL}           /* sentinel */
+};
 
-static PyTypeObject KmodType = {
+
+static PyTypeObject KmodObjType = {
     PyObject_HEAD_INIT(NULL)
     .tp_name = "kmod.kmod",
     .tp_basicsize = sizeof(kmodobject),
-    //.tp_new = PyType_GenericNew,
+    .tp_new = PyType_GenericNew,
     .tp_init = libkmod_init,
     .tp_dealloc = libkmod_dealloc,
-    .tp_flags =Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     .tp_doc = "Libkmod objects",
-    .tp_methods = Libkmod_methods,
+    .tp_methods = kmodobj_methods,
 };
 
 #ifndef PyMODINIT_FUNC    /* declarations for DLL import/export */
 #define PyMODINIT_FUNC void
 #endif
 PyMODINIT_FUNC
-initlibkmod(void)
+initkmod(void)
 {
     PyObject *m;
 
-    KmodType.tp_new = PyType_GenericNew;
-    if (PyType_Ready(&KmodType) < 0)
+    if (PyType_Ready(&KmodObjType) < 0)
         return;
 
-    m = Py_InitModule3("libkmod", Libkmod_methods, "Libkmod module");
-    if (m == NULL)
+    m = Py_InitModule3("kmod", Libkmod_methods, "kmod module");
+    if (!m)
         return;
 
-    Py_INCREF(&KmodType);
-    PyModule_AddObject(m, "Kmod", (PyObject *)&KmodType);
+    Py_INCREF(&KmodObjType);
+    PyModule_AddObject(m, "Kmod", (PyObject *)&KmodObjType);
 
-    LibKmodError = PyErr_NewException("Libkmod.LibKmodError",
-                                      NULL, NULL);
-    if (LibKmodError) {
+    KmodError = PyErr_NewException("kmod.KmodError",
+                                   NULL, NULL);
+    if (KmodError) {
         /* Each call to PyModule_AddObject decrefs it; compensate: */
-        Py_INCREF(LibKmodError);
-        Py_INCREF(LibKmodError);
-        PyModule_AddObject(m, "error", LibKmodError);
-        PyModule_AddObject(m, "LibKmodError", LibKmodError);
+        Py_INCREF(KmodError);
+        PyModule_AddObject(m, "KmodError", KmodError);
     }
 
 }
-
index 55e390931f2f185bbdddb8fbf1fc03b74ec0e1ed..9c6e422257c81b3716345bba4dbb7058db62608e 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -1,10 +1,10 @@
 from distutils.core import setup, Extension
 
-libkmod = Extension('libkmod',
+libkmod = Extension('kmod',
                     sources = ['libkmod.c'],
                     libraries= ['kmod'])
 
-setup (name = 'libkmod',
+setup (name = 'kmod',
        version = '1.0',
        description = 'Python binding for kmod',
        ext_modules = [libkmod])