diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded
index 12f6b7a48b35f791b33593dc72b0409486bd5b78..665b84c3c3d2892b6b36b212ea682fae38d5ead3 100755
--- a/daemons/ganeti-noded
+++ b/daemons/ganeti-noded
@@ -135,7 +135,7 @@ class ServerObject(pb.Avatar):
     return backend.ShutdownBlockDevice(bdev)
 
   @staticmethod
-  def perspective_blockdev_addchild(params):
+  def perspective_blockdev_addchildren(params):
     """Add a child to a mirror device.
 
     Note: this is only valid for mirror devices. It's the caller's duty
@@ -144,13 +144,13 @@ class ServerObject(pb.Avatar):
     """
     bdev_s, ndev_s = params
     bdev = objects.Disk.FromDict(bdev_s)
-    ndev = objects.Disk.FromDict(ndev_s)
-    if bdev is None or ndev is None:
+    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
+    if bdev is None or ndevs.count(None) > 0:
       raise ValueError("can't unserialize data!")
-    return backend.MirrorAddChild(bdev, ndev)
+    return backend.MirrorAddChildren(bdev, ndevs)
 
   @staticmethod
-  def perspective_blockdev_removechild(params):
+  def perspective_blockdev_removechildren(params):
     """Remove a child from a mirror device.
 
     This is only valid for mirror devices, of course. It's the callers
@@ -159,10 +159,10 @@ class ServerObject(pb.Avatar):
     """
     bdev_s, ndev_s = params
     bdev = objects.Disk.FromDict(bdev_s)
-    ndev = objects.Disk.FromDict(ndev_s)
-    if bdev is None or ndev is None:
+    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
+    if bdev is None or ndevs.count(None) > 0:
       raise ValueError("can't unserialize data!")
-    return backend.MirrorRemoveChild(bdev, ndev)
+    return backend.MirrorRemoveChildren(bdev, ndevs)
 
   @staticmethod
   def perspective_blockdev_getmirrorstatus(params):
diff --git a/lib/backend.py b/lib/backend.py
index 78ce3816d35304b92125fff6e938c8a714607861..56dab650d82fb2fb0d159f4bf331f6be872c39ee 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -768,35 +768,33 @@ def ShutdownBlockDevice(disk):
   return result
 
 
-def MirrorAddChild(md_cdev, new_cdev):
-  """Extend an MD raid1 array.
+def MirrorAddChildren(parent_cdev, new_cdevs):
+  """Extend a mirrored block device.
 
   """
-  md_bdev = _RecursiveFindBD(md_cdev, allow_partial=True)
-  if md_bdev is None:
-    logger.Error("Can't find md device")
+  parent_bdev = _RecursiveFindBD(parent_cdev, allow_partial=True)
+  if parent_bdev is None:
+    logger.Error("Can't find parent device")
     return False
-  new_bdev = _RecursiveFindBD(new_cdev)
-  if new_bdev is None:
-    logger.Error("Can't find new device to add")
+  new_bdevs = [_RecursiveFindBD(disk) for disk in new_cdevs]
+  if new_bdevs.count(None) > 0:
+    logger.Error("Can't find new device(s) to add")
     return False
-  new_bdev.Open()
-  md_bdev.AddChild(new_bdev)
+  parent_bdev.AddChildren(new_bdevs)
   return True
 
 
-def MirrorRemoveChild(md_cdev, new_cdev):
-  """Reduce an MD raid1 array.
+def MirrorRemoveChildren(parent_cdev, new_cdevs):
+  """Shrink a mirrored block device.
 
   """
-  md_bdev = _RecursiveFindBD(md_cdev)
-  if md_bdev is None:
+  parent_bdev = _RecursiveFindBD(parent_cdev)
+  if parent_bdev is None:
     return False
-  new_bdev = _RecursiveFindBD(new_cdev)
-  if new_bdev is None:
+  new_bdevs = [_RecursiveFindBD(disk) for disk in new_cdevs]
+  if new_bdevs.count(None) > 0:
     return False
