From 36a566e87f9133d73329c900870815bce32b20ce Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Fri, 1 Mar 2013 12:45:38 +0100 Subject: [PATCH] Allow iallocator to work without LVM storage Currently, the iallocator interface requires LVM storage, due to the way it computes the node storage information. By changing the code to understand that GetVGName() can return None, and by setting the disk_total/disk_free node parameters to the value zero, we can workaround this issue until proper multi-storage reporting is implemented. The hail iallocator plugin works without changes once this is implemented, as it already handles non-LVM storage as "foreign" storage (with unlimited capacity). The patch also changes a bit how the parameters are retrieved and used; hopefully this is a bit safer and more readable. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> --- lib/masterd/iallocator.py | 50 +++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/masterd/iallocator.py b/lib/masterd/iallocator.py index d5762b669..7179b0ea6 100644 --- a/lib/masterd/iallocator.py +++ b/lib/masterd/iallocator.py @@ -431,7 +431,14 @@ class IAllocator(object): node_whitelist = None es_flags = rpc.GetExclusiveStorageForNodeNames(cfg, node_list) - node_data = self.rpc.call_node_info(node_list, [cfg.GetVGName()], + vg_name = cfg.GetVGName() + if vg_name is not None: + has_lvm = True + vg_req = [vg_name] + else: + has_lvm = False + vg_req = [] + node_data = self.rpc.call_node_info(node_list, vg_req, [hypervisor_name], es_flags) node_iinfo = \ self.rpc.call_all_instances_info(node_list, @@ -441,7 +448,7 @@ class IAllocator(object): config_ndata = self._ComputeBasicNodeData(cfg, ninfo, node_whitelist) data["nodes"] = self._ComputeDynamicNodeData(ninfo, node_data, node_iinfo, - i_list, config_ndata) + i_list, config_ndata, has_lvm) assert len(data["nodes"]) == len(ninfo), \ "Incomplete node data computed" @@ -494,7 +501,7 @@ class IAllocator(object): @staticmethod def _ComputeDynamicNodeData(node_cfg, node_data, node_iinfo, i_list, - node_results): + node_results, has_lvm): """Compute global node data. @param node_results: the basic node structures as filled from the config @@ -511,17 +518,22 @@ class IAllocator(object): nresult.Raise("Can't get data for node %s" % nname) node_iinfo[nname].Raise("Can't get node instance info from node %s" % nname) - remote_info = rpc.MakeLegacyNodeInfo(nresult.payload) + remote_info = rpc.MakeLegacyNodeInfo(nresult.payload, + require_vg_info=has_lvm) - for attr in ["memory_total", "memory_free", "memory_dom0", - "vg_size", "vg_free", "cpu_total"]: + def get_attr(attr): if attr not in remote_info: raise errors.OpExecError("Node '%s' didn't return attribute" " '%s'" % (nname, attr)) - if not isinstance(remote_info[attr], int): + value = remote_info[attr] + if not isinstance(value, int): raise errors.OpExecError("Node '%s' returned invalid value" " for '%s': %s" % - (nname, attr, remote_info[attr])) + (nname, attr, value)) + return value + + mem_free = get_attr("memory_free") + # compute memory used by primary instances i_p_mem = i_p_up_mem = 0 for iinfo, beinfo in i_list: @@ -532,19 +544,27 @@ class IAllocator(object): else: i_used_mem = int(node_iinfo[nname].payload[iinfo.name]["memory"]) i_mem_diff = beinfo[constants.BE_MAXMEM] - i_used_mem - remote_info["memory_free"] -= max(0, i_mem_diff) + mem_free -= max(0, i_mem_diff) if iinfo.admin_state == constants.ADMINST_UP: i_p_up_mem += beinfo[constants.BE_MAXMEM] + # TODO: replace this with proper storage reporting + if has_lvm: + total_disk = get_attr("vg_size") + free_disk = get_attr("vg_free") + else: + # we didn't even ask the node for VG status, so use zeros + total_disk = free_disk = 0 + # compute memory used by instances pnr_dyn = { - "total_memory": remote_info["memory_total"], - "reserved_memory": remote_info["memory_dom0"], - "free_memory": remote_info["memory_free"], - "total_disk": remote_info["vg_size"], - "free_disk": remote_info["vg_free"], - "total_cpus": remote_info["cpu_total"], + "total_memory": get_attr("memory_total"), + "reserved_memory": get_attr("memory_dom0"), + "free_memory": mem_free, + "total_disk": total_disk, + "free_disk": free_disk, + "total_cpus": get_attr("cpu_total"), "i_pri_memory": i_p_mem, "i_pri_up_memory": i_p_up_mem, } -- GitLab