示例#1
0
def is_mpath_partition(devpath, info=None):
    """ Check if a device is a multipath partition, returns boolean. """
    result = False
    if devpath.startswith('/dev/dm-'):
        if not info:
            info = udev.udevadm_info(devpath)
        if 'DM_PART' in udev.udevadm_info(devpath):
            result = True

    LOG.debug("%s is multipath device partition? %s", devpath, result)
    return result
示例#2
0
def mpath_partition_to_mpath_id(devpath):
    """ Return the mpath id of a multipath partition. """
    info = udev.udevadm_info(devpath)
    if 'DM_MPATH' in info:
        return info['DM_MPATH']

    return None
示例#3
0
    def test_udevadm_info_escape_quotes(self, m_subp):
        """verify we escape quotes when we fail to split. """
        mypath = '/dev/sdz'
        datafile = 'tests/data/udevadm_info_sandisk_cruzer.txt'
        m_subp.return_value = (util.load_file(datafile), "")
        info = udevadm_info(mypath)
        m_subp.assert_called_with(
            ['udevadm', 'info', '--query=property', '--export', mypath],
            capture=True)
        """
        Replicate what udevadm_info parsing does and use pdb to examine what's
        happening.

        (Pdb) original_value
        "SanDisk'"
        (Pdb) quoted_value
        '\'SanDisk\'"\'"\'\''
        (Pdb) split_value
        ["SanDisk'"]
        (Pdb) expected_value
        "SanDisk'"
        """
        original_value = "SanDisk'"
        quoted_value = shlex_quote(original_value)
        split_value = shlex.split(quoted_value)
        expected_value = split_value if ' ' in split_value else split_value[0]

        self.assertEqual(expected_value, info['SCSI_VENDOR'])
        self.assertEqual(expected_value, info['SCSI_VENDOR_ENC'])
示例#4
0
def lookup_disk(serial):
    """
    Search for a disk by its serial number using /dev/disk/by-id/
    """
    # Get all volumes in /dev/disk/by-id/ containing the serial string. The
    # string specified can be either in the short or long serial format
    # hack, some serials have spaces, udev usually converts ' ' -> '_'
    serial_udev = serial.replace(' ', '_')
    LOG.info('Processing serial %s via udev to %s', serial, serial_udev)

    disks = list(
        filter(lambda x: serial_udev in x, os.listdir("/dev/disk/by-id/")))
    if not disks or len(disks) < 1:
        raise ValueError("no disk with serial '%s' found" % serial_udev)

    # Sort by length and take the shortest path name, as the longer path names
    # will be the partitions on the disk. Then use os.path.realpath to
    # determine the path to the block device in /dev/
    disks.sort(key=lambda x: len(x))
    LOG.debug('lookup_disks found: %s', disks)
    path = os.path.realpath("/dev/disk/by-id/%s" % disks[0])
    # /dev/dm-X
    if multipath.is_mpath_device(path):
        info = udevadm_info(path)
        path = os.path.join('/dev/mapper', info['DM_NAME'])
    # /dev/sdX
    elif multipath.is_mpath_member(path):
        mp_name = multipath.find_mpath_id_by_path(path)
        path = os.path.join('/dev/mapper', mp_name)

    if not os.path.exists(path):
        raise ValueError("path '%s' to block device for disk with serial '%s' \
            does not exist" % (path, serial_udev))
    LOG.debug('block.lookup_disk() returning path %s', path)
    return path
示例#5
0
def _device_is_multipathed(devpath):
    devpath = os.path.realpath(devpath)
    info = udevadm_info(devpath)
    if multipath.is_mpath_device(devpath, info=info):
        return True
    if multipath.is_mpath_partition(devpath, info=info):
        return True

    if devpath.startswith('/dev/dm-'):
        # check members of composed devices (LVM, dm-crypt)
        if 'DM_LV_NAME' in info:
            volgroup = info.get('DM_VG_NAME')
            if volgroup:
                if any((multipath.is_mpath_member(pv)
                        for pv in lvm.get_pvols_in_volgroup(volgroup))):
                    return True

    elif devpath.startswith('/dev/md'):
        if any((multipath.is_mpath_member(md)
                for md in md_get_devices_list(devpath) +
                md_get_spares_list(devpath))):
            return True

    result = multipath.is_mpath_member(devpath)
    return result
