Merge pull request #1190 from poettering/rework-virt

basic: rework virtualization detection API
This commit is contained in:
Daniel Mack 2015-09-08 15:53:56 +02:00
commit da323858ef
29 changed files with 335 additions and 312 deletions

View File

@ -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);

View File

@ -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)) {
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);
if (r >= 0) {
char *cap, *i = domcap;
if (r == -ENOENT)
return VIRTUALIZATION_NONE;
while ((cap = strsep(&i, ",")))
if (streq(cap, "control_d"))
break;
i = domcap;
while ((cap = strsep(&i, ",")))
if (streq(cap, "control_d"))
break;
if (!cap) {
_id = "xen";
r = 1;
}
return cap ? VIRTUALIZATION_NONE : VIRTUALIZATION_XEN;
}
goto finish;
static int detect_vm_hypervisor(void) {
_cleanup_free_ char *hvtype = NULL;
int r;
} 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
r = read_one_line_file("/sys/hypervisor/type", &hvtype);
if (r == -ENOENT)
return VIRTUALIZATION_NONE;
if (r < 0)
return r;
/* this will set _id to "other" and return 0 for unknown hypervisors */
r = detect_vm_cpuid(&_id);
if (streq(hvtype, "xen"))
return VIRTUALIZATION_XEN;
else
return VIRTUALIZATION_VM_OTHER;
}
/* finish when found a known hypervisor other than kvm */
if (r < 0 || (r > 0 && !streq(_id, "kvm")))
goto finish;
_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;
}
static int detect_vm_uml(void) {
_cleanup_free_ char *cpuinfo_contents = NULL;
int r;
/* 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")) {
_id = "uml";
r = 1;
goto finish;
}
if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n"))
return VIRTUALIZATION_UML;
return VIRTUALIZATION_NONE;
}
static int detect_vm_zvm(void) {
#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);
if (r >= 0) {
if (streq(t, "z/VM"))
_id = "zvm";
else
_id = "kvm";
r = 1;
r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t);
if (r == -ENOENT)
return VIRTUALIZATION_NONE;
if (r < 0)
return r;
goto finish;
}
}
if (streq(t, "z/VM"))
return VIRTUALIZATION_ZVM;
else
return VIRTUALIZATION_KVM;
#else
return VIRTUALIZATION_NONE;
#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:
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)
r = detect_container();
if (r != 0)
return r;
if (r > 0)
return VIRTUALIZATION_CONTAINER;
r = detect_vm(id);
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);

View File

@ -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_;

View File

@ -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(

View File

@ -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();

View File

@ -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],

View File

@ -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;
}
}
}

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'
* 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);

View File

@ -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

View File

@ -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");

View File

@ -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;

View File

@ -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;
}

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
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.

View File

@ -3510,7 +3510,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) {

View File

@ -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");
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:
r = detect_vm(&id);
r = detect_vm();
if (r < 0) {
log_error_errno(r, "Failed to check for vm: %m");
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;
}
if (!arg_quiet)
puts(id ? id : "none");
puts(virtualization_to_string(r));
retval = r != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
return retval;
}

View File

@ -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;
}

View File

@ -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.");

View File

@ -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;
}

View File

@ -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);

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;
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)];

View File

@ -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;

View File

@ -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,

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);
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);

View File

@ -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();

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,