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