[blivet 07/13] Change MDRaidArrayDevice to use raid package.

mulhern amulhern at redhat.com
Tue Nov 26 18:47:12 UTC 2013


The basic change is that the only call to a function in the mdraid
package is the call to mdraid.getRaidLevel which sets the level field.

After that, all calls are method calls on the level field, so the definitions
of the methods are in the raid package.

Most of the changes did not change the external behavior of the class.

Significant changes are:
* The definition of level was changed.
* rawArraySize now does the same as size and just returns 0 if there
are no member devices.
* Instead of logging an error if the level is container, now rawArraySize
throws an exception, because the definition of the method in the MDCONTAINER
class throws an exception.
* size raises an exception if the level is container, previously it would
have returned 0.
* description is removed. It does not appear to be used by either of our
downstream clients.

Several tests had to be updated, mostly due to the change in the definition
of the level property.
---
 blivet/devices.py     | 113 +++++++++++++++-----------------------------------
 tests/devices_test.py |  69 +++++++++++++-----------------
 2 files changed, 62 insertions(+), 120 deletions(-)

diff --git a/blivet/devices.py b/blivet/devices.py
index b8503fe..be4374c 100644
--- a/blivet/devices.py
+++ b/blivet/devices.py
@@ -2983,14 +2983,13 @@ class MDRaidArrayDevice(StorageDevice):
         self.level = level
 
         # For new arrays check if we have enough members
-        if (not exists and parents and
-                len(parents) < mdraid.get_raid_min_members(self.level)):
+        if (not exists and parents and len(parents) < self.level.min_members):
             for dev in self.parents:
                 dev.removeChild()
-            raise DeviceError, P_("A RAID%(raidLevel)d set requires at least %(minMembers)d member",
-                                 "A RAID%(raidLevel)d set requires at least %(minMembers)d members",
-                                 mdraid.get_raid_min_members(self.level)) % \
-                                 {"raidLevel": self.level, "minMembers": mdraid.get_raid_min_members(self.level)}
+            raise DeviceError, P_("A %(raidLevel)s set requires at least %(minMembers)d member",
+                                 "A %(raidLevel)s set requires at least %(minMembers)d members",
+                                 self.level.min_members) % \
+                                 {"raidLevel": self.level, "minMembers": self.level.min_members}
 
         self.uuid = uuid
         self._totalDevices = util.numeric_type(totalDevices)
@@ -3026,7 +3025,7 @@ class MDRaidArrayDevice(StorageDevice):
         """ Return the raid level
 
             :returns: raid level value
-            :rtype:   an int representing a raid level or "container"
+            :rtype:   an object that represents a RAID level
         """
         return self._level
 
@@ -3035,18 +3034,15 @@ class MDRaidArrayDevice(StorageDevice):
         """ Set the RAID level and enforce restrictions based on it.
 
             :param value: new raid level
-            :param type:  a valid raid level int or "container"
+            :param type:  a valid raid level descriptor
             :returns:     None
 
             Sets createBitmap True unless level is 0
         """
-        if value != "container":
-            self._level = mdraid.raidLevel(value)
-        else:
-            self._level = value
+        self._level = mdraid.getRaidLevel(value)
 
         # bitmaps are not meaningful on raid0 according to mdadm-3.0.3
-        self.createBitmap = self._level != 0
+        self.createBitmap = self._level.name != "raid0"
 
     @property
     def rawArraySize(self):
@@ -3057,30 +3053,17 @@ class MDRaidArrayDevice(StorageDevice):
         metadata.
 
         Returns the raw size in MB
