summaryrefslogtreecommitdiff
path: root/src/shared/virt.c
diff options
context:
space:
mode:
authorThomas Blume <Thomas.Blume@suse.com>2014-06-06 16:36:45 +0200
committerLennart Poettering <lennart@poettering.net>2014-06-10 18:16:47 +0200
commit37287585b6ba9a55065c8f94458f6db3c0abe0af (patch)
tree1cee8ba99a220e0276f6a440849be726c3988996 /src/shared/virt.c
parent299a55075d1bf478b9190191caefd5c1b934340d (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.c34
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 */