示例#1
0
    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)))
示例#3
0
    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
示例#5
0
 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))