mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
virt: Fix Xen PV detection when nested inside another hypervisor
Currently, when Xen PV domains are nested within a hypervisor which is detected through CPUID (such as VMware), the detected hypervisor might not be Xen, because we don't check for Xen until after the CPUID check. This change moves the Xen check before CPUID checks to fix the issue, and moves Dom0 checking to detect_vm_xen so that we keep ignoring Xen when we are in Dom0.
This commit is contained in:
parent
a6089431d5
commit
599be274c1
@ -276,19 +276,6 @@ static int detect_vm_dmi(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static int detect_vm_xen(void) {
|
||||
|
||||
/* Check for Dom0 will be executed later in detect_vm_xen_dom0
|
||||
The presence of /proc/xen indicates some form of a Xen domain */
|
||||
if (access("/proc/xen", F_OK) < 0) {
|
||||
log_debug("Virtualization XEN not found, /proc/xen does not exist");
|
||||
return VIRTUALIZATION_NONE;
|
||||
}
|
||||
|
||||
log_debug("Virtualization XEN found (/proc/xen exists)");
|
||||
return VIRTUALIZATION_XEN;
|
||||
}
|
||||
|
||||
#define XENFEAT_dom0 11 /* xen/include/public/features.h */
|
||||
#define PATH_FEATURES "/sys/hypervisor/properties/features"
|
||||
/* Returns -errno, or 0 for domU, or 1 for dom0 */
|
||||
@ -342,6 +329,26 @@ static int detect_vm_xen_dom0(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static int detect_vm_xen(void) {
|
||||
int r;
|
||||
|
||||
/* The presence of /proc/xen indicates some form of a Xen domain */
|
||||
if (access("/proc/xen", F_OK) < 0) {
|
||||
log_debug("Virtualization XEN not found, /proc/xen does not exist");
|
||||
return VIRTUALIZATION_NONE;
|
||||
}
|
||||
log_debug("Virtualization XEN found (/proc/xen exists)");
|
||||
|
||||
/* Ignore the Xen hypervisor if we are in Dom0 */
|
||||
r = detect_vm_xen_dom0();
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
return VIRTUALIZATION_NONE;
|
||||
|
||||
return VIRTUALIZATION_XEN;
|
||||
}
|
||||
|
||||
static int detect_vm_hypervisor(void) {
|
||||
_cleanup_free_ char *hvtype = NULL;
|
||||
int r;
|
||||
@ -435,7 +442,8 @@ int detect_vm(void) {
|
||||
*
|
||||
* → First, try to detect Oracle Virtualbox and Amazon EC2 Nitro, even if they use KVM, as well as Xen even if
|
||||
* it cloaks as Microsoft Hyper-V. Attempt to detect uml at this stage also since it runs as a user-process
|
||||
* nested inside other VMs.
|
||||
* nested inside other VMs. Also check for Xen now, because Xen PV mode does not override CPUID when nested
|
||||
* inside another hypervisor.
|
||||
*
|
||||
* → Second, try to detect from CPUID, this will report KVM for whatever software is used even if info in DMI is
|
||||
* overwritten.
|
||||
@ -457,6 +465,15 @@ int detect_vm(void) {
|
||||
else if (r != VIRTUALIZATION_NONE)
|
||||
goto finish;
|
||||
|
||||
/* Detect Xen */
|
||||
r = detect_vm_xen();
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == VIRTUALIZATION_VM_OTHER)
|
||||
other = true;
|
||||
else if (r != VIRTUALIZATION_NONE)
|
||||
goto finish;
|
||||
|
||||
/* Detect from CPUID */
|
||||
r = detect_vm_cpuid();
|
||||
if (r < 0)
|
||||
@ -476,20 +493,7 @@ int detect_vm(void) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* x86 xen will most likely be detected by cpuid. If not (most likely
|
||||
* because we're not an x86 guest), then we should try the /proc/xen
|
||||
* directory next. If that's not found, then we check for the high-level
|
||||
* hypervisor sysfs file.
|
||||
*/
|
||||
|
||||
r = detect_vm_xen();
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == VIRTUALIZATION_VM_OTHER)
|
||||
other = true;
|
||||
else if (r != VIRTUALIZATION_NONE)
|
||||
goto finish;
|
||||
|
||||
/* Check high-level hypervisor sysfs file */
|
||||
r = detect_vm_hypervisor();
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -511,18 +515,7 @@ int detect_vm(void) {
|
||||
return r;
|
||||
|
||||
finish:
|
||||
/* x86 xen Dom0 is detected as XEN in hypervisor and maybe others.
|
||||
* In order to detect the Dom0 as not virtualization we need to
|
||||
* double-check it */
|
||||
if (r == VIRTUALIZATION_XEN) {
|
||||
int dom0;
|
||||
|
||||
dom0 = detect_vm_xen_dom0();
|
||||
if (dom0 < 0)
|
||||
return dom0;
|
||||
if (dom0 > 0)
|
||||
r = VIRTUALIZATION_NONE;
|
||||
} else if (r == VIRTUALIZATION_NONE && other)
|
||||
if (r == VIRTUALIZATION_NONE && other)
|
||||
r = VIRTUALIZATION_VM_OTHER;
|
||||
|
||||
cached_found = r;
|
||||
|
Loading…
Reference in New Issue
Block a user