+
+        Raises an MDRaidError if this operation is not meaningful for the
+        raid level.
         """
         smallestMember = self.smallestMember
         if smallestMember is None:
-            log.debug("device has no members, size is 0")
-            smallestMemberSize = 0
-        else:
-            smallestMemberSize = smallestMember.size
-
-        if self.level == mdraid.RAID0:
-            size = self.memberDevices * smallestMemberSize
-        elif self.level == mdraid.RAID1:
-            size = smallestMemberSize
-        elif self.level == mdraid.RAID4:
-            size = (self.memberDevices - 1) * smallestMemberSize
-        elif self.level == mdraid.RAID5:
-            size = (self.memberDevices - 1) * smallestMemberSize
-        elif self.level == mdraid.RAID6:
-            size = (self.memberDevices - 2) * smallestMemberSize
-        elif self.level == mdraid.RAID10:
-            size = (self.memberDevices / 2) * smallestMemberSize
-        else:
-            size = smallestMemberSize
-            log.error("unknown RAID level %s" % (self.level))
+            return 0
 
+        smallestMemberSize = smallestMember.size
+        size = self.level.get_raw_array_size(self.memberDevices,
+           smallestMemberSize)
         log.debug("raw RAID %s size == %s" % (self.level, size))
         return size
 
@@ -3098,7 +3081,14 @@ class MDRaidArrayDevice(StorageDevice):
 
     @property
     def size(self):
-        if not self.devices:
+        """Returns the actual or estimated size depending on whether or
+           not the array exists.
+
+           Raises an MDRaidError if this operation is not defined for the
+           level.
+        """
+        smallestMember = self.smallestMember
+        if smallestMember is None:
             return 0
 
         # For container members return probed size, as we cannot determine it
@@ -3106,26 +3096,11 @@ class MDRaidArrayDevice(StorageDevice):
         if self.type == "mdbiosraidarray":
             return self._size
 
-        size = 0
         smallestMemberSize = self.smallestMember.size - self.superBlockSize
         if not self.exists or not self.partedDevice:
-            if self.level == mdraid.RAID0:
-                size = self.memberDevices * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID1:
-                size = smallestMemberSize
-            elif self.level == mdraid.RAID4:
-                size = (self.memberDevices - 1) * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID5:
-                size = (self.memberDevices - 1) * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID6:
-                size = (self.memberDevices - 2) * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID10:
-                size = (self.memberDevices / 2) * smallestMemberSize
-                size -= size % self.chunkSize
+            size = self.level.get_size(self.memberDevices,
+                smallestMemberSize,
+                self.chunkSize)
             log.debug("non-existent RAID %s size == %s" % (self.level, size))
         else:
             size = self.partedDevice.getSize()
@@ -3133,22 +3108,6 @@ class MDRaidArrayDevice(StorageDevice):
 
         return size
 
-    @property
-    def description(self):
-        if self.level == mdraid.RAID0:
-            levelstr = "stripe"
-        elif self.level == mdraid.RAID1:
-            levelstr = "mirror"
-        else:
-            levelstr = "raid%s" % self.level
-
-        if self.type == "mdcontainer":
-            return "BIOS RAID container"
-        elif self.type == "mdbiosraidarray":
-            return "BIOS RAID set (%s)" % levelstr
-        else:
-            return "MDRAID set (%s)" % levelstr
-
     def __repr__(self):
         s = StorageDevice.__repr__(self)
         s += ("  level = %(level)s  spares = %(spares)s\n"
@@ -3173,7 +3132,7 @@ class MDRaidArrayDevice(StorageDevice):
     @property
     def mdadmConfEntry(self):
         """ This array's mdadm.conf entry. """
-        if self.level is None or self.memberDevices is None or not self.uuid:
+        if self.memberDevices is None or not self.uuid:
             raise DeviceError("array is not fully defined", self.name)
 
         # containers and the sets within must only have a UUID= parameter
@@ -3181,7 +3140,7 @@ class MDRaidArrayDevice(StorageDevice):
             fmt = "ARRAY %s UUID=%s\n"
             return fmt % (self.path, self.uuid)
 
-        fmt = "ARRAY %s level=raid%d num-devices=%d UUID=%s\n"
+        fmt = "ARRAY %s level=%s num-devices=%d UUID=%s\n"
         return fmt % (self.path, self.level, self.memberDevices, self.uuid)
 
     @property
