[PATCH 3/3] Make multipath support use device-mapper-multipath to setup mpaths.

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

 



Use device-mapper-multipath's "multipath" tool to find and set up
multipath devices.
---
 storage/devicelibs/mpath.py |   75 ++++++++++++++++++++++++++++--------------
 storage/devices.py          |   77 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 114 insertions(+), 38 deletions(-)

diff --git a/storage/devicelibs/mpath.py b/storage/devicelibs/mpath.py
index 4d1b262..247e837 100644
--- a/storage/devicelibs/mpath.py
+++ b/storage/devicelibs/mpath.py
@@ -1,4 +1,5 @@
 from ..udev import *
+import iutil
 
 def parseMultipathOutput(output):
     # this function parses output from "multipath -d", so we can use its
@@ -43,57 +44,81 @@ def identifyMultipaths(devices):
     # [sr0, sda, sdb, sdc, sdd, sde, sde1]
 
     log.info("devices to scan for multipath: %s" % [d['name'] for d in devices])
-    serials = {}
+
+    mpathinfo = iutil.execWithCapture("multipath", ["-d",])
+    if not mpathinfo:
+        return devices
+
+    devmap = {}
     non_disk_devices = {}
     for d in devices:
-        serial = udev_device_get_serial(d)
-        if (not udev_device_is_disk(d)) or \
-                (not d.has_key('ID_SERIAL_SHORT')):
-            non_disk_devices.setdefault(serial, [])
-            non_disk_devices[serial].append(d)
+        if not udev_device_is_disk(d):
+            non_disk_devices[d['name']] = d
             log.info("adding %s to non_disk_device list" % (d['name'],))
             continue
+        devmap[d['name']] = d
 
-        serials.setdefault(serial, [])
-        serials[serial].append(d)
-
+    topology = parseMultipathOutput(mpathinfo)
+    topomap = {}
     singlepath_disks = []
     multipaths = []
-    for serial, disks in serials.items():
+
+    for (name, disks) in topology.items():
+        # we should really never see a disk here that's non in devmap...
+        for disk in disks:
+            if not devmap.has_key(disk) and non_disk_devices.has_key(disk):
+                log.warning("non-disk device %s is part of an mpath")
+                devmap[disk] = non_disk_devices[disk]
+                del non_disk_devices[disk]
+
+            topomap[disk] = name
+
+    for (mpname, disks) in topology.items():
         if len(disks) == 1:
-            log.info("adding %s to singlepath_disks" % (disks[0]['name'],))
-            singlepath_disks.append(disks[0])
+            log.info("adding %s to singlepath_disks" % (disks[0],))
+            singlepath_disks.append(devmap[disk])
         else:
             # some usb cardreaders use multiple lun's (for different slots)
             # and report a fake disk serial which is the same for all the
             # lun's (#517603)
             all_usb = True
-            for d in disks:
+            for disk in disks:
+                d = devmap[disk]
                 if d.get("ID_USB_DRIVER") != "usb-storage":
                     all_usb = False
                     break
             if all_usb:
                 log.info("adding multi lun usb mass storage device to singlepath_disks: %s" %
-                         [disk['name'] for disk in disks])
-                singlepath_disks.extend(disks)
+                         (disks,))
+                singlepath_disks.extend([devmap[d] for d in disks])
                 continue
 
-            for d in disks:
-                log.info("adding %s to multipath_disks" % (d['name'],))
+            for disk in disks:
+                d = devmap[disk]
+                log.info("adding %s to multipath_disks" % (disk,))
                 d["ID_FS_TYPE"] = "multipath_member"
+                d["ID_MPATH_NAME"] = mpname
+            
+            multipaths.append([devmap[d] for d in disks])
+            log.info("found multipath set: [%s]" % (disks,))
 
-            multipaths.append(disks)
-            log.info("found multipath set: [%s]" % [d['name'] for d in disks])
+    non_disk_serials = {}
+    for name,device in non_disk_devices.items():
+        serial = udev_device_get_serial(device)
+        non_disk_serials.setdefault(serial, [])
+        non_disk_serials[serial].append(device)
 
     for mpath in multipaths:
