From cd591cc7b40ee6212ef40c0240a4299432aed01c Mon Sep 17 00:00:00 2001 From: Thomas Blume Date: Thu, 5 Jun 2014 09:35:02 +0200 Subject: [PATCH] systemd-detect-virt: only discover Xen domU The current vm detection lacks the distinction between Xen dom0 and Xen domU. Both, dom0 and domU are running inside the hypervisor. Therefore systemd-detect-virt and the ConditionVirtualization directive detect dom0 as a virtual machine. But, dom0 is not using virtual devices but is accessing the real hardware. Therefore dom0 should be considered the virtualisation host and not a virtual machine. --- src/shared/virt.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/shared/virt.c b/src/shared/virt.c index 1e227c5..d7c94e4 100644 --- a/src/shared/virt.c +++ b/src/shared/virt.c @@ -162,18 +162,36 @@ int detect_vm(const char **id) { return cached_found; } - /* Try high-level hypervisor sysfs file first: + /* Try xen capabilities file first, if not found try high-level hypervisor sysfs file: * - * https://bugs.freedesktop.org/show_bug.cgi?id=61491 */ - r = read_one_line_file("/sys/hypervisor/type", &hvtype); + * https://bugs.freedesktop.org/show_bug.cgi?id=77271 */ + char *domcap = NULL, *cap = NULL; + r = read_one_line_file("/proc/xen/capabilities", &domcap); if (r >= 0) { - if (streq(hvtype, "xen")) { - _id = "xen"; - r = 1; - goto finish; - } - } else if (r != -ENOENT) - return r; + cap = strsep(&domcap, ","); + do { + if (streq(cap, "control_d")) { + break; + } else if (domcap == NULL) { + r = 1; + _id = "xen"; + } + cap = strsep(&domcap, ","); + } while (cap != NULL); + goto finish; + } else if (r == -ENOENT) { + r = read_one_line_file("/sys/hypervisor/type", &hvtype); + if (r >= 0) { + if (streq(hvtype, "xen")) { + r = 1; + _id = "xen"; + goto finish; + } + } else if (r != -ENOENT) + return r; + } else { + return r; + } /* this will set _id to "other" and return 0 for unknown hypervisors */ r = detect_vm_cpuid(&_id); -- 1.8.4.5