diff options
author | Thomas Blume <Thomas.Blume@suse.com> | 2014-06-06 16:36:45 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-06-10 18:16:47 +0200 |
commit | 37287585b6ba9a55065c8f94458f6db3c0abe0af (patch) | |
tree | 1cee8ba99a220e0276f6a440849be726c3988996 /src/shared/virt.c | |
parent | 299a55075d1bf478b9190191caefd5c1b934340d (diff) |
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.
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.
https://bugs.freedesktop.org/show_bug.cgi?id=77271
Diffstat (limited to 'src/shared/virt.c')
-rw-r--r-- | src/shared/virt.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/src/shared/virt.c b/src/shared/virt.c index 1e227c5fbd..774915f4be 100644 --- a/src/shared/virt.c +++ b/src/shared/virt.c @@ -148,7 +148,7 @@ static int detect_vm_dmi(const char **_id) { /* Returns a short identifier for the various VM implementations */ int detect_vm(const char **id) { - _cleanup_free_ char *hvtype = NULL, *cpuinfo_contents = NULL; + _cleanup_free_ char *domcap = NULL, *cpuinfo_contents = NULL; static thread_local int cached_found = -1; static thread_local const char *cached_id = NULL; const char *_id = NULL; @@ -162,17 +162,37 @@ 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 */ + r = read_one_line_file("/proc/xen/capabilities", &domcap); if (r >= 0) { - if (streq(hvtype, "xen")) { + char *cap, *i = domcap; + + while ((cap = strsep(&i, ","))) + if (streq(cap, "control_d")) + break; + + if (!i) { _id = "xen"; r = 1; - goto finish; } - } else if (r != -ENOENT) + + goto finish; + + } else if (r == -ENOENT) { + _cleanup_free_ char *hvtype = NULL; + + r = read_one_line_file("/sys/hypervisor/type", &hvtype); + if (r >= 0) { + if (streq(hvtype, "xen")) { + _id = "xen"; + r = 1; + goto finish; + } + } else if (r != -ENOENT) + return r; + } else return r; /* this will set _id to "other" and return 0 for unknown hypervisors */ |