You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
systemd/SOURCES/0850-virt-use-string-table-...

135 lines
5.1 KiB

From efa2cdb699df3e5d5d7180e50f3ebfff74788c5c Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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));