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>
"""
vgname = params[0]
- return backend.GetVolumeList(vgname)
+ return True, backend.GetVolumeList(vgname)
@staticmethod
def perspective_vg_list(params):
"--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():
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())
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):
"""
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")
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)
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)