[PATCH 3/4] Support for MD containers.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds new class MDRaidContainerDevice.

---
 storage/devicelibs/mdraid.py |   11 ++++--
 storage/devices.py           |   31 ++++++++++++++++++
 storage/devicetree.py        |   70 ++++++++++++++++++++++++++++++++++++++++++
 storage/udev.py              |    9 ++++-
 4 files changed, 115 insertions(+), 6 deletions(-)

diff --git a/storage/devicelibs/mdraid.py b/storage/devicelibs/mdraid.py
index 56fd626..ade42fd 100644
--- a/storage/devicelibs/mdraid.py
+++ b/storage/devicelibs/mdraid.py
@@ -149,11 +149,14 @@ def mddestroy(device):
     if rc:
         raise MDRaidError("mddestroy failed for %s" % device)
 
-def mdadd(device):
+def mdadd(device, no_degraded=False):
+    args = ["--incremental", "--quiet"]
+    if no_degraded:
+        args.append("--no-degraded")
+    args.append(device)
+
     rc = iutil.execWithRedirect("mdadm",
-                                ["--incremental", 
-                                 "--quiet",
-                                 device],
+                                args,
                                 stderr = "/dev/tty5",
                                 stdout = "/dev/tty5",
                                 searchPath=1)
diff --git a/storage/devices.py b/storage/devices.py
index b5e32af..7d21084 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -2560,6 +2560,37 @@ class MDRaidArrayDevice(StorageDevice):
         # real work, but it isn't our place to do it from here.
         self.exists = False
 
+class MDRaidContainerDevice(MDRaidArrayDevice):
+    """ An mdraid container device.
+    """
+    _type = "mdcontainer"
+    _devDir = "/dev/md"
+
+    def __init__(self, name, 
+                 memberDevices=None, 
+                 uuid=None, exists=None,
+                 parents=None):
+        """ Create a MDRaidContainerDevice instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+
+            Keyword Arguments:
+
+                parents -- list of member devices (StorageDevice instances)
+                uuid -- the device's UUID
+                exists -- indicates whether this is an existing device
+        """
+        MDRaidArrayDevice.__init__(self, name, 
+                                  memberDevices=memberDevices,
+                                  uuid=uuid, exists=exists, parents=parents)
+
+    def addFirstDevice(self, path):
+        mdraid.mdadd(path, True)
+        udev_settle(timeout=10)
+        real=os.readlink(self.path).split('/')[1]
+        self.sysfsPath = "/devices/virtual/block/%s" % real
 
 class DMRaidArrayDevice(DiskDevice):
     """ A dmraid (device-mapper RAID) device """
diff --git a/storage/devicetree.py b/storage/devicetree.py
index c7ba51d..ddbe917 100644
--- a/storage/devicetree.py
+++ b/storage/devicetree.py
@@ -969,6 +969,68 @@ class DeviceTree(object):
 
         return device
 
+
+    def addUdevMDContainerDevice(self, info):
+        log.debug("info=%s" % info)
+        if info.has_key("MD_DEVNAME"):
+            log.debug("real MD container")
+        else:
+            log.debug("isw md member")
+            name = udev_device_get_name(info)
+            sysfs_path = udev_device_get_sysfs_path(info)
+            
+            device = StorageDevice(name,
+                            major=udev_device_get_major(info),
+                            minor=udev_device_get_minor(info),
+                            sysfsPath=sysfs_path, exists=True)
+            self._addDevice(device)
+
+            format_type = udev_device_get_format(info)
+            args = [format_type]
+            kwargs = {"mdUuid": udev_device_get_md_uuid(info),
+                      "uuid": udev_device_get_uuid(info),
+                  "label": udev_device_get_label(info),
+                  "device": device.path,
+                  "exists": True}
+
+            log.debug("uuid=%s" % kwargs["uuid"])
+            log.debug("mdUuid=%s" % kwargs["mdUuid"])
+            device.format = formats.getFormat(*args, **kwargs)
+            log.debug("format=%s mdUuid=%s" % (device.format, device.format.mdUuid))
+            
+            if device.format.mdUuid:
+                md_array = self.getDeviceByUuid(device.format.mdUuid)
+                if md_array:
+                    log.debug("_addDevice to array")
+                    md_array._addDevice(device)
+                else:
+                    try:
+                        md_level = udev_device_get_md_level(info)
+                        md_devices = int(udev_device_get_md_devices(info))
+                        md_uuid = udev_device_get_md_uuid(info)
+                    except (KeyError, ValueError) as e:
+                        log.warning("invalid data for %s: %s" % (name, e))
+                        return
+         
+                    minor = 0
+                    while True:
+                          if self.getDeviceByName("imsm%d" % minor):
+                                minor += 1
+                          else:
+                                break
+                    md_name = "imsm%d" % minor
+                    md_array = MDRaidContainerDevice(name=md_name,
+                                                 memberDevices=md_devices,
+                                                 uuid=md_uuid,
+                                                 exists=True,
+                                                 parents=[device])
+                    try: 
+                        md_array.addFirstDevice(device.path)
+                        self._addDevice(md_array)
+                        return 
+                    except MDRaidError as e:
+                          log.warning("failed to add member to md array %s" % e)
+
     def addUdevMDDevice(self, info):
         name = udev_device_get_name(info)
         log_method_call(self, name=name)
@@ -1164,6 +1226,14 @@ class DeviceTree(object):
 
             if device is None:
                 device = self.addUdevDMDevice(info)
+        elif udev_device_is_md_container(info):
+            log.debug("%s is an md container device" % name)
+            if device is None and uuid:
+                # try to find the device by uuid
+                device = self.getDeviceByUuid(uuid)
+
+            if device is None:
+                device = self.addUdevMDContainerDevice(info)
         elif udev_device_is_md(info):
             log.debug("%s is an md device" % name)
             if device is None and uuid:
diff --git a/storage/udev.py b/storage/udev.py
index 63cc3fd..5c17a34 100644
--- a/storage/udev.py
+++ b/storage/udev.py
@@ -195,9 +195,14 @@ def udev_device_is_dm(info):
     """ Return True if the device is a device-mapper device. """
     return info.has_key("DM_NAME")
 
+def udev_device_is_md_container(info):
+    """ Return True if the device is a mdraid container device. """
+    return info.get("MD_LEVEL") == "container"
+
 def udev_device_is_md(info):
-    """ Return True is the device is an mdraid array device. """
-    return info.has_key("MD_METADATA")
+    """ Return True if the device is a mdraid array device. """
+    return info.has_key("MD_DEVNAME") and \
+           info.has_key("MD_METADATA")
 
 def udev_device_is_cdrom(info):
     """ Return True if the device is an optical drive. """
-- 
1.6.3.1.54.g99dd

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux