Ejemplo n.º 1
0
def gen_holders_tree(device):
    """
    generate a tree representing the current storage hirearchy above 'device'
    """
    device = block.sys_block_path(device)
    dev_name = block.path_to_kname(device)
    # the holders for a device should consist of the devices in the holders/
    # dir in sysfs and any partitions on the device. this ensures that a
    # storage tree starting from a disk will include all devices holding the
    # disk's partitions
    holder_paths = ([block.sys_block_path(h) for h in get_holders(device)] +
                    block.get_sysfs_partitions(device))
    # the DEV_TYPE registry contains a function under the key 'ident' for each
    # device type entry that returns true if the device passed to it is of the
    # correct type. there should never be a situation in which multiple
    # identify functions return true. therefore, it will always work to take
    # the device type with the first identify function that returns true as the
    # device type for the current device. in the event that no identify
    # functions return true, the device will be treated as a disk
    # (DEFAULT_DEV_TYPE). the identify function for disk never returns true.
    # the next() builtin in python will not raise a StopIteration exception if
    # there is a default value defined
    dev_type = next((k for k, v in DEV_TYPES.items() if v['ident'](device)),
                    DEFAULT_DEV_TYPE)
    return {
        'device': device,
        'dev_type': dev_type,
        'name': dev_name,
        'holders': [gen_holders_tree(h) for h in holder_paths],
    }
Ejemplo n.º 2
0
 def test_cciss_sysfs_path(self, m_os_path_exists, m_get_blk):
     m_os_path_exists.return_value = True
     m_get_blk.return_value = ('cciss!c0d0', None)
     self.assertEqual('/sys/class/block/cciss!c0d0',
                      block.sys_block_path('/dev/cciss/c0d0'))
     m_get_blk.return_value = ('cciss!c0d0', 1)
     self.assertEqual('/sys/class/block/cciss!c0d0/cciss!c0d0p1',
                      block.sys_block_path('/dev/cciss/c0d0p1'))
Ejemplo n.º 3
0
def md_sysfs_attr_path(md_devname, attrname):
    """ Return the path to a md device attribute under the 'md' dir """
    # build /sys/class/block/<md_short>/md
    sysmd = sys_block_path(md_devname, "md")

    # append attrname
    return os.path.join(sysmd, attrname)
Ejemplo n.º 4
0
def shutdown_lvm(device):
    """
    Shutdown specified lvm device.
    """
    device = block.sys_block_path(device)
    # lvm devices have a dm directory that containes a file 'name' containing
    # '{volume group}-{logical volume}'. The volume can be freed using lvremove
    name_file = os.path.join(device, 'dm', 'name')
    lvm_name = util.load_file(name_file).strip()
    (vg_name, lv_name) = lvm.split_lvm_name(lvm_name)
    vg_lv_name = "%s/%s" % (vg_name, lv_name)
    devname = "/dev/" + vg_lv_name

    # wipe contents of the logical volume first
    LOG.info('Wiping lvm logical volume: %s', devname)
    block.quick_zero(devname, partitions=False)

    # remove the logical volume
    LOG.debug('using "lvremove" on %s', vg_lv_name)
    util.subp(['lvremove', '--force', '--force', vg_lv_name])

    # if that was the last lvol in the volgroup, get rid of volgroup
    if len(lvm.get_lvols_in_volgroup(vg_name)) == 0:
        pvols = lvm.get_pvols_in_volgroup(vg_name)
        util.subp(['vgremove', '--force', '--force', vg_name], rcs=[0, 5])

        # wipe the underlying physical volumes
        for pv in pvols:
            LOG.info('Wiping lvm physical volume: %s', pv)
            block.quick_zero(pv, partitions=False)

    # refresh lvmetad
    lvm.lvm_scan()
Ejemplo n.º 5
0
def md_get_devices_list(devpath):
    sysfs_md = sys_block_path(devpath, "md")
    devices = [
        dev_path(dev[4:]) for dev in os.listdir(sysfs_md)
        if (dev.startswith('dev-') and util.load_file(
            os.path.join(sysfs_md, dev, 'state')).strip() != 'spare')
    ]
    return devices
Ejemplo n.º 6
0
def get_holders(device):
    """
    Look up any block device holders, return list of knames
    """
    # block.sys_block_path works when given a /sys or /dev path
    sysfs_path = block.sys_block_path(device)
    # get holders
    holders = os.listdir(os.path.join(sysfs_path, 'holders'))
    LOG.debug("devname '%s' had holders: %s", device, holders)
    return holders
