Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Debian User (http://www.linux-archive.org/debian-user/)
-   -   Make multipath support use device-mapper-multipath to setup mpaths. (http://www.linux-archive.org/debian-user/311792-make-multipath-support-use-device-mapper-multipath-setup-mpaths.html)

Hans de Goede 01-19-2010 07:15 PM

Make multipath support use device-mapper-multipath to setup mpaths.
 
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@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


All times are GMT. The time now is 06:09 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.