Add --mount flag for 9p host directory sharing
CI / build (push) Successful in 13s

Add support for sharing host directories into the VM via QEMU 9p
(virtio-9p).

The --mount flag can be repeated.

The format is `<host-path>` or `<host-path>:<guest-path>`

Relative guest paths are relative to the configured WORKDIR.

Design:
- QEMU: each --mount gets a short 9p tag (slim0, slim1, …) via
  -virtfs local,path=…,mount_tag=slimN,security_model=mapped-xattr.
  Tags are kept short because 9p mount_tag has a ~31-byte limit.
- Kernel cmdline: the full destination path is passed as
  slim.mount=<tag>:<base64(path)> so the init script knows where to
  mount each tag.  Base64 avoids issues with spaces/special chars.
- slim-init.sh: after networking, parse slim.mount= entries, mkdir -p
  the destination, and mount -t 9p <tag> <dest> -o trans=virtio,version=9p2000.L

Tests verify: 9p share detection via sysfs mount_tag, 9p entry in
mount output, file content accessible at the expected path, and clean
VM exit.
This commit is contained in:
2026-09-11 09:39:34 +02:00
committed by hulthe
parent 6111bbeb8d
commit 3a99da196d
5 changed files with 192 additions and 7 deletions
+12 -3
View File
@@ -100,9 +100,14 @@ fn install_into_rootfs(mount: &str, name: &str, mode: &str, content: &str) -> Re
Ok(())
}
/// Inject /slim/init, /slim/exec, and optionally /slim/user into a mounted
/// container image rootfs.
pub fn inject(mount_path: &Path, exec_script: &str, user: Option<&str>) -> Result<()> {
/// Inject /slim/init, /slim/exec, and optionally /slim/user and /slim/workdir
/// into a mounted container image rootfs.
pub fn inject(
mount_path: &Path,
exec_script: &str,
user: Option<&str>,
working_dir: Option<&str>,
) -> Result<()> {
let mount_str = mount_path.to_str().context("mount path is not UTF-8")?;
install_into_rootfs(mount_str, "init", "755", SLIM_INIT)?;
@@ -112,5 +117,9 @@ pub fn inject(mount_path: &Path, exec_script: &str, user: Option<&str>) -> Resul
install_into_rootfs(mount_str, "user", "644", user)?;
}
if let Some(dir) = working_dir.filter(|d| !d.is_empty()) {
install_into_rootfs(mount_str, "workdir", "644", dir)?;
}
Ok(())
}