From: Michael Tremer Date: Sun, 26 Dec 2010 14:50:11 +0000 (+0100) Subject: Implement the VMWare hypervisor port check. X-Git-Tag: v0.13~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2dc5f0d087b8f59f64c399a5ed4bdc1787f7f66a;p=oddments%2Ffireinfo.git Implement the VMWare hypervisor port check. We need this because sometimes, the general check fails. --- diff --git a/fireinfo/hypervisor.py b/fireinfo/hypervisor.py index 46b58e1..83f2a85 100644 --- a/fireinfo/hypervisor.py +++ b/fireinfo/hypervisor.py @@ -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__": diff --git a/src/fireinfo.c b/src/fireinfo.c index 70ddf78..3a03a39 100644 --- a/src/fireinfo.c +++ b/src/fireinfo.c @@ -34,6 +34,20 @@ #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 } };