[PATCH 1/6] Replace our pyudev with the package python-pyudev.

David Lehman dlehman at redhat.com
Fri Aug 1 16:27:33 UTC 2014


On 08/01/2014 10:34 AM, Anne Mulhern wrote:
>
>
>
>
> ----- Original Message -----
>> From: "David Lehman" <dlehman at redhat.com>
>> To: anaconda-patches at lists.fedorahosted.org
>> Sent: Friday, August 1, 2014 1:22:29 AM
>> Subject: [PATCH 1/6] Replace our pyudev with the package python-pyudev.
>>
>> There are two major differences in how we use the module. Each device
>> is represented by a pyudev.Device instance, which is based on
>> collections.abc.Mapping. That means we can no longer change the data
>> to do things like set a "multipath_member" format type or inject LVM
>> or MD metadata.
>>
>> The other difference is that sysfs paths now include the "/sys", which
>> is great since it's always mounted in the same place.
>> ---
>>   blivet/deviceaction.py |   4 +-
>>   blivet/devices.py      |  95 +++++++--------------
>>   blivet/devicetree.py   |  49 +++++------
>>   blivet/pyudev.py       | 226
>>   -------------------------------------------------
>>   blivet/udev.py         | 122 +++++++++-----------------
>>   blivet/util.py         |   2 +-
>>   python-blivet.spec     |   1 +
>>   tests/udev_test.py     |  91 +-------------------
>>   8 files changed, 99 insertions(+), 491 deletions(-)
>>   delete mode 100644 blivet/pyudev.py
>>
>> diff --git a/blivet/deviceaction.py b/blivet/deviceaction.py
>> index db4c7a7..d2818c1 100644
>> --- a/blivet/deviceaction.py
>> +++ b/blivet/deviceaction.py
>> @@ -553,9 +553,7 @@ class ActionCreateFormat(DeviceAction):
>>               self.device.format.create(device=self.device.path,
>>                                         options=self.device.formatArgs)
>>               # Get the UUID now that the format is created
>> -            udev.settle()
>> -            self.device.updateSysfsPath()
>> -            info = udev.get_block_device(self.device.sysfsPath)
>> +            info = udev.get_device(self.device.sysfsPath)
>>               # only do this if the format has a device known to udev
>>               # (the format might not have a normal device at all)
>>               if info:
>> diff --git a/blivet/devices.py b/blivet/devices.py
>> index c238e94..25b7586 100644
>> --- a/blivet/devices.py
>> +++ b/blivet/devices.py
>> @@ -27,6 +27,7 @@ import tempfile
>>   import abc
>>   from decimal import Decimal
>>   import re
>> +import pyudev
>>
>>   from six import add_metaclass
>>
>> @@ -107,7 +108,7 @@ def deviceNameToDiskByPath(deviceName=None):
>>           return ""
>>
>>       ret = None
>> -    for dev in udev.get_block_devices():
>> +    for dev in udev.get_devices():
>>           if udev.device_get_name(dev) == deviceName:
>>               ret = udev.device_get_by_path(dev)
>>               break
>> @@ -508,7 +509,6 @@ class StorageDevice(Device):
>>
>>       _type = "blivet"
>>       _devDir = "/dev"
>> -    sysfsBlockDir = "class/block"
>>       _formatImmutable = False
>>       _partitionable = False
>>       _isDisk = False
>> @@ -751,11 +751,22 @@ class StorageDevice(Device):
>>
>>       def updateSysfsPath(self):
>>           """ Update this device's sysfs path. """
>> -        log_method_call(self, self.name, status=self.status)
>> -        sysfsName = self.name.replace("/", "!")
>> -        path = os.path.join("/sys", self.sysfsBlockDir, sysfsName)
>> -        self.sysfsPath = os.path.realpath(path)[4:]
>> -        log.debug("%s sysfsPath set to %s", self.name, self.sysfsPath)
>> +        # We're using os.path.exists as a stand-in for status. We can't use
>> +        # the status property directly because MDRaidArrayDevice.status
>> calls
>> +        # this method.
>> +        log_method_call(self, self.name, status=os.path.exists(self.path))
>> +        if not self.exists:
>> +            raise errors.DeviceError("device has not been created",
>> self.name)
>> +
>> +        try:
>> +            udev_device = pyudev.Device.from_device_file(udev.global_udev,
>> +                                                         self.path)
>> +        except pyudev.DeviceNotFoundError as e:
>> +            log.error("failed to update sysfs path for %s: %s", self.name,
>> e)
>> +            self.sysfsPath = ''
>> +        else:
>> +            self.sysfsPath = udev_device.sys_path
>> +            log.debug("%s sysfsPath set to %s", self.name, self.sysfsPath)
>>
>>       @property
>>       def formatArgs(self):
>> @@ -780,7 +791,7 @@ class StorageDevice(Device):
>>               log.debug("not sending change uevent for inactive device")
>>               return
>>
>> -        path = os.path.normpath("/sys/%s" % self.sysfsPath)
>> +        path = os.path.normpath(self.sysfsPath)
>>           try:
>>               util.notify_kernel(path, action="change")
>>           except (ValueError, IOError) as e:
>> @@ -1055,7 +1066,7 @@ class StorageDevice(Device):
>>
>>       @property
>>       def removable(self):
>> -        devpath = os.path.normpath("/sys/%s" % self.sysfsPath)
>> +        devpath = os.path.normpath(self.sysfsPath)
>>           remfile = os.path.normpath("%s/removable" % devpath)
>>           return (self.sysfsPath and os.path.exists(devpath) and
>>                   os.access(remfile, os.R_OK) and
>> @@ -1575,23 +1586,6 @@ class PartitionDevice(StorageDevice):
>>       weight = property(lambda d: d._getWeight(),
>>                         lambda d,w: d._setWeight(w))
>>
>> -    def updateSysfsPath(self):
>> -        """ Update this device's sysfs path. """
>> -        log_method_call(self, self.name, status=self.status)
>> -        if not self.parents:
>> -            self.sysfsPath = ''
>> -
>> -        elif isinstance(self.parents[0], DMDevice):
>> -            dm_node = dm.dm_node_from_name(self.name)
>> -            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
>> -            self.sysfsPath = os.path.realpath(path)[4:]
>> -        elif isinstance(self.parents[0], MDRaidArrayDevice):
>> -            md_node = mdraid.md_node_from_name(self.name)
>> -            path = os.path.join("/sys", self.sysfsBlockDir, md_node)
>> -            self.sysfsPath = os.path.realpath(path)[4:]
>> -        else:
>> -            StorageDevice.updateSysfsPath(self)
>> -
>>       def _setName(self, value):
>>           self._name = value  # actual name setting is done by parted
>>
>> @@ -2054,19 +2048,6 @@ class DMDevice(StorageDevice):
>>              None)
>>           return (match.live_table and not match.suspended) if match else
>>           False
>>
>> -    def updateSysfsPath(self):
>> -        """ Update this device's sysfs path. """
>> -        log_method_call(self, self.name, status=self.status)
>> -        if not self.exists:
>> -            raise errors.DeviceError("device has not been created",
>> self.name)
>> -
>> -        if self.status:
>> -            dm_node = self.getDMNode()
>> -            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
>> -            self.sysfsPath = os.path.realpath(path)[4:]
>> -        else:
>> -            self.sysfsPath = ''
>> -
>>       #def getTargetType(self):
>>       #    return dm.getDmTarget(name=self.name)
>>
>> @@ -3810,22 +3791,6 @@ class MDRaidArrayDevice(ContainerDevice):
>>
>>       spares = property(_getSpares, _setSpares)
>>
>> -    def updateSysfsPath(self):
>> -        """ Update this device's sysfs path. """
>> -        # don't include self.status here since this method is called by
>> -        # MDRaidArrayDevice.status
>> -        log_method_call(self, self.name)
>> -        if not self.exists:
>> -            raise errors.DeviceError("device has not been created",
>> self.name)
>> -
>> -        # We don't use self.status here because self.status requires a valid
>> -        # sysfs path to function correctly.
>> -        if os.path.exists(self.path):
>> -            md_node = mdraid.md_node_from_name(self.name)
>> -            self.sysfsPath = "/devices/virtual/block/%s" % md_node
>> -        else:
>> -            self.sysfsPath = ''
>> -
>>       def _addParent(self, member):
>>           super(MDRaidArrayDevice, self)._addParent(member)
>>
>> @@ -3886,7 +3851,7 @@ class MDRaidArrayDevice(ContainerDevice):
>>               self.updateSysfsPath()
>>
>>               # make sure the active array is the one we expect
>> -            info = udev.get_block_device(self.sysfsPath)
>> +            info = udev.get_device(self.sysfsPath)
>>               uuid = udev.device_get_md_uuid(info)
>>               if uuid and uuid != self.uuid:
>>                   log.warning("md array %s is active, but has UUID %s -- not
>>                   %s",
>> @@ -3894,7 +3859,7 @@ class MDRaidArrayDevice(ContainerDevice):
>>                   self.sysfsPath = ""
>>                   return status
>>
>> -        state_file = "/sys/%s/md/array_state" % self.sysfsPath
>> +        state_file = "%s/md/array_state" % self.sysfsPath
>>           try:
>>               state = open(state_file).read().strip()
>>               if state in ("clean", "active", "active-idle", "readonly",
>>               "read-auto"):
>> @@ -3924,7 +3889,7 @@ class MDRaidArrayDevice(ContainerDevice):
>>       def degraded(self):
>>           """ Return True if the array is running in degraded mode. """
>>           rc = False
>> -        degraded_file = "/sys/%s/md/degraded" % self.sysfsPath
>> +        degraded_file = "%s/md/degraded" % self.sysfsPath
>>           if os.access(degraded_file, os.R_OK):
>>               val = open(degraded_file).read().strip()
>>               if val == "1":
>> @@ -3982,7 +3947,7 @@ class MDRaidArrayDevice(ContainerDevice):
>>           # mdadm reuses minors indiscriminantly when there is no mdadm.conf,
>>           so
>>           # we need to clear the sysfs path now so our status method continues
>>           to
>>           # give valid results
>> -        self.updateSysfsPath()
>> +        self.sysfsPath = ''
>>
>>       def teardown(self, recursive=None):
>>           """ Close, or tear down, a device. """
>> @@ -4024,15 +3989,13 @@ class MDRaidArrayDevice(ContainerDevice):
>>
>>       def _postCreate(self):
>>           # this is critical since our status method requires a valid sysfs
>>           path
>> -        md_node = mdraid.md_node_from_name(self.name)
>> -        self.sysfsPath = "/devices/virtual/block/%s" % md_node
>> -        self.exists = True  # I think we can remove this.
>> -
>> +        self.exists = True  # this is needed to run updateSysfsPath
>> +        self.updateSysfsPath()
>>           StorageDevice._postCreate(self)
>>
>>           # update our uuid attribute with the new array's UUID
>> -        info = udev.get_block_device(self.sysfsPath)
>> -        self.uuid = udev.device_get_md_uuid(info)
>> +        info = mdraid.mddetail(self.path)
>> +        self.uuid = info.get("UUID")
>>           for member in self.devices:
>>               member.format.mdUuid = self.uuid
>>
>> @@ -5229,7 +5192,7 @@ class BTRFSVolumeDevice(BTRFSDevice, ContainerDevice):
>>
>>       def _postCreate(self):
>>           super(BTRFSVolumeDevice, self)._postCreate()
>> -        info = udev.get_block_device(self.sysfsPath)
>> +        info = udev.get_device(self.sysfsPath)
>>           if not info:
>>               log.error("failed to get updated udev info for new btrfs
>>               volume")
>>           else:
>> diff --git a/blivet/devicetree.py b/blivet/devicetree.py
>> index c4cb1b7..755f782 100644
>> --- a/blivet/devicetree.py
>> +++ b/blivet/devicetree.py
>> @@ -660,7 +660,7 @@ class DeviceTree(object):
>>
>>           if self.udevDeviceIsDisk(info):
>>               # Ignore any readonly disks
>> -            if util.get_sysfs_attr(info["sysfs_path"], 'ro') == '1':
>> +            if util.get_sysfs_attr(udev.device_get_sysfs_path(info), 'ro')
>> == '1':
>>                   log.debug("Ignoring read only device %s", name)
>>                   # FIXME: We have to handle this better, ie: not ignore
>>                   these.
>>                   self.addIgnoredDisk(name)
>> @@ -706,10 +706,10 @@ class DeviceTree(object):
>>           if not device:
>>               # initiate detection of all PVs and hope that it leads to us
>>               having
>>               # the VG and LVs in the tree
>> -            for pv_name in os.listdir("/sys" + sysfs_path + "/slaves"):
>> -                link = os.readlink("/sys" + sysfs_path + "/slaves/" +
>> pv_name)
>> +            for pv_name in os.listdir(sysfs_path + "/slaves"):
>> +                link = os.readlink(sysfs_path + "/slaves/" + pv_name)
>>                   pv_sysfs_path = os.path.normpath(sysfs_path + '/slaves/' +
>>                   link)
>> -                pv_info = udev.get_block_device(pv_sysfs_path)
>> +                pv_info = udev.get_device(pv_sysfs_path)
>>                   self.addUdevDevice(pv_info)
>>
>>           vg_name = udev.device_get_lv_vg_name(info)
>> @@ -752,7 +752,7 @@ class DeviceTree(object):
>>           if device is None:
>>               # we couldn't find it, so create it
>>               # first, get a list of the slave devs and look them up
>> -            slave_dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
>> +            slave_dir = os.path.normpath("%s/slaves" % sysfs_path)
>>               slave_names = os.listdir(slave_dir)
>>               for slave_name in slave_names:
>>                   # if it's a dm-X name, resolve it to a map name first
>> @@ -762,7 +762,7 @@ class DeviceTree(object):
>>                       dev_name = slave_name.replace("!", "/") # handles cciss
>>                   slave_dev = self.getDeviceByName(dev_name)
>>                   path = os.path.normpath("%s/%s" % (slave_dir, slave_name))
>> -                new_info = udev.get_block_device(os.path.realpath(path)[4:])
>> +                new_info = udev.get_device(os.path.realpath(path))
>>                   if not slave_dev:
>>                       # we haven't scanned the slave yet, so do it now
>>                       if new_info:
>> @@ -822,7 +822,7 @@ class DeviceTree(object):
>>           # TODO: look for this device by dm-uuid?
>>
>>           # first, get a list of the slave devs and look them up
>> -        slave_dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
>> +        slave_dir = os.path.normpath("%s/slaves" % sysfs_path)
>>           slave_names = os.listdir(slave_dir)
>>           for slave_name in slave_names:
>>               # if it's a dm-X name, resolve it to a map name first
>> @@ -832,7 +832,7 @@ class DeviceTree(object):
>>                   dev_name = slave_name.replace("!", "/") # handles cciss
>>               slave_dev = self.getDeviceByName(dev_name)
>>               path = os.path.normpath("%s/%s" % (slave_dir, slave_name))
>> -            new_info = udev.get_block_device(os.path.realpath(path)[4:])
>> +            new_info = udev.get_device(os.path.realpath(path))
>>               if not slave_dev:
>>                   # we haven't scanned the slave yet, so do it now
>>                   if new_info:
>> @@ -865,7 +865,7 @@ class DeviceTree(object):
>>           log_method_call(self, name=name)
>>           sysfs_path = udev.device_get_sysfs_path(info)
>>
>> -        slave_dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
>> +        slave_dir = os.path.normpath("%s/slaves" % sysfs_path)
>>           slave_names = os.listdir(slave_dir)
>>           for slave_name in slave_names:
>>               # if it's a dm-X name, resolve it to a map name
>> @@ -877,7 +877,7 @@ class DeviceTree(object):
>>               if not slave_dev:
>>                   # we haven't scanned the slave yet, so do it now
>>                   path = os.path.normpath("%s/%s" % (slave_dir, slave_name))
>> -                new_info = udev.get_block_device(os.path.realpath(path)[4:])
>> +                new_info = udev.get_device(os.path.realpath(path))
>>                   if new_info:
>>                       self.addUdevDevice(new_info)
>>                       if self.getDeviceByName(dev_name) is None:
>> @@ -936,7 +936,7 @@ class DeviceTree(object):
>>
>>           if disk is None:
>>               # create a device instance for the disk
>> -            new_info = udev.get_block_device(os.path.dirname(sysfs_path))
>> +            new_info = udev.get_device(os.path.dirname(sysfs_path))
>>               if new_info:
>>                   self.addUdevDevice(new_info)
>>                   disk = self.getDeviceByName(disk_name)
>> @@ -1030,7 +1030,7 @@ class DeviceTree(object):
>>               if not container:
>>                   parentSysName = mdraid.md_node_from_name(parentName)
>>                   container_sysfs = "/class/block/" + parentSysName
>> -                container_info = udev.get_block_device(container_sysfs)
>> +                container_info = udev.get_device(container_sysfs)
>>                   if not container_info:
>>                       log.error("failed to find md container %s at %s",
>>                                   parentName, container_sysfs)
>> @@ -1102,7 +1102,7 @@ class DeviceTree(object):
>>           name = udev.device_get_name(info)
>>           log_method_call(self, name=name)
>>           sysfs_path = udev.device_get_sysfs_path(info)
>> -        sys_file = "/sys/%s/loop/backing_file" % sysfs_path
>> +        sys_file = "%s/loop/backing_file" % sysfs_path
>>           backing_file = open(sys_file).read().strip()
>>           file_device = self.getDeviceByName(backing_file)
>>           if not file_device:
>> @@ -1122,7 +1122,7 @@ class DeviceTree(object):
>>
>>       def addUdevDevice(self, info):
>>           name = udev.device_get_name(info)
>> -        log_method_call(self, name=name, info=pprint.pformat(info))
>> +        log_method_call(self, name=name, info=pprint.pformat(dict(info)))
>>           uuid = udev.device_get_uuid(info)
>>           sysfs_path = udev.device_get_sysfs_path(info)
>>
>> @@ -1490,7 +1490,7 @@ class DeviceTree(object):
>>
>>                   if lv_device.status:
>>                       lv_device.updateSysfsPath()
>> -                    lv_info = udev.get_block_device(lv_device.sysfsPath)
>> +                    lv_info = udev.get_device(lv_device.sysfsPath)
>>                       if not lv_info:
>>                           log.error("failed to get udev data for lv %s",
>>                           lv_device.name)
>>                           return
>> @@ -1587,7 +1587,7 @@ class DeviceTree(object):
>>
>>               # check the list of devices udev knows about to see if the array
>>               # this device belongs to is already active
>> -            for dev in udev.get_block_devices():
>> +            for dev in udev.get_devices():
>>                   if not udev.device_is_md(dev):
>>                       continue
>>
>> @@ -1682,13 +1682,13 @@ class DeviceTree(object):
>>                   self._addDevice(dm_array)
>>
>>                   # Wait for udev to scan the just created nodes, to avoid a
>>                   race
>> -                # with the udev.get_block_device() call below.
>> +                # with the udev.get_device() call below.
>>                   udev.settle()
>>
>>                   # Get the DMRaidArrayDevice a DiskLabel format *now*, in
>>                   case
>>                   # its partitions get scanned before it does.
>>                   dm_array.updateSysfsPath()
>> -                dm_array_info = udev.get_block_device(dm_array.sysfsPath)
>> +                dm_array_info = udev.get_device(dm_array.sysfsPath)
>>                   self.handleUdevDiskLabelFormat(dm_array_info, dm_array)
>>
>>                   # Use the rs's object on the device.
>> @@ -1889,7 +1889,7 @@ class DeviceTree(object):
>>       def updateDeviceFormat(self, device):
>>           log.info("updating format of device: %s", device)
>>           try:
>> -            util.notify_kernel("/sys%s" % device.sysfsPath)
>> +            util.notify_kernel(device.sysfsPath)
>>           except (ValueError, IOError) as e:
>>               log.warning("failed to notify kernel of change: %s", e)
>>
>> @@ -2032,7 +2032,7 @@ class DeviceTree(object):
>>                   self._addDevice(filedev)
>>                   self._addDevice(loopdev)
>>                   self._addDevice(dmdev)
>> -                info = udev.get_block_device(dmdev.sysfsPath)
>> +                info = udev.get_device(dmdev.sysfsPath)
>>                   self.addUdevDevice(info)
>>
>>       def backupConfigs(self, restore=False):
>> @@ -2146,18 +2146,19 @@ class DeviceTree(object):
>>           # blocks or since previous iterations.
>>           while True:
>>               devices = []
>> -            new_devices = udev.get_block_devices()
>> +            new_devices = udev.get_devices()
>>
>>               for new_device in new_devices:
>> -                if new_device['name'] not in old_devices:
>> -                    old_devices[new_device['name']] = new_device
>> +                new_name = udev.device_get_name(new_device)
>> +                if new_name not in old_devices:
>> +                    old_devices[new_name] = new_device
>>                       devices.append(new_device)
>>
>>               if len(devices) == 0:
>>                   # nothing is changing -- we are finished building devices
>>                   break
>>
>> -            log.info("devices to scan: %s", [d['name'] for d in devices])
>> +            log.info("devices to scan: %s", [udev.device_get_name(d) for d
>> in devices])
>>               for dev in devices:
>>                   self.addUdevDevice(dev)
>>
>> diff --git a/blivet/pyudev.py b/blivet/pyudev.py
>> deleted file mode 100644
>> index fa0846f..0000000
>> --- a/blivet/pyudev.py
>> +++ /dev/null
>> @@ -1,226 +0,0 @@
>> -from __future__ import print_function
>> -
>> -import sys
>> -import os
>> -import fnmatch
>> -from ctypes import CDLL, c_char_p, c_int, c_void_p
>> -
>> -
>> -# XXX this one may need some tweaking...
>> -def find_library(name, somajor=0):
>> -    env = os.environ.get("LD_LIBRARY_PATH")
>> -    common = ["/lib64", "/lib"]
>> -
>> -    if env:
>> -        libdirs = env.split(":") + common
>> -    else:
>> -        libdirs = common
>> -
>> -    for ldir in filter(os.path.isdir, libdirs):
>> -        files = fnmatch.filter(os.listdir(ldir), "lib%s.so.%d" % (name,
>> somajor))
>> -        if files:
>> -            return next(os.path.join(ldir, lfile) for lfile in files)
>> -
>> -    return None
>> -
>> -def get_library():
>> -    name = "udev"
>> -    somajor = 1
>> -    lib = find_library(name=name, somajor=somajor)
>> -
>> -    if not lib or not os.path.exists(lib):
>> -        raise ImportError("No library named %s.%d" % (name, somajor))
>> -    return lib
>> -
>> -# load the udev library
>> -libudev = CDLL(get_library())
>> -
>> -
>> -# create aliases for needed functions and set the return types where needed
>> -libudev_udev_new = libudev.udev_new
>> -libudev_udev_new.argtypes = []
>> -libudev_udev_new.restype = c_void_p
>> -libudev_udev_unref = libudev.udev_unref
>> -libudev_udev_unref.argtypes = [ c_void_p ]
>> -
>> -libudev_udev_device_new_from_syspath = libudev.udev_device_new_from_syspath
>> -libudev_udev_device_new_from_syspath.restype = c_void_p
>> -libudev_udev_device_new_from_syspath.argtypes = [ c_void_p, c_char_p ]
>> -libudev_udev_device_unref = libudev.udev_device_unref
>> -libudev_udev_device_unref.argtypes = [ c_void_p ]
>> -
>> -libudev_udev_device_get_syspath = libudev.udev_device_get_syspath
>> -libudev_udev_device_get_syspath.restype = c_char_p
>> -libudev_udev_device_get_syspath.argtypes = [ c_void_p ]
>> -libudev_udev_device_get_sysname = libudev.udev_device_get_sysname
>> -libudev_udev_device_get_sysname.restype = c_char_p
>> -libudev_udev_device_get_sysname.argtypes = [ c_void_p ]
>> -libudev_udev_device_get_devpath = libudev.udev_device_get_devpath
>> -libudev_udev_device_get_devpath.restype = c_char_p
>> -libudev_udev_device_get_devpath.argtypes = [ c_void_p ]
>> -libudev_udev_device_get_devtype = libudev.udev_device_get_devtype
>> -libudev_udev_device_get_devtype.restype = c_char_p
>> -libudev_udev_device_get_devtype.argtypes = [ c_void_p ]
>> -libudev_udev_device_get_devnode = libudev.udev_device_get_devnode
>> -libudev_udev_device_get_devnode.restype = c_char_p
>> -libudev_udev_device_get_devnode.argtypes = [ c_void_p ]
>> -libudev_udev_device_get_subsystem = libudev.udev_device_get_subsystem
>> -libudev_udev_device_get_subsystem.restype = c_char_p
>> -libudev_udev_device_get_subsystem.argtypes = [ c_void_p ]
>> -libudev_udev_device_get_sysnum = libudev.udev_device_get_sysnum
>> -libudev_udev_device_get_sysnum.restype = c_char_p
>> -libudev_udev_device_get_sysnum.argtypes = [ c_void_p ]
>> -
>> -libudev_udev_device_get_properties_list_entry =
>> libudev.udev_device_get_properties_list_entry
>> -libudev_udev_device_get_properties_list_entry.restype = c_void_p
>> -libudev_udev_device_get_properties_list_entry.argtypes = [ c_void_p ]
>> -libudev_udev_list_entry_get_next = libudev.udev_list_entry_get_next
>> -libudev_udev_list_entry_get_next.restype = c_void_p
>> -libudev_udev_list_entry_get_next.argtypes = [ c_void_p ]
>> -
>> -libudev_udev_list_entry_get_name = libudev.udev_list_entry_get_name
>> -libudev_udev_list_entry_get_name.restype = c_char_p
>> -libudev_udev_list_entry_get_name.argtypes = [ c_void_p ]
>> -libudev_udev_list_entry_get_value = libudev.udev_list_entry_get_value
>> -libudev_udev_list_entry_get_value.restype = c_char_p
>> -libudev_udev_list_entry_get_value.argtypes = [ c_void_p ]
>> -
>> -libudev_udev_enumerate_new = libudev.udev_enumerate_new
>> -libudev_udev_enumerate_new.restype = c_void_p
>> -libudev_udev_enumerate_new.argtypes = [ c_void_p ]
>> -libudev_udev_enumerate_unref = libudev.udev_enumerate_unref
>> -libudev_udev_enumerate_unref.argtypes = [ c_void_p ]
>> -
>> -libudev_udev_enumerate_add_match_subsystem =
>> libudev.udev_enumerate_add_match_subsystem
>> -libudev_udev_enumerate_add_match_subsystem.restype = c_int
>> -libudev_udev_enumerate_add_match_subsystem.argtypes = [ c_void_p, c_char_p ]
>> -libudev_udev_enumerate_scan_devices = libudev.udev_enumerate_scan_devices
>> -libudev_udev_enumerate_scan_devices.restype = c_int
>> -libudev_udev_enumerate_scan_devices.argtypes = [ c_void_p ]
>> -libudev_udev_enumerate_get_list_entry =
>> libudev.udev_enumerate_get_list_entry
>> -libudev_udev_enumerate_get_list_entry.restype = c_void_p
>> -libudev_udev_enumerate_get_list_entry.argtypes = [ c_void_p ]
>> -
>> -libudev_udev_device_get_devlinks_list_entry =
>> libudev.udev_device_get_devlinks_list_entry
>> -libudev_udev_device_get_devlinks_list_entry.restype = c_void_p
>> -libudev_udev_device_get_devlinks_list_entry.argtypes = [ c_void_p ]
>> -
>> -
>> -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 devlinks list
>> -        devlinks = []
>> -        devlinks_entry =
>> libudev_udev_device_get_devlinks_list_entry(udev_device)
>> -
>> -        while devlinks_entry:
>> -            path = libudev_udev_list_entry_get_name(devlinks_entry)
>> -            devlinks.append(path)
>> -
>> -            devlinks_entry =
>> libudev_udev_list_entry_get_next(devlinks_entry)
>> -
>> -        # add devlinks list to the dictionary
>> -        self["symlinks"] = devlinks
>> -
>> -        # 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)
>> -
>> -            # lvm outputs values for multiple lvs in one line
>> -            # we want to split them and make a list
>> -            # if the first lv's value is empty we end up with a value
>> starting
>> -            # with name=, prepend a space that our split does the right
>> thing
>> -            if value.startswith("%s=" % name):
>> -                value = " " + value
>> -
>> -            if value.count(" %s=" % name):
>> -                value = value.split(" %s=" % name)
>> -
>> -            self[name] = value
>> -
>> -            # get next property entry
>> -            property_entry =
>> libudev_udev_list_entry_get_next(property_entry)
>> -
>> -        # set additional properties
>> -        self.devpath = libudev_udev_device_get_devpath(udev_device)
>> -        self.subsystem = libudev_udev_device_get_subsystem(udev_device)
>> -        self.devtype = libudev_udev_device_get_devtype(udev_device)
>> -        self.sysnum = libudev_udev_device_get_sysnum(udev_device)
>> -        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):
>> -        context = libudev_udev_enumerate_new(self.udev)
>> -
>> -        # add the match subsystem
>> -        if subsystem is not None:
>> -            rc = libudev_udev_enumerate_add_match_subsystem(context,
>> subsystem)
>> -            if not rc == 0:
>> -                print("error: unable to add the match subsystem",
>> file=sys.stderr)
>> -                libudev_udev_enumerate_unref(context)
>> -                return []
>> -
>> -        # scan the devices
>> -        rc = libudev_udev_enumerate_scan_devices(context)
>> -        if not rc == 0:
>> -            print("error: unable to enumerate the devices", file=sys.stderr)
>> -            libudev_udev_enumerate_unref(context)
>> -            return []
>> -
>> -        # create the list of sysfs paths
>> -        sysfs_paths = []
>> -
>> -        # get the first list entry
>> -        list_entry = libudev_udev_enumerate_get_list_entry(context)
>> -
>> -        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(context)
>> -
>> -        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
>> diff --git a/blivet/udev.py b/blivet/udev.py
>> index b66e30b..d0eb543 100644
>> --- a/blivet/udev.py
>> +++ b/blivet/udev.py
>> @@ -27,45 +27,28 @@ import re
>>   from . import util
>>   from .size import Size
>>
>> -from . import pyudev
>> -global_udev = pyudev.Udev()
>> +import pyudev
>> +global_udev = pyudev.Context()
>>
>>   import logging
>>   log = logging.getLogger("blivet")
>>
>> -def enumerate_devices(deviceClass="block"):
>> -    devices = global_udev.enumerate_devices(subsystem=deviceClass)
>> -    return [path[4:] for path in devices]
>> -
>>   def get_device(sysfs_path):
>> -    if not os.path.exists("/sys%s" % sysfs_path):
>> -        log.debug("%s does not exist", sysfs_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["sysfs_path"] = sysfs_path
>> -
>> -        # now add in the contents of the uevent file since they're handy
>> -        dev = parse_uevent_file(dev)
>> +    try:
>> +        dev = pyudev.Device.from_sys_path(global_udev, sysfs_path)
>> +    except pyudev.DeviceNotFoundError as e:
>> +        log.error(e)
>> +        dev = None
>>
>>       return dev
>>
>> -def get_devices(deviceClass="block"):
>> +def get_devices(subsystem="block"):
>>       settle()
>> -    entries = []
>> -    for path in enumerate_devices(deviceClass):
>> -        entry = get_device(path)
>> -        if entry:
>> -            entries.append(entry)
>> -    return entries
>> +    return [d for d in global_udev.list_devices(subsystem=subsystem)
>> +                        if not __is_blacklisted_blockdev(d.sys_name)]
>>
>>   def parse_uevent_file(dev):
>> -    path = os.path.normpath("/sys/%s/uevent" % dev['sysfs_path'])
>> +    path = os.path.normpath("%s/uevent" % device_get_sysfs_path(dev))
>>       if not os.access(path, os.R_OK):
>>           return dev
>>
>> @@ -103,7 +86,7 @@ def resolve_devspec(devspec):
>>       from . import devices
>>
>>       ret = None
>> -    for dev in get_block_devices():
>> +    for dev in get_devices():
>>           if devspec.startswith("LABEL="):
>>               if device_get_label(dev) == devspec[6:]:
>>                   ret = dev
>> @@ -120,7 +103,7 @@ def resolve_devspec(devspec):
>>               if not spec.startswith("/dev/"):
>>                   spec = os.path.normpath("/dev/" + spec)
>>
>> -            for link in dev["symlinks"]:
>> +            for link in device_get_symlinks(dev):
>>                   if spec == link:
>>                       ret = dev
>>                       break
>> @@ -135,37 +118,18 @@ def resolve_glob(glob):
>>       if not glob:
>>           return ret
>>
>> -    for dev in get_block_devices():
>> +    for dev in get_devices():
>>           name = device_get_name(dev)
>>
>>           if fnmatch.fnmatch(name, glob):
>>               ret.append(name)
>>           else:
>> -            for link in dev["symlinks"]:
>> +            for link in device_get_symlinks(dev):
>>                   if fnmatch.fnmatch(link, glob):
>>                       ret.append(name)
>>
>>       return ret
>>
>> -def get_block_devices():
>> -    settle()
>> -    entries = []
>> -    for path in enumerate_block_devices():
>> -        entry = get_block_device(path)
>> -        if entry:
>> -            if entry["name"].startswith("md"):
>> -                # mdraid is really braindead, when a device is stopped
>> -                # it is no longer usefull in anyway (and we should not
>> -                # probe it) yet it still sticks around, see bug rh523387
>> -                state = None
>> -                state_file = "/sys/%s/md/array_state" % entry["sysfs_path"]
>> -                if os.access(state_file, os.R_OK):
>> -                    state = open(state_file).read().strip()
>> -                if state == "clear":
>> -                    continue
>> -            entries.append(entry)
>> -    return entries
>> -
>>   def __is_blacklisted_blockdev(dev_name):
>>       """Is this a blockdev we never want for an install?"""
>>       if dev_name.startswith("ram") or dev_name.startswith("fd"):
>> @@ -180,17 +144,6 @@ def __is_blacklisted_blockdev(dev_name):
>>
>>       return False
>>
>> -def enumerate_block_devices():
>> -    return [d for d in enumerate_devices(deviceClass="block") if not
>> __is_blacklisted_blockdev(os.path.basename(d))]
>> -
>> -def get_block_device(sysfs_path):
>> -    dev = get_device(sysfs_path)
>> -    if not dev or 'name' not in dev:
>> -        return None
>> -    else:
>> -        return dev
>> -
>> -
>>   # These are functions for retrieving specific pieces of information from
>>   # udev database entries.
>>   def device_get_name(udev_info):
>> @@ -198,7 +151,7 @@ def device_get_name(udev_info):
>>       if "DM_NAME" in udev_info:
>>           name = udev_info["DM_NAME"]
>>       else:
>> -        name = udev_info["name"]
>> +        name = udev_info.sys_name
>>
>>       return name
>>
>> @@ -236,7 +189,7 @@ def device_is_md(info):
>>
>>       # The udev information keeps shifting around. Only md arrays have a
>>       # /sys/class/block/<name>/md/ subdirectory.
>> -    md_dir = "/sys" + device_get_sysfs_path(info) + "/md"
>> +    md_dir = device_get_sysfs_path(info) + "/md"
>>       return os.path.exists(md_dir)
>>
>>   def device_is_cciss(info):
>> @@ -256,7 +209,7 @@ def device_is_zfcp(info):
>>       if info.get("DEVTYPE") != "disk":
>>           return False
>>
>> -    subsystem = "/sys" + info.get("sysfs_path")
>> +    subsystem = device_get_sysfs_path(info)
>>
>>       while True:
>>           topdir = os.path.realpath(os.path.dirname(subsystem))
>> @@ -284,7 +237,7 @@ def device_get_zfcp_attribute(info, attr=None):
>>           log.debug("device_get_zfcp_attribute() called with attr=None")
>>           return None
>>
>> -    attribute = "/sys%s/device/%s" % (info.get("sysfs_path"), attr,)
>> +    attribute = "%s/device/%s" % (device_get_sysfs_path(info), attr)
>>       attribute = os.path.realpath(attribute)
>>
>>       if not os.path.isfile(attribute):
>> @@ -295,14 +248,14 @@ def device_get_zfcp_attribute(info, attr=None):
>>
>>   def device_get_dasd_bus_id(info):
>>       """ Return the CCW bus ID of the dasd device. """
>> -    return info.get("sysfs_path").split("/")[-3]
>> +    return device_get_sysfs_path(info).split("/")[-3]
>>
>>   def device_get_dasd_flag(info, flag=None):
>>       """ Return the specified flag for the dasd device. """
>>       if flag is None:
>>           return None
>>
>> -    path = "/sys" + info.get("sysfs_path") + "/device/" + flag
>> +    path = device_get_sysfs_path(info) + "/device/" + flag
>>       if not os.path.isfile(path):
>>           return None
>>
>> @@ -318,17 +271,17 @@ def device_is_disk(info):
>>       """ Return True is the device is a disk. """
>>       if device_is_cdrom(info):
>>           return False
>> -    has_range = os.path.exists("/sys/%s/range" % info['sysfs_path'])
>> +    has_range = os.path.exists("%s/range" % device_get_sysfs_path(info))
>>       return info.get("DEVTYPE") == "disk" or has_range
>>
>>   def device_is_partition(info):
>> -    has_start = os.path.exists("/sys/%s/start" % info['sysfs_path'])
>> +    has_start = os.path.exists("%s/start" % device_get_sysfs_path(info))
>>       return info.get("DEVTYPE") == "partition" or has_start
>>
>>   def device_is_loop(info):
>>       """ Return True if the device is a configured loop device. """
>>       return (device_get_name(info).startswith("loop") and
>> -            os.path.isdir("/sys/%s/loop" % info['sysfs_path']))
>> +            os.path.isdir("%s/loop" % device_get_sysfs_path(info)))
>>
>>   def device_get_serial(udev_info):
>>       """ Get the serial number/UUID from the device as reported by udev. """
>> @@ -356,7 +309,7 @@ def device_get_path(info):
>>       return info["ID_PATH"]
>>
>>   def device_get_symlinks(info):
>> -    return info.get("symlinks", [])
>> +    return info.get("DEVLINKS", [])
>>
>>   def device_get_by_path(info):
>>       for link in device_get_symlinks(info):
>> @@ -366,7 +319,7 @@ def device_get_by_path(info):
>>       return device_get_name(info)
>>
>>   def device_get_sysfs_path(info):
>> -    return info['sysfs_path']
>> +    return info.sys_path
>>
>>   def device_get_major(info):
>>       return int(info["MAJOR"])
>> @@ -675,7 +628,7 @@ def device_get_iscsi_session(info):
>>       # The position of sessionX part depends on device
>>       # (e.g. offload vs. sw; also varies for different offload devs)
>>       session = None
>> -    match = re.match(r'/.*/(session\d+)', info["sysfs_path"])
>> +    match = re.match(r'/.*/(session\d+)', device_get_sysfs_path(info))
>>       if match:
>>           session = match.groups()[0]
>>       else:
>> @@ -694,7 +647,7 @@ def device_get_iscsi_nic(info):
>>   def device_get_iscsi_initiator(info):
>>       initiator = None
>>       if device_is_partoff_iscsi(info):
>> -        host = re.match(r'.*/(host\d+)', info["sysfs_path"]).groups()[0]
>> +        host = re.match(r'.*/(host\d+)',
>> device_get_sysfs_path(info)).groups()[0]
>>           if host:
>>               initiator_file = "/sys/class/iscsi_host/%s/initiatorname" % host
>>               if os.access(initiator_file, os.R_OK):
>> @@ -738,10 +691,10 @@ def device_get_iscsi_initiator(info):
>>
>>   def _detect_broadcom_fcoe(info):
>>       re_pci_host=re.compile(r'/(.*)/(host\d+)')
>> -    match = re_pci_host.match(info["sysfs_path"])
>> +    match = re_pci_host.match(device_get_sysfs_path(info))
>>       if match:
>>           sysfs_pci, host = match.groups()
>> -        if os.access('/sys/%s/%s/fc_host' %(sysfs_pci, host), os.X_OK) and \
>> +        if os.access('%s/%s/fc_host' %(sysfs_pci, host), os.X_OK) and \
>>                   'net' in sysfs_pci:
>>               return (sysfs_pci, host)
>>       return (None, None)
>> @@ -757,7 +710,7 @@ def device_is_fcoe(info):
>>          path_components[2] == "fc":
>>           return True
>>
>> -    if path.startswith("fc-") and "fcoe" in info["sysfs_path"]:
>> +    if path.startswith("fc-") and "fcoe" in device_get_sysfs_path(info):
>>           return True
>>
>>       if _detect_broadcom_fcoe(info) != (None, None):
>> @@ -768,20 +721,21 @@ def device_is_fcoe(info):
>>   def device_get_fcoe_nic(info):
>>       path = info.get("ID_PATH", "")
>>       path_components = path.split("-")
>> +    sysfs_path = device_get_sysfs_path(info)
>>
>>       if path.startswith("pci-eth") and len(path_components) >= 4 and \
>>          path_components[2] == "fc":
>>           return path_components[1]
>>
>> -    if path.startswith("fc-") and "fcoe" in info["sysfs_path"]:
>> -        return info["sysfs_path"].split("/")[4].split(".")[0]
>> +    if path.startswith("fc-") and "fcoe" in sysfs_path:
>> +        return sysfs_path.split("/")[4].split(".")[0]
>>
>>       (sysfs_pci, host) = _detect_broadcom_fcoe(info)
>>       if (sysfs_pci, host) != (None, None):
>> -        net, iface = info['sysfs_path'].split("/")[5:7]
>> +        net, iface = sysfs_path.split("/")[5:7]
>>           if net != "net":
>> -            log.warning("unexpected sysfs_path of bnx2fc device: %s",
>> info['sysfs_path'])
>> -            match = re.compile(r'.*/net/([^/]*)').match(info['sysfs_path'])
>> +            log.warning("unexpected sysfs_path of bnx2fc device: %s",
>> sysfs_path)
>> +            match = re.compile(r'.*/net/([^/]*)').match(sysfs_path)
>>               if match:
>>                   return match.groups()[0].split(".")[0]
>>           else:
>> @@ -795,7 +749,7 @@ def device_get_fcoe_identifier(info):
>>          path_components[2] == "fc":
>>           return path_components[3]
>>
>> -    if path.startswith("fc-") and "fcoe" in info["sysfs_path"]:
>> +    if path.startswith("fc-") and "fcoe" in device_get_sysfs_path(info):
>>           return path_components[1]
>>
>>       if device_is_fcoe(info) and len(path_components) >= 4 and \
>> diff --git a/blivet/util.py b/blivet/util.py
>> index a15bb4a..28dc125 100644
>> --- a/blivet/util.py
>> +++ b/blivet/util.py
>> @@ -178,7 +178,7 @@ def get_sysfs_attr(path, attr):
>>           log.debug("get_sysfs_attr() called with attr=None")
>>           return None
>>
>> -    attribute = "/sys%s/%s" % (path, attr)
>> +    attribute = "%s/%s" % (path, attr)
>>       attribute = os.path.realpath(attribute)
>>
>>       if not os.path.isfile(attribute) and not os.path.islink(attribute):
>> diff --git a/python-blivet.spec b/python-blivet.spec
>> index abbbb0f..b668d94 100644
>> --- a/python-blivet.spec
>> +++ b/python-blivet.spec
>> @@ -28,6 +28,7 @@ Requires: python
>>   Requires: python-six
>>   Requires: pykickstart >= %{pykickstartver}
>>   Requires: util-linux >= %{utillinuxver}
>> +Requires: python-pyudev
>>   Requires: parted >= %{partedver}
>>   Requires: pyparted >= %{pypartedver}
>>   Requires: device-mapper >= %{dmver}
>> diff --git a/tests/udev_test.py b/tests/udev_test.py
>> index a7b09ab..86cc434 100644
>> --- a/tests/udev_test.py
>> +++ b/tests/udev_test.py
>> @@ -11,94 +11,11 @@ class UdevTest(unittest.TestCase):
>>           blivet.udev.os = mock.Mock()
>>           blivet.udev.log = mock.Mock()
>>
>> -    def test_udev_enumerate_devices(self):
>> +    def test_udev_get_device(self):
>>           import blivet.udev
>> -        ENUMERATE_LIST = [
>> -
>> '/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda',
>> -            '/sys/devices/virtual/block/loop0',
>> -            '/sys/devices/virtual/block/loop1',
>> -            '/sys/devices/virtual/block/ram0',
>> -            '/sys/devices/virtual/block/ram1',
>> -            '/sys/devices/virtual/block/dm-0',
>> -        ]
>> -        blivet.udev.global_udev.enumerate_devices =
>> mock.Mock(return_value=ENUMERATE_LIST)
>> -        ret = blivet.udev.enumerate_devices()
>> -        self.assertEqual(set(ret),
>> -
>> set(['/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda',
>> -            '/devices/virtual/block/loop0', '/devices/virtual/block/loop1',
>> -            '/devices/virtual/block/ram0', '/devices/virtual/block/ram1',
>> -            '/devices/virtual/block/dm-0'])
>> -        )
>> -
>> -    def test_udev_get_device_1(self):
>> -        import blivet.udev
>> -
>> -        class Device(object):
>> -            def __init__(self):
>> -                self.sysname = 'loop1'
>> -                self.dict = {'symlinks': ['/dev/block/7:1'],
>> -                    'SUBSYSTEM': 'block',
>> -                    'MAJOR': '7',
>> -                    'DEVPATH': '/devices/virtual/block/loop1',
>> -                    'UDISKS_PRESENTATION_NOPOLICY': '1',
>> -                    'UDEV_LOG': '3',
>> -                    'DEVNAME': '/dev/loop1',
>> -                    'DEVTYPE': 'disk',
>> -                    'DEVLINKS': '/dev/block/7:1',
>> -                    'MINOR': '1'
>> -                }
>> -
>> -            def __getitem__(self, key):
>> -                return self.dict[key]
>> -
>> -            def __setitem__(self, key, value):
>> -                self.dict[key] = value
>> -
>> -        blivet.udev.os.path.exists.return_value = True
>> -        DEV_PATH = '/devices/virtual/block/loop1'
>> -        dev = Device()
>> -        blivet.udev.global_udev = mock.Mock()
>> -        blivet.udev.global_udev.create_device.return_value = dev
>> -
>> -        saved = blivet.udev.parse_uevent_file
>> -        blivet.udev.parse_uevent_file = mock.Mock(return_value=dev)
>> -
>> -        ret = blivet.udev.get_device(DEV_PATH)
>> -        self.assertTrue(isinstance(ret, Device))
>> -        self.assertEqual(ret['name'], ret.sysname)
>> -        self.assertEqual(ret['sysfs_path'], DEV_PATH)
>> -        self.assertTrue(blivet.udev.parse_uevent_file.called)
>> -
>> -        blivet.udev.parse_uevent_file = saved
>> -
>> -    def test_udev_get_device_2(self):
>> -        import blivet.udev
>> -        blivet.udev.os.path.exists.return_value = False
>> -        ret = blivet.udev.get_device('')
>> -        self.assertEqual(ret, None)
>> -
>> -    def test_udev_get_device_3(self):
>> -        import blivet.udev
>> -        blivet.udev.os.path.exists.return_value = True
>> -        blivet.udev.global_udev = mock.Mock()
>> -        blivet.udev.global_udev.create_device.return_value = None
>> -        ret = blivet.udev.get_device('')
>> -        self.assertEqual(ret, None)
>> -
>> -    def test_udev_get_devices(self):
>> -        import blivet.udev
>> -        saved = blivet.udev.settle
>> -        blivet.udev.settle = mock.Mock()
>> -        DEVS = \
>> -
>> ['/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda',
>> -            '/devices/virtual/block/loop0', '/devices/virtual/block/loop1',
>> -            '/devices/virtual/block/ram0', '/devices/virtual/block/ram1',
>> -            '/devices/virtual/block/dm-0']
>> -        blivet.udev.enumerate_devices = mock.Mock(return_value=DEVS)
>> -        blivet.udev.get_device = lambda x: x
>> -        ret = blivet.udev.get_devices()
>> -        self.assertEqual(ret, DEVS)
>> -        blivet.udev.settle = saved
>> +        devices = blivet.udev.global_udev.list_devices(subsystem="block")
>> +        for device in devices:
>> +            self.assertNotEqual(blivet.udev.get_device(device.sys_path),
>> None)
>>
>>       def test_udev_parse_uevent_file_1(self):
>>           import blivet.udev
>> --
>> 1.9.3
>>
>> _______________________________________________
>> anaconda-patches mailing list
>> anaconda-patches at lists.fedorahosted.org
>> https://lists.fedorahosted.org/mailman/listinfo/anaconda-patches
>>
>
> A couple of comments:
>
> * mddetail will not have UUID if the level is Container.

That doesn't matter since we don't create md containers, but I can note 
that in MDRaidArrayDevice._postCreate for future reference.

> * It might be a good idea to attach docstrings to the udev.py
> methods, since they've been worked over so much otherwise.

Maybe so, but that's outside the scope of this patch set.

> * You get rid of the use of parse_uevent_file. Apparently,
> parsing the uevent file was a way of obtaining additional
> information not obtained from pyudev/libudev. Can we
> guarantee that the pyudev library obtains all the data
> previously obtained by our pyudev library + parse_uevent_file()
> method.

It's all in there. The only difference, which I've accounted for in one 
place (udev.device_is_dasd) locally, is that DEVNAME is a full path in 
pyudev, whereas it was a basename in the uevent file.

>
> - mulhern
> _______________________________________________
> anaconda-patches mailing list
> anaconda-patches at lists.fedorahosted.org
> https://lists.fedorahosted.org/mailman/listinfo/anaconda-patches
>



More information about the anaconda-patches mailing list