From 735ea55f5cd87a82757a8911edd80fba799b46ee Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 7 Jan 2020 11:49:39 +0900 Subject: [PATCH] virt: use string table to detect VM or container --- src/basic/virt.c | 81 ++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/src/basic/virt.c b/src/basic/virt.c index 6ba880dbc4a..787ce106225 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -20,29 +20,28 @@ #include "string-util.h" #include "virt.h" +static const char *const vm_table[_VIRTUALIZATION_MAX] = { + [VIRTUALIZATION_XEN] = "XenVMMXenVMM", + [VIRTUALIZATION_KVM] = "KVMKVMKVM", + [VIRTUALIZATION_QEMU] = "TCGTCGTCGTCG", + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + [VIRTUALIZATION_VMWARE] = "VMwareVMware", + /* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs */ + [VIRTUALIZATION_MICROSOFT] = "Microsoft Hv", + /* https://wiki.freebsd.org/bhyve */ + [VIRTUALIZATION_BHYVE] = "bhyve bhyve ", + [VIRTUALIZATION_QNX] = "QNXQVMBSQG", + /* https://projectacrn.org */ + [VIRTUALIZATION_ACRN] = "ACRNACRNACRN", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(vm, int); + static int detect_vm_cpuid(void) { /* CPUID is an x86 specific interface. */ #if defined(__i386__) || defined(__x86_64__) - static const struct { - const char *cpuid; - int id; - } cpuid_vendor_table[] = { - { "XenVMMXenVMM", VIRTUALIZATION_XEN }, - { "KVMKVMKVM", VIRTUALIZATION_KVM }, - { "TCGTCGTCGTCG", VIRTUALIZATION_QEMU }, - /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ - { "VMwareVMware", VIRTUALIZATION_VMWARE }, - /* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs */ - { "Microsoft Hv", VIRTUALIZATION_MICROSOFT }, - /* https://wiki.freebsd.org/bhyve */ - { "bhyve bhyve ", VIRTUALIZATION_BHYVE }, - { "QNXQVMBSQG", VIRTUALIZATION_QNX }, - /* https://projectacrn.org */ - { "ACRNACRNACRN", VIRTUALIZATION_ACRN }, - }; - uint32_t eax, ebx, ecx, edx; bool hypervisor; @@ -59,7 +58,7 @@ static int detect_vm_cpuid(void) { uint32_t sig32[3]; char text[13]; } sig = {}; - unsigned j; + int v; /* There is a hypervisor, see what it is */ __cpuid(0x40000000U, eax, ebx, ecx, edx); @@ -70,11 +69,11 @@ static int detect_vm_cpuid(void) { log_debug("Virtualization found, CPUID=%s", sig.text); - for (j = 0; j < ELEMENTSOF(cpuid_vendor_table); j ++) - if (streq(sig.text, cpuid_vendor_table[j].cpuid)) - return cpuid_vendor_table[j].id; + v = vm_from_string(sig.text); + if (v < 0) + return VIRTUALIZATION_VM_OTHER; - return VIRTUALIZATION_VM_OTHER; + return v; } #endif log_debug("No virtualization found in CPUID"); @@ -432,25 +431,23 @@ finish: return r; } -int detect_container(void) { - 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 }, - { "podman", VIRTUALIZATION_PODMAN }, - { "rkt", VIRTUALIZATION_RKT }, - { "wsl", VIRTUALIZATION_WSL }, - }; +static const char *const container_table[_VIRTUALIZATION_MAX] = { + [VIRTUALIZATION_LXC] = "lxc", + [VIRTUALIZATION_LXC_LIBVIRT] = "lxc-libvirt", + [VIRTUALIZATION_SYSTEMD_NSPAWN] = "systemd-nspawn", + [VIRTUALIZATION_DOCKER] = "docker", + [VIRTUALIZATION_PODMAN] = "podman", + [VIRTUALIZATION_RKT] = "rkt", + [VIRTUALIZATION_WSL] = "wsl", +}; +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(container, int); + +int detect_container(void) { static thread_local int cached_found = _VIRTUALIZATION_INVALID; _cleanup_free_ char *m = NULL; _cleanup_free_ char *o = NULL; const char *e = NULL; - unsigned j; int r; if (cached_found >= 0) @@ -532,13 +529,9 @@ int detect_container(void) { goto finish; translate_name: - for (j = 0; j < ELEMENTSOF(value_table); j++) - if (streq(e, value_table[j].value)) { - r = value_table[j].id; - goto finish; - } - - r = VIRTUALIZATION_CONTAINER_OTHER; + r = container_from_string(e); + if (r < 0) + r = VIRTUALIZATION_CONTAINER_OTHER; finish: log_debug("Found container virtualization %s.", virtualization_to_string(r));