Ejemplo n.º 7
0
def assert_clear(base_paths):
    """
    Check if all paths in base_paths are clear to use
    """
    valid = ('disk', 'partition')
    if not isinstance(base_paths, (list, tuple)):
        base_paths = [base_paths]
    base_paths = [block.sys_block_path(path) for path in base_paths]
    for holders_tree in [gen_holders_tree(p) for p in base_paths]:
        if any(holder_type not in valid and path not in base_paths
               for (holder_type, path) in get_holder_types(holders_tree)):
            raise OSError('Storage not clear, remaining:\n{}'.format(
                format_holders_tree(holders_tree)))
Ejemplo n.º 8
0
def identify_partition(device):
    """
    determine if specified device is a partition
    """
    blockdev = block.sys_block_path(device)
    path = os.path.join(blockdev, 'partition')
    if os.path.exists(path):
        return True

    if multipath.is_mpath_partition(blockdev):
        return True

    return False
Ejemplo n.º 9
0
def get_bcache_sys_path(device, strict=True):
    """
    Get the /sys/class/block/<device>/bcache path
    """
    sysfs_path = block.sys_block_path(device, strict=strict)
    path = os.path.join(sysfs_path, 'bcache')
    if strict and not os.path.exists(path):
        err = OSError("device '{}' did not have existing syspath '{}'".format(
            device, path))
        err.errno = errno.ENOENT
        raise err

    return path
Ejemplo n.º 10
0
def get_bcache_using_dev(device, strict=True):
    """
    Get the /sys/fs/bcache/ path of the bcache cache device bound to
    specified device
    """
    # FIXME: when block.bcache is written this should be moved there
    sysfs_path = block.sys_block_path(device)
    path = os.path.realpath(os.path.join(sysfs_path, 'bcache', 'cache'))
    if strict and not os.path.exists(path):
        err = OSError("device '{}' did not have existing syspath '{}'".format(
            device, path))
        err.errno = errno.ENOENT
        raise err

    return path
Ejemplo n.º 11
0
 def test_not_strict_does_not_care(self, m_os_path_exists, m_get_blk):
     m_os_path_exists.return_value = False
     m_get_blk.return_value = ('foodev', None)
     self.assertEqual('/sys/class/block/foodev/md/b',
                      block.sys_block_path("foodev", "/md/b", strict=False))
Ejemplo n.º 12
0
 def test_invalid_devname_raises(self, m_os_path_exists, m_get_blk):
     m_os_path_exists.return_value = False
     with self.assertRaises(ValueError):
         block.sys_block_path("foodevice")
Ejemplo n.º 13
0
 def test_add_works_leading_slash(self, m_os_path_exists, m_get_blk):
     m_os_path_exists.return_value = True
     m_get_blk.return_value = ('foodev', None)
     self.assertEqual('/sys/class/block/foodev/md/b',
                      block.sys_block_path("/dev/foodev", "/md/b"))
Ejemplo n.º 14
0
 def test_existing_devpath_allowed(self, m_os_path_exists, m_get_blk):
     m_os_path_exists.return_value = True
     m_get_blk.return_value = ('foodev', None)
     self.assertEqual('/sys/class/block/foodev',
                      block.sys_block_path("/dev/foodev"))
Ejemplo n.º 15
0
 def test_existing_valid_devname(self, m_os_path_exists, m_get_blk):
     m_os_path_exists.return_value = True
     m_get_blk.return_value = ('foodevice', None)
     self.assertEqual('/sys/class/block/foodevice',
                      block.sys_block_path("foodevice"))
Ejemplo n.º 16
0
 def test_cciss_sysfs_path(self, m_os_path_exists):
     m_os_path_exists.return_value = True
     self.assertEqual('/sys/class/block/cciss!c0d0',
                      block.sys_block_path('/dev/cciss/c0d0'))
Ejemplo n.º 17
0
 def test_add_works(self, m_os_path_exists):
     m_os_path_exists.return_value = True
     self.assertEqual('/sys/class/block/foodev/md/b',
                      block.sys_block_path("/dev/foodev", "md/b"))
Ejemplo n.º 18
0
def identify_partition(device):
    """
    determine if specified device is a partition
    """
    path = os.path.join(block.sys_block_path(device), 'partition')
    return os.path.exists(path)