QEMU QemuOpts splits on commas; escape literal commas in the host path as ,, per QEMU convention to prevent option injection and boot failures on paths containing commas. Fix U5: extract b64dec() helper in slim-init.sh Deduplicate the 3-line base64 fallback decode block used by both the slim.mount and slim.cmd handlers into a single b64dec() function. Fix U6: add multi-mount test case test_mount now passes two --mount flags and asserts both slim0 and slim1 9p tags appear, covering the multi-mount tag-generation path.
This commit is contained in:
+9
-3
@@ -109,9 +109,11 @@ test_mount() {
|
|||||||
work="$(mktemp -d)"
|
work="$(mktemp -d)"
|
||||||
img="slim-test-mount"
|
img="slim-test-mount"
|
||||||
share_dir="$work/share"
|
share_dir="$work/share"
|
||||||
|
share_dir2="$work/share2"
|
||||||
|
|
||||||
mkdir -p "$share_dir"
|
mkdir -p "$share_dir" "$share_dir2"
|
||||||
echo "hello from host" > "$share_dir/testfile.txt"
|
echo "hello from host" > "$share_dir/testfile.txt"
|
||||||
|
echo "second share" > "$share_dir2/testfile2.txt"
|
||||||
|
|
||||||
cat > "$work/Containerfile" <<'EOF'
|
cat > "$work/Containerfile" <<'EOF'
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
@@ -136,16 +138,20 @@ EOF
|
|||||||
# The 9p share appears at the same path inside the VM as on the host.
|
# The 9p share appears at the same path inside the VM as on the host.
|
||||||
# Use --cmd to run the verification snippet with the canonical path.
|
# Use --cmd to run the verification snippet with the canonical path.
|
||||||
share_canon=$(readlink -f "$share_dir")
|
share_canon=$(readlink -f "$share_dir")
|
||||||
|
share_canon2=$(readlink -f "$share_dir2")
|
||||||
|
|
||||||
echo "-- Booting VM with --mount $share_dir ..."
|
echo "-- Booting VM with --mount $share_dir --mount $share_dir2 ..."
|
||||||
output=$(timeout "$TIMEOUT" "$SLIM_BIN" run "$img" \
|
output=$(timeout "$TIMEOUT" "$SLIM_BIN" run "$img" \
|
||||||
--mount "$share_dir" \
|
--mount "$share_dir" \
|
||||||
--cmd "echo Available 9p shares:; for f in /sys/bus/virtio/drivers/9pnet_virtio/virtio*/mount_tag; do [ -f \"\$f\" ] && echo \"\$f: \$(tr -d '\\0' < \"\$f\")\"; done; echo Mounts:; mount -v; cat \"${share_canon}/testfile.txt\" 2>/dev/null || echo NO_FILE; echo MOUNT_VERIFY_DONE; poweroff -f" \
|
--mount "$share_dir2" \
|
||||||
|
--cmd "echo Available 9p shares:; for f in /sys/bus/virtio/drivers/9pnet_virtio/virtio*/mount_tag; do [ -f \"\$f\" ] && echo \"\$f: \$(tr -d '\\0' < \"\$f\")\"; done; echo Mounts:; mount -v; cat \"${share_canon}/testfile.txt\" 2>/dev/null || echo NO_FILE; cat \"${share_canon2}/testfile2.txt\" 2>/dev/null || echo NO_FILE2; echo MOUNT_VERIFY_DONE; poweroff -f" \
|
||||||
2>&1 || true)
|
2>&1 || true)
|
||||||
|
|
||||||
check_output "$output" "mount_tag: slim0" "--mount 9p share detected"
|
check_output "$output" "mount_tag: slim0" "--mount 9p share detected"
|
||||||
|
check_output "$output" "mount_tag: slim1" "--mount second 9p share detected"
|
||||||
check_output "$output" "type 9p" "--mount 9p filesystem in mount list"
|
check_output "$output" "type 9p" "--mount 9p filesystem in mount list"
|
||||||
check_output "$output" "hello from host" "--mount file accessible in VM"
|
check_output "$output" "hello from host" "--mount file accessible in VM"
|
||||||
|
check_output "$output" "second share" "--mount second share file accessible in VM"
|
||||||
check_output "$output" "MOUNT_VERIFY_DONE" "--mount VM ran to completion"
|
check_output "$output" "MOUNT_VERIFY_DONE" "--mount VM ran to completion"
|
||||||
|
|
||||||
cleanup "$img" "$img"
|
cleanup "$img" "$img"
|
||||||
|
|||||||
+4
-1
@@ -101,9 +101,12 @@ pub(crate) fn run(
|
|||||||
let tag = format!("slim{i}");
|
let tag = format!("slim{i}");
|
||||||
let dest_b64 = base64::engine::general_purpose::STANDARD.encode(path_str.as_bytes());
|
let dest_b64 = base64::engine::general_purpose::STANDARD.encode(path_str.as_bytes());
|
||||||
|
|
||||||
|
// QEMU's QemuOpts splits on commas — escape literal commas in the
|
||||||
|
// path as ",," per QEMU convention.
|
||||||
|
let path_escaped = path_str.replace(',', ",,");
|
||||||
virtfs_args.push("-virtfs".into());
|
virtfs_args.push("-virtfs".into());
|
||||||
virtfs_args.push(format!(
|
virtfs_args.push(format!(
|
||||||
"local,path={path_str},mount_tag={tag},security_model=mapped-xattr"
|
"local,path={path_escaped},mount_tag={tag},security_model=mapped-xattr"
|
||||||
));
|
));
|
||||||
cmdline.push(format!("slim.mount={tag}:{dest_b64}"));
|
cmdline.push(format!("slim.mount={tag}:{dest_b64}"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
# slim universal init - distro-agnostic VM bootstrap.
|
# slim universal init - distro-agnostic VM bootstrap.
|
||||||
# Injected by `slim build` at /slim/init and invoked via init=/slim/init.
|
# Injected by `slim build` at /slim/init and invoked via init=/slim/init.
|
||||||
|
|
||||||
|
# === Helpers ===
|
||||||
|
b64dec() {
|
||||||
|
printf '%s' "$1" | base64 -d 2>/dev/null || printf '%s' "$1" | openssl base64 -d 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
# === Devices & special filesystems ===
|
# === Devices & special filesystems ===
|
||||||
[ -c /dev/console ] || mknod -m 600 /dev/console c 5 1
|
[ -c /dev/console ] || mknod -m 600 /dev/console c 5 1
|
||||||
mkdir -p /proc /sys /dev/pts /dev/shm
|
mkdir -p /proc /sys /dev/pts /dev/shm
|
||||||
@@ -45,9 +50,7 @@ for tok in $(cat /proc/cmdline 2>/dev/null); do
|
|||||||
v=${tok#slim.mount=}
|
v=${tok#slim.mount=}
|
||||||
tag=${v%%:*}
|
tag=${v%%:*}
|
||||||
dest_b64=${v#*:}
|
dest_b64=${v#*:}
|
||||||
dest=$(printf '%s' "$dest_b64" | base64 -d 2>/dev/null) \
|
dest=$(b64dec "$dest_b64") || echo "base64 decode failed"
|
||||||
|| dest=$(printf '%s' "$dest_b64" | openssl base64 -d 2>/dev/null) \
|
|
||||||
|| echo "base64 decode failed"
|
|
||||||
if [ -n "$tag" ] && [ -n "$dest" ]; then
|
if [ -n "$tag" ] && [ -n "$dest" ]; then
|
||||||
mkdir -p "$dest"
|
mkdir -p "$dest"
|
||||||
mount -t 9p "$tag" "$dest" -o trans=virtio,version=9p2000.L 2>/dev/null \
|
mount -t 9p "$tag" "$dest" -o trans=virtio,version=9p2000.L 2>/dev/null \
|
||||||
@@ -66,9 +69,7 @@ for tok in $(cat /proc/cmdline 2>/dev/null); do
|
|||||||
case "$tok" in
|
case "$tok" in
|
||||||
slim.cmd=*)
|
slim.cmd=*)
|
||||||
v=${tok#slim.cmd=}
|
v=${tok#slim.cmd=}
|
||||||
decoded=$(printf '%s' "$v" | base64 -d 2>/dev/null) \
|
decoded=$(b64dec "$v") || echo "base64 decode failed"
|
||||||
|| decoded=$(printf '%s' "$v" | openssl base64 -d 2>/dev/null) \
|
|
||||||
|| echo "base64 decode failed"
|
|
||||||
if [ -n "$decoded" ]; then
|
if [ -n "$decoded" ]; then
|
||||||
exec /bin/sh -c "$decoded"
|
exec /bin/sh -c "$decoded"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user