diff --git a/lib/constants.py b/lib/constants.py index 175782f79c974e560736166b034adec58e17c063..03ed03dd1abca790e1675f91ff511e1e92ab877e 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -199,6 +199,9 @@ SF_FREE = "free" SF_USED = "used" SF_ALLOCATABLE = "allocatable" +# Storage operations +SO_FIX_CONSISTENCY = "fix-consistency" + # Available fields per storage type VALID_STORAGE_FIELDS = { ST_FILE: frozenset([SF_NAME, SF_USED, SF_FREE]), @@ -211,6 +214,7 @@ MODIFIABLE_STORAGE_FIELDS = { } VALID_STORAGE_OPERATIONS = { + ST_LVM_VG: frozenset([SO_FIX_CONSISTENCY]), } # Local disk status diff --git a/lib/storage.py b/lib/storage.py index 19563bf6296c8023ef9826866ea83c263192ec17..e589dd8dbb5ea646837df67b23eb96fec51eda32 100644 --- a/lib/storage.py +++ b/lib/storage.py @@ -374,6 +374,39 @@ class LvmVgStorage(_LvmBase): (constants.SF_SIZE, "vg_size", _ParseSize), ] + def _RemoveMissing(self, name): + """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 = utils.RunCmd(["vgreduce", "--removemissing", name]) + + # Keep output in case something went wrong + vgreduce_output = result.output + + result = utils.RunCmd(["vgs", "--noheadings", "--nosuffix", name]) + if result.failed: + raise errors.StorageError(("Volume group '%s' still not consistent," + " 'vgreduce' output: %r," + " 'vgs' output: %r") % + (name, vgreduce_output, result.output)) + + def Execute(self, name, op): + """Executes an operation on a virtual volume. + + See L{_Base.Execute}. + + """ + if op == constants.SO_FIX_CONSISTENCY: + return self._RemoveMissing(name) + + return _LvmBase.Execute(self, name, op) + # Lookup table for storage types _STORAGE_TYPES = {