]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic: rework virtualization detection API 1190/head
authorLennart Poettering <lennart@poettering.net>
Mon, 7 Sep 2015 11:42:47 +0000 (13:42 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 7 Sep 2015 11:42:47 +0000 (13:42 +0200)
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.

29 files changed:
src/basic/util.c
src/basic/virt.c
src/basic/virt.h
src/core/dbus-manager.c
src/core/job.c
src/core/locale-setup.c
src/core/machine-id-setup.c
src/core/main.c
src/core/manager.c
src/core/mount-setup.c
src/core/shutdown.c
src/core/swap.c
src/core/umount.c
src/core/unit.c
src/detect-virt/detect-virt.c
src/fstab-generator/fstab-generator.c
src/getty-generator/getty-generator.c
src/gpt-auto-generator/gpt-auto-generator.c
src/hostname/hostnamed.c
src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/test-dhcp6-client.c
src/locale/localectl.c
src/network/networkd-link.c
src/network/networkd-manager.c
src/shared/condition.c
src/shared/efivars.c
src/test/test-architecture.c
src/test/test-process-util.c
src/vconsole/vconsole-setup.c

index 86aacad30744b03eb0df36f93d4a29a739eab6cc..3e41e6ad41de667a558df683a12d4cd63cc7cf5e 100644 (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);
index 4a4bebd528bc180cf8b43ce049fa40d6ff7ecddd..1fc6c1babad643f2472bb9329a61d36d8576ba18 100644 (file)
 #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);
index 7194ab2bf781ac1e946c3987b22e482afb74caa8..449e069901777787fe37a4e16a7cbe3009b97224 100644 (file)
   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_;
index 0b365391ecd85407d14d4a30dbb605338f99e7df..4e5d67fc192f38987d7fdaf725883fa98daa5c47 100644 (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(
index 15f5cc0cc9327af6ad92be221735cdbc162a5f89..2a35d1e2dece0eeced25baa51d063d35611f7e36 100644 (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();
index 108072ca9fb45b04aca2a2133ccb47ad1de3bc9a..6961c26674515a8658c50daa7d0a4095a97fea09 100644 (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],
index 2d5ae3b3b92618f369b8dba8ad3f4cfa6b413730..8f682c6d101fb7bb0ddb7ce86ac8ee296b1098d6 100644 (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;
                                         }
                                 }
                         }
index 4cd2b08c386877ba8635eea3dbc3458b4435c31d..fe8f1924bda6201c310f0760f10bf8ad75be1094 100644 (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);
index fc10ddb5d9466d29ac03fdc9353ad44b3dfc9bc8..56f2c92febeefb1a98acdeaafa3b34f96eb5c37d 100644 (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
index c6f356991556f3717743aceea33499928e884310..e84f80b61b48d12230d48cd2179fc3948e574afc 100644 (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");
 
index aba16b4689c0bc81434441d481c3520b16fbaf37..8a6fd25f313768cabc8a7f7d6a1659b1a47cc01f 100644 (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;
index 4f3ddc9f04e7ba20a37c9c4dd45b0898984e4da6..2f462e339d30dcc170292fcc56d979ea061d50ac 100644 (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;
 }
index d59b5d0ffbc0933f7f7244f70a3a4b39989bebb6..22dbe67259acd5fe498a4aa34ee768c7752df0ee 100644 (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.
index 45ce1b172df929213e2b024c531fc63093b2def5..be38f1fa2741729ac2d61fc575cf29c5c4d4800d 100644 (file)
@@ -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) {
index 606d073cbcf7b0a68ed5db069f3784744422a7ca..97ae569ca59bb8901f96d486659e5ac389f3133a 100644 (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");
+        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;
 }
index a88b68e2c0b80d7e929401445afb32445f8f214b..3f8ea5647cddeb7610f05c31a1eb77d252025bc8 100644 (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;
         }
index d23caab44a7a2305d58a24141742959cab2889cf..9a4b038ef3d31e3e5e4957663eff061f569bc0be 100644 (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.");
index cf25d9847f02a0386e43a31543b795bfafa1b066..c97be2dabf49ea6475d762653909ecfb4e9247f9 100644 (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;
         }
index c423be3767f4db40bc116222aec1217a873f394a..e90ae541564245a9b8f9620a39d4654ad2f07ea8 100644 (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);
index 70c68ad131b8f6a0cfd19d02e845926aafc86245..7d9cad2a708edbe2cc7d2ad2c6a6847ad5b0a6b0 100644 (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)];
index 12daac3211005bde7e41bee1356b1e062bfb1bd3..9c7f9ffb1b55d7355a358e9d88c2015c16a7849e 100644 (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;
index 1e06f2251cd14234eb7052c94de6513b8336fb88..4a91c7420a6470e1089bfbfa7c4fbd9bd17a969f 100644 (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,
index 1dc9db0fca156444f76fedc925c7f070aa6f7cc3..9d4a69b0db729ce7bfb5a767a65f219b726a0550 100644 (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);
index 92b607297da66366b5f979181b471087a8b6d0cf..b4259cafefa57e2162a8f7997b02061efd46cb7d 100644 (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();
index f58e84a3d0daf62d5e8334c39b8bbdda8fc05d3d..1d7dd49e042ce2148f8eec444efa7f84aa689e24 100644 (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) {
index 347cd30b09dd41558039d6b4301e5f55a0e9d798..f087c2a5663974bbd2cc61f56a7d361428f269aa 100644 (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);
index 30bdec45e56babdd95f76e08d5dbdb86e9717c81..a5b66a7d2f2171337ae66ec18736aa97a96e71df 100644 (file)
 #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);
index e4e2efecd50856046b9c88ba51a7e42514f4d959..eb0f443a4385fc37fabf093da22fed128c6463bf 100644 (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);
index 7bdc158ad76f2816b3f375308174fded11b765a9..6353579283fd3d87b304272f0813dd4e86a84454 100644 (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,