[blivet:master 09/11] Canonicalize mdadm generated UUIDS (#1070095)

mulhern amulhern at redhat.com
Thu Jul 3 15:19:48 UTC 2014


Related: rhbz#1070095

Examined alternatives are:
1) To make use of the uuid.UUID class to store uuids. The difficulty
with this idea is that some things that are labeled uuids are not proper
uuids at all.
2) To make the udev_info dict more object oriented, and have it sanitize
uuids when they are added. A lot of work for very limited benefit.
3) To canonicalize uuids everytime they are extracted from the info.
Brittle, since you can't stop code from accessing the entries directly,
and annoyingly inefficient.

This alternative is pretty simple, and to a certain extent it's a
workaround for a bug in mdadm, so it wins.

Signed-off-by: mulhern <amulhern at redhat.com>
---
 blivet/devicelibs/mdraid.py          | 9 +++++++++
 tests/devicelibs_test/mdraid_test.py | 6 ++++++
 2 files changed, 15 insertions(+)

diff --git a/blivet/devicelibs/mdraid.py b/blivet/devicelibs/mdraid.py
index f46571a..31e5b80 100644
--- a/blivet/devicelibs/mdraid.py
+++ b/blivet/devicelibs/mdraid.py
@@ -242,6 +242,15 @@ def mdexamine(device):
             if name == "metadata":
                 info["MD_METADATA"] = value
 
+    # mdadm's UUIDs are actual 128 bit uuids, but it formats them strangely.
+    # This converts the uuids to canonical form.
+    # Example:
+    #     mdadm UUID: '3386ff85:f5012621:4a435f06:1eb47236'
+    # canonical UUID: '3386ff85-f501-2621-4a43-5f061eb47236'
+    import uuid
+    for k, v in ((k,v) for (k,v) in info.iteritems() if k.endswith("UUID")):
+        info[k] = str(uuid.UUID(v.replace(':', '')))
+
     return info
 
 def md_node_from_name(name):
diff --git a/tests/devicelibs_test/mdraid_test.py b/tests/devicelibs_test/mdraid_test.py
index 760643f..4f2e6d8 100755
--- a/tests/devicelibs_test/mdraid_test.py
+++ b/tests/devicelibs_test/mdraid_test.py
@@ -1,6 +1,7 @@
 #!/usr/bin/python
 import unittest
 import time
+import uuid
 
 import blivet.devicelibs.raid as raid
 import blivet.devicelibs.mdraid as mdraid
@@ -119,6 +120,7 @@ class MDRaidAsRootTestCase(loopbackedtestcase.LoopBackedTestCase):
             Verifies that:
               - exactly the predicted names are returned by mdexamine
               - RAID level and number of devices are correct
+              - UUIDs have canonical form
         """
         level = mdraid.RAID_levels.raidLevel(level or raid.RAID1)
         mdraid.mdcreate(self._dev_name, level, self.loopDevices, metadataVer=metadataVersion)
@@ -138,6 +140,10 @@ class MDRaidAsRootTestCase(loopbackedtestcase.LoopBackedTestCase):
         self.assertEqual(info['MD_DEVICES'], '2')
         self.assertEqual(info['MD_LEVEL'], str(level))
 
+        # verify that uuids are in canonical form
+        for name in (k for k in iter(info.keys()) if k.endswith('UUID')):
+            self.assertTrue(str(uuid.UUID(info[name])) == info[name])
+
     def testMDExamineContainerDefault(self):
         self._testMDExamine(self.names_container, level="container")
 
-- 
1.9.3



More information about the anaconda-patches mailing list