--- storage/devices.py | 69 +++++++++++++++++++++++++++++++++++++++++---- storage/devicetree.py | 60 +++++++++++++++++++++++++++++++++++--- storage/formats/dmraid.py | 23 +++++++++++---- storage/udev.py | 10 ++++++- 4 files changed, 144 insertions(+), 18 deletions(-) diff --git a/storage/devices.py b/storage/devices.py index 3cc2599..63a0638 100644 --- a/storage/devices.py +++ b/storage/devices.py @@ -536,7 +536,6 @@ class StorageDevice(Device): #for parent in self.parents: # parent.removeChild() - class DiskDevice(StorageDevice): """ A disk """ _type = "disk" @@ -575,9 +574,11 @@ class DiskDevice(StorageDevice): if not self.partedDevice: raise DeviceError("cannot find parted device instance") log.debug("creating parted Disk: %s" % self.path) - self.partedDisk = parted.Disk(device=self.partedDevice) - if not self.partedDisk: - raise DeviceError("failed to create parted Disk") + try: + self.partedDisk = parted.Disk(device=self.partedDevice) + except: + # It is perfectly fine to have a device with no label. + self.partedDisk = None self.probe() @@ -1981,16 +1982,18 @@ class DMRaidArrayDevice(DMDevice): _type = "dm-raid array" _packages = ["dmraid"] - def __init__(self, name, format=None, size=None, + def __init__(self, name, raidSet=None, level=None, format=None, size=None, exists=None, parents=None, sysfsPath=''): """ Create a DMRaidArrayDevice instance. Arguments: - name -- the device name (generally a device node's basename) + name -- the dmraid name also the device node's basename Keyword Arguments: + raidSet -- the RaidSet object from block + level -- the type of dmraid parents -- a list of the member devices sysfsPath -- sysfs device path size -- the device's size @@ -2005,6 +2008,60 @@ class DMRaidArrayDevice(DMDevice): parents=parents, sysfsPath=sysfsPath, exists=exists) + self.formatClass = get_device_format_class("dmraidmember") + if not self.formatClass: + raise DeviceError("cannot find class for 'dmraidmember'") + + + self._raidSet = raidSet + self._level = level + + @property + def raidSet(self): + return self._raidSet + + @raidSet.setter + def raidSet(self, val): + # If we change self._raidSet, parents list will be invalid. + # Don't allow the change. + pass + + def _addDevice(self, device): + """ Add a new member device to the array. + + XXX This is for use when probing devices, not for modification + of arrays. + """ + log_method_call(self, self.name, device=device.name, status=self.status) + + if not self.exists: + raise DeviceError("device has not been created") + + if not isinstance(device.format, self.formatClass): + raise ValueError("invalid device format for dmraid member") + + if device in self.members: + raise ValueError("device is already a member of this array") + + # we added it, so now set up the relations + self.devices.append(device) + device.addChild() + + @property + def members(self): + return self.parents + + @property + def devices(self): + """ Return a list of this array's member device instances. """ + return self.parents + + def activate(self, mknod=True): + self._raidSet.activate(mknod=mknod) + + def deactivate(self): + self._raidSet.deactivate() + def probe(self): """ Probe for any missing information about this device. diff --git a/storage/devicetree.py b/storage/devicetree.py index cdd41f0..6790c66 100644 --- a/storage/devicetree.py +++ b/storage/devicetree.py @@ -21,6 +21,7 @@ # import os +import block from errors import * from devices import * @@ -561,6 +562,17 @@ class DeviceTree(object): minor=udev_device_get_minor(info), sysfsPath=sysfs_path) self._addDevice(device) + elif udev_device_is_dmraid(info): + # This is just temporary as I need to differentiate between the + # device that has partitions and device that dont. + log.debug("%s is part of a dmraid" % name) + device = self.getDeviceByName(name) + if device is None: + device = StorageDevice(name, + major=udev_device_get_major(info), + minor=udev_device_get_minor(info), + sysfsPath=sysfs_path) + self._addDevice(device) elif udev_device_is_disk(info): log.debug("%s is a disk" % name) device = self.getDeviceByName(name) @@ -619,9 +631,8 @@ class DeviceTree(object): # mdraid kwargs["mdUuid"] = udev_device_get_md_uuid(info) elif format_type == "isw_raid_member": - # dmraid - # TODO: collect name of containing raidset - # TODO: implement dmraid member format class + # We dont add any new args because we intend to use the same + # block.RaidSet object for all the related devices. pass elif format_type == "LVM2_member": # lvm @@ -703,8 +714,47 @@ class DeviceTree(object): parents=[device]) self._addDevice(md_array) elif format.type == "dmraidmember": - # look up or create the dmraid array - pass + import pdb ; pdb.set_trace() + # Have we already created the DMRaidArrayDevice? + rs = block.getRaidSetFromRelatedMem(uuid=uuid, name=name, \ + major = udev_device_get_major(info), \ + minor = udev_device_get_minor(info)) + if rs is None: + # FIXME: Should handle not finding a dmriad dev better + pass + + dm_array = self.getDeviceByName(rs.name) + if dm_array is not None: + # Use the rs's object on the device. + device.format.raidmem = block.getMemFromRaidSet(dm_array, \ + major = udev_device_get_major(info), \ + minor = udev_device_get_minor(info), \ + uuid=uuid, name=name) + + # We add the new device. + dm_array._addDevice(device) + + else: + # Use the rs's object on the device. + device.format.raidmem = block.getMemFromRaidSet(rs, \ + major = udev_device_get_major(info), \ + minor = udev_device_get_minor(info), \ + uuid=uuid, name=name) + + # Activate the Raid set. + rs.activate(mknod=True) + + # For size. dmraid uses sector. use parted. + dm_size = parted.getDevice(rs.bdev.path).getSize(unit="MB") + # Create the DMRaidArray + dm_array = DMRaidArrayDevice(rs.name, + raidSet=rs, + level=rs.level, + size=dm_size, + exists=True, + parents=[device]) + + self._addDevice(dm_array) elif format.type == "lvmpv": # lookup/create the VG and LVs try: diff --git a/storage/formats/dmraid.py b/storage/formats/dmraid.py index d458b45..ef80902 100644 --- a/storage/formats/dmraid.py +++ b/storage/formats/dmraid.py @@ -20,6 +20,8 @@ # Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx> # +import block + from iutil import log_method_call #from dm import dm_node_from_name from ..errors import * @@ -65,25 +67,34 @@ class DMRaidMember(DeviceFormat): device -- path to the underlying device uuid -- this format's UUID - raidSet -- the name of the raidset this member belongs to exists -- indicates whether this is an existing format + On initialization this format is like DeviceFormat + """ log_method_call(self, *args, **kwargs) DeviceFormat.__init__(self, *args, **kwargs) - - self.raidSet = kwargs.get("raidSet") + + # Initialize the attribute that will hold the block object. + self._raidmem = None + + @property + def raidmem(self): + return self._raidmem + + @raidmem.setter + def raidmem(self, raidmem): + self._raidmem = raidmem def create(self, *args, **kwargs): log_method_call(self, device=self.device, type=self.type, status=self.status) - raise DMRaidMemberError("creation of dmraid members is not supported") + raise DMRaidMemberError("creation of dmraid members is non-sense") def destroy(self, *args, **kwargs): log_method_call(self, device=self.device, type=self.type, status=self.status) - raise DMRaidMemberError("destruction of dmraid members is not supported") - + raise DMRaidMemberError("destruction of dmraid members is non-sense") register_device_format(DMRaidMember) diff --git a/storage/udev.py b/storage/udev.py index 4f83c2a..087f811 100644 --- a/storage/udev.py +++ b/storage/udev.py @@ -270,4 +270,12 @@ def udev_device_get_lv_sizes(info): return [float(s) / 1024 for s in sizes] - +def udev_device_is_dmraid(info): + # Note that this function does *not* identify raid sets. + # Tests to see if device is parto of a dmraid set. + # dmraid and mdriad have the same ID_FS_USAGE string, ID_FS_TYPE has a + # string that describes the type of dmraid (isw_raid_member...), I don't + # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so + # dmraid will be everything that is raid and not linux_raid_member + return info["ID_FS_USAGE"] == "raid" and \ + info["ID_FS_TYPE"] != "linux_raid_member" -- 1.6.0.6 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list