[rhel5-branch] kickstart option to make mpath0 point to arbitrary LUN (#502768)

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

 



patch created by Masahiro Matsuya (mmatsuya@xxxxxxxxxx), he claims that the change works for him.
I have reviewed Masahiro's patch carefully for not breaking existing stufff but did not do any tests of the new functionality.
The BZ lists three new tests cases for the QA team.
---
 dmraid.py     |    4 +-
 fsset.py      |    8 +++++-
 iutil.py      |   40 +++++++++++++++++++++++++++++++++
 kickstart.py  |   46 ++++++++++++++++++++++++++++++-------
 yuminstall.py |   69 ++++++++++++++++++++++++++++++++++++++-------------------
 5 files changed, 132 insertions(+), 35 deletions(-)

diff --git a/dmraid.py b/dmraid.py
index 4fb7129..ed05341 100644
--- a/dmraid.py
+++ b/dmraid.py
@@ -82,7 +82,7 @@ class DmDriveCache:
             if self.cache.has_key(obj.name):
                 del self.cache[obj.name][obj.name]
                 for k,v in self.cache[obj.name].items():
-                    log.debug("adding %s to isys cache" % (name,))
+                    log.debug("adding %s to isys cache" % (k,))
                     isys.cachedDrives[k] = v
                 log.debug("removing %s from dm cache" % (obj,))
                 del self.cache[obj.name]
@@ -91,7 +91,7 @@ class DmDriveCache:
         oldname = 'mapper/' + obj.name
         if isys.cachedDrives.has_key(oldname):
             dmNameUpdates[obj.name] = newname
-            self.remove(oldname)
+            self.remove(obj.name)
             # XXX why doesn't setting the property work?
             obj.set_name(newname)
             self.add(obj)
diff --git a/fsset.py b/fsset.py
index 771a482..54753a0 100644
--- a/fsset.py
+++ b/fsset.py
@@ -1380,8 +1380,14 @@ class FileSystemSet:
             if entry.mountpoint:
                 # use LABEL if the device has a label except for multipath
                 # devices and LUKS devices, which always use devname
+                ismpath = False
+                for mpdev in self.anaconda.id.diskset.mpList or []:
+                    if not entry.device.getDevice().find(mpdev.get_name()) == -1:
+                        ismpath = True
+                        break
+
                 if entry.getLabel() and \
-                   entry.device.getDevice().find('mpath') == -1 and \
+                   not ismpath and \
                    not entry.device.crypto:
                     device = "LABEL=%s" % (entry.getLabel(),)
                 else:
diff --git a/iutil.py b/iutil.py
index d221d9c..289f5c7 100644
--- a/iutil.py
+++ b/iutil.py
@@ -490,3 +490,43 @@ def inVmware():
     if "VMware" in out:
         return True
     return False
+
+
+def getScsiDeviceByWwpnLunid(wwpn, lunid):
+    found = 0
+    for tgt in os.listdir('/sys/class/fc_transport'):
+        if tgt[:6] != "target":
+            continue
+        dir= '/sys/class/fc_transport/%s' % tgt
+        f = open('%s/port_name' % dir, "r")
+        tgt_wwpn = f.readline()
+        tgt_wwpn = tgt_wwpn.rstrip("\n")
+        if tgt_wwpn.startswith("0x"):
+            tgt_wwpn = tgt_wwpn[2:]
+        tgt_wwpn = tgt_wwpn.upper()
+        f.close()
+        ## check the first match only
+        if tgt_wwpn == wwpn:
+            found = 1
+            break
+
+    if found == 0:
+        return ""
+
+    scsi_hctl="%s:%s" % (tgt[6:], lunid)
+
+    found = 0
+    for tgt in os.listdir('/sys/block'):
+        devf = '/sys/block/%s/device' % tgt
+        if not os.path.exists(devf):
+            continue
+        devf = os.readlink(devf)
+        devf = os.path.basename(devf)
+        if devf == scsi_hctl:
+            found = 1
+            break
+    if found == 0:
+        tgt = ""
+    return tgt
+
+
diff --git a/kickstart.py b/kickstart.py
index 37b4246..deb46d4 100644
--- a/kickstart.py
+++ b/kickstart.py
@@ -133,6 +133,7 @@ class AnacondaKSHandlers(KickstartHandlers):
     def doBootloader (self, args):
         KickstartHandlers.doBootloader(self, args)
         dict = self.ksdata.bootloader
+        self.id.bootloader.updateDriveList()
 
         if dict["location"] == "none":
             location = None
@@ -359,23 +360,50 @@ class AnacondaKSHandlers(KickstartHandlers):
         ds = DiskSet(self.anaconda)
         ds.startMPath()
 
+        from bdevid import bdevid as _bdevid
+        bd = _bdevid()
+        bd.load("scsi")
+
         mpath = self.ksdata.mpaths[-1]
-        log.debug("Searching for mpath '%s'" % (mpath.name,))
         for mp in DiskSet.mpList or []:
+            newname = ""
             it = True
-            for dev in mpath.devices:
-                dev = dev.split('/')[-1]
+            for path in mpath.paths:
+                dev = path.device
+                log.debug("Searching for mpath having '%s' as a member, the scsi id or wwpn:lunid" % (dev,))
                 log.debug("mpath '%s' has members %s" % (mp.name, list(mp.members)))
+                if dev.find(':') != -1:
+                    (wwpn, lunid) = dev.split(':')
+                    if wwpn != "" and lunid != "":
+                        if wwpn.startswith("0x"):
+                            wwpn = wwpn[2:]
+                        wwpn = wwpn.upper()
+                        scsidev = iutil.getScsiDeviceByWwpnLunid(wwpn, lunid)
+                        if scsidev != "":
+                            dev = "/dev/%s" % scsidev
+                            log.debug("'%s' is a member of the multipath device WWPN '%s' LUNID '%s'" % (dev, wwpn, lunid))
                 if not dev in mp.members:
-                    log.debug("mpath '%s' does not have device %s, skipping" \
-                        % (mp.name, dev))
-                    it = False
-            if it:
+                    mpscsiid = bd.probe("/dev/mapper/%s" % mp.name)[0]['unique_id']
+                    if dev != mpscsiid:
+                        log.debug("mpath '%s' does not have device %s, skipping" \
+                            % (mp.name, dev))
+                        it = False
+                    else:
+                        log.debug("Recognized --device=%s as the scsi id of '%s'" % (dev, mp.name))
+                        newname = path.name
+                        break
+                else:
+                    log.debug("Recognized --device=%s as a member of '%s'" % (dev, mp.name))
+                    newname = path.name
+                    break
+            if it and mp.name != newname:
                 log.debug("found mpath '%s', changing name to %s" \
-                    % (mp.name, mpath.name))
-                newname = mpath.name
+                    % (mp.name, newname))
+                mpath.name = mp.name
                 ds.renameMPath(mp, newname)
