From 6ee6afa2a0d58eab23351d0770288f242e0248be Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 12 Mar 2012 23:16:35 -0700 Subject: [PATCH] Add support for listing loaded modules, modprobe, rmmod And other misc. cleanups and changes. Signed-off-by: Andy Grover --- libkmod.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++-------- setup.py | 4 +- 2 files changed, 140 insertions(+), 25 deletions(-) diff --git a/libkmod.c b/libkmod.c index 7b4e82f..b309620 100644 --- 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); } } - diff --git a/setup.py b/setup.py index 55e3909..9c6e422 100644 --- 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]) -- 2.26.2