示例#6
0
def is_mpath_partition(devpath):
    if devpath.startswith('/dev/dm-'):
        if 'DM_PART' in udev.udevadm_info(devpath):
            LOG.debug("%s is multipath device partition", devpath)
            return True

    return False
示例#7
0
def mpath_partition_to_mpath_id_and_partnumber(devpath):
    """ Return the mpath id and partition number of a multipath partition. """
    info = udev.udevadm_info(devpath)
    if 'DM_MPATH' in info and 'DM_PART' in info:
        return info['DM_MPATH'], info['DM_PART']

    return None
示例#8
0
 def test_udevadm_info(self, m_subp):
     """ udevadm_info returns dictionary for specified device """
     mypath = '/dev/nvme0n1'
     m_subp.return_value = (UDEVADM_INFO_QUERY, "")
     info = udev.udevadm_info(mypath)
     m_subp.assert_called_with(
         ['udevadm', 'info', '--query=property', mypath], capture=True)
     self.assertEqual(sorted(INFO_DICT), sorted(info))
示例#9
0
def is_mpath_device(devpath, info=None):
    """ Check if devpath is a multipath device, returns boolean. """
    result = False
    if not info:
        info = udev.udevadm_info(devpath)
    if info.get('DM_UUID', '').startswith('mpath-'):
        result = True

    LOG.debug('%s is multipath device? %s', devpath, result)
    return result
示例#10
0
def get_mpath_id_from_device(device):
    # /dev/dm-X
    if is_mpath_device(device) or is_mpath_partition(device):
        info = udev.udevadm_info(device)
        return info.get('DM_NAME')
    # /dev/sdX
    if is_mpath_member(device):
        return find_mpath_id_by_path(device)

    return None
示例#11
0
 def test_udevadm_info_multiple_equals(self, m_subp):
     """ udevadm_info handles parsing values with multiple '=' chars. """
     mypath = '/dev/nvme0n1'
     m_subp.return_value = ("SCSI_IDENT_TARGET_VENDOR='clusterid=92901'",
                            "")
     info = udevadm_info(mypath)
     m_subp.assert_called_with(
         ['udevadm', 'info', '--query=property', '--export', mypath],
         capture=True)
     self.assertEqual({'SCSI_IDENT_TARGET_VENDOR': 'clusterid=92901'}, info)
示例#12
0
def is_mpath_member(devpath, info=None):
    """ Check if a device is a multipath member (a path), returns boolean. """
    result = False
    if not info:
        info = udev.udevadm_info(devpath)
    if info.get("DM_MULTIPATH_DEVICE_PATH") == "1":
        result = True

    LOG.debug('%s is multipath device member? %s', devpath, result)
    return result
示例#13
0
def get_device_mapper_links(devpath, first=False):
    """ Return the best devlink to device at devpath. """
    info = udevadm_info(devpath)
    if 'DEVLINKS' not in info:
        raise ValueError('Device %s does not have device symlinks' % devpath)
    devlinks = [devlink for devlink in sorted(info['DEVLINKS']) if devlink]
    if not devlinks:
        raise ValueError('Unexpected DEVLINKS list contained empty values')

    if first:
        return devlinks[0]

    return devlinks
示例#14
0
def is_mpath_device(devpath):
    info = udev.udevadm_info(devpath)
    if info.get('DM_UUID', '').startswith('mpath-'):
        return True

    return False
示例#15
0
def mpath_partition_to_mpath_id(devpath):
    info = udev.udevadm_info(devpath)
    if 'DM_MPATH' in info:
        return info['DM_MPATH']

    return None
示例#16
0
def find_mpath_id(devpath):
    """ Return the mpath_id associated with a specified device path. """
    info = udev.udevadm_info(devpath)
    return info.get('DM_NAME')
示例#17
0
 def test_udevadm_info_path_not_exists(self, m_subp):
     """ udevadm_info raises ProcessExecutionError for invalid path value"""
     mypath = self.random_string()
     m_subp.side_effect = util.ProcessExecutionError()
     with self.assertRaises(util.ProcessExecutionError):
         udevadm_info(mypath)
示例#18
0
 def test_udevadm_info_no_path(self):
     """ udevadm_info raises ValueError for invalid path value"""
     mypath = None
     with self.assertRaises(ValueError):
         udevadm_info(mypath)