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

[rhel6-branch 3/4] mpath: use both 'multipath -d' and 'multipath -ll' to get the topology.



Related: rhbz#636570
---
 storage/devicelibs/mpath.py |   77 ++++++++++++++++++++++++++-----------------
 1 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/storage/devicelibs/mpath.py b/storage/devicelibs/mpath.py
index 4909314..0d0efde 100644
--- a/storage/devicelibs/mpath.py
+++ b/storage/devicelibs/mpath.py
@@ -8,32 +8,44 @@ import logging
 log = logging.getLogger("storage")
 
 def parseMultipathOutput(output):
-    # this function parses output from "multipath -d", so we can use its
-    # logic for our topology.
-    # The input looks like:
-    # create: mpathc (1ATA     ST3120026AS                                         5M) undef ATA,ST3120026AS
-    # size=112G features='0' hwhandler='0' wp=undef
-    # `-+- policy='round-robin 0' prio=1 status=undef
-    #   `- 2:0:0:0 sda 8:0  undef ready running
-    # create: mpathb (36006016092d21800703762872c60db11) undef DGC,RAID 5
-    # size=10G features='1 queue_if_no_path' hwhandler='1 emc' wp=undef
-    # `-+- policy='round-robin 0' prio=2 status=undef
-    #   |- 6:0:0:0 sdb 8:16 undef ready running
-    #   `- 7:0:0:0 sdc 8:32 undef ready running
-    # create: mpatha (36001438005deb4710000500000270000) dm-0 HP,HSV400
-    # size=20G features='0' hwhandler='0' wp=rw
-    # |-+- policy='round-robin 0' prio=-1 status=active
-    # | |- 7:0:0:1 sda 8:0  active undef running
-    # | `- 7:0:1:1 sdb 8:16 active undef running
-    # `-+- policy='round-robin 0' prio=-1 status=enabled
-    #   |- 7:0:2:1 sdc 8:32 active undef running
-    #   `- 7:0:3:1 sdd 8:48 active undef running
-    #
-    # (In anaconda, the first one there won't be included because we blacklist
-    # "ATA" as a vendor.)
-    #
-    # It returns a structure like:
-    # [ {'mpatha':['sdb','sdc']}, ... ]
+    """
+    Parse output from "multipath -d" or "multipath -ll" and form a topology.
+
+    Returns a dictionary:
+    {'mpatha':['sdb','sdc'], 'mpathb': ['sdd', 'sde'], ... }
+
+    The 'multipath -d' output looks like:
+    create: mpathc (1ATA     ST3120026AS                                         5M) undef ATA,ST3120026AS
+    size=112G features='0' hwhandler='0' wp=undef
+    `-+- policy='round-robin 0' prio=1 status=undef
+    `- 2:0:0:0 sda 8:0  undef ready running
+    create: mpathb (36006016092d21800703762872c60db11) undef DGC,RAID 5
+    size=10G features='1 queue_if_no_path' hwhandler='1 emc' wp=undef
+    `-+- policy='round-robin 0' prio=2 status=undef
+    |- 6:0:0:0 sdb 8:16 undef ready running
+    `- 7:0:0:0 sdc 8:32 undef ready running
+    create: mpatha (36001438005deb4710000500000270000) dm-0 HP,HSV400
+    size=20G features='0' hwhandler='0' wp=rw
+    |-+- policy='round-robin 0' prio=-1 status=active
+    | |- 7:0:0:1 sda 8:0  active undef running
+    | `- 7:0:1:1 sdb 8:16 active undef running
+    `-+- policy='round-robin 0' prio=-1 status=enabled
+    |- 7:0:2:1 sdc 8:32 active undef running
+    `- 7:0:3:1 sdd 8:48 active undef running
+
+    (In anaconda, the first one there won't be included because we blacklist
+    "ATA" as a vendor.)
+
+    The 'multipath -ll' output looks like (notice the missing 'create' before
+    'mpatha'):
+
+    mpatha (3600a0b800067fcc9000001694b557dd1) dm-0 IBM,1726-4xx  FAStT
+    size=360G features='0' hwhandler='1 rdac' wp=rw
+    `-+- policy='round-robin 0' prio=3 status=active
+      |- 2:0:0:0 sda 8:0  active ready running
+      `- 3:0:0:0 sdb 8:16 active ready running
+
+    """
     mpaths = {}
     if output is None:
         return mpaths
@@ -43,20 +55,22 @@ def parseMultipathOutput(output):
 
     policy = re.compile('^[|+` -]+policy')
     device = re.compile('^[|+` -]+[0-9]+:[0-9]+:[0-9]+:[0-9]+ +([a-zA-Z0-9!/]+)')
+    create = re.compile('^(create: )?(mpath\w+)')
 
     lines = output.split('\n')
     for line in lines:
         pmatch = policy.match(line)
         dmatch = device.match(line)
+        cmatch = create.match(line)
         lexemes = line.split()
         if not lexemes:
             break
-        if lexemes[0] == 'create:':
+        if cmatch and cmatch.group(2):
             if name and devices:
                 mpaths[name] = devices
                 name = None
                 devices = []
-            name = lexemes[1]
+            name = cmatch.group(2)
         elif lexemes[0].startswith('size='):
             pass
         elif pmatch:
@@ -85,7 +99,10 @@ def identifyMultipaths(devices):
         map(lambda line: log.debug(line.rstrip()), conf)
         log.debug("(end of /etc/multipath.conf)")
 
-    topology = parseMultipathOutput(iutil.execWithCapture("multipath", ["-d",]))
+    topology = parseMultipathOutput(
+        iutil.execWithCapture("multipath", ["-d",]))
+    topology.update(parseMultipathOutput(
+            iutil.execWithCapture("multipath", ["-ll",])))
     # find the devices that aren't in topology, and add them into it...
     topodevs = reduce(lambda x,y: x.union(y), topology.values(), set())
     for name in set([d['name'] for d in devices]).difference(topodevs):
@@ -145,7 +162,7 @@ def identifyMultipaths(devices):
                 log.info("adding %s to multipath_disks" % (disk,))
                 d["ID_FS_TYPE"] = "multipath_member"
                 d["ID_MPATH_NAME"] = name
-            
+
             multipaths.append([devmap[d] for d in disks])
 
     non_disk_serials = {}
-- 
1.7.3.3


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