summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-09-07 13:42:47 +0200
committerLennart Poettering <lennart@poettering.net>2015-09-07 13:42:47 +0200
commit75f86906c52735c98dc0aa7e24b773edb42ee814 (patch)
treed2d0701f8df51d5a09586073ebd387bb831743e7
parent47f5a38cdf98a220d6a0d4eb11a710a0a42ae5c4 (diff)
basic: rework virtualization detection API
Introduce a proper enum, and don't pass around string ids anymore. This simplifies things quite a bit, and makes virtualization detection more similar to architecture detection.
-rw-r--r--src/basic/util.c2
-rw-r--r--src/basic/virt.c395
-rw-r--r--src/basic/virt.h46
-rw-r--r--src/core/dbus-manager.c6
-rw-r--r--src/core/job.c2
-rw-r--r--src/core/locale-setup.c2
-rw-r--r--src/core/machine-id-setup.c30
-rw-r--r--src/core/main.c14
-rw-r--r--src/core/manager.c6
-rw-r--r--src/core/mount-setup.c4
-rw-r--r--src/core/shutdown.c2
-rw-r--r--src/core/swap.c8
-rw-r--r--src/core/umount.c2
-rw-r--r--src/core/unit.c2
-rw-r--r--src/detect-virt/detect-virt.c31
-rw-r--r--src/fstab-generator/fstab-generator.c2
-rw-r--r--src/getty-generator/getty-generator.c2
-rw-r--r--src/gpt-auto-generator/gpt-auto-generator.c4
-rw-r--r--src/hostname/hostnamed.c6
-rw-r--r--src/libsystemd-network/dhcp-identifier.c2
-rw-r--r--src/libsystemd-network/test-dhcp6-client.c12
-rw-r--r--src/locale/localectl.c2
-rw-r--r--src/network/networkd-link.c2
-rw-r--r--src/network/networkd-manager.c2
-rw-r--r--src/shared/condition.c9
-rw-r--r--src/shared/efivars.c2
-rw-r--r--src/test/test-architecture.c8
-rw-r--r--src/test/test-process-util.c2
-rw-r--r--src/vconsole/vconsole-setup.c2
29 files changed, 316 insertions, 293 deletions
diff --git a/src/basic/util.c b/src/basic/util.c
index 86aacad307..3e41e6ad41 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -4817,7 +4817,7 @@ int shall_restore_state(void) {
int proc_cmdline(char **ret) {
assert(ret);
- if (detect_container(NULL) > 0)
+ if (detect_container() > 0)
return get_process_cmdline(1, 0, false, ret);
else
return read_one_line_file("/proc/cmdline", ret);
diff --git a/src/basic/virt.c b/src/basic/virt.c
index 4a4bebd528..1fc6c1baba 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -28,25 +28,24 @@
#include "virt.h"
#include "fileio.h"
-static int detect_vm_cpuid(const char **_id) {
+static int detect_vm_cpuid(void) {
/* Both CPUID and DMI are x86 specific interfaces... */
#if defined(__i386__) || defined(__x86_64__)
- static const char cpuid_vendor_table[] =
- "XenVMMXenVMM\0" "xen\0"
- "KVMKVMKVM\0" "kvm\0"
+ static const struct {
+ const char *cpuid;
+ int id;
+ } cpuid_vendor_table[] = {
+ { "XenVMMXenVMM", VIRTUALIZATION_XEN },
+ { "KVMKVMKVM", VIRTUALIZATION_KVM },
/* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
- "VMwareVMware\0" "vmware\0"
+ { "VMwareVMware", VIRTUALIZATION_VMWARE },
/* http://msdn.microsoft.com/en-us/library/ff542428.aspx */
- "Microsoft Hv\0" "microsoft\0";
+ { "Microsoft Hv", VIRTUALIZATION_MICROSOFT },
+ };
uint32_t eax, ecx;
- union {
- uint32_t sig32[3];
- char text[13];
- } sig = {};
- const char *j, *k;
bool hypervisor;
/* http://lwn.net/Articles/301888/ */
@@ -74,6 +73,11 @@ static int detect_vm_cpuid(const char **_id) {
hypervisor = !!(ecx & 0x80000000U);
if (hypervisor) {
+ union {
+ uint32_t sig32[3];
+ char text[13];
+ } sig = {};
+ unsigned j;
/* There is a hypervisor, see what it is */
eax = 0x40000000U;
@@ -88,57 +92,54 @@ static int detect_vm_cpuid(const char **_id) {
: "0" (eax)
);
- NULSTR_FOREACH_PAIR(j, k, cpuid_vendor_table)
- if (streq(sig.text, j)) {
- *_id = k;
- return 1;
- }
+ for (j = 0; j < ELEMENTSOF(cpuid_vendor_table); j ++)
+ if (streq(sig.text, cpuid_vendor_table[j].cpuid))
+ return cpuid_vendor_table[j].id;
- *_id = "other";
- return 0;
+ return VIRTUALIZATION_VM_OTHER;
}
#endif
- return 0;
+ return VIRTUALIZATION_NONE;
}
-static int detect_vm_devicetree(const char **_id) {
+static int detect_vm_device_tree(void) {
#if defined(__arm__) || defined(__aarch64__) || defined(__powerpc__) || defined(__powerpc64__)
_cleanup_free_ char *hvtype = NULL;
int r;
r = read_one_line_file("/proc/device-tree/hypervisor/compatible", &hvtype);
- if (r >= 0) {
- if (streq(hvtype, "linux,kvm")) {
- *_id = "kvm";
- return 1;
- } else if (strstr(hvtype, "xen")) {
- *_id = "xen";
- return 1;
- }
- } else if (r == -ENOENT) {
+ if (r == -ENOENT) {
_cleanup_closedir_ DIR *dir = NULL;
struct dirent *dent;
dir = opendir("/proc/device-tree");
if (!dir) {
if (errno == ENOENT)
- return 0;
+ return VIRTUALIZATION_NONE;
return -errno;
}
- FOREACH_DIRENT(dent, dir, return -errno) {
- if (strstr(dent->d_name, "fw-cfg")) {
- *_id = "qemu";
- return 1;
- }
- }
- }
+ FOREACH_DIRENT(dent, dir, return -errno)
+ if (strstr(dent->d_name, "fw-cfg"))
+ return VIRTUALIZATION_QEMU;
+
+ return VIRTUALIZATION_NONE;
+ } else if (r < 0)
+ return r;
+
+ if (streq(hvtype, "linux,kvm"))
+ return VIRTUALIZATION_KVM;
+ else if (strstr(hvtype, "xen"))
+ return VIRTUALIZATION_XEN;
+ else
+ return VIRTUALIZATION_VM_OTHER;
+#else
+ return VIRTUALIZATION_NONE;
#endif
- return 0;
}
-static int detect_vm_dmi(const char **_id) {
+static int detect_vm_dmi(void) {
/* Both CPUID and DMI are x86 specific interfaces... */
#if defined(__i386__) || defined(__x86_64__)
@@ -149,188 +150,195 @@ static int detect_vm_dmi(const char **_id) {
"/sys/class/dmi/id/bios_vendor"
};
- static const char dmi_vendor_table[] =
- "QEMU\0" "qemu\0"
+ static const struct {
+ const char *vendor;
+ int id;
+ } dmi_vendor_table[] = {
+ { "QEMU", VIRTUALIZATION_QEMU },
/* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
- "VMware\0" "vmware\0"
- "VMW\0" "vmware\0"
- "innotek GmbH\0" "oracle\0"
- "Xen\0" "xen\0"
- "Bochs\0" "bochs\0"
- "Parallels\0" "parallels\0";
+ { "VMware", VIRTUALIZATION_VMWARE },
+ { "VMW", VIRTUALIZATION_VMWARE },
+ { "innotek GmbH", VIRTUALIZATION_ORACLE },
+ { "Xen", VIRTUALIZATION_XEN },
+ { "Bochs", VIRTUALIZATION_BOCHS },
+ { "Parallels", VIRTUALIZATION_PARALLELS },
+ };
unsigned i;
+ int r;
for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) {
_cleanup_free_ char *s = NULL;
- const char *j, *k;
- int r;
+ unsigned j;
r = read_one_line_file(dmi_vendors[i], &s);
if (r < 0) {
- if (r != -ENOENT)
- return r;
+ if (r == -ENOENT)
+ continue;
- continue;
+ return r;
}
- NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table)
- if (startswith(s, j)) {
- *_id = k;
- return 1;
- }
+ for (j = 0; j < ELEMENTSOF(dmi_vendor_table); j++)
+ if (startswith(s, dmi_vendor_table[j].vendor))
+ return dmi_vendor_table[j].id;
}
#endif
- return 0;
+ return VIRTUALIZATION_NONE;
}
-/* Returns a short identifier for the various VM implementations */
-int detect_vm(const char **id) {
- _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, *_id_cpuid = NULL;
+static int detect_vm_xen(void) {
+ _cleanup_free_ char *domcap = NULL;
+ char *cap, *i;
int r;
- if (_likely_(cached_found >= 0)) {
+ r = read_one_line_file("/proc/xen/capabilities", &domcap);
+ if (r == -ENOENT)
+ return VIRTUALIZATION_NONE;
- if (id)
- *id = cached_id;
+ i = domcap;
+ while ((cap = strsep(&i, ",")))
+ if (streq(cap, "control_d"))
+ break;
- return cached_found;
- }
-
- /* Try xen capabilities file first, if not found try high-level hypervisor sysfs file:
- *
- * https://bugs.freedesktop.org/show_bug.cgi?id=77271 */
- r = read_one_line_file("/proc/xen/capabilities", &domcap);
- if (r >= 0) {
- char *cap, *i = domcap;
+ return cap ? VIRTUALIZATION_NONE : VIRTUALIZATION_XEN;
+}
- while ((cap = strsep(&i, ",")))
- if (streq(cap, "control_d"))
- break;
+static int detect_vm_hypervisor(void) {
+ _cleanup_free_ char *hvtype = NULL;
+ int r;
- if (!cap) {
- _id = "xen";
- r = 1;
- }
+ r = read_one_line_file("/sys/hypervisor/type", &hvtype);
+ if (r == -ENOENT)
+ return VIRTUALIZATION_NONE;
+ if (r < 0)
+ return r;
- goto finish;
+ if (streq(hvtype, "xen"))
+ return VIRTUALIZATION_XEN;
+ else
+ return VIRTUALIZATION_VM_OTHER;
+}
- } else if (r == -ENOENT) {
- _cleanup_free_ char *hvtype = NULL;
+static int detect_vm_uml(void) {
+ _cleanup_free_ char *cpuinfo_contents = NULL;
+ int r;
- 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
+ /* Detect User-Mode Linux by reading /proc/cpuinfo */
+ r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
+ if (r < 0)
return r;
+ if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n"))
+ return VIRTUALIZATION_UML;
- /* this will set _id to "other" and return 0 for unknown hypervisors */
- r = detect_vm_cpuid(&_id);
+ return VIRTUALIZATION_NONE;
+}
- /* finish when found a known hypervisor other than kvm */
- if (r < 0 || (r > 0 && !streq(_id, "kvm")))
- goto finish;
+static int detect_vm_zvm(void) {
- _id_cpuid = _id;
+#if defined(__s390__)
+ _cleanup_free_ char *t = NULL;
+ int r;
- r = detect_vm_dmi(&_id);
+ r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t);
+ if (r == -ENOENT)
+ return VIRTUALIZATION_NONE;
+ if (r < 0)
+ return r;
- /* kvm with and without Virtualbox */
- /* Parallels exports KVMKVMKVM leaf */
- if (streq_ptr(_id_cpuid, "kvm")) {
- if (r > 0 && (streq(_id, "oracle") || streq(_id, "parallels")))
- goto finish;
+ if (streq(t, "z/VM"))
+ return VIRTUALIZATION_ZVM;
+ else
+ return VIRTUALIZATION_KVM;
+#else
+ return VIRTUALIZATION_NONE;
+#endif
+}
- _id = _id_cpuid;
- r = 1;
- goto finish;
- }
+/* Returns a short identifier for the various VM implementations */
+int detect_vm(void) {
+ static thread_local int cached_found = _VIRTUALIZATION_INVALID;
+ int r;
- /* information from dmi */
- if (r != 0)
- goto finish;
+ if (cached_found >= 0)
+ return cached_found;
- r = detect_vm_devicetree(&_id);
- if (r != 0)
+ /* Try xen capabilities file first, if not found try
+ * high-level hypervisor sysfs file:
+ *
+ * https://bugs.freedesktop.org/show_bug.cgi?id=77271 */
+
+ r = detect_vm_xen();
+ if (r < 0)
+ return r;
+ if (r != VIRTUALIZATION_NONE)
goto finish;
- if (_id) {
- /* "other" */
- r = 1;
+ r = detect_vm_dmi();
+ if (r < 0)
+ return r;
+ if (r != VIRTUALIZATION_NONE)
goto finish;
- }
- /* Detect User-Mode Linux by reading /proc/cpuinfo */
- r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
+ r = detect_vm_cpuid();
if (r < 0)
return r;
- if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) {
- _id = "uml";
- r = 1;
+ if (r != VIRTUALIZATION_NONE)
goto finish;
- }
-#if defined(__s390__)
- {
- _cleanup_free_ char *t = NULL;
+ r = detect_vm_hypervisor();
+ if (r < 0)
+ return r;
+ if (r != VIRTUALIZATION_NONE)
+ goto finish;
- r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t);
- if (r >= 0) {
- if (streq(t, "z/VM"))
- _id = "zvm";
- else
- _id = "kvm";
- r = 1;
+ r = detect_vm_device_tree();
+ if (r < 0)
+ return r;
+ if (r != VIRTUALIZATION_NONE)
+ goto finish;
- goto finish;
- }
- }
-#endif
+ r = detect_vm_uml();
+ if (r < 0)
+ return r;
+ if (r != VIRTUALIZATION_NONE)
+ goto finish;
- r = 0;
+ r = detect_vm_zvm();
+ if (r < 0)
+ return r;
finish:
cached_found = r;
-
- cached_id = _id;
- if (id)
- *id = _id;
-
return r;
}
-int detect_container(const char **id) {
+int detect_container(void) {
- static thread_local int cached_found = -1;
- static thread_local const char *cached_id = NULL;
+ static const struct {
+ const char *value;
+ int id;
+ } value_table[] = {
+ { "lxc", VIRTUALIZATION_LXC },
+ { "lxc-libvirt", VIRTUALIZATION_LXC_LIBVIRT },
+ { "systemd-nspawn", VIRTUALIZATION_SYSTEMD_NSPAWN },
+ { "docker", VIRTUALIZATION_DOCKER },
+ };
+ static thread_local int cached_found = _VIRTUALIZATION_INVALID;
_cleanup_free_ char *m = NULL;
- const char *_id = NULL, *e = NULL;
+ const char *e = NULL;
+ unsigned j;
int r;
- if (_likely_(cached_found >= 0)) {
-
- if (id)
- *id = cached_id;
-
+ if (cached_found >= 0)
return cached_found;
- }
/* /proc/vz exists in container and outside of the container,
* /proc/bc only outside of the container. */
if (access("/proc/vz", F_OK) >= 0 &&
access("/proc/bc", F_OK) < 0) {
- _id = "openvz";
- r = 1;
+ r = VIRTUALIZATION_OPENVZ;
goto finish;
}
@@ -340,7 +348,7 @@ int detect_container(const char **id) {
e = getenv("container");
if (isempty(e)) {
- r = 0;
+ r = VIRTUALIZATION_NONE;
goto finish;
}
} else {
@@ -369,7 +377,7 @@ int detect_container(const char **id) {
* as /proc/1/environ is only readable
* with privileges. */
- r = 0;
+ r = VIRTUALIZATION_NONE;
goto finish;
}
}
@@ -379,46 +387,49 @@ int detect_container(const char **id) {
e = m;
}
- /* We only recognize a selected few here, since we want to
- * enforce a redacted namespace */
- if (streq(e, "lxc"))
- _id ="lxc";
- else if (streq(e, "lxc-libvirt"))
- _id = "lxc-libvirt";
- else if (streq(e, "systemd-nspawn"))
- _id = "systemd-nspawn";
- else if (streq(e, "docker"))
- _id = "docker";
- else
- _id = "other";
+ for (j = 0; j < ELEMENTSOF(value_table); j++)
+ if (streq(e, value_table[j].value)) {
+ r = value_table[j].id;
+ goto finish;
+ }
- r = 1;
+ r = VIRTUALIZATION_NONE;
finish:
cached_found = r;
-
- cached_id = _id;
- if (id)
- *id = _id;
-
return r;
}
-/* Returns a short identifier for the various VM/container implementations */
-int detect_virtualization(const char **id) {
+int detect_virtualization(void) {
int r;
- r = detect_container(id);
- if (r < 0)
- return r;
- if (r > 0)
- return VIRTUALIZATION_CONTAINER;
-
- r = detect_vm(id);
- if (r < 0)
+ r = detect_container();
+ if (r != 0)
return r;
- if (r > 0)
- return VIRTUALIZATION_VM;
- return VIRTUALIZATION_NONE;
+ return detect_vm();
}
+
+static const char *const virtualization_table[_VIRTUALIZATION_MAX] = {
+ [VIRTUALIZATION_NONE] = "none",
+ [VIRTUALIZATION_KVM] = "kvm",
+ [VIRTUALIZATION_QEMU] = "qemu",
+ [VIRTUALIZATION_BOCHS] = "bochs",
+ [VIRTUALIZATION_XEN] = "xen",
+ [VIRTUALIZATION_UML] = "uml",
+ [VIRTUALIZATION_VMWARE] = "vmware",
+ [VIRTUALIZATION_ORACLE] = "oracle",
+ [VIRTUALIZATION_MICROSOFT] = "microsoft",
+ [VIRTUALIZATION_ZVM] = "zvm",
+ [VIRTUALIZATION_PARALLELS] = "parallels",
+ [VIRTUALIZATION_VM_OTHER] = "vm-other",
+
+ [VIRTUALIZATION_SYSTEMD_NSPAWN] = "systemd-nspawn",
+ [VIRTUALIZATION_LXC_LIBVIRT] = "lxc-libvirt",
+ [VIRTUALIZATION_LXC] = "lxc",
+ [VIRTUALIZATION_OPENVZ] = "openvz",
+ [VIRTUALIZATION_DOCKER] = "docker",
+ [VIRTUALIZATION_CONTAINER_OTHER] = "container-other",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(virtualization, int);
diff --git a/src/basic/virt.h b/src/basic/virt.h
index 7194ab2bf7..449e069901 100644
--- a/src/basic/virt.h
+++ b/src/basic/virt.h
@@ -21,15 +21,51 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-int detect_vm(const char **id);
-int detect_container(const char **id);
+#include <stdbool.h>
+
+#include "macro.h"
enum {
VIRTUALIZATION_NONE = 0,
- VIRTUALIZATION_VM,
- VIRTUALIZATION_CONTAINER,
+
+ VIRTUALIZATION_VM_FIRST,
+ VIRTUALIZATION_KVM = VIRTUALIZATION_VM_FIRST,
+ VIRTUALIZATION_QEMU,
+ VIRTUALIZATION_BOCHS,
+ VIRTUALIZATION_XEN,
+ VIRTUALIZATION_UML,
+ VIRTUALIZATION_VMWARE,
+ VIRTUALIZATION_ORACLE,
+ VIRTUALIZATION_MICROSOFT,
+ VIRTUALIZATION_ZVM,
+ VIRTUALIZATION_PARALLELS,
+ VIRTUALIZATION_VM_OTHER,
+ VIRTUALIZATION_VM_LAST = VIRTUALIZATION_VM_OTHER,
+
+ VIRTUALIZATION_CONTAINER_FIRST,
+ VIRTUALIZATION_SYSTEMD_NSPAWN = VIRTUALIZATION_CONTAINER_FIRST,
+ VIRTUALIZATION_LXC_LIBVIRT,
+ VIRTUALIZATION_LXC,
+ VIRTUALIZATION_OPENVZ,
+ VIRTUALIZATION_DOCKER,
+ VIRTUALIZATION_CONTAINER_OTHER,
+ VIRTUALIZATION_CONTAINER_LAST = VIRTUALIZATION_CONTAINER_OTHER,
+
_VIRTUALIZATION_MAX,
_VIRTUALIZATION_INVALID = -1
};
-int detect_virtualization(const char **id);
+static inline bool VIRTUALIZATION_IS_VM(int x) {
+ return x >= VIRTUALIZATION_VM_FIRST && x <= VIRTUALIZATION_VM_LAST;
+}
+
+static inline bool VIRTUALIZATION_IS_CONTAINER(int x) {
+ return x >= VIRTUALIZATION_CONTAINER_FIRST && x <= VIRTUALIZATION_CONTAINER_LAST;
+}
+
+int detect_vm(void);
+int detect_container(void);
+int detect_virtualization(void);
+
+const char *virtualization_to_string(int v) _const_;
+int virtualization_from_string(const char *s) _pure_;
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 0b365391ec..4e5d67fc19 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -81,14 +81,10 @@ static int property_get_virtualization(
void *userdata,
sd_bus_error *error) {
- const char *id = NULL;
-
assert(bus);
assert(reply);
- detect_virtualization(&id);
-
- return sd_bus_message_append(reply, "s", id);
+ return sd_bus_message_append(reply, "s", virtualization_to_string(detect_virtualization()));
}
static int property_get_architecture(
diff --git a/src/core/job.c b/src/core/job.c
index 15f5cc0cc9..2a35d1e2de 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -1137,7 +1137,7 @@ void job_shutdown_magic(Job *j) {
/* In case messages on console has been disabled on boot */
j->unit->manager->no_console_output = false;
- if (detect_container(NULL) > 0)
+ if (detect_container() > 0)
return;
asynchronous_sync();
diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c
index 108072ca9f..6961c26674 100644
--- a/src/core/locale-setup.c
+++ b/src/core/locale-setup.c
@@ -35,7 +35,7 @@ int locale_setup(char ***environment) {
char *variables[_VARIABLE_LC_MAX] = {};
int r = 0, i;
- if (detect_container(NULL) <= 0) {
+ if (detect_container() <= 0) {
r = parse_env_file("/proc/cmdline", WHITESPACE,
"locale.LANG", &variables[VARIABLE_LANG],
"locale.LANGUAGE", &variables[VARIABLE_LANGUAGE],
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
index 2d5ae3b3b9..8f682c6d10 100644
--- a/src/core/machine-id-setup.c
+++ b/src/core/machine-id-setup.c
@@ -108,7 +108,7 @@ static int generate_machine_id(char id[34], const char *root) {
unsigned char *p;
sd_id128_t buf;
char *q;
- const char *vm_id, *dbus_machine_id;
+ const char *dbus_machine_id;
assert(id);
@@ -133,8 +133,8 @@ static int generate_machine_id(char id[34], const char *root) {
/* If that didn't work, see if we are running in a container,
* and a machine ID was passed in via $container_uuid the way
* libvirt/LXC does it */
- r = detect_container(NULL);
- if (r > 0) {
+
+ if (detect_container() > 0) {
_cleanup_free_ char *e = NULL;
r = getenv_for_pid(1, "container_uuid", &e);
@@ -146,26 +146,24 @@ static int generate_machine_id(char id[34], const char *root) {
}
}
- } else {
+ } else if (detect_vm() == VIRTUALIZATION_KVM) {
+
/* If we are not running in a container, see if we are
* running in qemu/kvm and a machine ID was passed in
* via -uuid on the qemu/kvm command line */
- r = detect_vm(&vm_id);
- if (r > 0 && streq(vm_id, "kvm")) {
- char uuid[36];
+ char uuid[36];
- fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
- if (fd >= 0) {
- r = loop_read_exact(fd, uuid, 36, false);
- safe_close(fd);
+ fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+ if (fd >= 0) {
+ r = loop_read_exact(fd, uuid, 36, false);
+ safe_close(fd);
+ if (r >= 0) {
+ r = shorten_uuid(id, uuid);
if (r >= 0) {
- r = shorten_uuid(id, uuid);
- if (r >= 0) {
- log_info("Initializing machine ID from KVM UUID.");
- return 0;
- }
+ log_info("Initializing machine ID from KVM UUID.");
+ return 0;
}
}
}
diff --git a/src/core/main.c b/src/core/main.c
index 4cd2b08c38..fe8f1924bd 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -374,7 +374,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
/* Note that log_parse_environment() handles 'debug'
* too, and sets the log level to LOG_DEBUG. */
- if (detect_container(NULL) > 0)
+ if (detect_container() > 0)
log_set_target(LOG_TARGET_CONSOLE);
} else if (!in_initrd() && !value) {
@@ -1297,7 +1297,7 @@ int main(int argc, char *argv[]) {
if (getpid() == 1)
umask(0);
- if (getpid() == 1 && detect_container(NULL) <= 0) {
+ if (getpid() == 1 && detect_container() <= 0) {
/* Running outside of a container as PID 1 */
arg_running_as = MANAGER_SYSTEM;
@@ -1551,14 +1551,14 @@ int main(int argc, char *argv[]) {
}
if (arg_running_as == MANAGER_SYSTEM) {
- const char *virtualization = NULL;
+ int v;
log_info(PACKAGE_STRING " running in %ssystem mode. (" SYSTEMD_FEATURES ")",
arg_action == ACTION_TEST ? "test " : "" );
- detect_virtualization(&virtualization);
- if (virtualization)
- log_info("Detected virtualization %s.", virtualization);
+ v = detect_virtualization();
+ if (v > 0)
+ log_info("Detected virtualization %s.", virtualization_to_string(v));
write_container_id();
@@ -2046,7 +2046,7 @@ finish:
/* Avoid the creation of new processes forked by the
* kernel; at this point, we will not listen to the
* signals anyway */
- if (detect_container(NULL) <= 0)
+ if (detect_container() <= 0)
(void) cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER);
execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
diff --git a/src/core/manager.c b/src/core/manager.c
index fc10ddb5d9..56f2c92feb 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -554,7 +554,7 @@ int manager_new(ManagerRunningAs running_as, bool test_run, Manager **_m) {
return -ENOMEM;
#ifdef ENABLE_EFI
- if (running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0)
+ if (running_as == MANAGER_SYSTEM && detect_container() <= 0)
boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
#endif
@@ -2156,7 +2156,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
if (m->running_as != MANAGER_SYSTEM)
return;
- if (detect_container(NULL) > 0)
+ if (detect_container() > 0)
return;
if (u->type != UNIT_SERVICE &&
@@ -2613,7 +2613,7 @@ static void manager_notify_finished(Manager *m) {
if (m->test_run)
return;
- if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) {
+ if (m->running_as == MANAGER_SYSTEM && detect_container() <= 0) {
/* Note that m->kernel_usec.monotonic is always at 0,
* and m->firmware_usec.monotonic and
diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index c6f3569915..e84f80b61b 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -164,7 +164,7 @@ static int mount_one(const MountPoint *p, bool relabel) {
return 0;
/* Skip securityfs in a container */
- if (!(p->mode & MNT_IN_CONTAINER) && detect_container(NULL) > 0)
+ if (!(p->mode & MNT_IN_CONTAINER) && detect_container() > 0)
return 0;
/* The access mode here doesn't really matter too much, since
@@ -385,7 +385,7 @@ int mount_setup(bool loaded_policy) {
* nspawn and the container tools work out of the box. If
* specific setups need other settings they can reset the
* propagation mode to private if needed. */
- if (detect_container(NULL) <= 0)
+ if (detect_container() <= 0)
if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0)
log_warning_errno(errno, "Failed to set up the root directory for shared mount propagation: %m");
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index aba16b4689..8a6fd25f31 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -202,7 +202,7 @@ int main(int argc, char *argv[]) {
log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false);
- in_container = detect_container(NULL) > 0;
+ in_container = detect_container() > 0;
need_umount = !in_container;
need_swapoff = !in_container;
diff --git a/src/core/swap.c b/src/core/swap.c
index 4f3ddc9f04..2f462e339d 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -215,7 +215,7 @@ static int swap_add_default_dependencies(Swap *s) {
if (UNIT(s)->manager->running_as != MANAGER_SYSTEM)
return 0;
- if (detect_container(NULL) > 0)
+ if (detect_container() > 0)
return 0;
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
@@ -824,7 +824,7 @@ static int swap_start(Unit *u) {
assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
- if (detect_container(NULL) > 0)
+ if (detect_container() > 0)
return -EPERM;
/* If there's a job for another swap unit for the same node
@@ -857,7 +857,7 @@ static int swap_stop(Unit *u) {
s->state == SWAP_ACTIVATING_DONE ||
s->state == SWAP_ACTIVE);
- if (detect_container(NULL) > 0)
+ if (detect_container() > 0)
return -EPERM;
swap_enter_deactivating(s);
@@ -1404,7 +1404,7 @@ static bool swap_supported(void) {
if (supported < 0)
supported =
access("/proc/swaps", F_OK) >= 0 &&
- detect_container(NULL) <= 0;
+ detect_container() <= 0;
return supported;
}
diff --git a/src/core/umount.c b/src/core/umount.c
index d59b5d0ffb..22dbe67259 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -368,7 +368,7 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
read-only mount anything as that brings no real
benefits, but might confuse the host, as we remount
the superblock here, not the bind mound. */
- if (detect_container(NULL) <= 0) {
+ if (detect_container() <= 0) {
/* We always try to remount directories
* read-only first, before we go on and umount
* them.
diff --git a/src/core/unit.c b/src/core/unit.c
index 45ce1b172d..be38f1fa27 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -3505,7 +3505,7 @@ int unit_kill_context(
* them.*/
if (cg_unified() > 0 ||
- (detect_container(NULL) == 0 && !unit_cgroup_delegate(u)))
+ (detect_container() == 0 && !unit_cgroup_delegate(u)))
wait_for_exit = true;
if (c->send_sighup && k != KILL_KILL) {
diff --git a/src/detect-virt/detect-virt.c b/src/detect-virt/detect-virt.c
index 606d073cbc..97ae569ca5 100644
--- a/src/detect-virt/detect-virt.c
+++ b/src/detect-virt/detect-virt.c
@@ -108,9 +108,7 @@ static int parse_argv(int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
- const char *id = NULL;
- int retval = EXIT_SUCCESS;
- int r;
+ int retval = EXIT_SUCCESS, r;
/* This is mostly intended to be used for scripts which want
* to detect whether we are being run in a virtualized
@@ -125,42 +123,39 @@ int main(int argc, char *argv[]) {
switch (arg_mode) {
- case ANY_VIRTUALIZATION: {
- int v;
-
- v = detect_virtualization(&id);
- if (v < 0) {
- log_error_errno(v, "Failed to check for virtualization: %m");
+ case ONLY_VM:
+ r = detect_vm();
+ if (r < 0) {
+ log_error_errno(r, "Failed to check for vm: %m");
return EXIT_FAILURE;
}
- retval = v != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
break;
- }
case ONLY_CONTAINER:
- r = detect_container(&id);
+ r = detect_container();
if (r < 0) {
log_error_errno(r, "Failed to check for container: %m");
return EXIT_FAILURE;
}
- retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
break;
- case ONLY_VM:
- r = detect_vm(&id);
+ case ANY_VIRTUALIZATION:
+ default:
+ r = detect_virtualization();
if (r < 0) {
- log_error_errno(r, "Failed to check for vm: %m");
+ log_error_errno(r, "Failed to check for virtualization: %m");
return EXIT_FAILURE;
}
- retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
break;
}
if (!arg_quiet)
- puts(id ? id : "none");
+ puts(virtualization_to_string(r));
+
+ retval = r != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
return retval;
}
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index a88b68e2c0..3f8ea5647c 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -65,7 +65,7 @@ static int add_swap(
return 0;
}
- if (detect_container(NULL) > 0) {
+ if (detect_container() > 0) {
log_info("Running in a container, ignoring fstab swap entry for %s.", what);
return 0;
}
diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c
index d23caab44a..9a4b038ef3 100644
--- a/src/getty-generator/getty-generator.c
+++ b/src/getty-generator/getty-generator.c
@@ -142,7 +142,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- if (detect_container(NULL) > 0) {
+ if (detect_container() > 0) {
_cleanup_free_ char *container_ttys = NULL;
log_debug("Automatically adding console shell.");
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index cf25d9847f..c97be2dabf 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -460,7 +460,7 @@ static int add_boot(const char *what) {
return 0;
}
- if (detect_container(NULL) > 0) {
+ if (detect_container() > 0) {
log_debug("In a container, ignoring /boot.");
return 0;
}
@@ -992,7 +992,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- if (detect_container(NULL) > 0) {
+ if (detect_container() > 0) {
log_debug("In a container, exiting.");
return EXIT_SUCCESS;
}
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index c423be3767..e90ae54156 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -155,11 +155,11 @@ static const char* fallback_chassis(void) {
unsigned t;
int v;
- v = detect_virtualization(NULL);
+ v = detect_virtualization();
- if (v == VIRTUALIZATION_VM)
+ if (VIRTUALIZATION_IS_VM(v))
return "vm";
- if (v == VIRTUALIZATION_CONTAINER)
+ if (VIRTUALIZATION_IS_CONTAINER(v))
return "container";
r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type);
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
index 70c68ad131..7d9cad2a70 100644
--- a/src/libsystemd-network/dhcp-identifier.c
+++ b/src/libsystemd-network/dhcp-identifier.c
@@ -66,7 +66,7 @@ int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_i
const char *name = NULL;
uint64_t id;
- if (detect_container(NULL) <= 0) {
+ if (detect_container() <= 0) {
/* not in a container, udev will be around */
_cleanup_udev_unref_ struct udev *udev;
char ifindex_str[2 + DECIMAL_STR_MAX(int)];
diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c
index 12daac3211..9c7f9ffb1b 100644
--- a/src/libsystemd-network/test-dhcp6-client.c
+++ b/src/libsystemd-network/test-dhcp6-client.c
@@ -357,18 +357,6 @@ static int test_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
return 0;
}
-int detect_vm(const char **id) {
- return 1;
-}
-
-int detect_container(const char **id) {
- return 1;
-}
-
-int detect_virtualization(const char **id) {
- return 1;
-}
-
static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
void *userdata) {
sd_event *e = userdata;
diff --git a/src/locale/localectl.c b/src/locale/localectl.c
index 1e06f2251c..4a91c7420a 100644
--- a/src/locale/localectl.c
+++ b/src/locale/localectl.c
@@ -96,7 +96,7 @@ static void print_overridden_variables(void) {
LocaleVariable j;
bool print_warning = true;
- if (detect_container(NULL) > 0 || arg_host)
+ if (detect_container() > 0 || arg_host)
return;
r = parse_env_file("/proc/cmdline", WHITESPACE,
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 1dc9db0fca..9d4a69b0db 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2152,7 +2152,7 @@ int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
log_link_debug(link, "Link %d added", link->ifindex);
- if (detect_container(NULL) <= 0) {
+ if (detect_container() <= 0) {
/* not in a container, udev will be around */
sprintf(ifindex_str, "n%d", link->ifindex);
device = udev_device_new_from_device_id(m->udev, ifindex_str);
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 92b607297d..b4259cafef 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -241,7 +241,7 @@ static int manager_connect_udev(Manager *m) {
/* udev does not initialize devices inside containers,
* so we rely on them being already initialized before
* entering the container */
- if (detect_container(NULL) > 0)
+ if (detect_container() > 0)
return 0;
m->udev = udev_new();
diff --git a/src/shared/condition.c b/src/shared/condition.c
index f58e84a3d0..1d7dd49e04 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -125,13 +125,12 @@ static int condition_test_kernel_command_line(Condition *c) {
static int condition_test_virtualization(Condition *c) {
int b, v;
- const char *id;
assert(c);
assert(c->parameter);
assert(c->type == CONDITION_VIRTUALIZATION);
- v = detect_virtualization(&id);
+ v = detect_virtualization();
if (v < 0)
return v;
@@ -145,14 +144,14 @@ static int condition_test_virtualization(Condition *c) {
return true;
/* Then, compare categorization */
- if (v == VIRTUALIZATION_VM && streq(c->parameter, "vm"))
+ if (VIRTUALIZATION_IS_VM(v) && streq(c->parameter, "vm"))
return true;
- if (v == VIRTUALIZATION_CONTAINER && streq(c->parameter, "container"))
+ if (VIRTUALIZATION_IS_CONTAINER(v) && streq(c->parameter, "container"))
return true;
/* Finally compare id */
- return v > 0 && streq(c->parameter, id);
+ return v != VIRTUALIZATION_NONE && streq(c->parameter, virtualization_to_string(v));
}
static int condition_test_architecture(Condition *c) {
diff --git a/src/shared/efivars.c b/src/shared/efivars.c
index 347cd30b09..f087c2a566 100644
--- a/src/shared/efivars.c
+++ b/src/shared/efivars.c
@@ -101,7 +101,7 @@ int efi_reboot_to_firmware_supported(void) {
uint64_t b;
_cleanup_free_ void *v = NULL;
- if (!is_efi_boot() || detect_container(NULL) > 0)
+ if (!is_efi_boot() || detect_container() > 0)
return -EOPNOTSUPP;
r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s);
diff --git a/src/test/test-architecture.c b/src/test/test-architecture.c
index 30bdec45e5..a5b66a7d2f 100644
--- a/src/test/test-architecture.c
+++ b/src/test/test-architecture.c
@@ -25,18 +25,18 @@
#include "log.h"
int main(int argc, char *argv[]) {
- const char *id = NULL;
int a, v;
- v = detect_virtualization(&id);
+ v = detect_virtualization();
if (v == -EPERM || v == -EACCES)
return EXIT_TEST_SKIP;
assert_se(v >= 0);
log_info("virtualization=%s id=%s",
- v == VIRTUALIZATION_CONTAINER ? "container" : v == VIRTUALIZATION_VM ? "vm" : "n/a",
- strna(id));
+ VIRTUALIZATION_IS_CONTAINER(v) ? "container" :
+ VIRTUALIZATION_IS_VM(v) ? "vm" : "n/a",
+ virtualization_to_string(v));
a = uname_architecture();
assert_se(a >= 0);
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index e4e2efecd5..eb0f443a43 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -85,7 +85,7 @@ static void test_get_process_comm(void) {
assert_se(r >= 0 || r == -EACCES);
log_info("self strlen(environ): '%zu'", strlen(env));
- if (!detect_container(NULL))
+ if (!detect_container())
assert_se(get_ctty_devnr(1, &h) == -ENXIO);
getenv_for_pid(1, "PATH", &i);
diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c
index 7bdc158ad7..6353579283 100644
--- a/src/vconsole/vconsole-setup.c
+++ b/src/vconsole/vconsole-setup.c
@@ -293,7 +293,7 @@ int main(int argc, char **argv) {
log_warning_errno(r, "Failed to read /etc/vconsole.conf: %m");
/* Let the kernel command line override /etc/vconsole.conf */
- if (detect_container(NULL) <= 0) {
+ if (detect_container() <= 0) {
r = parse_env_file("/proc/cmdline", WHITESPACE,
"vconsole.keymap", &vc_keymap,
"vconsole.keymap.toggle", &vc_keymap_toggle,