diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 380650e4809414660f54c101c5660de4b18c7076..61b19805aaff99325a0a2e8fb9ea0cdc5ebd3611 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -4255,17 +4255,32 @@ class LUReplaceDisks(LogicalUnit):
   _OP_REQP = ["instance_name", "mode", "disks"]
   REQ_BGL = False
 
-  def ExpandNames(self):
-    self._ExpandAndLockInstance()
-
+  def CheckArguments(self):
     if not hasattr(self.op, "remote_node"):
       self.op.remote_node = None
-
-    ia_name = getattr(self.op, "iallocator", None)
-    if ia_name is not None:
-      if self.op.remote_node is not None:
+    if not hasattr(self.op, "iallocator"):
+      self.op.iallocator = None
+
+    # check for valid parameter combination
+    cnt = [self.op.remote_node, self.op.iallocator].count(None)
+    if self.op.mode == constants.REPLACE_DISK_CHG:
+      if cnt == 2:
+        raise errors.OpPrereqError("When changing the secondary either an"
+                                   " iallocator script must be used or the"
+                                   " new node given")
+      elif cnt == 0:
         raise errors.OpPrereqError("Give either the iallocator or the new"
                                    " secondary, not both")
+    else: # not replacing the secondary
+      if cnt != 2:
+        raise errors.OpPrereqError("The iallocator and new node options can"
+                                   " be used only when changing the"
+                                   " secondary node")
+
+  def ExpandNames(self):
+    self._ExpandAndLockInstance()
+
+    if self.op.iallocator is not None:
       self.needed_locks[locking.LEVEL_NODE] = locking.ALL_SET
     elif self.op.remote_node is not None:
       remote_node = self.cfg.ExpandNodeName(self.op.remote_node)
@@ -4340,9 +4355,9 @@ class LUReplaceDisks(LogicalUnit):
       "Cannot retrieve locked instance %s" % self.op.instance_name
     self.instance = instance
 
