[PATCH 1/6] Write mdadm.conf lines for mdraid container formats (imsm)

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

 



Ok, so the purpose of this patch is too write mdadm.conf lines for
mdraid container formats (imsm), but what it does is it cleans up
handling of mdraid container formats in general, with the
writing of mdadm.conf writing as a bonus effect really.

We were adding mdraid container members (raidsets inside the container)
to the device tree as DiskDevices. Which works, but is not completely
correct. This patch introduce a PartitionableMDRaidArrayDevice and
uses that for mdraid container members instead. This means we now also
correctly tear them down / set them up when asked. In the future (mostly
needs UI work to export the functionality) PartitionableMDRaidArrayDevice
can be used to create partitionable normal (native metadata) mdraid sets too.
---
 storage/__init__.py   |    2 ++
 storage/devices.py    |   41 ++++++++++++++++++++++++++++++++++++-----
 storage/devicetree.py |   15 +++++++++++----
 storage/udev.py       |    3 +++
 4 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/storage/__init__.py b/storage/__init__.py
index 200fd66..e8b7b52 100644
--- a/storage/__init__.py
+++ b/storage/__init__.py
@@ -1918,6 +1918,8 @@ class FSSet(object):
     def mdadmConf(self):
         """ Return the contents of mdadm.conf. """
         arrays = self.devicetree.getDevicesByType("mdarray")
+        arrays.extend(self.devicetree.getDevicesByType("partitionable mdarray"))
+        arrays.extend(self.devicetree.getDevicesByType("mdcontainer"))
         conf = "# mdadm.conf written out by anaconda\n"
         conf += "MAILADDR root\n"
         devices = self.mountpoints.values() + self.swapDevices
diff --git a/storage/devices.py b/storage/devices.py
index fa34d91..756b9b2 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -2112,12 +2112,12 @@ class LVMLogicalVolumeDevice(DMDevice):
 class MDRaidArrayDevice(StorageDevice):
     """ An mdraid (Linux RAID) device.
 
-        Since this is derived from StorageDevice, not PartitionDevice, it
-        can be used to represent a partitionable device.
+        Since this is derived from StorageDevice, not DiskDevice, it
+        can NOT be used to represent a partitionable device.
     """
     _type = "mdarray"
 
