From: Michael Tremer Date: Wed, 24 Nov 2010 16:33:38 +0000 (+0100) Subject: New class and C functions for hypervisor detection. X-Git-Tag: v0.2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=715ba5acbbe2d6e376bae74c251d935047c284cf;p=oddments%2Ffireinfo.git New class and C functions for hypervisor detection. --- diff --git a/fireinfo/hypervisor.py b/fireinfo/hypervisor.py new file mode 100644 index 0000000..dc0d373 --- /dev/null +++ b/fireinfo/hypervisor.py @@ -0,0 +1,51 @@ +#!/usr/bin/python + +import _fireinfo + +class Hypervisor(object): + def __init__(self): + self.__info = _fireinfo.get_hypervisor() + + @property + def vendor(self): + """ + Returns the name of the hypervisor vendor. + """ + if not self.virtual: + return None + + # If the script already returned a hypervisor, we return the name. + if self.__info["hypervisor"]: + return self.__info["hypervisor"] + + # XXX fill in some code to detect hypervisors, that do + # not say their name. + + return "unknown" + + @property + def type(self): + """ + Returns if the host is running in full virt mode or + if it is running in a paravirtualized environment. + """ + if not self.virtual: + return None + + return self.__info["virtype"] + + @property + def virtual(self): + """ + Returns true if the host is running in a virtual environment. + Otherwise: false. + """ + return _fireinfo.is_virtualized() + + +if __name__ == "__main__": + h = Hypervisor() + + print "Vendor:", h.vendor + print "Type:", h.type + print "Virtual:", h.virtual diff --git a/fireinfo/system.py b/fireinfo/system.py index 3202054..7355ab6 100644 --- a/fireinfo/system.py +++ b/fireinfo/system.py @@ -5,9 +5,9 @@ import json import os import string -import _fireinfo import cpu import device +import hypervisor class System(object): @@ -16,7 +16,8 @@ class System(object): self.devices = [] self.scan() self.cpu = cpu.CPU() - + self.hypervisor = hypervisor.Hypervisor() + def profile(self): p = { "public_id" : self.public_id, @@ -53,7 +54,14 @@ class System(object): "family" : self.cpu.family, "count" : self.cpu.count } - + + # Only append hypervisor information if we are virtualized. + if self.virtual: + p["hypervisor"] = { + "type" : self.hypervisor.type, + "vendor" : self.hypervisor.vendor, + } + return json.dumps(p) @@ -144,7 +152,7 @@ class System(object): """ Say if the host is running in a virtual environment. """ - return _fireinfo.is_virtualized() + return self.hypervisor.virtual diff --git a/src/fireinfo.c b/src/fireinfo.c index 67e7020..fcc9720 100644 --- a/src/fireinfo.c +++ b/src/fireinfo.c @@ -88,6 +88,11 @@ struct lscpu_desc { int ncpus; /* number of CPUs */ }; +struct hypervisor_desc { + int hyper; /* hypervisor vendor ID */ + int virtype; /* VIRT_PARA|FULL|NONE ? */ +}; + static size_t sysrootlen; static char pathbuf[PATH_MAX]; static int maxcpus; /* size in bits of kernel cpu mask */ @@ -335,8 +340,8 @@ cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, : "1" (op), "c"(0)); } -static void -read_hypervisor_cpuid(struct lscpu_desc *desc) +static int +read_hypervisor_cpuid(struct hypervisor_desc *desc) { unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0; char hyper_vendor_id[13]; @@ -370,7 +375,7 @@ read_hypervisor_cpuid(struct lscpu_desc *desc) #endif static void -read_hypervisor(struct lscpu_desc *desc) +read_hypervisor(struct hypervisor_desc *desc) { read_hypervisor_cpuid(desc); @@ -501,6 +506,38 @@ do_cpuinfo() { return d; } +static PyObject * +do_get_hypervisor() { + /* + Get hypervisor from the cpuid command. + */ + struct hypervisor_desc _desc, *desc = &_desc; + memset(desc, 0, sizeof(*desc)); + + read_hypervisor(desc); + + PyObject *d = PyDict_New(); + PyObject *o; + + /* Hypervisor */ + if (desc->hyper == HYPER_NONE) { + o = Py_None; + } else { + o = PyString_FromString((const char *)hv_vendors[desc->hyper]); + } + PyDict_SetItemString(d, "hypervisor", o); + + /* Virtualization type */ + if (desc->virtype == VIRT_NONE) { + o = Py_None; + } else { + o = PyString_FromString((const char *)virt_types[desc->virtype]); + } + PyDict_SetItemString(d, "virtype", o); + + return d; +} + static PyObject * do_is_virtualized() { /* @@ -515,6 +552,7 @@ do_is_virtualized() { static PyMethodDef fireinfoModuleMethods[] = { { "cpuinfo", (PyCFunction) do_cpuinfo, METH_NOARGS, NULL }, + { "get_hypervisor", (PyCFunction) do_get_hypervisor, METH_NOARGS, NULL }, { "is_virtualized", (PyCFunction) do_is_virtualized, METH_NOARGS, NULL }, { NULL, NULL, 0, NULL } };