@@ -3465,15 +3424,9 @@ class MDRaidArrayDevice(StorageDevice):
     def formatArgs(self):
         formatArgs = []
         if self.format.type == "ext2":
-            if self.level == mdraid.RAID5:
-                formatArgs = ['-R',
-                              'stride=%d' % ((self.memberDevices - 1) * 16)]
-            if self.level == mdraid.RAID4:
-                formatArgs = ['-R',
-                              'stride=%d' % ((self.memberDevices - 1) * 16)]
-            elif self.level == mdraid.RAID0:
-                formatArgs = ['-R',
-                              'stride=%d' % (self.memberDevices * 16)]
+            recommended_stride = self.level.get_recommended_stride(self.memberDevices)
+            if recommended_stride:
+                formatArgs = ['-R', 'stride=%d' % recommended_stride ]
         return formatArgs
 
     @property
@@ -3510,7 +3463,7 @@ class MDRaidArrayDevice(StorageDevice):
             return
 
         super(MDRaidArrayDevice, self).populateKSData(data)
-        data.level = self.level
+        data.level = self.level.name
         data.spares = self.spares
         data.members = ["raid.%d" % p.id for p in self.parents]
         data.preexist = self.exists
diff --git a/tests/devices_test.py b/tests/devices_test.py
index d86d7b9..8f342e1 100644
--- a/tests/devices_test.py
+++ b/tests/devices_test.py
@@ -34,7 +34,6 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
         state_functions = {
            "createBitmap" : lambda x,m: self.assertTrue(x, m),
            "currentSize" : lambda x, m: self.assertEqual(x, 0, m),
-           "description" : lambda x, m: self.assertEqual(x, "MDRAID set (unknown level)", m),
            "devices" : lambda x, m: self.assertEqual(x, [], m),
            "exists" : self.assertFalse,
            "format" : self.assertIsNotNone,
@@ -84,9 +83,11 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
         self.dev9 = MDRaidArrayDevice(
            "dev9",
            level="raid0",
+           memberDevices=2,
            parents=[
               MDRaidArrayDevice("parent", level="container"),
-              MDRaidArrayDevice("other", level=0)])
+              MDRaidArrayDevice("other", level=0)],
+           totalDevices=2)
 
         self.dev10 = MDRaidArrayDevice(
            "dev10",
@@ -96,10 +97,12 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
         self.dev11 = MDRaidArrayDevice(
            "dev11",
            level=1,
+           memberDevices=2,
            parents=[
               MDRaidArrayDevice("parent", level="container"),
               MDRaidArrayDevice("other", level="raid0")],
-           size=32)
+           size=32,
+           totalDevices=2)
 
         self.dev12 = MDRaidArrayDevice(
            "dev12",
@@ -186,36 +189,28 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
         ## level tests
         ##
         self.stateCheck(self.dev1,
-                        description=lambda x, m: self.assertEqual(x, "BIOS RAID container", m),
-                        level=lambda x, m: self.assertEqual(x, "container", m),
+                        level=lambda x, m: self.assertEqual(x.name, "container", m),
                         type=lambda x, m: self.assertEqual(x, "mdcontainer", m))
         self.stateCheck(self.dev2,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (stripe)", m),
                         createBitmap=self.assertFalse,
-                        level=lambda x, m: self.assertEqual(x, 0, m))
+                        level=lambda x, m: self.assertEqual(x.number, 0, m))
         self.stateCheck(self.dev3,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (mirror)", m),
-                        level=lambda x, m: self.assertEqual(x, 1, m))
+                        level=lambda x, m: self.assertEqual(x.number, 1, m))
         self.stateCheck(self.dev4,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid4)", m),
-                        level=lambda x, m: self.assertEqual(x, 4, m))
+                        level=lambda x, m: self.assertEqual(x.number, 4, m))
         self.stateCheck(self.dev5,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid5)", m),
