def __init__(self, target_devices): # Working set: accumulate device paths for each (uuid, name). This is # necessary because in multipathed environments we will see the same # lustre target on more than one block device. The reason we use name # as well as UUID is that two logical targets can have the same UUID # when we see a combined MGS+MDT uuid_name_to_target = {} for device in target_devices: block_device = BlockDevice(device["type"], device["path"]) # If the target_device has no uuid then it doesn't have a filesystem and is of no use to use, but # for now let's fill it in an see what happens. if device['uuid'] == None: try: device['uuid'] = block_device.uuid except AgentShell.CommandExecutionError: pass # OK, so we really don't have a uuid for this, so we won't find a lustre filesystem on it. if device['uuid'] == None: daemon_log.info( "Device %s had no UUID and so will not be examined for Lustre" % device['path']) continue targets = block_device.targets(uuid_name_to_target, device, daemon_log) mounted = ndp.normalized_device_path(device['path']) in set([ ndp.normalized_device_path(path) for path, _, _ in Mounts().all() ]) for name in targets.names: daemon_log.info( "Device %s contained name:%s and is %smounted" % (device['path'], name, "" if mounted else "un")) try: target_dict = uuid_name_to_target[(device['uuid'], name)] target_dict['devices'].append(device) except KeyError: target_dict = { "name": name, "uuid": device['uuid'], "params": targets.params, "device_paths": [device['path']], "mounted": mounted, 'type': device['type'] } uuid_name_to_target[(device['uuid'], name)] = target_dict self.targets = uuid_name_to_target.values()
def assertNormalizedPaths(self, normalized_values): class mock_open: def __init__(self, fname): pass def read(self): return "root=/not/a/real/path" with mock.patch('__builtin__.open', mock_open): for path, normalized_path in normalized_values.items(): self.assertEqual( normalized_path, ndp.normalized_device_path(path), "Normalized path failure %s != %s" % (normalized_path, ndp.normalized_device_path(path)))
def _scan_mounts(self): mounts = {} for device, mntpnt, fstype in Mounts().all(): if fstype != 'lustre': continue # Assume that while a filesystem is mounted, its UUID and LABEL don't change. # Therefore we can avoid repeated blkid calls with a little caching. if device in self._mount_cache: fs_uuid = self._mount_cache[device]['fs_uuid'] fs_label = self._mount_cache[device]['fs_label'] else: # Sending none as the type means BlockDevice will use it's local cache to work the type. # This is not a good method, and we should work on a way of not storing such state but for the # present it is the best we have. try: fs_uuid = BlockDevice(None, device).uuid fs_label = FileSystem(None, device).label # If we have scanned the devices then it is safe to cache the values. if LinuxDevicePlugin.devices_scanned: self._mount_cache[device]['fs_uuid'] = fs_uuid self._mount_cache[device]['fs_label'] = fs_label except AgentShell.CommandExecutionError: continue dev_normalized = ndp.normalized_device_path(device) recovery_status = {} try: recovery_file = glob.glob( "/proc/fs/lustre/*/%s/recovery_status" % fs_label)[0] recovery_status_text = open(recovery_file).read() for line in recovery_status_text.split("\n"): tokens = line.split(":") if len(tokens) != 2: continue k = tokens[0].strip() v = tokens[1].strip() recovery_status[k] = v except IndexError: # If the recovery_status file doesn't exist, # we will return an empty dict for recovery info pass mounts[device] = { 'device': dev_normalized, 'fs_uuid': fs_uuid, 'mount_point': mntpnt, 'recovery_status': recovery_status } # Drop cached info about anything that is no longer mounted for k in self._mount_cache.keys(): if not k in mounts: del self._mount_cache[k] return mounts.values()
def find_device_and_children(device_path): devices = [] try: # Then find all the partitions for that disk and add them, they are all a child of this # zfs pool, so # scsi-0QEMU_QEMU_HARDDISK_WD-WMAP3333333 includes # scsi-0QEMU_QEMU_HARDDISK_WD-WMAP3333333-part1 for device in ndp.find_normalized_start(ndp.normalized_device_path(device_path)): daemon_log.debug("zfs device '%s'" % device) devices.append(device) except KeyError: pass return devices
def path_to_major_minor(self, device_path): """ Return device major minor for a given device path """ return self.node_block_devices.get( ndp.normalized_device_path(device_path))