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):