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 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list