-  new_bdev.Open()
-  md_bdev.RemoveChild(new_bdev.dev_path)
+  parent_bdev.RemoveChildren(new_bdevs)
   return True
 
 
diff --git a/lib/bdev.py b/lib/bdev.py
index 0e8ddf4d48e8e9353d0f173a558accc69a542cc6..a01f813051ecfceb55eab2b547869ecfdc38978d 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -701,59 +701,71 @@ class MDRaid1(BlockDev):
     return self.Shutdown()
 
 
-  def AddChild(self, device):
-    """Add a new member to the md raid1.
+  def AddChildren(self, devices):
+    """Add new member(s) to the md raid1.
 
     """
     if self.minor is None and not self.Attach():
       raise errors.BlockDeviceError("Can't attach to device")
-    if device.dev_path is None:
-      raise errors.BlockDeviceError("New child is not initialised")
-    result = utils.RunCmd(["mdadm", "-a", self.dev_path, device.dev_path])
+
+    args = ["mdadm", "-a", self.dev_path]
+    for dev in devices:
+      if dev.dev_path is None:
+        raise errors.BlockDeviceError("Child '%s' is not initialised" % dev)
+      dev.Open()
+      args.append(dev.dev_path)
+    result = utils.RunCmd(args)
     if result.failed:
       raise errors.BlockDeviceError("Failed to add new device to array: %s" %
                                     result.output)
-    new_len = len(self._children) + 1
+    new_len = len(self._children) + len(devices)
     result = utils.RunCmd(["mdadm", "--grow", self.dev_path, "-n", new_len])
     if result.failed:
       raise errors.BlockDeviceError("Can't grow md array: %s" %
                                     result.output)
-    self._children.append(device)
+    self._children.extend(devices)
 
 
-  def RemoveChild(self, dev_path):
-    """Remove member from the md raid1.
+  def RemoveChildren(self, devices):
+    """Remove member(s) from the md raid1.
 
     """
     if self.minor is None and not self.Attach():
       raise errors.BlockDeviceError("Can't attach to device")
-    if len(self._children) == 1:
-      raise errors.BlockDeviceError("Can't reduce member when only one"
-                                    " child left")
-    for device in self._children:
-      if device.dev_path == dev_path:
-        break
-    else:
-      raise errors.BlockDeviceError("Can't find child with this path")
-    new_len = len(self._children) - 1
-    result = utils.RunCmd(["mdadm", "-f", self.dev_path, dev_path])
+    new_len = len(self._children) - len(devices)
+    if new_len < 1:
+      raise errors.BlockDeviceError("Can't reduce to less than one child")
+    args = ["mdadm", "-f", self.dev_path]
+    orig_devs = []
+    for dev in devices:
+      args.append(dev.dev_path)
+      for c in self._children:
+        if c.dev_path == dev.dev_path:
+          orig_devs.append(c)
+          break
+      else:
+        raise errors.BlockDeviceError("Can't find device '%s' for removal" %
+                                      dev)
+    result = utils.RunCmd(args)
     if result.failed:
