So far the error only showed that there are disks of a certain template
and that that template can therefore not be disabled. The new error also
shows on what instance (if any) it is mounted.

Signed-off-by: Aaron Karper <[email protected]>
---
 lib/cmdlib/cluster/__init__.py     | 15 +++++++++++++--
 lib/config.py                      | 30 ++++++++++++++++++++++++++++++
 test/py/cmdlib/cluster_unittest.py |  2 +-
 3 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/lib/cmdlib/cluster/__init__.py b/lib/cmdlib/cluster/__init__.py
index 28ddb96..6244e17 100644
--- a/lib/cmdlib/cluster/__init__.py
+++ b/lib/cmdlib/cluster/__init__.py
@@ -1150,10 +1150,21 @@ class LUClusterSetParams(LogicalUnit):
 
     """
     for disk_template in disabled_disk_templates:
-      if self.cfg.HasAnyDiskOfType(disk_template):
+      disks_with_type = [d for d in self.cfg.GetAllDiskInfo().values()
+                         if d.dev_type == disk_template]
+      if disks_with_type:
+        disk_desc = []
+        for disk in disks_with_type:
+          instance_uuid = self.cfg.GetInstanceForDisk(d.uuid)
+          instance = self.cfg.GetInstanceInfo(instance_uuid)
+          if instance:
+            instance_desc = "on " + instance.name
+          else:
+            instance_desc = "detached"
+          disk_desc.append("%s (%s)" % (disk, instance_desc))
         raise errors.OpPrereqError(
             "Cannot disable disk template '%s', because there is at least one"
-            " instance using it." % disk_template,
+            " disk using it:\n * %s" % (disk_template, "\n * 
".join(disk_desc)),
             errors.ECODE_STATE)
 
   @staticmethod
diff --git a/lib/config.py b/lib/config.py
index 816e947..cfddeab 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -3557,6 +3557,36 @@ class ConfigWriter(object):
     if not self._offline:
       self._wconfd.FlushConfig()
 
+  @_ConfigSync(shared=1)
+  def GetAllDiskInfo(self):
+    """Get the configuration of all disks.
+
+    @rtype: dict
+    @return: dict of (disk, disk_info), where disk_info is what
+              would GetDiskInfo return for disk
+    """
+    return self._UnlockedGetAllDiskInfo()
+
+  def _UnlockedGetAllDiskInfo(self):
+    return dict((disk_uuid, self._UnlockedGetDiskInfo(disk_uuid))
+                for disk_uuid in self._UnlockedGetDiskList())
+
+  def _UnlockedGetDiskList(self):
+    return self._ConfigData().disks.keys()
+
+  @_ConfigSync(shared=1)
+  def GetInstanceForDisk(self, disk_uuid):
+    """Returns the instance the disk is currently attached to.
+
+    @type disk_uuid: string
+    @param disk_uuid: the identifier of the disk in question.
+
+    @rtype: string
+    @return: uuid of instance the disk is attached to.
+    """
+    for inst_uuid, inst_info in self._UnlockedGetAllInstancesInfo().items():
+      if disk_uuid in inst_info.disks:
+        return inst_uuid
 
 class DetachedConfig(ConfigWriter):
   def __init__(self, config_data):
diff --git a/test/py/cmdlib/cluster_unittest.py 
b/test/py/cmdlib/cluster_unittest.py
index fca96ad..803c373 100644
--- a/test/py/cmdlib/cluster_unittest.py
+++ b/test/py/cmdlib/cluster_unittest.py
@@ -866,7 +866,7 @@ class TestLUClusterSetParams(CmdlibTestCase):
     op = opcodes.OpClusterSetParams(
            enabled_disk_templates=new_disk_templates,
            ipolicy={constants.IPOLICY_DTS: new_disk_templates})
-    self.ExecOpCodeExpectOpPrereqError(op, "least one instance using it")
+    self.ExecOpCodeExpectOpPrereqError(op, "least one disk using it")
 
   def testEnabledDiskTemplatesWithoutVgName(self):
     enabled_disk_templates = [constants.DT_PLAIN]
-- 
2.1.0.rc2.206.gedb03e5

Reply via email to