diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index bd2f5a5d84c38fd92e5eaabd9714882178ca2c04..09d2bbcf247575f0a15f2031db4fe0cfbe15aebf 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -6441,6 +6441,62 @@ class TLReplaceDisks(Tasklet):
     self._RemoveOldStorage(self.target_node, iv_names)
 
 
+class LURepairNodeStorage(NoHooksLU):
+  """Repairs the volume group on a node.
+
+  """
+  _OP_REQP = ["node_name"]
+  REQ_BGL = False
+
+  def CheckArguments(self):
+    node_name = self.cfg.ExpandNodeName(self.op.node_name)
+    if node_name is None:
+      raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name)
+
+    self.op.node_name = node_name
+
+  def ExpandNames(self):
+    self.needed_locks = {
+      locking.LEVEL_NODE: [self.op.node_name],
+      }
+
+  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'" % (inst.name, node_name))
+
+  def CheckPrereq(self):
+    """Check prerequisites.
+
+    """
+    storage_type = self.op.storage_type
+
+    if (constants.SO_FIX_CONSISTENCY not in
+        constants.VALID_STORAGE_OPERATIONS.get(storage_type, [])):
+      raise errors.OpPrereqError("Storage units of type '%s' can not be"
+                                 " repaired" % storage_type)
+
+    # Check whether any instance on this node has faulty disks
+    for inst in _GetNodeInstances(self.cfg, self.op.node_name):
+      check_nodes = set(inst.all_nodes)
+      check_nodes.discard(self.op.node_name)
+      for inst_node_name in check_nodes:
+        self._CheckFaultyDisks(inst, inst_node_name)
+
+  def Exec(self, feedback_fn):
+    feedback_fn("Repairing storage unit '%s' on %s ..." %
+                (self.op.name, self.op.node_name))
+
+    st_args = _GetStorageTypeArgs(self.cfg, self.op.storage_type)
+    result = self.rpc.call_storage_execute(self.op.node_name,
+                                           self.op.storage_type, st_args,
+                                           self.op.name,
+                                           constants.SO_FIX_CONSISTENCY)
+    result.Raise("Failed to repair storage unit '%s' on %s" %
+                 (self.op.name, self.op.node_name))
+
+
 class LUGrowDisk(LogicalUnit):
   """Grow a disk of an instance.
 
diff --git a/lib/mcpu.py b/lib/mcpu.py
index 1c1579b503be2e07a59ce45568f85fe4600178ea..ff5f5c3a3e626fdd0f7743e3f2494dcf61857254 100644
--- a/lib/mcpu.py
+++ b/lib/mcpu.py
@@ -58,6 +58,7 @@ class Processor(object):
     opcodes.OpQueryNodeVolumes: cmdlib.LUQueryNodeVolumes,
     opcodes.OpQueryNodeStorage: cmdlib.LUQueryNodeStorage,
     opcodes.OpModifyNodeStorage: cmdlib.LUModifyNodeStorage,
+    opcodes.OpRepairNodeStorage: cmdlib.LURepairNodeStorage,
     opcodes.OpRemoveNode: cmdlib.LURemoveNode,
     opcodes.OpSetNodeParams: cmdlib.LUSetNodeParams,
     opcodes.OpPowercycleNode: cmdlib.LUPowercycleNode,
diff --git a/lib/opcodes.py b/lib/opcodes.py
index dc2882ba3c6f2fe201175a573e33760ba61c7cf0..a08549ca73e9485fcd6e10f88bc43f18f5481b2b 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -381,6 +381,17 @@ class OpModifyNodeStorage(OpCode):
     ]
 
 
+class OpRepairNodeStorage(OpCode):
+  """Repairs the volume group on a node."""
+  OP_ID = "OP_REPAIR_NODE_STORAGE"
+  OP_DSC_FIELD = "node_name"
+  __slots__ = OpCode.__slots__ + [
+    "node_name",
+    "storage_type",
+    "name",
+    ]
+
+
 class OpSetNodeParams(OpCode):
   """Change the parameters of a node."""
   OP_ID = "OP_NODE_SET_PARAMS"
@@ -680,6 +691,7 @@ class OpTestAllocator(OpCode):
     "os", "tags", "nics", "vcpus", "hypervisor",
     ]
 
+
 OP_MAPPING = dict([(v.OP_ID, v) for v in globals().values()
                    if (isinstance(v, type) and issubclass(v, OpCode) and
                        hasattr(v, "OP_ID"))])