From 54155f5249e0e37f351b30834cb2c17a5fb5c08e Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Thu, 20 Nov 2008 06:22:52 +0000
Subject: [PATCH] Convert replace-disks (same nodes) to multi-disk

This patch changes the drbd8 replace disk only (no secondary change) to
work in with multi-disk. This mode of replaces works correctly with
replacing only a subset of disks.

Reviewed-by: imsnah
---
 lib/cmdlib.py        | 30 +++++++++++++++++-------------
 scripts/gnt-instance |  7 +++++--
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 4b66c1905..958f7f3b9 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -4035,8 +4035,11 @@ class LUReplaceDisks(LogicalUnit):
       else:
         raise errors.ProgrammerError("Unhandled disk replace mode")
 
-    for name in self.op.disks:
-      if instance.FindDisk(name) is None:
+    if not self.op.disks:
+      self.op.disks = range(len(instance.disks))
+
+    for disk_idx in self.op.disks:
+      if disk_idx < 0 or disk_idx >= len(instance.disks):
         raise errors.OpPrereqError("Disk '%s' not found for instance '%s'" %
                                    (name, instance.name))
 
@@ -4079,22 +4082,22 @@ class LUReplaceDisks(LogicalUnit):
       if not res or my_vg not in res:
         raise errors.OpExecError("Volume group '%s' not found on %s" %
                                  (my_vg, node))
-    for dev in instance.disks:
-      if not dev.iv_name in self.op.disks:
+    for idx, dev in enumerate(instance.disks):
+      if idx not in self.op.disks:
         continue
       for node in tgt_node, oth_node:
-        info("checking %s on %s" % (dev.iv_name, node))
+        info("checking disk/%d on %s" % (idx, node))
         cfg.SetDiskID(dev, node)
         if not self.rpc.call_blockdev_find(node, dev):
-          raise errors.OpExecError("Can't find device %s on node %s" %
-                                   (dev.iv_name, node))
+          raise errors.OpExecError("Can't find disk/%d on node %s" %
+                                   (idx, node))
 
     # Step: check other node consistency
     self.proc.LogStep(2, steps_total, "check peer consistency")
-    for dev in instance.disks:
-      if not dev.iv_name in self.op.disks:
+    for idx, dev in enumerate(instance.disks):
+      if idx not in self.op.disks:
         continue
-      info("checking %s consistency on %s" % (dev.iv_name, oth_node))
+      info("checking disk/%d consistency on %s" % (idx, oth_node))
       if not _CheckDiskConsistency(self, dev, oth_node,
                                    oth_node==instance.primary_node):
         raise errors.OpExecError("Peer node (%s) has degraded storage, unsafe"
@@ -4103,12 +4106,13 @@ class LUReplaceDisks(LogicalUnit):
 
     # Step: create new storage
     self.proc.LogStep(3, steps_total, "allocate new storage")
-    for dev in instance.disks:
-      if not dev.iv_name in self.op.disks:
+    for idx, dev in enumerate(instance.disks):
+      if idx not in self.op.disks:
         continue
       size = dev.size
       cfg.SetDiskID(dev, tgt_node)
-      lv_names = [".%s_%s" % (dev.iv_name, suf) for suf in ["data", "meta"]]
+      lv_names = [".disk%d_%s" % (idx, suf)
+                  for suf in ["data", "meta"]]
       names = _GenerateUniqueNames(self, lv_names)
       lv_data = objects.Disk(dev_type=constants.LD_LV, size=size,
                              logical_id=(vgname, names[0]))
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index 5b4162cc1..b102dce79 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -756,9 +756,12 @@ def ReplaceDisks(opts, args):
   new_2ndary = opts.new_secondary
   iallocator = opts.iallocator
   if opts.disks is None:
-    disks = ["sda", "sdb"]
+    disks = []
   else:
-    disks = opts.disks.split(",")
+    try:
+      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:
-- 
GitLab