|
|
a52f674 |
From d3a841560dfacf7b87980257bb6dd8b3fd3fbcdf Mon Sep 17 00:00:00 2001
|
|
|
d66047d |
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
|
d66047d |
Date: Thu, 28 Nov 2013 13:34:08 -0500
|
|
|
d66047d |
Subject: [PATCH] virt: split detect_vm into separate functions
|
|
|
d66047d |
|
|
|
d66047d |
It didn't build on arm. Let's simplify it a bit by
|
|
|
d66047d |
splitting x86 specific parts out, which should also make
|
|
|
d66047d |
things easier when arm virtualization support is added.
|
|
|
d66047d |
---
|
|
|
d66047d |
src/shared/virt.c | 140 +++++++++++++++++++++++++++++++-----------------------
|
|
|
d66047d |
1 file changed, 81 insertions(+), 59 deletions(-)
|
|
|
d66047d |
|
|
|
d66047d |
diff --git a/src/shared/virt.c b/src/shared/virt.c
|
|
|
d66047d |
index 537ccda..4e18638 100644
|
|
|
d66047d |
--- a/src/shared/virt.c
|
|
|
d66047d |
+++ b/src/shared/virt.c
|
|
|
d66047d |
@@ -27,30 +27,10 @@
|
|
|
d66047d |
#include "virt.h"
|
|
|
d66047d |
#include "fileio.h"
|
|
|
d66047d |
|
|
|
d66047d |
-/* Returns a short identifier for the various VM implementations */
|
|
|
d66047d |
-int detect_vm(const char **id) {
|
|
|
d66047d |
- _cleanup_free_ char *cpuinfo_contents = NULL;
|
|
|
d66047d |
- int r;
|
|
|
d66047d |
-
|
|
|
d66047d |
-#if defined(__i386__) || defined(__x86_64__)
|
|
|
d66047d |
+static int detect_vm_cpuid(const char **_id) {
|
|
|
d66047d |
|
|
|
d66047d |
/* Both CPUID and DMI are x86 specific interfaces... */
|
|
|
d66047d |
-
|
|
|
d66047d |
- static const char *const dmi_vendors[] = {
|
|
|
d66047d |
- "/sys/class/dmi/id/sys_vendor",
|
|
|
d66047d |
- "/sys/class/dmi/id/board_vendor",
|
|
|
d66047d |
- "/sys/class/dmi/id/bios_vendor"
|
|
|
d66047d |
- };
|
|
|
d66047d |
-
|
|
|
d66047d |
- static const char dmi_vendor_table[] =
|
|
|
d66047d |
- "QEMU\0" "qemu\0"
|
|
|
d66047d |
- /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
|
|
|
d66047d |
- "VMware\0" "vmware\0"
|
|
|
d66047d |
- "VMW\0" "vmware\0"
|
|
|
d66047d |
- "Microsoft Corporation\0" "microsoft\0"
|
|
|
d66047d |
- "innotek GmbH\0" "oracle\0"
|
|
|
d66047d |
- "Xen\0" "xen\0"
|
|
|
d66047d |
- "Bochs\0" "bochs\0";
|
|
|
d66047d |
+#if defined(__i386__) || defined(__x86_64__)
|
|
|
d66047d |
|
|
|
d66047d |
static const char cpuid_vendor_table[] =
|
|
|
d66047d |
"XenVMMXenVMM\0" "xen\0"
|
|
|
d66047d |
@@ -60,40 +40,13 @@ int detect_vm(const char **id) {
|
|
|
d66047d |
/* http://msdn.microsoft.com/en-us/library/ff542428.aspx */
|
|
|
d66047d |
"Microsoft Hv\0" "microsoft\0";
|
|
|
d66047d |
|
|
|
d66047d |
- static __thread int cached_found = -1;
|
|
|
d66047d |
- static __thread const char *cached_id = NULL;
|
|
|
d66047d |
-
|
|
|
d66047d |
uint32_t eax, ecx;
|
|
|
d66047d |
union {
|
|
|
d66047d |
uint32_t sig32[3];
|
|
|
d66047d |
char text[13];
|
|
|
d66047d |
} sig = {};
|
|
|
d66047d |
- unsigned i;
|
|
|
d66047d |
const char *j, *k;
|
|
|
d66047d |
bool hypervisor;
|
|
|
d66047d |
- _cleanup_free_ char *hvtype = NULL;
|
|
|
d66047d |
- const char *_id = NULL;
|
|
|
d66047d |
-
|
|
|
d66047d |
- if (_likely_(cached_found >= 0)) {
|
|
|
d66047d |
-
|
|
|
d66047d |
- if (id)
|
|
|
d66047d |
- *id = cached_id;
|
|
|
d66047d |
-
|
|
|
d66047d |
- return cached_found;
|
|
|
d66047d |
- }
|
|
|
d66047d |
-
|
|
|
d66047d |
- /* Try high-level hypervisor sysfs file first:
|
|
|
d66047d |
- *
|
|
|
d66047d |
- * https://bugs.freedesktop.org/show_bug.cgi?id=61491 */
|
|
|
d66047d |
- r = read_one_line_file("/sys/hypervisor/type", &hvtype);
|
|
|
d66047d |
- if (r >= 0) {
|
|
|
d66047d |
- if (streq(hvtype, "xen")) {
|
|
|
d66047d |
- _id = "xen";
|
|
|
d66047d |
- r = 1;
|
|
|
d66047d |
- goto finish;
|
|
|
d66047d |
- }
|
|
|
d66047d |
- } else if (r != -ENOENT)
|
|
|
d66047d |
- return r;
|
|
|
d66047d |
|
|
|
d66047d |
/* http://lwn.net/Articles/301888/ */
|
|
|
d66047d |
|
|
|
d66047d |
@@ -136,14 +89,44 @@ int detect_vm(const char **id) {
|
|
|
d66047d |
|
|
|
d66047d |
NULSTR_FOREACH_PAIR(j, k, cpuid_vendor_table)
|
|
|
d66047d |
if (streq(sig.text, j)) {
|
|
|
d66047d |
- _id = k;
|
|
|
d66047d |
- r = 1;
|
|
|
d66047d |
- goto finish;
|
|
|
d66047d |
+ *_id = k;
|
|
|
d66047d |
+ return 1;
|
|
|
d66047d |
}
|
|
|
d66047d |
+
|
|
|
d66047d |
+ *_id = "other";
|
|
|
d66047d |
+ return 0;
|
|
|
d66047d |
}
|
|
|
d66047d |
+#endif
|
|
|
d66047d |
+
|
|
|
d66047d |
+ return 0;
|
|
|
d66047d |
+}
|
|
|
d66047d |
+
|
|
|
d66047d |
+static int detect_vm_dmi(const char **_id) {
|
|
|
d66047d |
+
|
|
|
d66047d |
+ /* Both CPUID and DMI are x86 specific interfaces... */
|
|
|
d66047d |
+#if defined(__i386__) || defined(__x86_64__)
|
|
|
d66047d |
+
|
|
|
d66047d |
+ static const char *const dmi_vendors[] = {
|
|
|
d66047d |
+ "/sys/class/dmi/id/sys_vendor",
|
|
|
d66047d |
+ "/sys/class/dmi/id/board_vendor",
|
|
|
d66047d |
+ "/sys/class/dmi/id/bios_vendor"
|
|
|
d66047d |
+ };
|
|
|
d66047d |
+
|
|
|
d66047d |
+ static const char dmi_vendor_table[] =
|
|
|
d66047d |
+ "QEMU\0" "qemu\0"
|
|
|
d66047d |
+ /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
|
|
|
d66047d |
+ "VMware\0" "vmware\0"
|
|
|
d66047d |
+ "VMW\0" "vmware\0"
|
|
|
d66047d |
+ "Microsoft Corporation\0" "microsoft\0"
|
|
|
d66047d |
+ "innotek GmbH\0" "oracle\0"
|
|
|
d66047d |
+ "Xen\0" "xen\0"
|
|
|
d66047d |
+ "Bochs\0" "bochs\0";
|
|
|
d66047d |
+ unsigned i;
|
|
|
d66047d |
|
|
|
d66047d |
for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) {
|
|
|
d66047d |
_cleanup_free_ char *s = NULL;
|
|
|
d66047d |
+ const char *j, *k;
|
|
|
d66047d |
+ int r;
|
|
|
d66047d |
|
|
|
d66047d |
r = read_one_line_file(dmi_vendors[i], &s);
|
|
|
d66047d |
if (r < 0) {
|
|
|
d66047d |
@@ -155,20 +138,59 @@ int detect_vm(const char **id) {
|
|
|
d66047d |
|
|
|
d66047d |
NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table)
|
|
|
d66047d |
if (startswith(s, j)) {
|
|
|
d66047d |
- _id = k;
|
|
|
d66047d |
- r = 1;
|
|
|
d66047d |
- goto finish;
|
|
|
d66047d |
+ *_id = k;
|
|
|
d66047d |
+ return 1;
|
|
|
d66047d |
}
|
|
|
d66047d |
}
|
|
|
d66047d |
+#endif
|
|
|
d66047d |
|
|
|
d66047d |
- if (hypervisor || hvtype) {
|
|
|
d66047d |
- _id = "other";
|
|
|
d66047d |
+ return 0;
|
|
|
d66047d |
+}
|
|
|
d66047d |
+
|
|
|
d66047d |
+/* Returns a short identifier for the various VM implementations */
|
|
|
d66047d |
+int detect_vm(const char **id) {
|
|
|
d66047d |
+ _cleanup_free_ char *hvtype = NULL, *cpuinfo_contents = NULL;
|
|
|
d66047d |
+ static __thread int cached_found = -1;
|
|
|
d66047d |
+ static __thread const char *cached_id = NULL;
|
|
|
d66047d |
+ const char *_id = NULL;
|
|
|
d66047d |
+ int r;
|
|
|
d66047d |
+
|
|
|
d66047d |
+ if (_likely_(cached_found >= 0)) {
|
|
|
d66047d |
+
|
|
|
d66047d |
+ if (id)
|
|
|
d66047d |
+ *id = cached_id;
|
|
|
d66047d |
+
|
|
|
d66047d |
+ return cached_found;
|
|
|
d66047d |
+ }
|
|
|
d66047d |
+
|
|
|
d66047d |
+ /* Try high-level hypervisor sysfs file first:
|
|
|
d66047d |
+ *
|
|
|
d66047d |
+ * https://bugs.freedesktop.org/show_bug.cgi?id=61491 */
|
|
|
d66047d |
+ r = read_one_line_file("/sys/hypervisor/type", &hvtype);
|
|
|
d66047d |
+ if (r >= 0) {
|
|
|
d66047d |
+ if (streq(hvtype, "xen")) {
|
|
|
d66047d |
+ _id = "xen";
|
|
|
d66047d |
+ r = 1;
|
|
|
d66047d |
+ goto finish;
|
|
|
d66047d |
+ }
|
|
|
d66047d |
+ } else if (r != -ENOENT)
|
|
|
d66047d |
+ return r;
|
|
|
d66047d |
+
|
|
|
d66047d |
+ /* this will set _id to "other" and return 0 for unknown hypervisors */
|
|
|
d66047d |
+ r = detect_vm_cpuid(&_id);
|
|
|
d66047d |
+ if (r != 0)
|
|
|
d66047d |
+ goto finish;
|
|
|
d66047d |
+
|
|
|
d66047d |
+ r = detect_vm_dmi(&_id);
|
|
|
d66047d |
+ if (r != 0)
|
|
|
d66047d |
+ goto finish;
|
|
|
d66047d |
+
|
|
|
d66047d |
+ if (_id) {
|
|
|
d66047d |
+ /* "other" */
|
|
|
d66047d |
r = 1;
|
|
|
d66047d |
goto finish;
|
|
|
d66047d |
}
|
|
|
d66047d |
|
|
|
d66047d |
-#endif
|
|
|
d66047d |
-
|
|
|
d66047d |
/* Detect User-Mode Linux by reading /proc/cpuinfo */
|
|
|
d66047d |
r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
|
|
|
d66047d |
if (r < 0)
|