+                bd.unload("scsi")
                 return
+        bd.unload("scsi")
         ds.startMPath()
 
     def doDmRaid(self, args):
diff --git a/yuminstall.py b/yuminstall.py
index 50e6bb5..df898bf 100644
--- a/yuminstall.py
+++ b/yuminstall.py
@@ -1424,31 +1424,46 @@ class YumBackend(AnacondaBackend):
             if not os.path.isdir(d):
                 os.makedirs(d, mode=0755)
 
+            mpdevlst = []
+            for mpdev in anaconda.id.diskset.mpList or []:
+                mpdevlst.append(mpdev.name)
+
             for entry in anaconda.id.fsset.entries:
                 dev = entry.device.getDevice()
-                if dev.find('mpath') != -1:
-                    # grab just the mpathXXX part of the device name
-                    mpathname = dev.replace('/dev/', '')
-                    mpathname = mpathname.replace('mpath/', '')
-                    mpathname = mpathname.replace('mapper/', '')
-
-                    # we only want 'mpathNNN' where NNN is an int, strip all
-                    # trailing subdivisions of mpathNNN
-                    trail = re.search("(?<=^mpath).*$", mpathname)
-                    if trail is not None:
-                        i = 1
-                        major = None
-
-                        while i <= len(trail.group()):
-                            try:
-                                major = int(trail.group()[0:i])
-                                i += 1
-                            except:
-                                break
-
-                        if major is not None:
-                            mpathname = mpathname.replace(trail.group(), '')
-                            mpathname = "%s%d" % (mpathname, major,)
+                for mpdev in mpdevlst:
+                    # eliminate the major number (ex. mpath0 -> mpath)
+                    pos = 0
+                    while pos < len(mpdev):
+                        if mpdev[pos].isdigit():
+                            mpdev = mpdev[:pos]
+                            break
+                        pos += 1
+                    if dev.find(mpdev) != -1:
+                        # grab just the basename of the device
+                        mpathname = dev.replace('/dev/', '')
+                        mpathname = mpathname.replace('mpath/', '')
+                        mpathname = mpathname.replace('mapper/', '')
+
+                        # In case of mpathNNNpMMM, we only want 'mpathNNN' where 
+                        # NNN is an int, strip all trailing subdivisions of mpathNNN
+                        mpregex = "(?<=^%s).*$" % mpdev
+                        trail = re.search(mpregex, mpathname)
+                        if trail is not None:
+                            i = 1
+                            major = None
+
+                            while i <= len(trail.group()):
+                                try:
+                                    major = int(trail.group()[0:i])
+                                    i += 1
+                                except:
+                                    break
+
+                            if major is not None:
+                                mpathname = mpathname.replace(trail.group(), '')
+                                mpathname = "%s%d" % (mpathname, major,)
+                    else:
+                        continue
 
                     # if we have seen this mpath device, continue
                     if wwids != []:
@@ -1624,6 +1639,14 @@ class YumBackend(AnacondaBackend):
 
                 f.write('}\n\n')
 
+                for (mpathname, id) in wwids:
+                    if(mpathname.find("mpath") == -1):
+                        # this mpath device was renamed 
+                        f.write('\nmultipath {\n')
+                        f.write("        wwid \"%s\"\n" % (id,))
+                        f.write("        alias \"%s\"\n" % (mpathname,)) 
+                        f.write('}\n\n')
+
             f.close()
 
     def checkSupportedUpgrade(self, anaconda):
-- 
1.6.2.5

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux