diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py index b094b37dfbf7dba6bfc3c45f073fb619d431c7e4..e5de1b7cc09423f391a61b246dacfb48d0dbb0a4 100644 --- a/lib/hypervisor/hv_base.py +++ b/lib/hypervisor/hv_base.py @@ -23,6 +23,9 @@ """ +import re + + from ganeti import errors @@ -187,3 +190,64 @@ class BaseHypervisor(object): """ pass + + def GetLinuxNodeInfo(self): + """For linux systems, return actual OS information. + + This is an abstraction for all non-hypervisor-based classes, where + the node actually sees all the memory and CPUs via the /proc + interface and standard commands. The other case if for example + xen, where you only see the hardware resources via xen-specific + tools. + + @return: a dict with the following keys (values in MiB): + - memory_total: the total memory size on the node + - memory_free: the available memory on the node for instances + - memory_dom0: the memory used by the node itself, if available + + """ + try: + fh = file("/proc/meminfo") + try: + data = fh.readlines() + finally: + fh.close() + except EnvironmentError, err: + raise errors.HypervisorError("Failed to list node info: %s" % (err,)) + + result = {} + sum_free = 0 + try: + for line in data: + splitfields = line.split(":", 1) + + if len(splitfields) > 1: + key = splitfields[0].strip() + val = splitfields[1].strip() + if key == 'MemTotal': + result['memory_total'] = int(val.split()[0])/1024 + elif key in ('MemFree', 'Buffers', 'Cached'): + sum_free += int(val.split()[0])/1024 + elif key == 'Active': + result['memory_dom0'] = int(val.split()[0])/1024 + except (ValueError, TypeError), err: + raise errors.HypervisorError("Failed to compute memory usage: %s" % + (err,)) + result['memory_free'] = sum_free + + cpu_total = 0 + try: + fh = open("/proc/cpuinfo") + try: + cpu_total = len(re.findall("(?m)^processor\s*:\s*[0-9]+\s*$", + fh.read())) + finally: + fh.close() + except EnvironmentError, err: + raise errors.HypervisorError("Failed to list node info: %s" % (err,)) + result['cpu_total'] = cpu_total + # FIXME: export correct data here + result['cpu_nodes'] = 1 + result['cpu_sockets'] = 1 + + return result diff --git a/lib/hypervisor/hv_fake.py b/lib/hypervisor/hv_fake.py index 48e645bf7a493075782a957079feaea2525da8ea..ccac8427730d419579e141910fba4f204f95b449 100644 --- a/lib/hypervisor/hv_fake.py +++ b/lib/hypervisor/hv_fake.py @@ -155,61 +155,19 @@ class FakeHypervisor(hv_base.BaseHypervisor): def GetNodeInfo(self): """Return information about the node. + This is just a wrapper over the base GetLinuxNodeInfo method. + @return: a dict with the following keys (values in MiB): - memory_total: the total memory size on the node - memory_free: the available memory on the node for instances - memory_dom0: the memory used by the node itself, if available """ - # global ram usage from the xm info command - # memory : 3583 - # free_memory : 747 - # note: in xen 3, memory has changed to total_memory - try: - fh = file("/proc/meminfo") - try: - data = fh.readlines() - finally: - fh.close() - except IOError, err: - raise errors.HypervisorError("Failed to list node info: %s" % err) - - result = {} - sum_free = 0 - for line in data: - splitfields = line.split(":", 1) - - if len(splitfields) > 1: - key = splitfields[0].strip() - val = splitfields[1].strip() - if key == 'MemTotal': - result['memory_total'] = int(val.split()[0])/1024 - elif key in ('MemFree', 'Buffers', 'Cached'): - sum_free += int(val.split()[0])/1024 - elif key == 'Active': - result['memory_dom0'] = int(val.split()[0])/1024 - result['memory_free'] = sum_free - + result = self.GetLinuxNodeInfo() # substract running instances all_instances = self.GetAllInstancesInfo() result['memory_free'] -= min(result['memory_free'], sum([row[2] for row in all_instances])) - - cpu_total = 0 - try: - fh = open("/proc/cpuinfo") - try: - cpu_total = len(re.findall("(?m)^processor\s*:\s*[0-9]+\s*$", - fh.read())) - finally: - fh.close() - except EnvironmentError, err: - raise errors.HypervisorError("Failed to list node info: %s" % err) - result['cpu_total'] = cpu_total - # FIXME: export correct data here - result['cpu_nodes'] = 1 - result['cpu_sockets'] = 1 - return result @classmethod diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py index 246c7f9f7b7b7db9336e61912d8fd14ae492d74e..7e2fdea2c1fec6c5c076b43317000abe96afa8c1 100644 --- a/lib/hypervisor/hv_kvm.py +++ b/lib/hypervisor/hv_kvm.py @@ -618,57 +618,15 @@ class KVMHypervisor(hv_base.BaseHypervisor): def GetNodeInfo(self): """Return information about the node. + This is just a wrapper over the base GetLinuxNodeInfo method. + @return: a dict with the following keys (values in MiB): - memory_total: the total memory size on the node - memory_free: the available memory on the node for instances - memory_dom0: the memory used by the node itself, if available """ - # global ram usage from the xm info command - # memory : 3583 - # free_memory : 747 - # note: in xen 3, memory has changed to total_memory - try: - fh = file("/proc/meminfo") - try: - data = fh.readlines() - finally: - fh.close() - except EnvironmentError, err: - raise errors.HypervisorError("Failed to list node info: %s" % err) - - result = {} - sum_free = 0 - for line in data: - splitfields = line.split(":", 1) - - if len(splitfields) > 1: - key = splitfields[0].strip() - val = splitfields[1].strip() - if key == 'MemTotal': - result['memory_total'] = int(val.split()[0])/1024 - elif key in ('MemFree', 'Buffers', 'Cached'): - sum_free += int(val.split()[0])/1024 - elif key == 'Active': - result['memory_dom0'] = int(val.split()[0])/1024 - result['memory_free'] = sum_free - - cpu_total = 0 - try: - fh = open("/proc/cpuinfo") - try: - cpu_total = len(re.findall("(?m)^processor\s*:\s*[0-9]+\s*$", - fh.read())) - finally: - fh.close() - except EnvironmentError, err: - raise errors.HypervisorError("Failed to list node info: %s" % err) - result['cpu_total'] = cpu_total - # FIXME: export correct data here - result['cpu_nodes'] = 1 - result['cpu_sockets'] = 1 - - return result + return self.GetLinuxNodeInfo() @classmethod def GetShellCommandForConsole(cls, instance, hvparams, beparams):