]> git.ipfire.org Git - oddments/fireinfo.git/commitdiff
Implement the VMWare hypervisor port check.
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 26 Dec 2010 14:50:11 +0000 (15:50 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 26 Dec 2010 14:50:11 +0000 (15:50 +0100)
We need this because sometimes, the general check fails.

fireinfo/hypervisor.py
src/fireinfo.c

index 46b58e14e3ac940e837ba5c48ee184f025b8492f..83f2a8538fff85d9b97a51a4ef01c0999502980c 100644 (file)
@@ -37,11 +37,11 @@ class Hypervisor(object):
 
                if not self.__info["hypervisor"]:
                        # On VMWare systems, the bios vendor string contains "VMWare".
-                       if "VMWare" in self.system.bios_vendor:
+                       if self.__is_hypervisor_vmware():
                                return "VMWare"
 
                        # VirtualBox got "innotek GmbH" as bios vendor.
-                       elif self.system.bios_vendor == "innotek GmbH":
+                       elif self.__is_hypervisor_virtualbox():
                                return "VirtualBox"
 
                return "unknown"
@@ -65,7 +65,24 @@ class Hypervisor(object):
                """
                return _fireinfo.is_virtualized() or \
                        "hypervisor" in self.system.cpu.flags or \
-                       self.system.bios_vendor == "innotek GmbH"
+                       self.__is_hypervisor_virtualbox() or \
+                       self.__is_hypervisor_vmware()
+
+       def __is_hypervisor_virtualbox(self):
+               """
+                       Check for virtualbox hypervisor by comparing the bios vendor string
+                       to "innotek GmbH".
+               """
+               return self.system.bios_vendor == "innotek GmbH"
+
+       def __is_hypervisor_vmware(self):
+               """
+                       Check for the VMWare hypervisor by the VMWare Hypervisor port check.
+
+                       http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
+               """
+               return self.system.bios_vendor.startswith("VMWare-") and \
+                       _fireinfo.vmware_hypervisor_port_check()
 
 
 if __name__ == "__main__":
index 70ddf786db621e0f69e54a0f8e149af84be5cf09..3a03a39f0c574ac8be30d776f927aee8fe55dac4 100644 (file)
 #define _PATH_PROC_XENCAP      _PATH_PROC_XEN "/capabilities"
 #define _PATH_PROC_PCIDEVS     "/proc/bus/pci/devices"
 
+/* Used for the vmware hypervisor port detection */
+#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
+#define VMWARE_HYPERVISOR_PORT  0x5658
+
+#define VMWARE_PORT_CMD_GETVERSION      10
+
+#define VMWARE_PORT(cmd, eax, ebx, ecx, edx)                            \
+               __asm__("inl (%%dx)" :                                          \
+                                               "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :    \
+                                               "0"(VMWARE_HYPERVISOR_MAGIC),                   \
+                                               "1"(VMWARE_PORT_CMD_##cmd),                     \
+                                               "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) :    \
+                                               "memory");
+
 /* virtualization types */
 enum {
        VIRT_NONE       = 0,
@@ -274,6 +288,16 @@ is_virtualized() {
        return false;
 }
 
+int
+hypervisor_port_check(void) {
+        uint32_t eax, ebx, ecx, edx;
+        VMWARE_PORT(GETVERSION, eax, ebx, ecx, edx);
+        if (ebx == VMWARE_HYPERVISOR_MAGIC)
+                return 1; // Success - running under VMware
+        else
+                return 0;
+}
+
 static PyObject *
 do_get_hypervisor() {
        /*
@@ -339,10 +363,23 @@ do_get_harddisk_serial(PyObject *o, PyObject *args) {
        return Py_None;
 }
 
+static PyObject *
+do_hypervisor_port_check() {
+       /*
+               Python wrapper around hypervisor_port_check().
+       */
+
+       if (hypervisor_port_check())
+               return Py_True;
+
+       return Py_False;
+}
+
 static PyMethodDef fireinfoModuleMethods[] = {
        { "get_hypervisor", (PyCFunction) do_get_hypervisor, METH_NOARGS, NULL },
        { "is_virtualized", (PyCFunction) do_is_virtualized, METH_NOARGS, NULL },
        { "get_harddisk_serial", (PyCFunction) do_get_harddisk_serial, METH_VARARGS, NULL },
+       { "vmware_hypervisor_port_check", (PyCFunction) do_hypervisor_port_check, METH_NOARGS, NULL },
        { NULL, NULL, 0, NULL }
 };