def _RemoveMissing(self, name, _runcmd_fn=utils.RunCmd): """Runs "vgreduce --removemissing" on a volume group. @type name: string @param name: Volume group name """ # Ignoring vgreduce exit code. Older versions exit with an error even tough # the VG is already consistent. This was fixed in later versions, but we # cannot depend on it. result = _runcmd_fn([self.VGREDUCE_COMMAND, "--removemissing", name]) # Keep output in case something went wrong vgreduce_output = result.output # work around newer LVM version if ("Wrote out consistent volume group" not in vgreduce_output or "vgreduce --removemissing --force" in vgreduce_output): # we need to re-run with --force result = _runcmd_fn( [self.VGREDUCE_COMMAND, "--removemissing", "--force", name]) vgreduce_output += "\n" + result.output result = _runcmd_fn( [self.LIST_COMMAND, "--noheadings", "--nosuffix", name]) # we also need to check the output if result.failed or "Couldn't find device with uuid" in result.output: raise errors.StorageError( ("Volume group '%s' still not consistent," " 'vgreduce' output: %r," " 'vgs' output: %r") % (name, vgreduce_output, result.output))
def _GetLvmFields(fields_def, wanted_field_names): """Returns unique list of fields wanted from LVM command. @type fields_def: list @param fields_def: Field definitions @type wanted_field_names: list @param wanted_field_names: List of requested fields """ field_to_idx = dict([(field_name, idx) for (idx, (field_name, _, _)) in enumerate(fields_def)]) lvm_fields = [] for field_name in wanted_field_names: try: idx = field_to_idx[field_name] except IndexError: raise errors.StorageError("Unknown field: %r" % field_name) (_, lvm_names, _) = fields_def[idx] lvm_fields.extend(lvm_names) return utils.UniqueSequence(lvm_fields)
def GetStorageClass(name): """Returns the class for a storage type. @type name: string @param name: Storage type """ try: return _STORAGE_TYPES[name] except KeyError: raise errors.StorageError("Unknown storage type: %r" % name)
def _RunListCommand(args): """Run LVM command. """ result = utils.RunCmd(args) if result.failed: raise errors.StorageError("Failed to run %r, command output: %s" % (args[0], result.output)) return result.stdout
def _ListInner(path, fields): """Gathers requested information from directory. @type path: string @param path: Path to directory @type fields: list @param fields: Requested fields """ values = [] # Pre-calculate information in case it's requested more than once if constants.SF_USED in fields: dirsize = utils.CalculateDirectorySize(path) else: dirsize = None if constants.SF_FREE in fields or constants.SF_SIZE in fields: fsstats = utils.GetFilesystemStats(path) else: fsstats = None # Make sure to update constants.VALID_STORAGE_FIELDS when changing fields. for field_name in fields: if field_name == constants.SF_NAME: values.append(path) elif field_name == constants.SF_USED: values.append(dirsize) elif field_name == constants.SF_FREE: values.append(fsstats[1]) elif field_name == constants.SF_SIZE: values.append(fsstats[0]) elif field_name == constants.SF_ALLOCATABLE: values.append(True) else: raise errors.StorageError("Unknown field: %r" % field_name) return values
def _SetAllocatable(self, name, allocatable): """Sets the "allocatable" flag on a physical volume. @type name: string @param name: Physical volume name @type allocatable: bool @param allocatable: Whether to set the "allocatable" flag """ args = ["pvchange", "--allocatable"] if allocatable: args.append("y") else: args.append("n") args.append(name) result = utils.RunCmd(args) if result.failed: raise errors.StorageError("Failed to modify physical volume," " pvchange output: %s" % result.output)