From 58bc624193f22c5b923f7d3ff856be0521003851 Mon Sep 17 00:00:00 2001 From: Bernardo Dal Seno <bdalseno@google.com> Date: Fri, 7 Dec 2012 19:19:02 +0100 Subject: [PATCH] add-node checks PVs add-node now performs a few checks on LVM before adding a node to the cluster. Signed-off-by: Bernardo Dal Seno <bdalseno@google.com> Reviewed-by: Michael Hanselmann <hansmi@google.com> --- lib/cmdlib.py | 68 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/lib/cmdlib.py b/lib/cmdlib.py index f13b1c14f..29f930c12 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -1121,6 +1121,29 @@ def _CheckNodeHasSecondaryIP(lu, node, secondary_ip, prereq): raise errors.OpExecError(msg) +def _CheckNodePVs(nresult, exclusive_storage): + """Check node PVs. + + """ + pvlist_dict = nresult.get(constants.NV_PVLIST, None) + if pvlist_dict is None: + return (["Can't get PV list from node"], None) + pvlist = map(objects.LvmPvInfo.FromDict, pvlist_dict) + errlist = [] + # check that ':' is not present in PV names, since it's a + # special character for lvcreate (denotes the range of PEs to + # use on the PV) + for pv in pvlist: + if ":" in pv.name: + errlist.append("Invalid character ':' in PV '%s' of VG '%s'" % + (pv.name, pv.vg_name)) + es_pvinfo = None + if exclusive_storage: + (errmsgs, es_pvinfo) = utils.LvmExclusiveCheckNodePvs(pvlist) + errlist.extend(errmsgs) + return (errlist, es_pvinfo) + + def _GetClusterDomainSecret(): """Reads the cluster domain secret. @@ -2465,26 +2488,12 @@ class LUClusterVerifyGroup(LogicalUnit, _VerifyErrors): constants.MIN_VG_SIZE) _ErrorIf(vgstatus, constants.CV_ENODELVM, node, vgstatus) - # check pv names (and possibly sizes) - pvlist_dict = nresult.get(constants.NV_PVLIST, None) - test = pvlist_dict is None - _ErrorIf(test, constants.CV_ENODELVM, node, "Can't get PV list from node") - if not test: - pvlist = map(objects.LvmPvInfo.FromDict, pvlist_dict) - # check that ':' is not present in PV names, since it's a - # special character for lvcreate (denotes the range of PEs to - # use on the PV) - for pv in pvlist: - test = ":" in pv.name - _ErrorIf(test, constants.CV_ENODELVM, node, - "Invalid character ':' in PV '%s' of VG '%s'", - pv.name, pv.vg_name) - if self._exclusive_storage: - (errmsgs, (pvmin, pvmax)) = utils.LvmExclusiveCheckNodePvs(pvlist) - for msg in errmsgs: - self._Error(constants.CV_ENODELVM, node, msg) - nimg.pv_min = pvmin - nimg.pv_max = pvmax + # Check PVs + (errmsgs, pvminmax) = _CheckNodePVs(nresult, self._exclusive_storage) + for em in errmsgs: + self._Error(constants.CV_ENODELVM, node, em) + if pvminmax is not None: + (nimg.pv_min, nimg.pv_max) = pvminmax def _VerifyGroupLVM(self, node_image, vg_name): """Check cross-node consistency in LVM. @@ -6117,7 +6126,7 @@ class LUNodeAdd(LogicalUnit): secondary_ip=secondary_ip, master_candidate=self.master_candidate, offline=False, drained=False, - group=node_group) + group=node_group, ndparams={}) if self.op.ndparams: utils.ForceDictType(self.op.ndparams, constants.NDS_PARAMETER_TYPES) @@ -6130,7 +6139,8 @@ class LUNodeAdd(LogicalUnit): # TODO: If we need to have multiple DnsOnlyRunner we probably should make # it a property on the base class. - result = rpc.DnsOnlyRunner().call_version([node])[node] + rpcrunner = rpc.DnsOnlyRunner() + result = rpcrunner.call_version([node])[node] result.Raise("Can't get version information from node %s" % node) if constants.PROTOCOL_VERSION == result.payload: logging.info("Communication to node %s fine, sw version %s match", @@ -6141,6 +6151,20 @@ class LUNodeAdd(LogicalUnit): (constants.PROTOCOL_VERSION, result.payload), errors.ECODE_ENVIRON) + vg_name = cfg.GetVGName() + if vg_name is not None: + vparams = {constants.NV_PVLIST: [vg_name]} + excl_stor = _IsExclusiveStorageEnabledNode(cfg, self.new_node) + if self.op.ndparams: + excl_stor = self.op.ndparams.get(constants.ND_EXCLUSIVE_STORAGE, + excl_stor) + cname = self.cfg.GetClusterName() + result = rpcrunner.call_node_verify_light([node], vparams, cname)[node] + (errmsgs, _) = _CheckNodePVs(result.payload, excl_stor) + if errmsgs: + raise errors.OpPrereqError("Checks on node PVs failed: %s" % + "; ".join(errmsgs), errors.ECODE_ENVIRON) + def Exec(self, feedback_fn): """Adds the new node to the cluster. -- GitLab