Re: [PATCH] Make multipath support use device-mapper-multipath to setup mpaths.

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

 



Hi,

On 01/19/2010 04:38 PM, Peter Jones wrote:
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..0cd707f 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
+

This is wrong, callers of identifyMultipaths() expect it to
return a list containting 3 lists: (singles, mpaths, partitions)

This goes for both devicetree.py as the storage filtering code.

+    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[disks[0]])
          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. """



Otherwise it looks good.

Regards,

Hans

_______________________________________________
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