From 4d53d76f5e040a4dc5749aa2c401607933b957e5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 7 Mar 2025 11:56:33 +0100 Subject: [PATCH 1/2] virt: some modernizations Reduce scope of certain allocations, add more debug logging, and improve some log messages. --- src/basic/virt.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/basic/virt.c b/src/basic/virt.c index 905a37e4a9..f5a88ed3d6 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -103,32 +103,30 @@ static Virtualization detect_vm_device_tree(void) { r = read_one_line_file("/proc/device-tree/hypervisor/compatible", &hvtype); if (r == -ENOENT) { - _cleanup_closedir_ DIR *dir = NULL; - _cleanup_free_ char *compat = NULL; - if (access("/proc/device-tree/ibm,partition-name", F_OK) == 0 && access("/proc/device-tree/hmc-managed?", F_OK) == 0 && access("/proc/device-tree/chosen/qemu,graphic-width", F_OK) != 0) return VIRTUALIZATION_POWERVM; - dir = opendir("/proc/device-tree"); + _cleanup_closedir_ DIR *dir = opendir("/proc/device-tree"); if (!dir) { if (errno == ENOENT) { - log_debug_errno(errno, "/proc/device-tree: %m"); + log_debug_errno(errno, "/proc/device-tree/ does not exist"); return VIRTUALIZATION_NONE; } - return -errno; + return log_debug_errno(errno, "Opening /proc/device-tree/ failed: %m"); } - FOREACH_DIRENT(de, dir, return -errno) + FOREACH_DIRENT(de, dir, return log_debug_errno(errno, "Failed to enumerate /proc/device-tree/ contents: %m")) if (strstr(de->d_name, "fw-cfg")) { log_debug("Virtualization QEMU: \"fw-cfg\" present in /proc/device-tree/%s", de->d_name); return VIRTUALIZATION_QEMU; } + _cleanup_free_ char *compat = NULL; r = read_one_line_file("/proc/device-tree/compatible", &compat); if (r < 0 && r != -ENOENT) - return r; + return log_debug_errno(r, "Failed to read /proc/device-tree/compatible: %m"); if (r >= 0 && streq(compat, "qemu,pseries")) { log_debug("Virtualization %s found in /proc/device-tree/compatible", compat); return VIRTUALIZATION_QEMU; From 600e135a0bfaa343a1b938632f61acb54e2abf58 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 7 Mar 2025 11:57:43 +0100 Subject: [PATCH 2/2] virt: detect "linux,dummy-virt" devicetree VMs So apparently "linux,dummy-virt" is a devicetree in popular use by various hypervisors, including crosvm: https://github.com/google/crosvm/blob/e5d7a64d377d00b9b96bc026548769ab59cf216b/aarch64/src/fdt.rs#L692 and qemu: https://github.com/qemu/qemu/blob/98c7362b1efe651327385a25874a73e008c6549e/hw/arm/virt.c#L283 and that's because the kernel ships support for that natively: https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/linux%2Cdummy-virt.yaml It's explicitly for using in virtualization. Hence it's suitable for detecting it as generic fallback. This hence adds the check, similar to how we already look for one other qemu-specific devicetree. I ran into this while playing around with the new Pixel "Linux Terminal" app from google which runs a Debian in a crosvm apparently. So far systemd didn't recognize execution in it at all. Let's at least recognize it as VM at all, even if this doesn't recognize it as crosvm. --- src/basic/virt.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/basic/virt.c b/src/basic/virt.c index f5a88ed3d6..a69997b00a 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -127,9 +127,16 @@ static Virtualization detect_vm_device_tree(void) { r = read_one_line_file("/proc/device-tree/compatible", &compat); if (r < 0 && r != -ENOENT) return log_debug_errno(r, "Failed to read /proc/device-tree/compatible: %m"); - if (r >= 0 && streq(compat, "qemu,pseries")) { - log_debug("Virtualization %s found in /proc/device-tree/compatible", compat); - return VIRTUALIZATION_QEMU; + if (r >= 0) { + if (streq(compat, "qemu,pseries")) { + log_debug("Virtualization %s found in /proc/device-tree/compatible", compat); + return VIRTUALIZATION_QEMU; + } + if (streq(compat, "linux,dummy-virt")) { + /* https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/linux%2Cdummy-virt.yaml */ + log_debug("Generic virtualization %s found in /proc/device-tree/compatible", compat); + return VIRTUALIZATION_VM_OTHER; + } } log_debug("No virtualization found in /proc/device-tree/*");