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.
This commit is contained in:
Lennart Poettering
2015-09-07 13:42:47 +02:00
parent 47f5a38cdf
commit 75f86906c5
29 changed files with 335 additions and 312 deletions
+1 -1
View File
@@ -4817,7 +4817,7 @@ int shall_restore_state(void) {
int proc_cmdline(char **ret) { int proc_cmdline(char **ret) {
assert(ret); assert(ret);
if (detect_container(NULL) > 0) if (detect_container() > 0)
return get_process_cmdline(1, 0, false, ret); return get_process_cmdline(1, 0, false, ret);
else else
return read_one_line_file("/proc/cmdline", ret); return read_one_line_file("/proc/cmdline", ret);
+211 -200
View File
@@ -28,25 +28,24 @@
#include "virt.h" #include "virt.h"
#include "fileio.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... */ /* Both CPUID and DMI are x86 specific interfaces... */
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
static const char cpuid_vendor_table[] = static const struct {
"XenVMMXenVMM\0" "xen\0" const char *cpuid;
"KVMKVMKVM\0" "kvm\0" 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 */ /* 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 */ /* http://msdn.microsoft.com/en-us/library/ff542428.aspx */
"Microsoft Hv\0" "microsoft\0"; { "Microsoft Hv", VIRTUALIZATION_MICROSOFT },
};
uint32_t eax, ecx; uint32_t eax, ecx;
union {
uint32_t sig32[3];
char text[13];
} sig = {};
const char *j, *k;
bool hypervisor; bool hypervisor;
/* http://lwn.net/Articles/301888/ */ /* http://lwn.net/Articles/301888/ */
@@ -74,6 +73,11 @@ static int detect_vm_cpuid(const char **_id) {
hypervisor = !!(ecx & 0x80000000U); hypervisor = !!(ecx & 0x80000000U);
if (hypervisor) { if (hypervisor) {
union {
uint32_t sig32[3];
char text[13];
} sig = {};
unsigned j;
/* There is a hypervisor, see what it is */ /* There is a hypervisor, see what it is */
eax = 0x40000000U; eax = 0x40000000U;
@@ -88,57 +92,54 @@ static int detect_vm_cpuid(const char **_id) {
: "0" (eax) : "0" (eax)
); );
NULSTR_FOREACH_PAIR(j, k, cpuid_vendor_table) for (j = 0; j < ELEMENTSOF(cpuid_vendor_table); j ++)
if (streq(sig.text, j)) { if (streq(sig.text, cpuid_vendor_table[j].cpuid))
*_id = k; return cpuid_vendor_table[j].id;
return 1;
}
*_id = "other"; return VIRTUALIZATION_VM_OTHER;
return 0;
} }
#endif #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__) #if defined(__arm__) || defined(__aarch64__) || defined(__powerpc__) || defined(__powerpc64__)
_cleanup_free_ char *hvtype = NULL; _cleanup_free_ char *hvtype = NULL;
int r; int r;
r = read_one_line_file("/proc/device-tree/hypervisor/compatible", &hvtype); r = read_one_line_file("/proc/device-tree/hypervisor/compatible", &hvtype);
if (r >= 0) { if (r == -ENOENT) {
if (streq(hvtype, "linux,kvm")) {
*_id = "kvm";
return 1;
} else if (strstr(hvtype, "xen")) {
*_id = "xen";
return 1;
}
} else if (r == -ENOENT) {
_cleanup_closedir_ DIR *dir = NULL; _cleanup_closedir_ DIR *dir = NULL;
struct dirent *dent; struct dirent *dent;
dir = opendir("/proc/device-tree"); dir = opendir("/proc/device-tree");
if (!dir) { if (!dir) {
if (errno == ENOENT) if (errno == ENOENT)
return 0; return VIRTUALIZATION_NONE;
return -errno; return -errno;
} }
FOREACH_DIRENT(dent, dir, return -errno) { FOREACH_DIRENT(dent, dir, return -errno)
if (strstr(dent->d_name, "fw-cfg")) { if (strstr(dent->d_name, "fw-cfg"))
*_id = "qemu"; return VIRTUALIZATION_QEMU;
return 1;
} 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 #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... */ /* Both CPUID and DMI are x86 specific interfaces... */
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
@@ -149,188 +150,195 @@ static int detect_vm_dmi(const char **_id) {
"/sys/class/dmi/id/bios_vendor" "/sys/class/dmi/id/bios_vendor"
}; };
static const char dmi_vendor_table[] = static const struct {
"QEMU\0" "qemu\0" 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 */ /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
"VMware\0" "vmware\0" { "VMware", VIRTUALIZATION_VMWARE },
"VMW\0" "vmware\0" { "VMW", VIRTUALIZATION_VMWARE },
"innotek GmbH\0" "oracle\0" { "innotek GmbH", VIRTUALIZATION_ORACLE },
"Xen\0" "xen\0" { "Xen", VIRTUALIZATION_XEN },
"Bochs\0" "bochs\0" { "Bochs", VIRTUALIZATION_BOCHS },
"Parallels\0" "parallels\0"; { "Parallels", VIRTUALIZATION_PARALLELS },
};
unsigned i; unsigned i;
int r;
for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) {
_cleanup_free_ char *s = NULL; _cleanup_free_ char *s = NULL;
const char *j, *k; unsigned j;
int r;
r = read_one_line_file(dmi_vendors[i], &s); r = read_one_line_file(dmi_vendors[i], &s);
if (r < 0) { if (r < 0) {
if (r != -ENOENT) if (r == -ENOENT)
return r; continue;
continue; return r;
} }
NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table) for (j = 0; j < ELEMENTSOF(dmi_vendor_table); j++)
if (startswith(s, j)) { if (startswith(s, dmi_vendor_table[j].vendor))
*_id = k; return dmi_vendor_table[j].id;
return 1;
}
} }
#endif #endif
return 0; return VIRTUALIZATION_NONE;
} }
/* Returns a short identifier for the various VM implementations */ static int detect_vm_xen(void) {
int detect_vm(const char **id) { _cleanup_free_ char *domcap = NULL;
_cleanup_free_ char *domcap = NULL, *cpuinfo_contents = NULL; char *cap, *i;
static thread_local int cached_found = -1;
static thread_local const char *cached_id = NULL;
const char *_id = NULL, *_id_cpuid = NULL;
int r; int r;
if (_likely_(cached_found >= 0)) {
if (id)
*id = cached_id;
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); r = read_one_line_file("/proc/xen/capabilities", &domcap);
if (r >= 0) { if (r == -ENOENT)
char *cap, *i = domcap; return VIRTUALIZATION_NONE;
while ((cap = strsep(&i, ","))) i = domcap;
if (streq(cap, "control_d")) while ((cap = strsep(&i, ",")))
break; if (streq(cap, "control_d"))
break;
if (!cap) { return cap ? VIRTUALIZATION_NONE : VIRTUALIZATION_XEN;
_id = "xen"; }
r = 1;
}
goto finish; static int detect_vm_hypervisor(void) {
_cleanup_free_ char *hvtype = NULL;
int r;
} else if (r == -ENOENT) { r = read_one_line_file("/sys/hypervisor/type", &hvtype);
_cleanup_free_ char *hvtype = NULL; if (r == -ENOENT)
return VIRTUALIZATION_NONE;
r = read_one_line_file("/sys/hypervisor/type", &hvtype); if (r < 0)
if (r >= 0) {
if (streq(hvtype, "xen")) {
_id = "xen";
r = 1;
goto finish;
}
} else if (r != -ENOENT)
return r;
} else
return r; return r;
/* this will set _id to "other" and return 0 for unknown hypervisors */ if (streq(hvtype, "xen"))
r = detect_vm_cpuid(&_id); return VIRTUALIZATION_XEN;
else
return VIRTUALIZATION_VM_OTHER;
}
/* finish when found a known hypervisor other than kvm */ static int detect_vm_uml(void) {
if (r < 0 || (r > 0 && !streq(_id, "kvm"))) _cleanup_free_ char *cpuinfo_contents = NULL;
goto finish; int r;
_id_cpuid = _id;
r = detect_vm_dmi(&_id);
/* 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;
_id = _id_cpuid;
r = 1;
goto finish;
}
/* information from dmi */
if (r != 0)
goto finish;
r = detect_vm_devicetree(&_id);
if (r != 0)
goto finish;
if (_id) {
/* "other" */
r = 1;
goto finish;
}
/* Detect User-Mode Linux by reading /proc/cpuinfo */ /* Detect User-Mode Linux by reading /proc/cpuinfo */
r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL); r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
if (r < 0) if (r < 0)
return r; return r;
if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) { if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n"))
_id = "uml"; return VIRTUALIZATION_UML;
r = 1;
goto finish; return VIRTUALIZATION_NONE;
} }
static int detect_vm_zvm(void) {
#if defined(__s390__) #if defined(__s390__)
{ _cleanup_free_ char *t = NULL;
_cleanup_free_ char *t = NULL; int r;
r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t); r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t);
if (r >= 0) { if (r == -ENOENT)
if (streq(t, "z/VM")) return VIRTUALIZATION_NONE;
_id = "zvm"; if (r < 0)
else return r;
_id = "kvm";
r = 1;
goto finish; if (streq(t, "z/VM"))
} return VIRTUALIZATION_ZVM;
} else
return VIRTUALIZATION_KVM;
#else
return VIRTUALIZATION_NONE;
#endif #endif
}
r = 0; /* Returns a short identifier for the various VM implementations */
int detect_vm(void) {
static thread_local int cached_found = _VIRTUALIZATION_INVALID;
int r;
if (cached_found >= 0)
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 = detect_vm_xen();
if (r < 0)
return r;
if (r != VIRTUALIZATION_NONE)
goto finish;
r = detect_vm_dmi();
if (r < 0)
return r;
if (r != VIRTUALIZATION_NONE)
goto finish;
r = detect_vm_cpuid();
if (r < 0)
return r;
if (r != VIRTUALIZATION_NONE)
goto finish;
r = detect_vm_hypervisor();
if (r < 0)
return r;
if (r != VIRTUALIZATION_NONE)
goto finish;
r = detect_vm_device_tree();
if (r < 0)
return r;
if (r != VIRTUALIZATION_NONE)
goto finish;
r = detect_vm_uml();
if (r < 0)
return r;
if (r != VIRTUALIZATION_NONE)
goto finish;
r = detect_vm_zvm();
if (r < 0)
return r;
finish: finish:
cached_found = r; cached_found = r;
cached_id = _id;
if (id)
*id = _id;
return r; return r;
} }
int detect_container(const char **id) { int detect_container(void) {
static thread_local int cached_found = -1; static const struct {
static thread_local const char *cached_id = NULL; 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; _cleanup_free_ char *m = NULL;
const char *_id = NULL, *e = NULL; const char *e = NULL;
unsigned j;
int r; int r;
if (_likely_(cached_found >= 0)) { if (cached_found >= 0)
if (id)
*id = cached_id;
return cached_found; return cached_found;
}
/* /proc/vz exists in container and outside of the container, /* /proc/vz exists in container and outside of the container,
* /proc/bc only outside of the container. */ * /proc/bc only outside of the container. */
if (access("/proc/vz", F_OK) >= 0 && if (access("/proc/vz", F_OK) >= 0 &&
access("/proc/bc", F_OK) < 0) { access("/proc/bc", F_OK) < 0) {
_id = "openvz"; r = VIRTUALIZATION_OPENVZ;
r = 1;
goto finish; goto finish;
} }
@@ -340,7 +348,7 @@ int detect_container(const char **id) {
e = getenv("container"); e = getenv("container");
if (isempty(e)) { if (isempty(e)) {
r = 0; r = VIRTUALIZATION_NONE;
goto finish; goto finish;
} }
} else { } else {
@@ -369,7 +377,7 @@ int detect_container(const char **id) {
* as /proc/1/environ is only readable * as /proc/1/environ is only readable
* with privileges. */ * with privileges. */
r = 0; r = VIRTUALIZATION_NONE;
goto finish; goto finish;
} }
} }
@@ -379,46 +387,49 @@ int detect_container(const char **id) {
e = m; e = m;
} }
/* We only recognize a selected few here, since we want to for (j = 0; j < ELEMENTSOF(value_table); j++)
* enforce a redacted namespace */ if (streq(e, value_table[j].value)) {
if (streq(e, "lxc")) r = value_table[j].id;
_id ="lxc"; goto finish;
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";
r = 1; r = VIRTUALIZATION_NONE;
finish: finish:
cached_found = r; cached_found = r;
cached_id = _id;
if (id)
*id = _id;
return r; return r;
} }
/* Returns a short identifier for the various VM/container implementations */ int detect_virtualization(void) {
int detect_virtualization(const char **id) {
int r; int r;
r = detect_container(id); r = detect_container();
if (r < 0) if (r != 0)
return r; return r;
if (r > 0)
return VIRTUALIZATION_CONTAINER;
r = detect_vm(id); return detect_vm();
if (r < 0)
return r;
if (r > 0)
return VIRTUALIZATION_VM;
return VIRTUALIZATION_NONE;
} }
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);
+41 -5
View File
@@ -21,15 +21,51 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>. along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/ ***/
int detect_vm(const char **id); #include <stdbool.h>
int detect_container(const char **id);
#include "macro.h"
enum { enum {
VIRTUALIZATION_NONE = 0, 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_MAX,
_VIRTUALIZATION_INVALID = -1 _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_;
+1 -5
View File
@@ -81,14 +81,10 @@ static int property_get_virtualization(
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
const char *id = NULL;
assert(bus); assert(bus);
assert(reply); assert(reply);
detect_virtualization(&id); return sd_bus_message_append(reply, "s", virtualization_to_string(detect_virtualization()));
return sd_bus_message_append(reply, "s", id);
} }
static int property_get_architecture( static int property_get_architecture(
+1 -1
View File
@@ -1137,7 +1137,7 @@ void job_shutdown_magic(Job *j) {
/* In case messages on console has been disabled on boot */ /* In case messages on console has been disabled on boot */
j->unit->manager->no_console_output = false; j->unit->manager->no_console_output = false;
if (detect_container(NULL) > 0) if (detect_container() > 0)
return; return;
asynchronous_sync(); asynchronous_sync();
+1 -1
View File
@@ -35,7 +35,7 @@ int locale_setup(char ***environment) {
char *variables[_VARIABLE_LC_MAX] = {}; char *variables[_VARIABLE_LC_MAX] = {};
int r = 0, i; int r = 0, i;
if (detect_container(NULL) <= 0) { if (detect_container() <= 0) {
r = parse_env_file("/proc/cmdline", WHITESPACE, r = parse_env_file("/proc/cmdline", WHITESPACE,
"locale.LANG", &variables[VARIABLE_LANG], "locale.LANG", &variables[VARIABLE_LANG],
"locale.LANGUAGE", &variables[VARIABLE_LANGUAGE], "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE],
+14 -16
View File
@@ -108,7 +108,7 @@ static int generate_machine_id(char id[34], const char *root) {
unsigned char *p; unsigned char *p;
sd_id128_t buf; sd_id128_t buf;
char *q; char *q;
const char *vm_id, *dbus_machine_id; const char *dbus_machine_id;
assert(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, /* 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 * and a machine ID was passed in via $container_uuid the way
* libvirt/LXC does it */ * libvirt/LXC does it */
r = detect_container(NULL);
if (r > 0) { if (detect_container() > 0) {
_cleanup_free_ char *e = NULL; _cleanup_free_ char *e = NULL;
r = getenv_for_pid(1, "container_uuid", &e); 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 /* If we are not running in a container, see if we are
* running in qemu/kvm and a machine ID was passed in * running in qemu/kvm and a machine ID was passed in
* via -uuid on the qemu/kvm command line */ * via -uuid on the qemu/kvm command line */
r = detect_vm(&vm_id); char uuid[36];
if (r > 0 && streq(vm_id, "kvm")) {
char uuid[36];
fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
if (fd >= 0) { if (fd >= 0) {
r = loop_read_exact(fd, uuid, 36, false); r = loop_read_exact(fd, uuid, 36, false);
safe_close(fd); safe_close(fd);
if (r >= 0) {
r = shorten_uuid(id, uuid);
if (r >= 0) { if (r >= 0) {
r = shorten_uuid(id, uuid); log_info("Initializing machine ID from KVM UUID.");
if (r >= 0) { return 0;
log_info("Initializing machine ID from KVM UUID.");
return 0;
}
} }
} }
} }
+7 -7
View File
@@ -374,7 +374,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
/* Note that log_parse_environment() handles 'debug' /* Note that log_parse_environment() handles 'debug'
* too, and sets the log level to LOG_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); log_set_target(LOG_TARGET_CONSOLE);
} else if (!in_initrd() && !value) { } else if (!in_initrd() && !value) {
@@ -1297,7 +1297,7 @@ int main(int argc, char *argv[]) {
if (getpid() == 1) if (getpid() == 1)
umask(0); umask(0);
if (getpid() == 1 && detect_container(NULL) <= 0) { if (getpid() == 1 && detect_container() <= 0) {
/* Running outside of a container as PID 1 */ /* Running outside of a container as PID 1 */
arg_running_as = MANAGER_SYSTEM; arg_running_as = MANAGER_SYSTEM;
@@ -1551,14 +1551,14 @@ int main(int argc, char *argv[]) {
} }
if (arg_running_as == MANAGER_SYSTEM) { if (arg_running_as == MANAGER_SYSTEM) {
const char *virtualization = NULL; int v;
log_info(PACKAGE_STRING " running in %ssystem mode. (" SYSTEMD_FEATURES ")", log_info(PACKAGE_STRING " running in %ssystem mode. (" SYSTEMD_FEATURES ")",
arg_action == ACTION_TEST ? "test " : "" ); arg_action == ACTION_TEST ? "test " : "" );
detect_virtualization(&virtualization); v = detect_virtualization();
if (virtualization) if (v > 0)
log_info("Detected virtualization %s.", virtualization); log_info("Detected virtualization %s.", virtualization_to_string(v));
write_container_id(); write_container_id();
@@ -2046,7 +2046,7 @@ finish:
/* Avoid the creation of new processes forked by the /* Avoid the creation of new processes forked by the
* kernel; at this point, we will not listen to the * kernel; at this point, we will not listen to the
* signals anyway */ * signals anyway */
if (detect_container(NULL) <= 0) if (detect_container() <= 0)
(void) cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER); (void) cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER);
execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block); execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
+3 -3
View File
@@ -554,7 +554,7 @@ int manager_new(ManagerRunningAs running_as, bool test_run, Manager **_m) {
return -ENOMEM; return -ENOMEM;
#ifdef ENABLE_EFI #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); boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
#endif #endif
@@ -2156,7 +2156,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
if (m->running_as != MANAGER_SYSTEM) if (m->running_as != MANAGER_SYSTEM)
return; return;
if (detect_container(NULL) > 0) if (detect_container() > 0)
return; return;
if (u->type != UNIT_SERVICE && if (u->type != UNIT_SERVICE &&
@@ -2613,7 +2613,7 @@ static void manager_notify_finished(Manager *m) {
if (m->test_run) if (m->test_run)
return; 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, /* Note that m->kernel_usec.monotonic is always at 0,
* and m->firmware_usec.monotonic and * and m->firmware_usec.monotonic and
+2 -2
View File
@@ -164,7 +164,7 @@ static int mount_one(const MountPoint *p, bool relabel) {
return 0; return 0;
/* Skip securityfs in a container */ /* 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; return 0;
/* The access mode here doesn't really matter too much, since /* 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 * nspawn and the container tools work out of the box. If
* specific setups need other settings they can reset the * specific setups need other settings they can reset the
* propagation mode to private if needed. */ * 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) 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"); log_warning_errno(errno, "Failed to set up the root directory for shared mount propagation: %m");
+1 -1
View File
@@ -202,7 +202,7 @@ int main(int argc, char *argv[]) {
log_info("Sending SIGKILL to remaining processes..."); log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false); broadcast_signal(SIGKILL, true, false);
in_container = detect_container(NULL) > 0; in_container = detect_container() > 0;
need_umount = !in_container; need_umount = !in_container;
need_swapoff = !in_container; need_swapoff = !in_container;
+4 -4
View File
@@ -215,7 +215,7 @@ static int swap_add_default_dependencies(Swap *s) {
if (UNIT(s)->manager->running_as != MANAGER_SYSTEM) if (UNIT(s)->manager->running_as != MANAGER_SYSTEM)
return 0; return 0;
if (detect_container(NULL) > 0) if (detect_container() > 0)
return 0; return 0;
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); 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); assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
if (detect_container(NULL) > 0) if (detect_container() > 0)
return -EPERM; return -EPERM;
/* If there's a job for another swap unit for the same node /* 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_ACTIVATING_DONE ||
s->state == SWAP_ACTIVE); s->state == SWAP_ACTIVE);
if (detect_container(NULL) > 0) if (detect_container() > 0)
return -EPERM; return -EPERM;
swap_enter_deactivating(s); swap_enter_deactivating(s);
@@ -1404,7 +1404,7 @@ static bool swap_supported(void) {
if (supported < 0) if (supported < 0)
supported = supported =
access("/proc/swaps", F_OK) >= 0 && access("/proc/swaps", F_OK) >= 0 &&
detect_container(NULL) <= 0; detect_container() <= 0;
return supported; return supported;
} }
+1 -1
View File
@@ -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 read-only mount anything as that brings no real
benefits, but might confuse the host, as we remount benefits, but might confuse the host, as we remount
the superblock here, not the bind mound. */ the superblock here, not the bind mound. */
if (detect_container(NULL) <= 0) { if (detect_container() <= 0) {
/* We always try to remount directories /* We always try to remount directories
* read-only first, before we go on and umount * read-only first, before we go on and umount
* them. * them.
+1 -1
View File
@@ -3505,7 +3505,7 @@ int unit_kill_context(
* them.*/ * them.*/
if (cg_unified() > 0 || if (cg_unified() > 0 ||
(detect_container(NULL) == 0 && !unit_cgroup_delegate(u))) (detect_container() == 0 && !unit_cgroup_delegate(u)))
wait_for_exit = true; wait_for_exit = true;
if (c->send_sighup && k != KILL_KILL) { if (c->send_sighup && k != KILL_KILL) {
+24 -29
View File
@@ -108,9 +108,7 @@ static int parse_argv(int argc, char *argv[]) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
const char *id = NULL; int retval = EXIT_SUCCESS, r;
int retval = EXIT_SUCCESS;
int r;
/* This is mostly intended to be used for scripts which want /* This is mostly intended to be used for scripts which want
* to detect whether we are being run in a virtualized * to detect whether we are being run in a virtualized
@@ -125,42 +123,39 @@ int main(int argc, char *argv[]) {
switch (arg_mode) { 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");
return EXIT_FAILURE;
}
retval = v != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
break;
}
case ONLY_CONTAINER:
r = detect_container(&id);
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: case ONLY_VM:
r = detect_vm(&id); r = detect_vm();
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to check for vm: %m"); log_error_errno(r, "Failed to check for vm: %m");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE; break;
case ONLY_CONTAINER:
r = detect_container();
if (r < 0) {
log_error_errno(r, "Failed to check for container: %m");
return EXIT_FAILURE;
}
break;
case ANY_VIRTUALIZATION:
default:
r = detect_virtualization();
if (r < 0) {
log_error_errno(r, "Failed to check for virtualization: %m");
return EXIT_FAILURE;
}
break; break;
} }
if (!arg_quiet) if (!arg_quiet)
puts(id ? id : "none"); puts(virtualization_to_string(r));
retval = r != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
return retval; return retval;
} }
+1 -1
View File
@@ -65,7 +65,7 @@ static int add_swap(
return 0; return 0;
} }
if (detect_container(NULL) > 0) { if (detect_container() > 0) {
log_info("Running in a container, ignoring fstab swap entry for %s.", what); log_info("Running in a container, ignoring fstab swap entry for %s.", what);
return 0; return 0;
} }
+1 -1
View File
@@ -142,7 +142,7 @@ int main(int argc, char *argv[]) {
umask(0022); umask(0022);
if (detect_container(NULL) > 0) { if (detect_container() > 0) {
_cleanup_free_ char *container_ttys = NULL; _cleanup_free_ char *container_ttys = NULL;
log_debug("Automatically adding console shell."); log_debug("Automatically adding console shell.");
+2 -2
View File
@@ -460,7 +460,7 @@ static int add_boot(const char *what) {
return 0; return 0;
} }
if (detect_container(NULL) > 0) { if (detect_container() > 0) {
log_debug("In a container, ignoring /boot."); log_debug("In a container, ignoring /boot.");
return 0; return 0;
} }
@@ -992,7 +992,7 @@ int main(int argc, char *argv[]) {
umask(0022); umask(0022);
if (detect_container(NULL) > 0) { if (detect_container() > 0) {
log_debug("In a container, exiting."); log_debug("In a container, exiting.");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
+3 -3
View File
@@ -155,11 +155,11 @@ static const char* fallback_chassis(void) {
unsigned t; unsigned t;
int v; int v;
v = detect_virtualization(NULL); v = detect_virtualization();
if (v == VIRTUALIZATION_VM) if (VIRTUALIZATION_IS_VM(v))
return "vm"; return "vm";
if (v == VIRTUALIZATION_CONTAINER) if (VIRTUALIZATION_IS_CONTAINER(v))
return "container"; return "container";
r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type); r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type);
+1 -1
View File
@@ -66,7 +66,7 @@ int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_i
const char *name = NULL; const char *name = NULL;
uint64_t id; uint64_t id;
if (detect_container(NULL) <= 0) { if (detect_container() <= 0) {
/* not in a container, udev will be around */ /* not in a container, udev will be around */
_cleanup_udev_unref_ struct udev *udev; _cleanup_udev_unref_ struct udev *udev;
char ifindex_str[2 + DECIMAL_STR_MAX(int)]; char ifindex_str[2 + DECIMAL_STR_MAX(int)];
@@ -357,18 +357,6 @@ static int test_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
return 0; 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, static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
void *userdata) { void *userdata) {
sd_event *e = userdata; sd_event *e = userdata;
+1 -1
View File
@@ -96,7 +96,7 @@ static void print_overridden_variables(void) {
LocaleVariable j; LocaleVariable j;
bool print_warning = true; bool print_warning = true;
if (detect_container(NULL) > 0 || arg_host) if (detect_container() > 0 || arg_host)
return; return;
r = parse_env_file("/proc/cmdline", WHITESPACE, r = parse_env_file("/proc/cmdline", WHITESPACE,
+1 -1
View File
@@ -2152,7 +2152,7 @@ int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
log_link_debug(link, "Link %d added", link->ifindex); 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 */ /* not in a container, udev will be around */
sprintf(ifindex_str, "n%d", link->ifindex); sprintf(ifindex_str, "n%d", link->ifindex);
device = udev_device_new_from_device_id(m->udev, ifindex_str); device = udev_device_new_from_device_id(m->udev, ifindex_str);
+1 -1
View File
@@ -241,7 +241,7 @@ static int manager_connect_udev(Manager *m) {
/* udev does not initialize devices inside containers, /* udev does not initialize devices inside containers,
* so we rely on them being already initialized before * so we rely on them being already initialized before
* entering the container */ * entering the container */
if (detect_container(NULL) > 0) if (detect_container() > 0)
return 0; return 0;
m->udev = udev_new(); m->udev = udev_new();
+4 -5
View File
@@ -125,13 +125,12 @@ static int condition_test_kernel_command_line(Condition *c) {
static int condition_test_virtualization(Condition *c) { static int condition_test_virtualization(Condition *c) {
int b, v; int b, v;
const char *id;
assert(c); assert(c);
assert(c->parameter); assert(c->parameter);
assert(c->type == CONDITION_VIRTUALIZATION); assert(c->type == CONDITION_VIRTUALIZATION);
v = detect_virtualization(&id); v = detect_virtualization();
if (v < 0) if (v < 0)
return v; return v;
@@ -145,14 +144,14 @@ static int condition_test_virtualization(Condition *c) {
return true; return true;
/* Then, compare categorization */ /* Then, compare categorization */
if (v == VIRTUALIZATION_VM && streq(c->parameter, "vm")) if (VIRTUALIZATION_IS_VM(v) && streq(c->parameter, "vm"))
return true; return true;
if (v == VIRTUALIZATION_CONTAINER && streq(c->parameter, "container")) if (VIRTUALIZATION_IS_CONTAINER(v) && streq(c->parameter, "container"))
return true; return true;
/* Finally compare id */ /* 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) { static int condition_test_architecture(Condition *c) {
+1 -1
View File
@@ -101,7 +101,7 @@ int efi_reboot_to_firmware_supported(void) {
uint64_t b; uint64_t b;
_cleanup_free_ void *v = NULL; _cleanup_free_ void *v = NULL;
if (!is_efi_boot() || detect_container(NULL) > 0) if (!is_efi_boot() || detect_container() > 0)
return -EOPNOTSUPP; return -EOPNOTSUPP;
r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s); r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s);
+4 -4
View File
@@ -25,18 +25,18 @@
#include "log.h" #include "log.h"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
const char *id = NULL;
int a, v; int a, v;
v = detect_virtualization(&id); v = detect_virtualization();
if (v == -EPERM || v == -EACCES) if (v == -EPERM || v == -EACCES)
return EXIT_TEST_SKIP; return EXIT_TEST_SKIP;
assert_se(v >= 0); assert_se(v >= 0);
log_info("virtualization=%s id=%s", log_info("virtualization=%s id=%s",
v == VIRTUALIZATION_CONTAINER ? "container" : v == VIRTUALIZATION_VM ? "vm" : "n/a", VIRTUALIZATION_IS_CONTAINER(v) ? "container" :
strna(id)); VIRTUALIZATION_IS_VM(v) ? "vm" : "n/a",
virtualization_to_string(v));
a = uname_architecture(); a = uname_architecture();
assert_se(a >= 0); assert_se(a >= 0);
+1 -1
View File
@@ -85,7 +85,7 @@ static void test_get_process_comm(void) {
assert_se(r >= 0 || r == -EACCES); assert_se(r >= 0 || r == -EACCES);
log_info("self strlen(environ): '%zu'", strlen(env)); log_info("self strlen(environ): '%zu'", strlen(env));
if (!detect_container(NULL)) if (!detect_container())
assert_se(get_ctty_devnr(1, &h) == -ENXIO); assert_se(get_ctty_devnr(1, &h) == -ENXIO);
getenv_for_pid(1, "PATH", &i); getenv_for_pid(1, "PATH", &i);
+1 -1
View File
@@ -293,7 +293,7 @@ int main(int argc, char **argv) {
log_warning_errno(r, "Failed to read /etc/vconsole.conf: %m"); log_warning_errno(r, "Failed to read /etc/vconsole.conf: %m");
/* Let the kernel command line override /etc/vconsole.conf */ /* 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, r = parse_env_file("/proc/cmdline", WHITESPACE,
"vconsole.keymap", &vc_keymap, "vconsole.keymap", &vc_keymap,
"vconsole.keymap.toggle", &vc_keymap_toggle, "vconsole.keymap.toggle", &vc_keymap_toggle,