Verify disks: increase parallelism and other fixes
authorIustin Pop <iustin@google.com>
Wed, 26 Jan 2011 17:54:36 +0000 (18:54 +0100)
committerIustin Pop <iustin@google.com>
Wed, 26 Jan 2011 18:20:36 +0000 (19:20 +0100)
The recent work on multi-VG support has converted LUClusterVerifyDisks
into doing serialised calls to each node, as each node can have
different VGs. This is suboptimal, especially for big clusters, where
this LU is executed by the watcher very often.

This patch changes the logic based on the observation that querying a
node for its VGs and then requesting a LV list for those VGs is
equivalent to simply asking for all LVs, without specifying the VG
name(s). So backend.py needs changes to accept an empty VG list, and
the LU itself partially reverts to the previous version.

Additionally, we do two other fixes to this LU:

- small improvement in getting the instance list from the config
- MapLVsByNode works for all disk types, hence no need to restrict to
  the DRBD template, especially as today we can "recreate" disks for
  plain volumes too (the warning message in gnt-cluster is updated
  too)

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>

lib/backend.py
lib/client/gnt_cluster.py
lib/cmdlib.py

index 36a44b3..8f53364 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -642,7 +642,8 @@ def GetVolumeList(vg_names):
   """Compute list of logical volumes and their size.
 
   @type vg_names: list
-  @param vg_names: the volume groups whose LVs we should list
+  @param vg_names: the volume groups whose LVs we should list, or
+      empty for all volume groups
   @rtype: dict
   @return:
       dictionary of all partions (key) with value being a tuple of
@@ -656,6 +657,8 @@ def GetVolumeList(vg_names):
   """
   lvs = {}
   sep = '|'
+  if not vg_names:
+    vg_names = []
   result = utils.RunCmd(["lvs", "--noheadings", "--units=m", "--nosuffix",
                          "--separator=%s" % sep,
                          "-ovg_name,lv_name,lv_size,lv_attr"] + vg_names)
index 21b79bf..1755ef9 100644 (file)
@@ -504,7 +504,7 @@ def VerifyDisks(opts, args):
           else:
             ToStdout("\t%s /dev/%s", node, vol)
 
-    ToStdout("You need to run replace_disks for all the above"
+    ToStdout("You need to run replace or recreate disks for all the above"
              " instances, if this message persist after fixing nodes.")
     retcode |= 1
 
index e129a35..c562018 100644 (file)
@@ -2406,14 +2406,12 @@ class LUClusterVerifyDisks(NoHooksLU):
     result = res_nodes, res_instances, res_missing = {}, [], {}
 
     nodes = utils.NiceSort(self.cfg.GetVmCapableNodeList())
-    instances = [self.cfg.GetInstanceInfo(name)
-                 for name in self.cfg.GetInstanceList()]
+    instances = self.cfg.GetAllInstancesInfo().values()
 
     nv_dict = {}
     for inst in instances:
       inst_lvs = {}
-      if (not inst.admin_up or
-          inst.disk_template not in constants.DTS_NET_MIRROR):
+      if not inst.admin_up:
         continue
       inst.MapLVsByNode(inst_lvs)
       # transform { iname: {node: [vol,],},} to {(node, vol): iname}
@@ -2424,14 +2422,8 @@ class LUClusterVerifyDisks(NoHooksLU):
     if not nv_dict:
       return result
 
-    vg_names = self.rpc.call_vg_list(nodes)
-    for node in nodes:
-      vg_names[node].Raise("Cannot get list of VGs")
-
-    for node in nodes:
-      # node_volume
-      node_res = self.rpc.call_lv_list([node],
-                                       vg_names[node].payload.keys())[node]
+    node_lvs = self.rpc.call_lv_list(nodes, [])
+    for node, node_res in node_lvs.items():
       if node_res.offline:
         continue
       msg = node_res.fail_msg