summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Gracik <mgracik@redhat.com>2009-11-10 12:32:42 +0100
committerMartin Gracik <mgracik@redhat.com>2009-11-18 17:11:02 +0100
commitc0af09c9ea55321c185ae1a794f5aed8ac3190f6 (patch)
tree705e9ea4464a1ed61b9056360ee884d2863be8d9
parentbf00d61c0f070e3c0530757bf03972df65a43f31 (diff)
downloadanaconda-c0af09c9ea55321c185ae1a794f5aed8ac3190f6.tar.gz
anaconda-c0af09c9ea55321c185ae1a794f5aed8ac3190f6.tar.xz
anaconda-c0af09c9ea55321c185ae1a794f5aed8ac3190f6.zip
Added the libudev python bindings
Also rewrote the baseudev.py to use the bindings instead of parsing the udev db file
-rw-r--r--baseudev.py60
-rw-r--r--pyudev.py191
2 files changed, 203 insertions, 48 deletions
diff --git a/baseudev.py b/baseudev.py
index 76b14ccbb..d88d7fc41 100644
--- a/baseudev.py
+++ b/baseudev.py
@@ -24,6 +24,9 @@
import iutil
import os
+import pyudev
+global_udev = pyudev.Udev()
+
import logging
log = logging.getLogger("storage")
@@ -43,20 +46,18 @@ def udev_get_device(sysfs_path):
log.debug("%s does not exist" % sysfs_path)
return None
- db_entry = sysfs_path.replace("/", "\\x2f")
- db_root = "/dev/.udev/db"
- db_path = os.path.normpath("%s/%s" % (db_root, db_entry))
- if not os.access(db_path, os.R_OK):
- log.debug("db entry %s does not exist" % db_path)
- return None
+ # XXX we remove the /sys part when enumerating devices,
+ # so we have to prepend it when creating the device
+ dev = global_udev.create_device("/sys" + sysfs_path)
+
+ if dev:
+ dev["name"] = dev.sysname
+ dev["symlinks"] = dev["DEVLINKS"]
+ dev["sysfs_path"] = sysfs_path
- entry = open(db_path).read()
- dev = udev_parse_entry(entry)
- if dev.has_key("name"):
- dev['sysfs_path'] = sysfs_path
+ # now add in the contents of the uevent file since they're handy
dev = udev_parse_uevent_file(dev)
- # now add in the contents of the uevent file since they're handy
return dev
def udev_get_devices(deviceClass="block"):
@@ -68,43 +69,6 @@ def udev_get_devices(deviceClass="block"):
entries.append(entry)
return entries
-def udev_parse_entry(buf):
- dev = {}
-
- for line in buf.splitlines():
- line.strip()
- (tag, sep, val) = line.partition(":")
- if not sep:
- continue
-
- if tag == "N":
- dev['name'] = val
- elif tag == "S":
- if dev.has_key('symlinks'):
- dev['symlinks'].append(val)
- else:
- dev['symlinks'] = [val]
- elif tag == "E":
- if val.count("=") > 1 and val.count(" ") > 0:
- # eg: LVM2_LV_NAME when querying the VG for its LVs
- vars = val.split()
- vals = []
- var_name = None
- for (index, subval) in enumerate(vars):
- (var_name, sep, var_val) = subval.partition("=")
- if sep:
- vals.append(var_val)
-
- dev[var_name] = vals
- else:
- (var_name, sep, var_val) = val.partition("=")
- if not sep:
- continue
-
- dev[var_name] = var_val
-
- return dev
-
def udev_parse_uevent_file(dev):
path = os.path.normpath("/sys/%s/uevent" % dev['sysfs_path'])
if not os.access(path, os.R_OK):
diff --git a/pyudev.py b/pyudev.py
new file mode 100644
index 000000000..b6e5ea950
--- /dev/null
+++ b/pyudev.py
@@ -0,0 +1,191 @@
+from __future__ import print_function
+
+import sys
+import os
+import fnmatch
+from ctypes import *
+
+
+# XXX this one may need some tweaking...
+def find_library(name, somajor=0):
+ env = os.environ.get("LD_LIBRARY_PATH")
+
+ if env:
+ libdirs = env.split(":")
+ else:
+ libdirs = ["/lib64", "/lib"]
+
+ libdirs = filter(os.path.isdir, libdirs)
+
+ for dir in libdirs:
+ files = fnmatch.filter(os.listdir(dir), "lib%s.so.%d" % (name, somajor))
+ files = [os.path.join(dir, file) for file in files]
+
+ if files:
+ break
+
+ if files:
+ return files[0]
+ else:
+ return None
+
+
+# find the udev library
+libudev = find_library(name="udev", somajor=0)
+
+if not libudev or not os.path.exists(libudev):
+ raise ImportError, "No library named %s" % libudev
+
+# load the udev library
+libudev = CDLL(libudev)
+
+
+# create aliases for needed functions and set the return types where needed
+libudev_udev_new = libudev.udev_new
+libudev_udev_unref = libudev.udev_unref
+
+libudev_udev_device_new_from_syspath = libudev.udev_device_new_from_syspath
+libudev_udev_device_unref = libudev.udev_device_unref
+
+libudev_udev_device_get_syspath = libudev.udev_device_get_syspath
+libudev_udev_device_get_sysname = libudev.udev_device_get_sysname
+libudev_udev_device_get_syspath.restype = c_char_p
+libudev_udev_device_get_sysname.restype = c_char_p
+
+libudev_udev_device_get_properties_list_entry = libudev.udev_device_get_properties_list_entry
+libudev_udev_list_entry_get_next = libudev.udev_list_entry_get_next
+
+libudev_udev_list_entry_get_name = libudev.udev_list_entry_get_name
+libudev_udev_list_entry_get_value = libudev.udev_list_entry_get_value
+libudev_udev_list_entry_get_name.restype = c_char_p
+libudev_udev_list_entry_get_value.restype = c_char_p
+
+libudev_udev_enumerate_new = libudev.udev_enumerate_new
+libudev_udev_enumerate_unref = libudev.udev_enumerate_unref
+
+libudev_udev_enumerate_add_match_subsystem = libudev.udev_enumerate_add_match_subsystem
+libudev_udev_enumerate_scan_devices = libudev.udev_enumerate_scan_devices
+libudev_udev_enumerate_get_list_entry = libudev.udev_enumerate_get_list_entry
+
+
+class UdevDevice(dict):
+
+ def __init__(self, udev, sysfs_path):
+ dict.__init__(self)
+
+ # create new udev device from syspath
+ udev_device = libudev_udev_device_new_from_syspath(udev, sysfs_path)
+ if not udev_device:
+ # device does not exist
+ return
+
+ # set syspath and sysname properties
+ self.syspath = libudev_udev_device_get_syspath(udev_device)
+ self.sysname = libudev_udev_device_get_sysname(udev_device)
+
+ # get the first property entry
+ property_entry = libudev_udev_device_get_properties_list_entry(udev_device)
+
+ while property_entry:
+ name = libudev_udev_list_entry_get_name(property_entry)
+ value = libudev_udev_list_entry_get_value(property_entry)
+
+ # XXX we have to split some of the values into a list,
+ # the libudev is not so smart :(
+ fields = value.split()
+
+ if len(fields) > 1:
+ value = [fields[0]]
+
+ for item in fields[1:]:
+ (key, sep, val) = item.partition("=")
+ if sep:
+ value.append(val)
+ else:
+ value.append(key)
+
+ if len(value) == 1:
+ value = value[0]
+
+ self[name] = value
+
+ # get next property entry
+ property_entry = libudev_udev_list_entry_get_next(property_entry)
+
+ # set additional properties
+ libudev.udev_device_get_devpath.restype = c_char_p
+ self.devpath = libudev.udev_device_get_devpath(udev_device)
+
+ libudev.udev_device_get_subsystem.restype = c_char_p
+ self.subsystem = libudev.udev_device_get_subsystem(udev_device)
+
+ libudev.udev_device_get_devtype.restype = c_char_p
+ self.devtype = libudev.udev_device_get_devtype(udev_device)
+
+ libudev.udev_device_get_sysnum.restype = c_char_p
+ self.sysnum = libudev.udev_device_get_sysnum(udev_device)
+
+ libudev.udev_device_get_devnode.restype = c_char_p
+ self.devnode = libudev.udev_device_get_devnode(udev_device)
+
+ # cleanup
+ libudev_udev_device_unref(udev_device)
+
+
+class Udev(object):
+
+ def __init__(self):
+ self.udev = libudev_udev_new()
+
+ def create_device(self, sysfs_path):
+ return UdevDevice(self.udev, sysfs_path)
+
+ def enumerate_devices(self, subsystem=None):
+ enumerate = libudev_udev_enumerate_new(self.udev)
+
+ # add the match subsystem
+ if subsystem is not None:
+ rc = libudev_udev_enumerate_add_match_subsystem(enumerate, subsystem)
+ if not rc == 0:
+ print("error: unable to add the match subsystem", file=sys.stderr)
+ libudev_udev_enumerate_unref(enumerate)
+ return []
+
+ # scan the devices
+ rc = libudev_udev_enumerate_scan_devices(enumerate)
+ if not rc == 0:
+ print("error: unable to enumerate the devices", file=sys.stderr)
+ libudev_udev_enumerate_unref(enumerate)
+ return []
+
+ # create the list of sysfs paths
+ sysfs_paths = []
+
+ # get the first list entry
+ list_entry = libudev_udev_enumerate_get_list_entry(enumerate)
+
+ while list_entry:
+ sysfs_path = libudev_udev_list_entry_get_name(list_entry)
+ sysfs_paths.append(sysfs_path)
+
+ # get next list entry
+ list_entry = libudev_udev_list_entry_get_next(list_entry)
+
+ # cleanup
+ libudev_udev_enumerate_unref(enumerate)
+
+ return sysfs_paths
+
+ def scan_devices(self, sysfs_paths=None):
+ if sysfs_paths is None:
+ sysfs_paths = self.enumerate_devices()
+
+ for sysfs_path in sysfs_paths:
+ device = self.create_device(sysfs_path)
+
+ if device:
+ yield device
+
+ def unref(self):
+ libudev_udev_unref(self.udev)
+ self.udev = None