Compare commits

...

2 Commits

Author SHA1 Message Date
MJ Pooladkhay
7054bc6056 Merge branch 'qemu-virtiofsd' into 'master'
share host directories with Redox from 'make qemu' and add Cloud Hypervisor

See merge request redox-os/redox!2383
2026-10-29 20:03:55 +00:00
MJ Pooladkhay
807bbcbcd4 add the ability to have read-only virtio-fs shares
Signed-off-by: MJ Pooladkhay <mj@pooladkhay.com>
2026-10-29 20:03:41 +00:00
2 changed files with 20 additions and 8 deletions

View File

@ -5,16 +5,18 @@
# make qemu share="tag_1=/path/a tag_2=/path/b" # several shares: tag=dir ...
# make qemu share=redox # this build tree, tag "redox"
# make qemu share="redox=/other/path" # ordinary share, tag "redox"
# make qemu share=/path/to/dir:ro # read-only, also tag=dir:ro and redox:ro
# make ch share=... # the same, on Cloud Hypervisor
#
# Each share gets its own host-side virtiofsd daemon (started and stopped by
# scripts/virtiofs-run.sh), a vhost-user-fs device, and a virtio-fsd scheme
# process on Redox. In the guest, a share appears at /scheme/virtio-fsd.<tag>.
# The emulator flags for each share are added in mk/qemu.mk and mk/ch.mk.
# Shared directories must exist. The guest cannot change anything in a :ro share.
#
# WARNING: share=redox exposes the whole build tree to the guest, including
# the harddrive.img Redox is booted from, .git and .config. Writing to them
# from Redox can corrupt the build system.
# from Redox can corrupt the build system. share=redox:ro avoids that.
share?=
share_tag?=host
@ -22,7 +24,7 @@ share_sockdir?=$(BUILD)
VIRTIOFS_RUN=
ifneq ($(strip $(share)),)
share_norm:=$(foreach s,$(share),$(if $(filter redox,$(s)),redox=$(ROOT),$(s)))
share_norm:=$(foreach s,$(share),$(if $(filter redox redox:ro,$(s)),redox=$(ROOT)$(if $(filter %:ro,$(s)),:ro),$(s)))
ifeq ($(words $(share_norm)),1)
share_list:=$(if $(findstring =,$(share_norm)),$(share_norm),$(share_tag)=$(share_norm))
else

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Runs a command next to one virtiofsd per shared directory, for
# `make qemu share=...` and `make ch share=...`.
# virtiofs-run.sh --share <socket>.sock <tag>=<dir> [--share ...] -- <command...>
# virtiofs-run.sh --share <socket>.sock <tag>=<dir>[:ro] [--share ...] -- <command...>
set -euo pipefail
@ -13,19 +13,27 @@ die() {
}
usage() {
echo "usage: $0 --share <socket>.sock <tag>=<dir> [--share ...] -- <command...>" >&2
echo "usage: $0 --share <socket>.sock <tag>=<dir>[:ro] [--share ...] -- <command...>" >&2
exit 2
}
SOCKS=()
TAGS=()
DIRS=()
OPTS=()
LABELS=()
while [[ "${1:-}" == --share ]]; do
[[ $# -ge 3 ]] || usage
[[ "$3" == *=* ]] || die "share '$3': expected <tag>=<dir>"
entry="$3" opt="" label=""
if [[ "${entry}" == *:ro ]]; then
entry="${entry%:ro}" opt=--readonly label=" (read-only)"
fi
OPTS+=("${opt}")
LABELS+=("${label}")
SOCKS+=("$2")
TAGS+=("${3%%=*}")
DIRS+=("${3#*=}")
TAGS+=("${entry%%=*}")
DIRS+=("${entry#*=}")
shift 3
done
[[ ${#SOCKS[@]} -gt 0 && "${1:-}" == -- && $# -ge 2 ]] || usage
@ -48,6 +56,7 @@ validate_share() {
[[ -n "${dir}" ]] || die "share '${tag}': empty directory"
[[ "${dir}" != *[[:space:]]* ]] \
|| die "share '${tag}': directories containing whitespace are not supported ('${dir}')"
[[ -d "${dir}" ]] || die "share '${tag}': ${dir} is not a directory"
[[ "${sock}" == *.sock ]] || die "socket '${sock}' must end in .sock"
[[ ${#sock} -lt 108 ]] \
|| die "socket path too long (${#sock} bytes): ${sock}; use a shorter share_sockdir"
@ -93,7 +102,7 @@ trap 'exit 143' TERM
declare -A SHARED_DIRS=()
start_virtiofsd() {
local sock="${SOCKS[$1]}" dir
mkdir -p "${DIRS[$1]}" "$(dirname "${sock}")"
mkdir -p "$(dirname "${sock}")"
dir="$(cd "${DIRS[$1]}" && pwd)"
if [[ -n "${SHARED_DIRS[${dir}]:-}" ]]; then
echo "virtiofs: warning: ${dir} is shared more than once; the instances do not share caches" >&2
@ -107,6 +116,7 @@ start_virtiofsd() {
--log-level warn \
--translate-uid="map:0:$(id -u):1" \
--translate-gid="map:0:$(id -g):1" \
${OPTS[$1]} \
</dev/null >"${sock%.sock}.log" 2>&1 &
PIDS+=("$!")
}
@ -133,7 +143,7 @@ for i in "${!SOCKS[@]}"; do
done
wait_for_sockets
for i in "${!SOCKS[@]}"; do
echo "virtiofs: sharing '${TAGS[$i]}' = ${DIRS[$i]} (log: ${SOCKS[$i]%.sock}.log)" >&2
echo "virtiofs: sharing '${TAGS[$i]}' = ${DIRS[$i]}${LABELS[$i]} (log: ${SOCKS[$i]%.sock}.log)" >&2
done
# Not exec'd, so cleanup runs when the command ends.