diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index b7b2fa8d520a3685de0fdbabb44fe2a1627c8684..82bbdf958d8607ea998b8bcca43fa79e23433fb3 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -1437,6 +1437,33 @@ class LUSetClusterParams(LogicalUnit):
       _AdjustCandidatePool(self)
 
 
+class LURedistributeConfig(NoHooksLU):
+  """Force the redistribution of cluster configuration.
+
+  This is a very simple LU.
+
+  """
+  _OP_REQP = []
+  REQ_BGL = False
+
+  def ExpandNames(self):
+    self.needed_locks = {
+      locking.LEVEL_NODE: locking.ALL_SET,
+    }
+    self.share_locks[locking.LEVEL_NODE] = 1
+
+  def CheckPrereq(self):
+    """Check prerequisites.
+
+    """
+
+  def Exec(self, feedback_fn):
+    """Redistribute the configuration.
+
+    """
+    self.cfg.Update(self.cfg.GetClusterInfo())
+
+
 def _WaitForSync(lu, instance, oneshot=False, unlock=False):
   """Sleep and poll for an instance's disk to sync.
 
diff --git a/lib/mcpu.py b/lib/mcpu.py
index a41b5c1e033748ae5241ee0ab1ccca5c611a9fb7..1c3384da35c8fcc6dd8b812fdae0f65e16e9d288 100644
--- a/lib/mcpu.py
+++ b/lib/mcpu.py
@@ -49,6 +49,7 @@ class Processor(object):
     opcodes.OpRenameCluster: cmdlib.LURenameCluster,
     opcodes.OpVerifyDisks: cmdlib.LUVerifyDisks,
     opcodes.OpSetClusterParams: cmdlib.LUSetClusterParams,
+    opcodes.OpRedistributeConfig: cmdlib.LURedistributeConfig,
     # node lu
     opcodes.OpAddNode: cmdlib.LUAddNode,
     opcodes.OpQueryNodes: cmdlib.LUQueryNodes,
diff --git a/lib/opcodes.py b/lib/opcodes.py
index fbce4249b3b64c72b521839e95737243650b5e16..32edfaa7e68c1a01dd51f84303649106708a4177 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -171,6 +171,8 @@ class OpCode(BaseOpCode):
     return txt
 
 
+# cluster opcodes
+
 class OpDestroyCluster(OpCode):
   """Destroy the cluster.
 
@@ -264,6 +266,14 @@ class OpSetClusterParams(OpCode):
     ]
 
 
+class OpRedistributeConfig(OpCode):
+  """Force a full push of the cluster configuration.
+
+  """
+  OP_ID = "OP_CLUSTER_REDIST_CONF"
+  __slots__ = [
+    ]
+
 # node opcodes
 
 class OpRemoveNode(OpCode):
diff --git a/scripts/gnt-cluster b/scripts/gnt-cluster
index 1c9134b6f8dbeca96247920c4754d161f968f6e0..7f2382194bad82ad10dcd3b28a64462a55c0b782 100755
--- a/scripts/gnt-cluster
+++ b/scripts/gnt-cluster
@@ -177,6 +177,21 @@ def RenameCluster(opts, args):
   return 0
 
 
+def RedistributeConfig(opts, args):
+  """Forces push of the cluster configuration.
+
+  @param opts: the command line options selected by the user
+  @type args: list
+  @param args: empty list
+  @rtype: int
+  @return: the desired exit code
+
+  """
+  op = opcodes.OpRedistributeConf()
+  SubmitOrSend(op, opts)
+  return 0
+
+
 def ShowClusterVersion(opts, args):
   """Write version of ganeti software to the standard output.
 
@@ -589,6 +604,10 @@ commands = {
   'rename': (RenameCluster, ARGS_ONE, [DEBUG_OPT, FORCE_OPT],
                "<new_name>",
                "Renames the cluster"),
+  'redist-conf': (RedistributeConfig, ARGS_NONE, [DEBUG_OPT, SUBMIT_OPT],
+                  "",
+                  "Forces a push of the configuration file and ssconf files"
+                  " to the nodes in the cluster"),
   'verify': (VerifyCluster, ARGS_NONE, [DEBUG_OPT,
              make_option("--no-nplus1-mem", dest="skip_nplusone_mem",
                          help="Skip N+1 memory redundancy tests",