diff --git a/lib/cmdlib.py b/lib/cmdlib.py index be21ed1c795f1360eb906d996a91906667c27dae..588381729384e67498203cac1f0c614533b09dba 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -6989,11 +6989,18 @@ class LURepairNodeStorage(NoHooksLU): } def _CheckFaultyDisks(self, instance, node_name): - if _FindFaultyInstanceDisks(self.cfg, self.rpc, instance, - node_name, True): - raise errors.OpPrereqError("Instance '%s' has faulty disks on" - " node '%s'" % (instance.name, node_name), - errors.ECODE_STATE) + """Ensure faulty disks abort the opcode or at least warn.""" + try: + if _FindFaultyInstanceDisks(self.cfg, self.rpc, instance, + node_name, True): + raise errors.OpPrereqError("Instance '%s' has faulty disks on" + " node '%s'" % (instance.name, node_name), + errors.ECODE_STATE) + except errors.OpPrereqError, err: + if self.op.ignore_consistency: + self.proc.LogWarning(str(err.args[0])) + else: + raise def CheckPrereq(self): """Check prerequisites. @@ -7009,6 +7016,8 @@ class LURepairNodeStorage(NoHooksLU): # Check whether any instance on this node has faulty disks for inst in _GetNodeInstances(self.cfg, self.op.node_name): + if not inst.admin_up: + continue check_nodes = set(inst.all_nodes) check_nodes.discard(self.op.node_name) for inst_node_name in check_nodes: diff --git a/lib/opcodes.py b/lib/opcodes.py index 7e01595b1100d34078f7e147f67594902fa8a0fe..d1179e1f876687c161bc6812457deb50c7dc24ae 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -390,6 +390,7 @@ class OpRepairNodeStorage(OpCode): "node_name", "storage_type", "name", + "ignore_consistency", ] diff --git a/man/gnt-node.sgml b/man/gnt-node.sgml index a62edd04d408820e25441bf5ce23265b1ec96f8f..b16a4a71c9eb15ad42790924c7cb46efd83820d4 100644 --- a/man/gnt-node.sgml +++ b/man/gnt-node.sgml @@ -889,9 +889,9 @@ node2 lvm-pv /dev/sdb1 698.6G 0M 698.6G Y <command>modify-storage</command> <arg><option>--allocatable=yes|no</option></arg> <sbr> - <arg><replaceable>node</replaceable></arg> - <arg><replaceable>storage-type</replaceable></arg> - <arg><replaceable>volume-name</replaceable></arg> + <arg choice="req"><replaceable>node</replaceable></arg> + <arg choice="req"><replaceable>storage-type</replaceable></arg> + <arg choice="req"><replaceable>volume-name</replaceable></arg> </cmdsynopsis> <para> @@ -913,9 +913,10 @@ node2 lvm-pv /dev/sdb1 698.6G 0M 698.6G Y <cmdsynopsis> <command>repair-storage</command> - <arg><replaceable>node</replaceable></arg> - <arg><replaceable>storage-type</replaceable></arg> - <arg><replaceable>volume-name</replaceable></arg> + <arg>--ignore-consistency</arg> + <arg choice="req"><replaceable>node</replaceable></arg> + <arg choice="req"><replaceable>storage-type</replaceable></arg> + <arg choice="req"><replaceable>volume-name</replaceable></arg> </cmdsynopsis> <para> @@ -935,6 +936,12 @@ node2 lvm-pv /dev/sdb1 698.6G 0M 698.6G Y </para> </caution> + <para> + The <option>--ignore-consistency</option> option will ignore + any inconsistent disks (on the nodes paired with this + one). Use of this option is most likely to lead to data-loss. + </para> + <para> Example: <screen> diff --git a/scripts/gnt-node b/scripts/gnt-node index b14b04dbdb4ff60f0ec46ad54f97e16449e0ec72..205365af97c7e21e1ae117b23a2057b07d0d4464 100755 --- a/scripts/gnt-node +++ b/scripts/gnt-node @@ -597,7 +597,8 @@ def RepairStorage(opts, args): op = opcodes.OpRepairNodeStorage(node_name=node_name, storage_type=storage_type, - name=volume_name) + name=volume_name, + ignore_consistency=opts.ignore_consistency) SubmitOpCode(op) @@ -709,7 +710,7 @@ commands = { [ArgNode(min=1, max=1), ArgChoice(min=1, max=1, choices=_REPAIRABLE_STORAGE_TYPES), ArgFile(min=1, max=1)], - [], + [IGNORE_CONSIST_OPT], "<node_name> <storage_type> <name>", "Repairs a storage volume on a node"), 'list-tags': (