Re: [rhel6-branch 4/4] mpath: filter out the slave devices and their partitions.

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

 



This seems okay to me. We should be able to handle this better in the
device tree, but this approach will do for now.

Dave

On Wed, 2010-12-22 at 11:22 +0100, Ales Kozumplik wrote:
> This change necessitates from two previous commits:
> 1) 6e6d3df9a78730996e6ac7d463e3b50dbc164b4c, resulting in
> DeviceTree.populate() being called twice now, for the second time at the
> end of autopart.
> 
> 2) 5c83bbf01800ca86d1c8e4cd95d14480165b344c, which causes already
> coalesced mpath devices (disks and partitions) never to be torn down
> during anaconda run.
> 
> Given that, we don't want to let identifyMultipath give
> DeviceTree.populate() existing mpath devices (dm-0, dm-1,
> etc.). populate() would try to add those before the slave mpath members
> (sda, sdb) and although the addUdevDevice() logic will eventually
> recursively request sda and sdb while working on dm-0, the udev info we
> get for sda in sdb at that point is obtained thorugh a call to
> udev_get_block_device() which will not give us a correctly filled in
> ID_FS_TYPE (unlike the enriched info dictionaries that idenitfyMultipath()
> gives us).
> 
> Alternative solution would be to embed a layer between DeviceTree and
> udev.py. This layer would remember the additional database values that are
> not returned by udev itself but rather discovered by us, such as the
> "multipath_member" value of ID_FS_TYPE.
> 
> For the partitions part, the patch only does what identifyMultipath()'s
> documentation promises: "3) removes the individual members of an mpath's
> partitions". This step is optional and to make the function better
> defined: note that e.g. sda3 will be scanned later in populate() anyway as
> it will naturally still appear in udev_get_block_devices().
> 
> Resolves: rhbz#636570
> ---
>  storage/devicelibs/mpath.py |   70 +++++++++++++++++++++++++++---------------
>  storage/devicetree.py       |   13 ++++----
>  storage/udev.py             |    8 +++++
>  3 files changed, 59 insertions(+), 32 deletions(-)
> 
> diff --git a/storage/devicelibs/mpath.py b/storage/devicelibs/mpath.py
> index 0d0efde..113c544 100644
> --- a/storage/devicelibs/mpath.py
> +++ b/storage/devicelibs/mpath.py
> @@ -7,6 +7,31 @@ import logging
>  
>  log = logging.getLogger("storage")
>  
> +def _filter_out_mpath_devices(devices):
> +    retval = []
> +    for d in devices:
> +        if udev_device_is_multipath(d):
> +            log.debug("filtering out coalesced mpath device: %s" % d['name'])
> +        else:
> +            retval.append(d)
> +    return retval
> +
> +def _filter_out_mpath_partitions(devices, multipaths):
> +    """
> +    Use serial numbers of the multipath members to filter devices from the
> +    devices list. The returned list will only partitions that are NOT partitions
> +    of the multipath members.
> +    """
> +    serials = set(udev_device_get_serial(d)
> +                  for mpath_members in multipaths for d in mpath_members)
> +    retval = []
> +    for d in devices:
> +        if udev_device_get_serial(d) in serials:
> +            log.debug("filtering out mpath partition: %s" % d['name'])
> +        else:
> +            retval.append(d)
> +    return retval
> +
>  def parseMultipathOutput(output):
>      """
>      Parse output from "multipath -d" or "multipath -ll" and form a topology.
> @@ -84,14 +109,22 @@ def parseMultipathOutput(output):
>      return mpaths
>  
>  def identifyMultipaths(devices):
> -    # this function does a couple of things
> -    # 1) identifies multipath disks
> -    # 2) sets their ID_FS_TYPE to multipath_member
> -    # 3) removes the individual members of an mpath's partitions
> -    # sample input with multipath pair [sdb,sdc]
> -    # [sr0, sda, sda1, sdb, sdb1, sdb2, sdc, sdc1, sdd, sdd1, sdd2]
> -    # sample output:
> -    # [sda, sdd], [[sdb, sdc]], [sr0, sda1, sdd1, sdd2]]
> +    """
> +    This function does a couple of things:
> +    1) identifies multipath disks,
> +    2) sets their ID_FS_TYPE to multipath_member,
> +    3) removes the individual members of an mpath's partitions as well as any
> +    coalesced multipath devices:
> +
> +    sample input:
> +    [sr0, sda, sda1, sdb, sdb1, sdb2, sdc, sdc1, sdd, sdd1, sdd2, dm-0]
> +    where:
> +    [sdb, sdc] is a multipath pair
> +    dm-0 is a mutliapth device already coalesced from [sdb, sdc]
> +
> +    sample output:
> +    [sda, sdd], [[sdb, sdc]], [sr0, sda1, sdd1, sdd2]]
> +    """
>      log.info("devices to scan for multipath: %s" % [d['name'] for d in devices])
>  
>      with open("/etc/multipath.conf") as conf:
> @@ -165,23 +198,10 @@ def identifyMultipaths(devices):
>  
>              multipaths.append([devmap[d] 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.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 device in non_disk_devices.values():
> -        partition_devices.append(device)
> +    # singlepaths and partitions should not contain multipath devices:
> +    singlepath_disks = _filter_out_mpath_devices(singlepath_disks)
> +    partition_devices = _filter_out_mpath_partitions(
> +        non_disk_devices.values(), multipaths)
>  
>      # 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/devicetree.py b/storage/devicetree.py
> index 45fc455..f45e656 100644
> --- a/storage/devicetree.py
> +++ b/storage/devicetree.py
> @@ -2026,19 +2026,18 @@ class DeviceTree(object):
>                       % (livetarget,))
>              self.protectedDevNames.append(livetarget)
>  
> -        # First iteration - let's just look for disks.
> -        old_devices = {}
> -
> -        devices = udev_get_block_devices()
> -        for dev in devices:
> -            old_devices[dev['name']] = dev
> -
>          cfg = self.__multipathConfigWriter.write()
>          open("/etc/multipath.conf", "w+").write(cfg)
>          del cfg
>  
> +        devices = udev_get_block_devices()
>          (singles, mpaths, partitions) = devicelibs.mpath.identifyMultipaths(devices)
>          devices = singles + reduce(list.__add__, mpaths, []) + partitions
> +        # remember all the devices idenitfyMultipaths() gave us at this point
> +        old_devices = {}
> +        for dev in devices:
> +            old_devices[dev['name']] = dev
> +
>          log.info("devices to scan: %s" % [d['name'] for d in devices])
>          for dev in devices:
>              self.addUdevDevice(dev)
> diff --git a/storage/udev.py b/storage/udev.py
> index 59b7519..7ba5a9c 100644
> --- a/storage/udev.py
> +++ b/storage/udev.py
> @@ -472,6 +472,14 @@ def udev_device_is_dmraid_partition(info, devicetree):
>  
>      return False
>  
> +def udev_device_is_multipath(info):
> +    """ Return True if the device is a multipath device or a partition of one."""
> +    if not udev_device_is_dm(info):
> +        return False
> +    if udev_device_get_name(info).startswith("mpath"):
> +        return True
> +    return False
> +
>  def udev_device_is_multipath_partition(info, devicetree):
>      """ Return True if the device is a partition of a multipath device. """
>      if not udev_device_is_dm(info):


_______________________________________________
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