From e338dfb72ecd2c2705ddfc3d609df6899265465c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 2 Feb 2026 16:06:44 +0000 Subject: [PATCH] qemu: Add --allow-mmap to virtiofsd for mmap support The --cache=never flag (added in 50e7601 to avoid FD exhaustion) has a side effect: the guest kernel returns ENODEV for mmap() syscalls on virtiofs files. This breaks nontrivial use cases; while glibc has a fallback for failure to `mmap()` other tools don't. Assisted-by: OpenCode (claude-sonnet-4-20250514) Signed-off-by: Colin Walters --- .../src/tests/run_ephemeral.rs | 39 +++++++++++++++++++ crates/kit/src/qemu.rs | 6 ++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/crates/integration-tests/src/tests/run_ephemeral.rs b/crates/integration-tests/src/tests/run_ephemeral.rs index dd80c65..773dbe5 100644 --- a/crates/integration-tests/src/tests/run_ephemeral.rs +++ b/crates/integration-tests/src/tests/run_ephemeral.rs @@ -360,6 +360,45 @@ fn test_run_ephemeral_centos_uki() -> Result<()> { } integration_test!(test_run_ephemeral_centos_uki); +/// Test that mmap() works on virtiofs files +/// +/// The --allow-mmap flag (added to virtiofsd) negotiates FUSE_DIRECT_IO_ALLOW_MMAP +/// with the kernel (requires kernel 6.2+), allowing mmap() on virtiofs files. +/// Without this flag, mmap() returns ENODEV when --cache=never is used. +/// +/// This test verifies that shared libraries can be loaded (which requires mmap()) +/// and that we can explicitly mmap a file from the virtiofs root. +fn test_run_ephemeral_virtiofs_mmap() -> Result<()> { + let sh = shell()?; + let bck = get_bck_command()?; + let image = get_test_image(); + let label = INTEGRATION_TEST_LABEL; + + // Test that mmap works by running a dynamically linked binary. + // Loading shared libraries requires mmap() - if virtiofs mmap doesn't work, + // dynamically linked binaries will fail to execute. + // + // We use python3 to explicitly test mmap() on a virtiofs file (/etc/os-release). + // This directly validates that the --allow-mmap flag is working. + let script = + "python3 -c 'import mmap; f=open(\"/etc/os-release\",\"rb\"); m=mmap.mmap(f.fileno(),0,access=mmap.ACCESS_READ); print(\"MMAP_SUCCESS\" if b\"ID=\" in m.read(100) else \"MMAP_FAIL\")'"; + + let stdout = cmd!( + sh, + "{bck} ephemeral run --rm --label {label} --execute {script} {image}" + ) + .read()?; + + assert!( + stdout.contains("MMAP_SUCCESS"), + "mmap test should succeed - if this fails, --allow-mmap may not be working: {}", + stdout + ); + + Ok(()) +} +integration_test!(test_run_ephemeral_virtiofs_mmap); + /// Test that ephemeral VMs have the expected mount layout: /// - / is read-only virtiofs /// - /etc is overlayfs with tmpfs upper (writable) diff --git a/crates/kit/src/qemu.rs b/crates/kit/src/qemu.rs index ecb8f89..f381634 100644 --- a/crates/kit/src/qemu.rs +++ b/crates/kit/src/qemu.rs @@ -923,8 +923,12 @@ pub async fn spawn_virtiofsd_async(config: &VirtiofsConfig) -> Result