-    def __init__(self, name, level=None, minor=None, size=None,
+    def __init__(self, name, level=None, major=None, minor=None, size=None,
                  memberDevices=None, totalDevices=None, bitmap=False,
                  uuid=None, format=None, exists=None,
                  parents=None, sysfsPath=''):
@@ -2140,7 +2140,7 @@ class MDRaidArrayDevice(StorageDevice):
                 exists -- indicates whether this is an existing device
         """
         StorageDevice.__init__(self, name, format=format, exists=exists,
-                               minor=minor, size=size,
+                               major=major, minor=minor, size=size,
                                parents=parents, sysfsPath=sysfsPath)
 
         self.level = level
@@ -2156,6 +2156,10 @@ class MDRaidArrayDevice(StorageDevice):
         self.chunkSize = 64.0 / 1024.0          # chunk size in MB
         self.superBlockSize = 128.0 / 1024.0    # superblock size in MB
 
+        # For container members probe size now, as we cannot determine it
+        # when teared down.
+        if self.parents and self.parents[0].type == "mdcontainer":
+            self._size = self.currentSize
 
         # FIXME: Bitmap is more complicated than this.
         # It can be internal or external. External requires a filename.
@@ -2184,6 +2188,11 @@ class MDRaidArrayDevice(StorageDevice):
         if not self.devices:
             return 0
 
+        # For container members return probed size, as we cannot determine it
+        # when teared down.
+        if self.devices[0].type == "mdcontainer":
+            return self._size
+
         size = 0
         smallestMemberSize = self.smallestMember.size - self.superBlockSize
         if not self.exists or not self.partedDevice:
@@ -2345,6 +2354,8 @@ class MDRaidArrayDevice(StorageDevice):
         udev_settle(timeout=10)
         try:
             mdraid.mdadd(device.path, len(self.devices) < self.memberDevices)
+            # mdadd causes udev events
+            udev_settle(timeout=10)
         except MDRaidError as e:
             log.warning("failed to add member %s to md array %s: %s"
                         % (device.path, self.path, e))
@@ -2387,7 +2398,10 @@ class MDRaidArrayDevice(StorageDevice):
         if os.access(state_file, os.R_OK):
             state = open(state_file).read().strip()
             log.debug("%s state is %s" % (self.name, state))
-            if state in ("clean", "active", "active-idle"):
+            if state in ("clean", "active", "active-idle", "readonly", "read-auto"):
+                status = True
+            # mdcontainers have state inactive when started (clear if stopped)
+            if self._type == "mdcontainer" and state == "inactive":
                 status = True
 
         return status
@@ -2502,6 +2516,23 @@ class MDRaidArrayDevice(StorageDevice):
         self.exists = False
 
 
+class PartitionableMDRaidArrayDevice(MDRaidArrayDevice, DiskDevice):
+    """ A partitionable mdraid (Linux RAID) device.
+
+        Since this is derived from DiskDevice, not StorageDevice, it
+        can be used to represent a partitionable device.
+    """
+    _type = "partitionable mdarray"
+
+    @property
+    def mediaPresent(self):
+        # Even if stopped/deactivated we still want to show up in storage.disks
+        return True
+
+    @property
+    def model(self):
+        return "RAID%d Array" % self.level
+
 class DMRaidArrayDevice(DiskDevice):
     """ A dmraid (device-mapper RAID) device """
     _type = "dm-raid array"
diff --git a/storage/devicetree.py b/storage/devicetree.py
index 3a832f4..afbe475 100644
--- a/storage/devicetree.py
+++ b/storage/devicetree.py
@@ -1154,6 +1154,15 @@ class DeviceTree(object):
             kwargs["nic"]        = udev_device_get_fcoe_nic(info)
             kwargs["identifier"] = udev_device_get_fcoe_identifier(info)
             log.debug("%s is an fcoe disk" % name)
+        elif udev_device_get_md_container(info):
+            diskType = PartitionableMDRaidArrayDevice
+            parentName = devicePathToName(udev_device_get_md_container(info))
+            kwargs["parents"] = [ self.getDeviceByName(parentName) ]
+            kwargs["level"]  = udev_device_get_md_level(info)
+            kwargs["memberDevices"] = int(udev_device_get_md_devices(info))
+            # This needs bug #523314 fixed
+            kwargs["uuid"] = udev_device_get_md_uuid(info)
+            kwargs["exists"]  = True
         else:
             diskType = DiskDevice
             log.debug("%s is a disk" % name)
@@ -1259,9 +1268,7 @@ class DeviceTree(object):
         # Now, if the device is a disk, see if there is a usable disklabel.
         # If not, see if the user would like to create one.
         # XXX this is the bit that forces disklabels on disks. Lame.
-        if isinstance(device, DiskDevice) or \
-           isinstance(device, DMRaidArrayDevice) or \
-           isinstance(device, MultipathDevice):
+        if isinstance(device, DiskDevice):
             self.handleUdevDiskLabelFormat(info, device)
             return
 
@@ -1918,7 +1925,7 @@ class DeviceTree(object):
         for device in self.leaves:
             try:
                 device.teardown(recursive=True)
-            except (DeviceError, DeviceFormatError, LVMError) as e:
+            except (DeviceError, DeviceFormatError, LVMError, MDRaidError) as e:
                 log.info("teardown of %s failed: %s" % (device.name, e))
 
     def setupAll(self):
diff --git a/storage/udev.py b/storage/udev.py
index bb6310b..6dba824 100644
--- a/storage/udev.py
+++ b/storage/udev.py
@@ -186,6 +186,9 @@ def udev_device_get_md_devices(info):
 def udev_device_get_md_uuid(info):
     return info["MD_UUID"]
 
+def udev_device_get_md_container(info):
+    return info.get("MD_CONTAINER")
+
 def udev_device_get_vg_name(info):
     return info['LVM2_VG_NAME']
 
-- 
1.6.4.2

_______________________________________________
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