From 29d376ecbc0a436cdb499d3da742bf6d0bf0e2be Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Tue, 9 Jun 2009 14:45:49 +0200 Subject: [PATCH] Convert volume_list rpc to new style result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a big change, because we need to cleanup its users too. The call and thus LUVerifyDisks LU used to differentiate between failure at node level and failure at LV level, by returning different types in the RPC result. This is way too complicated for our needs. The patch changes to new style result (easy change), and then: - changes LUVerifyDisks.Exec() to return a tuple of 3-elements instead of 4-elements; we collapse the Β«nodes not reachableΒ» and Β«nodes with LVM errorsΒ» in a single dict - changes gnt-cluster to parse 3-element results and simplifies the different by-error handling code Note that the status is added in ganeti-noded, and not in the function itself, as the function is used in other places too. This was tested with down nodes and broken VGs. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> --- daemons/ganeti-noded | 2 +- lib/backend.py | 4 +--- lib/cmdlib.py | 30 ++++++++++++++---------------- scripts/gnt-cluster | 18 +++++++----------- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded index 96a642bd3..0678d114d 100755 --- a/daemons/ganeti-noded +++ b/daemons/ganeti-noded @@ -339,7 +339,7 @@ class NodeHttpServer(http.server.HttpServer): """ vgname = params[0] - return backend.GetVolumeList(vgname) + return True, backend.GetVolumeList(vgname) @staticmethod def perspective_vg_list(params): diff --git a/lib/backend.py b/lib/backend.py index b06e1f62b..1d6572908 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -494,9 +494,7 @@ def GetVolumeList(vg_name): "--separator=%s" % sep, "-olv_name,lv_size,lv_attr", vg_name]) if result.failed: - logging.error("Failed to list logical volumes, lvs output: %s", - result.output) - return result.output + _Fail("Failed to list logical volumes, lvs output: %s", result.output) valid_line_re = re.compile("^ *([^|]+)\|([0-9.]+)\|([^|]{6})\|?$") for line in result.stdout.splitlines(): diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 28e4abfad..c4a13b9ae 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -1289,8 +1289,13 @@ class LUVerifyDisks(NoHooksLU): def Exec(self, feedback_fn): """Verify integrity of cluster disks. + @rtype: tuple of three items + @return: a tuple of (dict of node-to-node_error, list of instances + which need activate-disks, dict of instance: (node, volume) for + missing volumes + """ - result = res_nodes, res_nlvm, res_instances, res_missing = [], {}, [], {} + result = res_nodes, res_instances, res_missing = {}, [], {} vg_name = self.cfg.GetVGName() nodes = utils.NiceSort(self.cfg.GetNodeList()) @@ -1317,24 +1322,17 @@ class LUVerifyDisks(NoHooksLU): to_act = set() for node in nodes: # node_volume - lvs = node_lvs[node] - if lvs.failed: - if not lvs.offline: - self.LogWarning("Connection to node %s failed: %s" % - (node, lvs.data)) - continue - lvs = lvs.data - if isinstance(lvs, basestring): - logging.warning("Error enumerating LVs on node %s: %s", node, lvs) - res_nlvm[node] = lvs + node_res = node_lvs[node] + if node_res.offline: continue - elif not isinstance(lvs, dict): - logging.warning("Connection to node %s failed or invalid data" - " returned", node) - res_nodes.append(node) + msg = node_res.RemoteFailMsg() + if msg: + logging.warning("Error enumerating LVs on node %s: %s", node, msg) + res_nodes[node] = msg continue - for lv_name, (_, lv_inactive, lv_online) in lvs.iteritems(): + lvs = node_res.payload + for lv_name, (_, lv_inactive, lv_online) in lvs.items(): inst = nv_dict.pop((node, lv_name), None) if (not lv_online and inst is not None and inst.name not in res_instances): diff --git a/scripts/gnt-cluster b/scripts/gnt-cluster index 15e0ce9e1..505ffa218 100755 --- a/scripts/gnt-cluster +++ b/scripts/gnt-cluster @@ -361,20 +361,16 @@ def VerifyDisks(opts, args): """ op = opcodes.OpVerifyDisks() result = SubmitOpCode(op) - if not isinstance(result, (list, tuple)) or len(result) != 4: + if not isinstance(result, (list, tuple)) or len(result) != 3: raise errors.ProgrammerError("Unknown result type for OpVerifyDisks") - nodes, nlvm, instances, missing = result + bad_nodes, instances, missing = result - if nodes: - ToStdout("Nodes unreachable or with bad data:") - for name in nodes: - ToStdout("\t%s", name) retcode = constants.EXIT_SUCCESS - if nlvm: - for node, text in nlvm.iteritems(): - ToStdout("Error on node %s: LVM error: %s", + if bad_nodes: + for node, text in bad_nodes.items(): + ToStdout("Error gathering data on node %s: %s", node, utils.SafeEncode(text[-400:])) retcode |= 1 ToStdout("You need to fix these nodes first before fixing instances") @@ -394,7 +390,7 @@ def VerifyDisks(opts, args): if missing: for iname, ival in missing.iteritems(): - all_missing = utils.all(ival, lambda x: x[0] in nlvm) + all_missing = utils.all(ival, lambda x: x[0] in bad_nodes) if all_missing: ToStdout("Instance %s cannot be verified as it lives on" " broken nodes", iname) @@ -402,7 +398,7 @@ def VerifyDisks(opts, args): ToStdout("Instance %s has missing logical volumes:", iname) ival.sort() for node, vol in ival: - if node in nlvm: + if node in bad_nodes: ToStdout("\tbroken node %s /dev/xenvg/%s", node, vol) else: ToStdout("\t%s /dev/xenvg/%s", node, vol) -- GitLab