Allow LVM output parsing to work for thin volumes
authorHrvoje Ribicic <riba@google.com>
Mon, 9 Feb 2015 17:23:55 +0000 (18:23 +0100)
committerHrvoje Ribicic <riba@google.com>
Mon, 9 Feb 2015 23:36:47 +0000 (00:36 +0100)
This patch modifies the LVM output parsing code to allow for an empty
list of physical devices, as is the case with thin LVM volumes.

Signed-off-by: Hrvoje Ribicic <riba@google.com>
Reviewed-by: Petr Pudlak <pudlak@google.com>

lib/storage/bdev.py
test/py/ganeti.storage.bdev_unittest.py

index 4e21011..1ffef76 100644 (file)
@@ -441,7 +441,15 @@ class LogicalVolume(base.BlockDev):
     """Parse one line of the lvs output used in L{_GetLvInfo}.
 
     """
-    elems = line.strip().rstrip(sep).split(sep)
+    elems = line.strip().split(sep)
+
+    # The previous iteration of code here assumed that LVM might put another
+    # separator to the right of the output. The PV info might be empty for
+    # thin volumes, so stripping off the separators might cut off the last
+    # empty element - do this instead.
+    if len(elems) == 7 and elems[-1] == "":
+      elems.pop()
+
     if len(elems) != 6:
       base.ThrowError("Can't parse LVS output, len(%s) != 6", str(elems))
 
@@ -466,12 +474,12 @@ class LogicalVolume(base.BlockDev):
       base.ThrowError("Can't parse the number of stripes: %s", err)
 
     pv_names = []
-    for pv in pvs.split(","):
-      m = re.match(cls._PARSE_PV_DEV_RE, pv)
-      if not m:
-        base.ThrowError("Can't parse this device list: %s", pvs)
-      pv_names.append(m.group(1))
-    assert len(pv_names) > 0
+    if pvs != "":
+      for pv in pvs.split(","):
+        m = re.match(cls._PARSE_PV_DEV_RE, pv)
+        if not m:
+          base.ThrowError("Can't parse this device list: %s", pvs)
+        pv_names.append(m.group(1))
 
     return (status, major, minor, pe_size, stripes, pv_names)
 
index 819c940..d6ba9f8 100755 (executable)
@@ -219,6 +219,8 @@ class TestLogicalVolume(unittest.TestCase):
       ("-wi-a-", 253, 7, 4096.00, 4, ["/dev/abc"]),
       ("-ri-a-", 253, 4, 4.00, 5, ["/dev/abc", "/dev/def"]),
       ("-wc-ao", 15, 18, 4096.00, 32, ["/dev/abc", "/dev/def", "/dev/ghi0"]),
+      # Physical devices might be missing with thin volumes
+      ("twc-ao", 15, 18, 4096.00, 32, []),
       ]
     for exp in true_out:
       for sep in "#;|":