-                        level=lambda x, m: self.assertEqual(x, 5, m))
+                        level=lambda x, m: self.assertEqual(x.number, 5, m))
         self.stateCheck(self.dev6,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid6)", m),
-                        level=lambda x, m: self.assertEqual(x, 6, m))
+                        level=lambda x, m: self.assertEqual(x.number, 6, m))
         self.stateCheck(self.dev7,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid10)", m),
-                        level=lambda x, m: self.assertEqual(x, 10, m))
+                        level=lambda x, m: self.assertEqual(x.number, 10, m))
 
         ##
         ## existing device tests
         ##
         self.stateCheck(self.dev8,
-                        description = lambda x, m: self.assertEqual(x, "MDRAID set (mirror)", m),
                         exists=self.assertTrue,
-                        level=lambda x, m: self.assertEqual(x, 1, m),
+                        level=lambda x, m: self.assertEqual(x.number, 1, m),
                         metadataVersion=self.assertIsNone)
 
 
@@ -224,14 +219,15 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
         ##
         self.stateCheck(self.dev9,
                         createBitmap=self.assertFalse,
-                        description=lambda x, m: self.assertEqual(x, "BIOS RAID set (stripe)", m),
                         devices=lambda x, m: self.assertEqual(len(x), 2, m),
                         isDisk=self.assertTrue,
-                        level=lambda x, m: self.assertEqual(x, 0, m),
+                        level=lambda x, m: self.assertEqual(x.number, 0, m),
                         mediaPresent=self.assertTrue,
+                        memberDevices=lambda x, m: self.assertEqual(x, 2, m),
                         parents=lambda x, m: self.assertNotEqual(x, [], m),
                         partitionable=self.assertTrue,
                         smallestMember=self.assertIsNotNone,
+                        totalDevices=lambda x, m: self.assertEqual(x, 2, m),
                         type = lambda x, m: self.assertEqual(x, "mdbiosraidarray", m))
 
         ##
@@ -239,28 +235,27 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
         ##
         self.stateCheck(self.dev10,
                         createBitmap=self.assertFalse,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (stripe)", m),
-                        level=lambda x, m: self.assertEqual(x, 0, m))
+                        level=lambda x, m: self.assertEqual(x.number, 0, m))
 
         self.stateCheck(self.dev11,
-                        description=lambda x, m: self.assertEqual(x, "BIOS RAID set (mirror)", m),
                         devices=lambda x, m: self.assertEqual(len(x), 2, m),
                         isDisk=self.assertTrue,
-                        level=lambda x, m: self.assertEqual(x, 1, m),
+                        level=lambda x, m: self.assertEqual(x.number, 1, m),
                         mediaPresent=self.assertTrue,
+                        memberDevices=lambda x, m: self.assertEqual(x, 2, m),
                         parents=lambda x, m: self.assertNotEqual(x, [], m),
                         partitionable=self.assertTrue,
                         smallestMember=self.assertIsNotNone,
+                        totalDevices=lambda x, m: self.assertEqual(x, 2, m),
                         type=lambda x, m: self.assertEqual(x, "mdbiosraidarray", m))
 
         ##
         ## rawArraySize tests
         ##
         self.stateCheck(self.dev12,
-                        description=lambda x, m: self.assertEqual(x, "BIOS RAID set (mirror)", m),
                         devices=lambda x, m: self.assertEqual(len(x), 2, m),
                         isDisk=self.assertTrue,
-                        level=lambda x, m: self.assertEqual(x, 1, m),
+                        level=lambda x, m: self.assertEqual(x.number, 1, m),
                         mediaPresent=self.assertTrue,
                         memberDevices=lambda x, m: self.assertEqual(x, 2, m),
                         parents=lambda x, m: self.assertNotEqual(x, [], m),
@@ -272,9 +267,8 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
 
         self.stateCheck(self.dev13,
                         createBitmap=self.assertFalse,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (stripe)", m),
                         devices=lambda x, m: self.assertEqual(len(x), 2, m),
-                        level=lambda x, m: self.assertEqual(x, 0, m),
+                        level=lambda x, m: self.assertEqual(x.number, 0, m),
                         memberDevices=lambda x, m: self.assertEqual(x, 3, m),
                         parents=lambda x, m: self.assertNotEqual(x, [], m),
                         rawArraySize=lambda x, m: self.assertEqual(x, 6, m),
@@ -283,9 +277,8 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
                         totalDevices=lambda x, m: self.assertEqual(x, 3, m))
 
         self.stateCheck(self.dev14,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid4)", m),
                         devices=lambda x, m: self.assertEqual(len(x), 3, m),
-                        level=lambda x, m: self.assertEqual(x, 4, m),
+                        level=lambda x, m: self.assertEqual(x.number, 4, m),
                         memberDevices=lambda x, m: self.assertEqual(x, 3, m),
                         parents=lambda x, m: self.assertNotEqual(x, [], m),
                         rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
@@ -294,9 +287,8 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
                         totalDevices=lambda x, m: self.assertEqual(x, 3, m))
 
         self.stateCheck(self.dev15,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid5)", m),
                         devices=lambda x, m: self.assertEqual(len(x), 3, m),
