X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Futil.c;h=e2859fafc1b115215eb7638125a126e031aa1bf5;hb=c0f9c7da07fccafed646e0a15df9bc132e3fc7fb;hp=aa49390b8738bfcf93174d6f17ac1a872ef8d3c8;hpb=4e08da90d4df797308d4646af345cfc0486b06d1;p=elogind.git diff --git a/src/util.c b/src/util.c index aa49390b8..e2859fafc 100644 --- a/src/util.c +++ b/src/util.c @@ -3713,7 +3713,7 @@ int detect_vm(const char **id) { /* Both CPUID and DMI are x86 specific interfaces... */ - const char *const dmi_vendors[] = { + static const char *const dmi_vendors[] = { "/sys/class/dmi/id/sys_vendor", "/sys/class/dmi/id/board_vendor", "/sys/class/dmi/id/bios_vendor" @@ -3727,6 +3727,7 @@ int detect_vm(const char **id) { "Microsoft Corporation\0" "microsoft\0" "innotek GmbH\0" "oracle\0" "Xen\0" "xen\0" + "Bochs\0" "bochs\0" "\0"; static const char cpuid_vendor_table[] = @@ -3743,34 +3744,9 @@ int detect_vm(const char **id) { uint32_t sig32[3]; char text[13]; } sig; - unsigned i; const char *j, *k; - - for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { - char *s; - int r; - const char *found = NULL; - - if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) { - if (r != -ENOENT) - return r; - - continue; - } - - NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table) - if (startswith(s, j)) - found = k; - free(s); - - if (found) { - if (id) - *id = found; - - return 1; - } - } + bool hypervisor; /* http://lwn.net/Articles/301888/ */ zero(sig); @@ -3795,7 +3771,9 @@ int detect_vm(const char **id) { : "0" (eax) ); - if (ecx & 0x80000000U) { + hypervisor = !!(ecx & ecx & 0x80000000U); + + if (hypervisor) { /* There is a hypervisor, see what it is */ eax = 0x40000000U; @@ -3818,14 +3796,41 @@ int detect_vm(const char **id) { return 1; } + } + for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { + char *s; + int r; + const char *found = NULL; + + if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) { + if (r != -ENOENT) + return r; + + continue; + } + + NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table) + if (startswith(s, j)) + found = k; + free(s); + + if (found) { + if (id) + *id = found; + + return 1; + } + } + + if (hypervisor) { if (id) *id = "other"; return 1; } -#endif +#endif return 0; }