-    if instance.disk_template not in constants.DTS_NET_MIRROR:
-      raise errors.OpPrereqError("Instance's disk layout is not"
-                                 " network mirrored.")
+    if instance.disk_template != constants.DT_DRBD8:
+      raise errors.OpPrereqError("Can only run replace disks for DRBD8-based"
+                                 " instances")
 
     if len(instance.secondary_nodes) != 1:
       raise errors.OpPrereqError("The instance has a strange layout,"
@@ -4351,8 +4366,7 @@ class LUReplaceDisks(LogicalUnit):
 
     self.sec_node = instance.secondary_nodes[0]
 
-    ia_name = getattr(self.op, "iallocator", None)
-    if ia_name is not None:
+    if self.op.iallocator is not None:
       self._RunAllocator()
 
     remote_node = self.op.remote_node
@@ -4366,42 +4380,24 @@ class LUReplaceDisks(LogicalUnit):
       raise errors.OpPrereqError("The specified node is the primary node of"
                                  " the instance.")
     elif remote_node == self.sec_node:
-      if self.op.mode == constants.REPLACE_DISK_SEC:
-        # this is for DRBD8, where we can't execute the same mode of
-        # replacement as for drbd7 (no different port allocated)
-        raise errors.OpPrereqError("Same secondary given, cannot execute"
-                                   " replacement")
-    if instance.disk_template == constants.DT_DRBD8:
-      if (self.op.mode == constants.REPLACE_DISK_ALL and
-          remote_node is not None):
-        # switch to replace secondary mode
-        self.op.mode = constants.REPLACE_DISK_SEC
-
-      if self.op.mode == constants.REPLACE_DISK_ALL:
-        raise errors.OpPrereqError("Template 'drbd' only allows primary or"
-                                   " secondary disk replacement, not"
-                                   " both at once")
-      elif self.op.mode == constants.REPLACE_DISK_PRI:
-        if remote_node is not None:
-          raise errors.OpPrereqError("Template 'drbd' does not allow changing"
-                                     " the secondary while doing a primary"
-                                     " node disk replacement")
-        self.tgt_node = instance.primary_node
-        self.oth_node = instance.secondary_nodes[0]
-        _CheckNodeOnline(self, self.tgt_node)
-        _CheckNodeOnline(self, self.oth_node)
-      elif self.op.mode == constants.REPLACE_DISK_SEC:
-        self.new_node = remote_node # this can be None, in which case
-                                    # we don't change the secondary
-        self.tgt_node = instance.secondary_nodes[0]
-        self.oth_node = instance.primary_node
-        _CheckNodeOnline(self, self.oth_node)
-        if self.new_node is not None:
-          _CheckNodeOnline(self, self.new_node)
-        else:
-          _CheckNodeOnline(self, self.tgt_node)
-      else:
-        raise errors.ProgrammerError("Unhandled disk replace mode")
+      raise errors.OpPrereqError("The specified node is already the"
+                                 " secondary node of the instance.")
+
+    if self.op.mode == constants.REPLACE_DISK_PRI:
+      n1 = self.tgt_node = instance.primary_node
+      n2 = self.oth_node = self.sec_node
+    elif self.op.mode == constants.REPLACE_DISK_SEC:
+      n1 = self.tgt_node = self.sec_node
+      n2 = self.oth_node = instance.primary_node
+    elif self.op.mode == constants.REPLACE_DISK_CHG:
+      n1 = self.new_node = remote_node
+      n2 = self.oth_node = instance.primary_node
+      self.tgt_node = self.sec_node
+    else:
+      raise errors.ProgrammerError("Unhandled disk replace mode")
+
+    _CheckNodeOnline(self, n1)
+    _CheckNodeOnline(self, n2)
 
     if not self.op.disks:
       self.op.disks = range(len(instance.disks))
@@ -4793,13 +4789,10 @@ class LUReplaceDisks(LogicalUnit):
     if instance.status == "down":
       _StartInstanceDisks(self, instance, True)
 
-    if instance.disk_template == constants.DT_DRBD8:
-      if self.op.remote_node is None:
-        fn = self._ExecD8DiskOnly
-      else:
-        fn = self._ExecD8Secondary
+    if self.op.mode == constants.REPLACE_DISK_CHG:
+      fn = self._ExecD8Secondary
     else:
-      raise errors.ProgrammerError("Unhandled disk replacement case")
+      fn = self._ExecD8DiskOnly
 
     ret = fn(feedback_fn)
 
diff --git a/lib/constants.py b/lib/constants.py
index 84e7b5925e5f8180415b16acb3aba0e2b898fb92..ab7f1dd4d95380b94cc0479d70993a050bbe5dc9 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -193,9 +193,9 @@ DISK_RDWR = "rw"
 DISK_ACCESS_SET = frozenset([DISK_RDONLY, DISK_RDWR])
 
 # disk replacement mode
-REPLACE_DISK_PRI = "replace_primary"
-REPLACE_DISK_SEC = "replace_secondary"
-REPLACE_DISK_ALL = "replace_all"
+REPLACE_DISK_PRI = "replace_primary"   # replace disks on primary
+REPLACE_DISK_SEC = "replace_secondary" # replace disks on secondary
+REPLACE_DISK_CHG = "replace_all"       # change secondary node
 
 # lock recalculate mode
 LOCKS_REPLACE = 'replace'
diff --git a/man/gnt-instance.sgml b/man/gnt-instance.sgml
index 9332dfa4b870b1ac793b5df8dafff50272c45a7b..e6d190ecec860a72d892103b4c4f16acd3b64147 100644
--- a/man/gnt-instance.sgml
+++ b/man/gnt-instance.sgml
@@ -1082,24 +1082,25 @@
 
         <cmdsynopsis>
           <command>replace-disks</command>
+          <arg choice="req">-p</arg>
+          <arg choice="req"><replaceable>instance</replaceable></arg>
+        </cmdsynopsis>
 
-          <group choice="req">
-            <arg>--iallocator <replaceable>name</replaceable></arg>
-            <arg>--new-secondary <replaceable>NODE</replaceable></arg>
-          </group>
-          <sbr>
+        <cmdsynopsis>
+          <command>replace-disks</command>
 
-          <arg choice="opt">-s</arg>
+          <arg choice="req">-s</arg>
           <arg choice="req"><replaceable>instance</replaceable></arg>
         </cmdsynopsis>
 
         <cmdsynopsis>
           <command>replace-disks</command>
 
-          <group>
-          <arg choice="req">-s</arg>
-          <arg choice="req">-p</arg>
+          <group choice="req">
+            <arg>--iallocator <replaceable>name</replaceable></arg>
+            <arg>--new-secondary <replaceable>NODE</replaceable></arg>
           </group>
+
           <arg choice="req"><replaceable>instance</replaceable></arg>
         </cmdsynopsis>
 
@@ -1110,16 +1111,21 @@
         </para>
 
         <para>
-          The first form will do a secondary node change, while the
-          second form will replace the disks on either the primary
-          (<option>-p</option>) or the secondary (<option>-s</option>)
-          node of the instance only, without changing the node.
+          The first form (when passing the <option>-p</option> option)
+          will replace the disks on the primary, while the second form
+          (when passing the <option>-s</option> option will replace
+          the disks on the secondary node.
         </para>
 
         <para>
-          Specifying <option>--iallocator</option> enables secondary node
-          replacement and and makes the new secondary be selected automatically
-          by the specified allocator plugin.
+          The third form (when passing either the
+          <option>--iallocator</option> or the
+          <option>--new-secondary</option> option) is designed to
+          change secondary node of the instance.  Specifying
+          <option>--iallocator</option> makes the new secondary be
+          selected automatically by the specified allocator plugin,
+          otherwise the new secondary node will be the one chosen
+          manually via the <option>--new-secondary</option> option.
         </para>
       </refsect3>
 
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index ac616f65532bcc9d07e2f9d3a5245faf65ec3c03..e2cea2603e3948782c8573a82ddb8ae4e894c4ad 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -772,16 +772,18 @@ def ReplaceDisks(opts, args):
       disks = [int(i) for i in opts.disks.split(",")]
     except ValueError, err:
       raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err))