-        for serial in [d['ID_SERIAL_SHORT'] for d in mpath]:
-            if non_disk_devices.has_key(serial):
-                log.info("filtering out non disk devices [%s]" % [d['name'] for d in non_disk_devices[serial]])
-                del non_disk_devices[serial]
+        for serial in [d.get('ID_SERIAL_SHORT') for d in mpath]:
+            if non_disk_serials.has_key(serial):
+                log.info("filtering out non disk devices [%s]" % [d['name'] for d in non_disk_serials[serial]])
+                for name in [d['name'] for d in non_disk_serials[serial]]:
+                    if non_disk_devices.has_key(name):
+                        del non_disk_devices[name]
 
     partition_devices = []
-    for devs in non_disk_devices.values():
-        partition_devices += devs
+    for device in non_disk_devices.values():
+        partition_devices.append(device)
 
     # this is the list of devices we want to keep from the original
     # device list, but we want to maintain its original order.
diff --git a/storage/devices.py b/storage/devices.py
index 694dca9..0fd10fb 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -2931,8 +2931,6 @@ class MultipathDevice(DMDevice):
         """
 
         self._info = info
-        self._isUp = False
-        self._pyBlockMultiPath = None
         self.setupIdentity()
         DMDevice.__init__(self, name, format=format, size=size,
                           parents=parents, sysfsPath=sysfsPath)
@@ -3008,21 +3006,74 @@ class MultipathDevice(DMDevice):
         else:
             self.parents.append(parent)
 
-    def setup(self, intf=None):
-        if self.status:
-            self.teardown()
-        self._isUp = True
-        parents = []
-        for p in self.parents:
-            parents.append(p.path)
-        self._pyBlockMultiPath = block.device.MultiPath(*parents)
+    def teardownPartitions(self):
+        log_method_call(self, name=self.name, kids=self.kids)
+        rc = iutil.execWithRedirect("kpartx",
+                                ["-d", "-p", "p", "/dev/mapper/%s" % self.name],
+                                stdout = "/dev/tty5",
+                                stderr = "/dev/tty5")
+        if rc:
+            raise MPathError("multipath partition deactivation failed for '%s'"\
+                            % self.name)
+        udev_settle()
+
+    def setupPartitions(self):
+        log_method_call(self, name=self.name, kids=self.kids)
+        rc = iutil.execWithRedirect("kpartx",
+                                ["-a", "-p", "p", "/dev/mapper/%s" % self.name],
+                                stdout = "/dev/tty5",
+                                stderr = "/dev/tty5")
+        if rc:
+            raise MPathError("multipath partition activation failed for '%s'" %
+                            self.name)
+        udev_settle()
+
+    def makeDMNodes(self):
+        log_method_call(self, name=self.name, kids=self.kids)
+        rc = iutil.execWithRedirect("dmsetup", ["mknodes"],
+                                stdout = "/dev/tty5",
+                                stderr = "/dev/tty5")
 
     def teardown(self, recursive=None):
-        if not self.status:
+        """ Tear down the mpath device. """
+        log_method_call(self, self.name, status=self.status)
+
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.exists and os.path.exists(self.path):
+            self.teardownPartitions()
+            rc = iutil.execWithRedirect("multipath",
+                                ['-f', self.name],
+                                stdout = "/dev/tty5",
+                                stderr = "/dev/tty5")
+            if rc:
+                raise MPathError("multipath deactivation failed for '%s'" %
+                                self.name)
+            udev_settle()
+
+        if recursive:
+            self.teardownParents(recursive=recursive)
+
+    def setup(self, intf=None):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, status=self.status)
+
+        if self.status:
             return
-        self._isUp = False
-        self._pyBlockMultiPath = None
 
+        StorageDevice.setup(self, intf=intf)
+        udev_settle()
+        rc = iutil.execWithRedirect("multipath",
+                            [self.name],
+                            stdout = "/dev/tty5",
+                            stderr = "/dev/tty5")
+        if rc:
+            raise MPathError("multipath activation failed for '%s'" %
+                            self.name)
+        udev_settle()
+        self.setupPartitions()
+        udev_settle()
 
 class NoDevice(StorageDevice):
     """ A nodev device for nodev filesystems like tmpfs. """
-- 
1.6.5.2

_______________________________________________
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