-      raise errors.BlockDeviceError("Failed to mark device as failed: %s" %
+      raise errors.BlockDeviceError("Failed to mark device(s) as failed: %s" %
                                     result.output)
 
     # it seems here we need a short delay for MD to update its
     # superblocks
     time.sleep(0.5)
-    result = utils.RunCmd(["mdadm", "-r", self.dev_path, dev_path])
+    args[1] = "-r"
+    result = utils.RunCmd(args)
     if result.failed:
-      raise errors.BlockDeviceError("Failed to remove device from array:"
-                                        " %s" % result.output)
+      raise errors.BlockDeviceError("Failed to remove device(s) from array:"
+                                    " %s" % result.output)
     result = utils.RunCmd(["mdadm", "--grow", "--force", self.dev_path,
                            "-n", new_len])
     if result.failed:
       raise errors.BlockDeviceError("Can't shrink md array: %s" %
                                     result.output)
-    self._children.remove(device)
+    for dev in orig_devs:
+      self._children.remove(dev)
 
 
   def GetStatus(self):
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index ab433ed09a0f23a9770a7ab61f1f9bdf4dd388f2..04612d77bb1e1500b8152f45749d23b84f3b96bc 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -3223,8 +3223,8 @@ class LUAddMDDRBDComponent(LogicalUnit):
     # the device exists now
     # call the primary node to add the mirror to md
     logger.Info("adding new mirror component to md")
-    if not rpc.call_blockdev_addchild(instance.primary_node,
-                                           disk, new_drbd):
+    if not rpc.call_blockdev_addchildren(instance.primary_node,
+                                         disk, [new_drbd]):
       logger.Error("Can't add mirror compoment to md!")
       self.cfg.SetDiskID(new_drbd, remote_node)
       if not rpc.call_blockdev_remove(remote_node, new_drbd):
@@ -3316,8 +3316,8 @@ class LURemoveMDDRBDComponent(LogicalUnit):
     child = self.child
     logger.Info("remove mirror component")
     self.cfg.SetDiskID(disk, instance.primary_node)
-    if not rpc.call_blockdev_removechild(instance.primary_node,
-                                              disk, child):
+    if not rpc.call_blockdev_removechildren(instance.primary_node,
+                                            disk, [child]):
       raise errors.OpExecError("Can't remove child from mirror.")
 
     for node in child.logical_id[:2]:
@@ -3427,8 +3427,8 @@ class LUReplaceDisks(LogicalUnit):
       # the device exists now
       # call the primary node to add the mirror to md
       logger.Info("adding new mirror component to md")
-      if not rpc.call_blockdev_addchild(instance.primary_node, dev,
-                                        new_drbd):
+      if not rpc.call_blockdev_addchildren(instance.primary_node, dev,
+                                           [new_drbd]):
         logger.Error("Can't add mirror compoment to md!")
         cfg.SetDiskID(new_drbd, remote_node)
         if not rpc.call_blockdev_remove(remote_node, new_drbd):
@@ -3462,8 +3462,8 @@ class LUReplaceDisks(LogicalUnit):
       dev, child, new_drbd = iv_names[name]
       logger.Info("remove mirror %s component" % name)
       cfg.SetDiskID(dev, instance.primary_node)
-      if not rpc.call_blockdev_removechild(instance.primary_node,
-                                                dev, child):
+      if not rpc.call_blockdev_removechildren(instance.primary_node,
+                                              dev, [child]):
         logger.Error("Can't remove child from mirror, aborting"
                      " *this device cleanup*.\nYou need to cleanup manually!!")
         continue
diff --git a/lib/rpc.py b/lib/rpc.py
index f545e79d0432b4a43979203c31ea5e35d0f7356b..4153da8f58d9628863275c54883a3de594a76309 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -539,27 +539,27 @@ def call_blockdev_shutdown(node, disk):
   return c.getresult().get(node, False)
 
 
-def call_blockdev_addchild(node, bdev, ndev):
-  """Request adding a new child to a (mirroring) device.
+def call_blockdev_addchildren(node, bdev, ndevs):
+  """Request adding a list of children to a (mirroring) device.
 
   This is a single-node call.
 
   """
-  params = [bdev.ToDict(), ndev.ToDict()]
-  c = Client("blockdev_addchild", params)
+  params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
+  c = Client("blockdev_addchildren", params)
   c.connect(node)
   c.run()
   return c.getresult().get(node, False)
 
 
-def call_blockdev_removechild(node, bdev, ndev):
-  """Request removing a new child from a (mirroring) device.
+def call_blockdev_removechildren(node, bdev, ndevs):
+  """Request removing a list of children from a (mirroring) device.
 
   This is a single-node call.
 
   """
-  params = [bdev.ToDict(), ndev.ToDict()]
-  c = Client("blockdev_removechild", params)
+  params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
+  c = Client("blockdev_removechildren", params)
   c.connect(node)
   c.run()
   return c.getresult().get(node, False)