From efa2cdb699df3e5d5d7180e50f3ebfff74788c5c 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 (cherry picked from commit 735ea55f5cd87a82757a8911edd80fba799b46ee) Related: #2117948 --- src/basic/virt.c | 73 ++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 40 deletions(-) diff --git a/src/basic/virt.c b/src/basic/virt.c index 78c68d66e0..6e4c702051 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -22,27 +22,26 @@ #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", +}; + +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 }, - }; - 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"); @@ -434,22 +433,20 @@ 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 }, - { "rkt", VIRTUALIZATION_RKT }, - }; +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_RKT] = "rkt", +}; + +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; const char *e = NULL; - unsigned j; int r; if (cached_found >= 0) @@ -522,13 +519,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));