-  if opts.on_primary == opts.on_secondary: # no -p or -s passed, or both passed
-    mode = constants.REPLACE_DISK_ALL
-  elif opts.on_primary: # only on primary:
+  cnt = [opts.on_primary, opts.on_secondary,
+         new_2ndary is not None, iallocator is not None].count(True)
+  if cnt != 1:
+    raise errors.OpPrereqError("One and only one of the -p, -s, -n and -i"
+                               " options must be passed")
+  elif opts.on_primary:
     mode = constants.REPLACE_DISK_PRI
-    if new_2ndary is not None or iallocator is not None:
-      raise errors.OpPrereqError("Can't change secondary node on primary disk"
-                                 " replacement")
-  elif opts.on_secondary is not None or iallocator is not None:
-    # only on secondary
+  elif opts.on_secondary:
     mode = constants.REPLACE_DISK_SEC
+  elif new_2ndary is not None or iallocator is not None:
+    # replace secondary
+    mode = constants.REPLACE_DISK_CHG
 
   op = opcodes.OpReplaceDisks(instance_name=args[0], disks=disks,
                               remote_node=new_2ndary, mode=mode,
@@ -1254,7 +1256,8 @@ commands = {
                     [DEBUG_OPT,
                      make_option("-n", "--new-secondary", dest="new_secondary",
                                  help=("New secondary node (for secondary"
-                                       " node change)"), metavar="NODE"),
+                                       " node change)"), metavar="NODE",
+                                 default=None),
                      make_option("-p", "--on-primary", dest="on_primary",
                                  default=False, action="store_true",
                                  help=("Replace the disk(s) on the primary"
@@ -1267,7 +1270,7 @@ commands = {
                                  help=("Comma-separated list of disks"
                                        " to replace (e.g. sda) (optional,"
                                        " defaults to all disks")),
-                     make_option("--iallocator", metavar="<NAME>",
+                     make_option("-i", "--iallocator", metavar="<NAME>",
                                  help="Select new secondary for the instance"
                                  " automatically using the"
                                  " <NAME> iallocator plugin (enables"