[blivet:all] Give mdadm format uuids to the outside world (#1155151)

mulhern amulhern at redhat.com
Wed Oct 22 17:43:18 UTC 2014


Resolves: rhbz#1155151

We need our uuids obtained from mdadm to be the canonical format internally,
as we need to compare them to other UUIDs obtained from other sources,
which are in canonical form.

But the outside world needs to see mdadm's own format UUIDs.

Hence, we need a conversion function to convert from canonical UUIDs to
mdadm format UUIDs, and we need to invoke that function in the correct
places.

Signed-off-by: mulhern <amulhern at redhat.com>
---
 blivet/devicelibs/mdraid.py          | 28 ++++++++++++++++++++++++++++
 blivet/devices.py                    | 11 ++++++-----
 tests/devicelibs_test/mdraid_test.py |  6 +++++-
 3 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/blivet/devicelibs/mdraid.py b/blivet/devicelibs/mdraid.py
index f4ed875..29579ae 100644
--- a/blivet/devicelibs/mdraid.py
+++ b/blivet/devicelibs/mdraid.py
@@ -22,6 +22,7 @@
 
 import os
 import re
+import string
 
 from .. import util
 from ..errors import MDRaidError
@@ -360,3 +361,30 @@ def name_from_md_node(node):
 
     log.debug("returning %s", name)
     return name
+
+def mduuid_from_canonical(a_uuid):
+    """ Change a canonicalized uuid to mdadm's preferred format.
+
+        :param str a_uuid: a string representing a UUID.
+
+        :returns: a UUID in mdadm's preferred format
+        :rtype: str
+
+        mdadm's UUIDs are actual 128 bit uuids, but it formats them strangely.
+        This converts a uuid from canonical form to mdadm's form.
+        Example:
+            mdadm UUID: '3386ff85:f5012621:4a435f06:1eb47236'
+        canonical UUID: '3386ff85-f501-2621-4a43-5f061eb47236'
+    """
+    NUM_DIGITS = 32
+    a_uuid = a_uuid.replace('-', '')
+
+    if len(a_uuid) != NUM_DIGITS:
+        raise MDRaidError("Missing digits in stripped UUID %s." % a_uuid)
+
+    if any(c not in string.hexdigits for c in a_uuid):
+        raise MDRaidError("Non-hex digits in stripped UUID %s." % a_uuid)
+
+    CHUNK_LEN = 8
+
+    return ":".join([a_uuid[n:n+CHUNK_LEN] for n in range(0, NUM_DIGITS, CHUNK_LEN)])
diff --git a/blivet/devices.py b/blivet/devices.py
index 59a3879..0cf47db 100644
--- a/blivet/devices.py
+++ b/blivet/devices.py
@@ -3829,8 +3829,9 @@ class MDRaidArrayDevice(ContainerDevice):
         if self.exists and self.uuid and not flags.testing:
             # this is a hack to work around mdadm's insistence on giving
             # really high minors to arrays it has no config entry for
+            external_uuid = mdraid.mduuid_from_canonical(self.uuid)
             open("/etc/mdadm.conf", "a").write("ARRAY %s UUID=%s\n"
-                                                % (self.path, self.uuid))
+                                                % (self.path, external_uuid))
 
     def _verifyMemberFormat(self, member):
         if member.type == "mdcontainer":
@@ -3946,10 +3947,10 @@ class MDRaidArrayDevice(ContainerDevice):
         # containers and the sets within must only have a UUID= parameter
         if self.type == "mdcontainer" or self.type == "mdbiosraidarray":
             fmt = "ARRAY %s UUID=%s\n"
-            return fmt % (self.path, self.uuid)
+            return fmt % (self.path, mdraid.mduuid_from_canonical(self.uuid))
 
         fmt = "ARRAY %s level=%s num-devices=%d UUID=%s\n"
-        return fmt % (self.path, self.level, self.memberDevices, self.uuid)
+        return fmt % (self.path, self.level, self.memberDevices, mdraid.mduuid_from_canonical(self.uuid))
 
     @property
     def totalDevices(self):
@@ -4161,7 +4162,7 @@ class MDRaidArrayDevice(ContainerDevice):
 
         mdraid.mdactivate(self.path,
                           members=disks,
-                          array_uuid=self.uuid)
+                          array_uuid=mdraid.mduuid_from_canonical(self.uuid))
 
     def _postTeardown(self, recursive=False):
         super(MDRaidArrayDevice, self)._postTeardown(recursive=recursive)
@@ -4286,7 +4287,7 @@ class MDRaidArrayDevice(ContainerDevice):
         return self.type == "mdbiosraidarray"
 
     def dracutSetupArgs(self):
-        return set(["rd.md.uuid=%s" % self.uuid])
+        return set(["rd.md.uuid=%s" % mdraid.mduuid_from_canonical(self.uuid)])
 
     def populateKSData(self, data):
         if self.isDisk:
diff --git a/tests/devicelibs_test/mdraid_test.py b/tests/devicelibs_test/mdraid_test.py
index e6fdf55..768baed 100755
--- a/tests/devicelibs_test/mdraid_test.py
+++ b/tests/devicelibs_test/mdraid_test.py
@@ -48,6 +48,10 @@ class MDRaidTestCase(unittest.TestCase):
                                                          version="version"),
                          mdraid.MD_SUPERBLOCK_SIZE)
 
+    def testMisc(self):
+        """ Miscellaneous testing. """
+        self.assertEqual(mdraid.mduuid_from_canonical('3386ff85-f501-2621-4a43-5f061eb47236'), '3386ff85:f5012621:4a435f06:1eb47236')
+
 class MDRaidAsRootTestCase(loopbackedtestcase.LoopBackedTestCase):
 
     def __init__(self, methodName='runTest', deviceSpec=None):
@@ -184,7 +188,7 @@ class SimpleRaidTest(MDRaidAsRootTestCase):
         with self.assertRaises(MDRaidError):
             mdraid.mdactivate("/dev/md1")
 
-        self.assertIsNone(mdraid.mdactivate(self._dev_name, array_uuid=info_pre['UUID']))
+        self.assertIsNone(mdraid.mdactivate(self._dev_name, array_uuid=mdraid.mduuid_from_canonical(info_pre['UUID'])))
         time.sleep(2)
         info_post = mdraid.mddetail(self._dev_name)
 
-- 
1.9.3



More information about the anaconda-patches mailing list