summaryrefslogtreecommitdiff
path: root/libkmod/python/kmod
diff options
context:
space:
mode:
authorW. Trevor King <wking@tremily.us>2012-10-18 23:30:30 -0400
committerLucas De Marchi <lucas.demarchi@intel.com>2014-03-20 07:22:52 -0300
commit118bb1fcba1358d81f0bb2e79cd046c4a170c883 (patch)
tree76f11fbe47a778299464b4a41d06964cd06df2d8 /libkmod/python/kmod
parentf58dff22d359c8dc2d956bb48f1a46c84411f285 (diff)
downloadkmod-118bb1fcba1358d81f0bb2e79cd046c4a170c883.tar.gz
python: Convert to Cython.
With Cython we get easier memory handling and Python 3 compatibility.
Diffstat (limited to 'libkmod/python/kmod')
-rw-r--r--libkmod/python/kmod/__init__.py17
-rw-r--r--libkmod/python/kmod/_libkmod_h.pxd77
-rw-r--r--libkmod/python/kmod/error.py2
-rw-r--r--libkmod/python/kmod/kmod.pxd5
-rw-r--r--libkmod/python/kmod/kmod.pyx101
-rw-r--r--libkmod/python/kmod/list.pxd9
-rw-r--r--libkmod/python/kmod/list.pyx29
-rw-r--r--libkmod/python/kmod/module.pxd8
-rw-r--r--libkmod/python/kmod/module.pyx65
-rw-r--r--libkmod/python/kmod/version.py1
10 files changed, 314 insertions, 0 deletions
diff --git a/libkmod/python/kmod/__init__.py b/libkmod/python/kmod/__init__.py
new file mode 100644
index 0000000..5d3f129
--- /dev/null
+++ b/libkmod/python/kmod/__init__.py
@@ -0,0 +1,17 @@
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+# 2012 W. Trevor King
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU Lesser General Public License v.2.1.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Author: Andy Grover <agrover redhat com>
+
+"Libkmod -- Python interface to kmod API."
+
+from .version import __version__
+from .kmod import Kmod
diff --git a/libkmod/python/kmod/_libkmod_h.pxd b/libkmod/python/kmod/_libkmod_h.pxd
new file mode 100644
index 0000000..975dfa3
--- /dev/null
+++ b/libkmod/python/kmod/_libkmod_h.pxd
@@ -0,0 +1,77 @@
+cdef extern from *:
+ ctypedef char* const_char_ptr 'const char *'
+ ctypedef char* const_char_const_ptr 'const char const *'
+ ctypedef void* const_void_ptr 'const void *'
+
+cdef extern from 'errno.h':
+ enum: EEXIST
+
+cdef extern from 'stdbool.h':
+ ctypedef struct bool:
+ pass
+
+
+cdef extern from 'libkmod.h':
+ # library user context - reads the config and system
+ # environment, user variables, allows custom logging
+ cdef struct kmod_ctx:
+ pass
+
+ kmod_ctx *kmod_new(
+ const_char_ptr dirname, const_char_const_ptr config_paths)
+ kmod_ctx *kmod_ref(kmod_ctx *ctx)
+ kmod_ctx *kmod_unref(kmod_ctx *ctx)
+
+ # Management of libkmod's resources
+ int kmod_load_resources(kmod_ctx *ctx)
+ void kmod_unload_resources(kmod_ctx *ctx)
+
+ # access to kmod generated lists
+ cdef struct kmod_list:
+ pass
+ ctypedef kmod_list* const_kmod_list_ptr 'const struct kmod_list *'
+ kmod_list *kmod_list_next(
+ const_kmod_list_ptr list, const_kmod_list_ptr curr)
+ kmod_list *kmod_list_prev(
+ const_kmod_list_ptr list, const_kmod_list_ptr curr)
+ kmod_list *kmod_list_last(const_kmod_list_ptr list)
+
+ # Operate on kernel modules
+ cdef struct kmod_module:
+ pass
+ ctypedef kmod_module* const_kmod_module_ptr 'const struct kmod_module *'
+ int kmod_module_new_from_name(
+ kmod_ctx *ctx, const_char_ptr name, kmod_module **mod)
+ int kmod_module_new_from_lookup(
+ kmod_ctx *ctx, const_char_ptr given_alias, kmod_list **list)
+ int kmod_module_new_from_loaded(kmod_ctx *ctx, kmod_list **list)
+
+ kmod_module *kmod_module_ref(kmod_module *mod)
+ kmod_module *kmod_module_unref(kmod_module *mod)
+ int kmod_module_unref_list(kmod_list *list)
+ kmod_module *kmod_module_get_module(kmod_list *entry)
+
+ # Flags to kmod_module_probe_insert_module
+ # codes below can be used in return value, too
+ enum: KMOD_PROBE_APPLY_BLACKLIST
+
+ #ctypedef int (*install_callback_t)(
+ # kmod_module *m, const_char_ptr cmdline, const_void_ptr data)
+ #ctypedef void (*print_action_callback_t)(
+ # kmod_module *m, bool install, const_char_ptr options)
+
+ int kmod_module_remove_module(
+ kmod_module *mod, unsigned int flags)
+ int kmod_module_insert_module(
+ kmod_module *mod, unsigned int flags, const_char_ptr options)
+ int kmod_module_probe_insert_module(
+ kmod_module *mod, unsigned int flags, const_char_ptr extra_options,
+ int (*run_install)(
+ kmod_module *m, const_char_ptr cmdline, void *data),
+ const_void_ptr data,
+ void (*print_action)(
+ kmod_module *m, bool install, const_char_ptr options),
+ )
+
+ const_char_ptr kmod_module_get_name(const_kmod_module_ptr mod)
+ long kmod_module_get_size(const_kmod_module_ptr mod)
diff --git a/libkmod/python/kmod/error.py b/libkmod/python/kmod/error.py
new file mode 100644
index 0000000..d976bb6
--- /dev/null
+++ b/libkmod/python/kmod/error.py
@@ -0,0 +1,2 @@
+class KmodError (Exception):
+ pass
diff --git a/libkmod/python/kmod/kmod.pxd b/libkmod/python/kmod/kmod.pxd
new file mode 100644
index 0000000..2933724
--- /dev/null
+++ b/libkmod/python/kmod/kmod.pxd
@@ -0,0 +1,5 @@
+cimport _libkmod_h
+
+cdef class Kmod (object):
+ cdef _libkmod_h.kmod_ctx *_kmod_ctx
+ cdef object mod_dir
diff --git a/libkmod/python/kmod/kmod.pyx b/libkmod/python/kmod/kmod.pyx
new file mode 100644
index 0000000..fdba4c6
--- /dev/null
+++ b/libkmod/python/kmod/kmod.pyx
@@ -0,0 +1,101 @@
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+# 2012 W. Trevor King
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU Lesser General Public License v.2.1.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+cimport cython as _cython
+cimport _libkmod_h
+from error import KmodError as _KmodError
+cimport module as _module
+import module as _module
+cimport list as _list
+import list as _list
+
+
+cdef class Kmod (object):
+ def __cinit__(self):
+ self._kmod_ctx = NULL
+
+ def __dealloc__(self):
+ self._cleanup()
+
+ def __init__(self, mod_dir=None):
+ self.set_mod_dir(mod_dir=mod_dir)
+
+ def set_mod_dir(self, mod_dir=None):
+ self.mod_dir = mod_dir
+ self._setup()
+
+ def _setup(self):
+ cdef char *mod_dir = NULL
+ self._cleanup()
+ if self.mod_dir:
+ mod_dir = self.mod_dir
+ self._kmod_ctx = _libkmod_h.kmod_new(mod_dir, NULL);
+ if self._kmod_ctx is NULL:
+ raise _KmodError('Could not initialize')
+ _libkmod_h.kmod_load_resources(self._kmod_ctx)
+
+ def _cleanup(self):
+ if self._kmod_ctx is not NULL:
+ _libkmod_h.kmod_unload_resources(self._kmod_ctx);
+ self._kmod_ctx = NULL
+
+ def loaded(self):
+ "iterate through currently loaded modules"
+ cdef _list.ModList ml = _list.ModList()
+ cdef _list.ModListItem mli
+ err = _libkmod_h.kmod_module_new_from_loaded(self._kmod_ctx, &ml.list)
+ if err < 0:
+ raise _KmodError('Could not get loaded modules')
+ for item in ml:
+ mli = <_list.ModListItem> item
+ mod = _module.Module()
+ mod.from_mod_list_item(item)
+ yield mod
+
+ def lookup(self, alias_name, flags=_libkmod_h.KMOD_PROBE_APPLY_BLACKLIST):
+ "iterate through modules matching `alias_name`"
+ cdef _list.ModList ml = _list.ModList()
+ cdef _list.ModListItem mli
+ if hasattr(alias_name, 'encode'):
+ alias_name = alias_name.encode('ascii')
+ err = _libkmod_h.kmod_module_new_from_lookup(
+ self._kmod_ctx, alias_name, &ml.list)
+ if err < 0:
+ raise _KmodError('Could not modprobe')
+ for item in ml:
+ mli = <_list.ModListItem> item
+ mod = _module.Module()
+ mod.from_mod_list_item(item)
+ yield mod
+
+ @_cython.always_allow_keywords(True)
+ def module_from_name(self, name):
+ cdef _module.Module mod = _module.Module()
+ if hasattr(name, 'encode'):
+ name = name.encode('ascii')
+ err = _libkmod_h.kmod_module_new_from_name(
+ self._kmod_ctx, name, &mod.module)
+ if err < 0:
+ raise _KmodError('Could not get module')
+ return mod
+
+ def list(self):
+ "iterate through currently loaded modules and sizes"
+ for mod in self.loaded():
+ yield (mod.name, mod.size)
+
+ def modprobe(self, alias_name, *args, **kwargs):
+ for mod in self.lookup(alias_name=alias_name):
+ mod.insert(*args, **kwargs)
+
+ def rmmod(self, module_name, *args, **kwargs):
+ mod = self.module_from_name(name=module_name)
+ mod.remove(*args, **kwargs)
diff --git a/libkmod/python/kmod/list.pxd b/libkmod/python/kmod/list.pxd
new file mode 100644
index 0000000..6c3725b
--- /dev/null
+++ b/libkmod/python/kmod/list.pxd
@@ -0,0 +1,9 @@
+cimport _libkmod_h
+
+
+cdef class ModListItem (object):
+ cdef _libkmod_h.kmod_list *list
+
+
+cdef class ModList (ModListItem):
+ cdef _libkmod_h.kmod_list *_next
diff --git a/libkmod/python/kmod/list.pyx b/libkmod/python/kmod/list.pyx
new file mode 100644
index 0000000..e2bf04f
--- /dev/null
+++ b/libkmod/python/kmod/list.pyx
@@ -0,0 +1,29 @@
+cimport _libkmod_h
+
+
+cdef class ModListItem (object):
+ "Wrap a struct kmod_list* list item"
+ def __cinit__(self):
+ self.list = NULL
+
+
+cdef class ModList (ModListItem):
+ "Wrap a struct kmod_list* list with iteration"
+ def __cinit__(self):
+ self._next = NULL
+
+ def __dealloc__(self):
+ if self.list is not NULL:
+ _libkmod_h.kmod_module_unref_list(self.list)
+
+ def __iter__(self):
+ self._next = self.list
+ return self
+
+ def __next__(self):
+ if self._next is NULL:
+ raise StopIteration()
+ mli = ModListItem()
+ mli.list = self._next
+ self._next = _libkmod_h.kmod_list_next(self.list, self._next)
+ return mli
diff --git a/libkmod/python/kmod/module.pxd b/libkmod/python/kmod/module.pxd
new file mode 100644
index 0000000..3cc4d63
--- /dev/null
+++ b/libkmod/python/kmod/module.pxd
@@ -0,0 +1,8 @@
+cimport _libkmod_h
+cimport list as _list
+
+
+cdef class Module (object):
+ cdef _libkmod_h.kmod_module *module
+
+ cpdef from_mod_list_item(self, _list.ModListItem item)
diff --git a/libkmod/python/kmod/module.pyx b/libkmod/python/kmod/module.pyx
new file mode 100644
index 0000000..1e66772
--- /dev/null
+++ b/libkmod/python/kmod/module.pyx
@@ -0,0 +1,65 @@
+import sys as _sys
+
+cimport _libkmod_h
+from error import KmodError as _KmodError
+cimport list as _list
+import list as _list
+
+
+cdef class Module (object):
+ "Wrap a struct kmod_module* item"
+ def __cinit__(self):
+ self.module = NULL
+
+ def __dealloc__(self):
+ self._cleanup()
+
+ def _cleanup(self):
+ if self.module is not NULL:
+ _libkmod_h.kmod_module_unref(self.module)
+ self.module = NULL
+
+ cpdef from_mod_list_item(self, _list.ModListItem item):
+ self._cleanup()
+ self.module = _libkmod_h.kmod_module_get_module(item.list)
+
+ def _name_get(self):
+ name = _libkmod_h.kmod_module_get_name(self.module)
+ if _sys.version_info >= (3,): # Python 3
+ name = str(name, 'ascii')
+ else: # Python 2
+ name = unicode(name, 'ascii')
+ return name
+ name = property(fget=_name_get)
+
+ def _size_get(self):
+ return _libkmod_h.kmod_module_get_size(self.module)
+ size = property(fget=_size_get)
+
+ def insert(self, flags=0, extra_options=None, install_callback=None,
+ data=None, print_action_callback=None):
+ cdef char *opt = NULL
+ #cdef _libkmod_h.install_callback_t install = NULL
+ cdef int (*install)(
+ _libkmod_h.kmod_module *, _libkmod_h.const_char_ptr, void *)
+ install = NULL
+ cdef void *d = NULL
+ #cdef _libkmod_h.print_action_callback_t print_action = NULL
+ cdef void (*print_action)(
+ _libkmod_h.kmod_module *, _libkmod_h.bool,
+ _libkmod_h.const_char_ptr)
+ print_action = NULL
+ if extra_options:
+ opt = extra_options
+ # TODO: convert callbacks and data from Python object to C types
+ err = _libkmod_h.kmod_module_probe_insert_module(
+ self.module, flags, opt, install, d, print_action)
+ if err == -_libkmod_h.EEXIST:
+ raise _KmodError('Module already loaded')
+ elif err < 0:
+ raise _KmodError('Could not load module')
+
+ def remove(self, flags=0):
+ err = _libkmod_h.kmod_module_remove_module(self.module, flags)
+ if err < 0:
+ raise _KmodError('Could not remove module')
diff --git a/libkmod/python/kmod/version.py b/libkmod/python/kmod/version.py
new file mode 100644
index 0000000..11d27f8
--- /dev/null
+++ b/libkmod/python/kmod/version.py
@@ -0,0 +1 @@
+__version__ = '0.1'