def get_real_device(self, devname): """ Get the device for multipath volume name. Do we have /dev/mapper/mpathX, or /dev/dm-X? """ if len(devname) > 5 and devname[:5] == "mpath": return misc.get_real_device("/dev/mapper/" + devname) elif len(devname) > 3 and devname[:3] == "dm-": return misc.get_real_device("/dev/" + devname) # Or maybe raise an exception? return devname
def _fill_aditional_info(self, snap): snap['dev_name'] = "{0}/{1}/{2}".format(DM_DEV_DIR, snap['pool_name'], snap['lv_name']) snap['hide'] = False snap['snap_path'] = snap['dev_name'] if snap['type'] != "thin": size = float(snap['vol_size']) * float(snap['snap_size']) snap['snap_size'] = str(size / 100.00) else: # Show thin-pool as a pool name in case of thin volumes snap['parent_pool'] = snap['pool_name'] snap['pool_name'] = snap['pool_lv'] snap['real_dev'] = misc.get_real_device(snap['dev_name']) sysfile = "/sys/block/{0}/dm/name".format( os.path.basename(snap['real_dev'])) # In some weird cases the "real" device might not be in /dev/dm-* # form (see tests). In this case constructed sysfile will not exist # so we just use real device name to search mounts. try: with open(sysfile, 'r') as f: lvname = f.readline()[:-1] snap['dm_name'] = "{0}/mapper/{1}".format(DM_DEV_DIR, lvname) except IOError: snap['dm_name'] = snap['real_dev'] if snap['real_dev'] in self.mounts: snap['mount'] = self.mounts[snap['real_dev']]['mp'] self.parse_attr(snap, snap['attr'])
def _fill_aditional_info(self, lv): lv['dev_name'] = "{0}/{1}/{2}".format(DM_DEV_DIR, lv['pool_name'], lv['lv_name']) if lv['origin'] or \ lv['attr'][0] == 't': lv['hide'] = True # Show thin-pool as a pool name in case of thin volumes if lv['type'] == 'thin': lv['parent_pool'] = lv['pool_name'] lv['pool_name'] = lv['pool_lv'] lv['real_dev'] = misc.get_real_device(lv['dev_name']) sysfile = "/sys/block/{0}/dm/name".format( os.path.basename(lv['real_dev'])) # In some weird cases the "real" device might not be in /dev/dm-* # form (see tests). In this case constructed sysfile will not exist # so we just use real device name to search mounts. try: with open(sysfile, 'r') as f: lvname = f.readline()[:-1] lv['dm_name'] = "{0}/mapper/{1}".format(DM_DEV_DIR, lvname) except IOError: lv['dm_name'] = lv['real_dev'] if lv['real_dev'] in self.mounts: lv['mount'] = self.mounts[lv['real_dev']]['mp'] self.parse_attr(lv, lv['attr'])
def __init__(self, *args, **kwargs): super(DmCryptVolume, self).__init__(*args, **kwargs) command = ['dmsetup', 'table'] self.output = misc.run(command, stderr=False)[1] for line in self.output.split("\n"): if not line or line == "No devices found": break dm = {} array = line.split() if len(array) == 1: continue dm['type'] = array[3] if dm['type'] != 'crypt': continue dm['vol_size'] = str(int(array[2]) / 2.0) devname = re.sub(":$", "", "{0}/mapper/{1}".format(DM_DEV_DIR, array[0])) dm['dm_name'] = devname dm['pool_name'] = self.default_pool_name dm['dev_name'] = devname dm['real_dev'] = misc.get_real_device(devname) if dm['real_dev'] in self.mounts: dm['mount'] = self.mounts[dm['real_dev']]['mp'] # Check if the device really exists in the system. In some cases # (tests) DM_DEV_DIR can lie to us, if that is the case, simple # ignore the device. if not os.path.exists(devname): continue command = ['cryptsetup', 'status', devname] self._parse_cryptsetup(command, dm) self.data[dm['dev_name']] = dm
def __getitem__(self, name): if name in self.data: return self.data[name] device = name if not os.path.exists(name): device = DM_DEV_DIR + "/" + name if not os.path.exists(device): return None device = misc.get_real_device(device) if device in self.data: return self.data[device] return None
def __init__(self, options, data=None): self.type = 'crypt' self.data = data or {} self.output = None self.options = options self.mounts = misc.get_mounts('{0}/mapper'.format(DM_DEV_DIR)) self.default_pool_name = SSM_CRYPT_DEFAULT_POOL self.problem = problem.ProblemSet(options) if not misc.check_binary('dmsetup') or \ not misc.check_binary('cryptsetup'): return command = ['dmsetup', 'table'] self.output = misc.run(command, stderr=False)[1] for line in self.output.split("\n"): if not line or line == "No devices found": break dm = {} array = line.split() dm['type'] = array[3] if dm['type'] != 'crypt': continue dm['vol_size'] = str(int(array[2]) / 2.0) devname = re.sub(":$", "", "{0}/mapper/{1}".format(DM_DEV_DIR, array[0])) dm['dm_name'] = devname dm['pool_name'] = 'dm-crypt' dm['dev_name'] = misc.get_real_device(devname) dm['real_dev'] = dm['dev_name'] if dm['real_dev'] in self.mounts: dm['mount'] = self.mounts[dm['real_dev']]['mp'] # Check if the device really exists in the system. In some cases # (tests) DM_DEV_DIR can lie to us, if that is the case, simple # ignore the device. if not os.path.exists(devname): continue command = ['cryptsetup', 'status', devname] self._parse_cryptsetup(command, dm) self.data[dm['dev_name']] = dm
def __init__(self, *args, **kwargs): super(Btrfs, self).__init__(*args, **kwargs) self.type = 'btrfs' self.default_pool_name = SSM_BTRFS_DEFAULT_POOL self._vol = {} self._pool = {} self._dev = {} self._snap = {} self._subvolumes = {} self._binary = misc.check_binary('btrfs') self.modified_list_version = True if not self._binary: return self.mounts = misc.get_mounts('btrfs') command = ['btrfs', 'filesystem', 'show'] self.output = misc.run(command, stderr=False)[1] vol = {} pool = {} dev = {} partitions = {} fs_size = pool_size = fs_used = 0 pool_name = '' for line in misc.get_partitions(): partitions[line[3]] = line for line in self.output.strip().split("\n"): if not line: continue array = line.split() if array[0] == 'Label:': if len(vol) > 0: self._store_data(vol, pool, fs_used, fs_size, pool_size, pool_name) vol = {} pool = {} fs_size = pool_size = 0 pool_name = '' label = array[1].strip("'") uuid = array[3] pool['uuid'] = vol['uuid'] = uuid try: vol['real_dev'] = misc.get_device_by_uuid(uuid) if vol['real_dev'] in self.mounts: pool['mount'] = self.mounts[vol['real_dev']]['mp'] vol['mount'] = self.mounts[vol['real_dev']]['mp'] else: for dev_i in self.mounts: found = re.findall( r'{0}:/.*'.format(vol['real_dev']), dev_i) if found: pool['mount'] = self.mounts[found[0]]['mp'] break except OSError: # udev is "hard-to-work-with" sometimes so this is fallback vol['real_dev'] = "" if label != 'none': vol['label'] = label vol['ID'] = 0 elif array[0] == 'Total': pool['dev_count'] = array[2] fs_used = float(misc.get_real_size(array[6])) elif array[0] == 'devid': # This is ugly hack to fix a problem with test suite and btrfs # where ?sometimes? btrfs prints out device name in the path # of the test suite rather than path in the real '/dev/' # directory. This should cover that without any impact on # real usage if not os.path.islink(array[7]): array[7] = re.sub(r'.*/dev/', '/dev/', array[7]) dev['dev_name'] = misc.get_real_device(array[7]) if not pool_name: pool_name = self._find_uniq_pool_name(label, array[7]) dev['pool_name'] = pool_name # Fallback in case we could not find real_dev by uuid if 'mount' not in pool: if dev['dev_name'] in self.mounts: pool['mount'] = self.mounts[dev['dev_name']]['mp'] vol['real_dev'] = dev['dev_name'] if 'root' in self.mounts[dev['dev_name']]: if self.mounts[dev['dev_name']]['root'] == '/': vol['mount'] = self.mounts[ dev['dev_name']]['mp'] else: for dev_i in self.mounts: found = re.findall( r'{0}:/.*'.format(dev['dev_name']), dev_i) if found: pool['mount'] = self.mounts[found[0]]['mp'] vol['real_dev'] = found[0].split(':')[0] break dev_used = float(misc.get_real_size(array[5])) dev['dev_used'] = str(dev_used) fs_size += float(misc.get_real_size(array[3])) dev_size = \ int(partitions[dev['dev_name']][2]) pool_size += dev_size dev['dev_free'] = dev_size - dev_used dev['hide'] = False self._dev[dev['dev_name']] = dev dev = {} if len(vol) > 0: self._store_data(vol, pool, fs_used, fs_size, pool_size, pool_name)
def _data_index(self, row): return misc.get_real_device(row['dev_name'])
def _get_dev_name(self, lv): real = misc.get_real_device(lv) if real in self.data: return self.data[real]['dev_name'] else: return lv