-                        level=lambda x, m: self.assertEqual(x, 5, m),
+                        level=lambda x, m: self.assertEqual(x.number, 5, m),
                         memberDevices=lambda x, m: self.assertEqual(x, 3, m),
                         parents=lambda x, m: self.assertNotEqual(x, [], m),
                         rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
@@ -305,9 +297,8 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
                         totalDevices=lambda x, m: self.assertEqual(x, 3, m))
 
         self.stateCheck(self.dev16,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid6)", m),
                         devices=lambda x, m: self.assertEqual(len(x), 4, m),
-                        level=lambda x, m: self.assertEqual(x, 6, m),
+                        level=lambda x, m: self.assertEqual(x.number, 6, m),
                         memberDevices=lambda x, m: self.assertEqual(x, 4, m),
                         parents=lambda x, m: self.assertNotEqual(x, [], m),
                         rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
@@ -316,9 +307,8 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
                         totalDevices=lambda x, m: self.assertEqual(x, 4, m))
 
         self.stateCheck(self.dev17,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid10)", m),
                         devices=lambda x, m: self.assertEqual(len(x), 4, m),
-                        level=lambda x, m: self.assertEqual(x, 10, m),
+                        level=lambda x, m: self.assertEqual(x.number, 10, m),
                         memberDevices=lambda x, m: self.assertEqual(x, 4, m),
                         parents=lambda x, m: self.assertNotEqual(x, [], m),
                         rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
@@ -327,9 +317,8 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
                         totalDevices=lambda x, m: self.assertEqual(x, 4, m))
 
         self.stateCheck(self.dev18,
-                        description=lambda x, m: self.assertEqual(x, "MDRAID set (raid10)", m),
                         devices=lambda x, m: self.assertEqual(len(x), 4, m),
-                        level=lambda x, m: self.assertEqual(x, 10, m),
+                        level=lambda x, m: self.assertEqual(x.number, 10, m),
                         memberDevices=lambda x, m: self.assertEqual(x, 4, m),
                         parents=lambda x, m: self.assertNotEqual(x, [], m),
                         rawArraySize=lambda x, m: self.assertEqual(x, 4, m),
@@ -356,7 +345,7 @@ class MDRaidArrayDeviceTestCase(unittest.TestCase):
                                 parents=[Device("parent")])
 
         self.assertRaisesRegexp(DeviceError,
-                                "A RAID0 set requires at least 2 members",
+                                "set requires at least 2 members",
                                 MDRaidArrayDevice,
                                 "dev",
                                 level="raid0",
-- 
1.8.3.1



More information about the anaconda-patches mailing list