Skip to content

Commit ff9f386

Browse files
committed
feat: add virtiofs support for Linux guests
Automatically use virtiofsd (vhost-user-fs-pci) instead of 9p when virtiofsd is present on the host and the guest OS is Linux. Falls back silently to 9p when virtiofsd is unavailable. Updates README to document the new capability.
1 parent b541fe1 commit ff9f386

File tree

2 files changed

+66
-8
lines changed

2 files changed

+66
-8
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ required to run the virtual machines.
4747
- **Nearly 1000 operating system editions are supported!**
4848
- Full SPICE support including host/guest clipboard sharing
4949
- VirtIO-webdavd file sharing for Linux and Windows guests
50+
- VirtIO-fs file sharing for Linux guests (*automatically preferred over 9p when `virtiofsd` is installed on the host*)
5051
- VirtIO-9p file sharing for Linux and macOS guests
5152
- [QEMU Guest Agent
5253
support](https://wiki.qemu.org/Features/GuestAgent); provides access

quickemu

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,15 +1544,16 @@ function configure_file_sharing() {
15441544
*) echo " - WebDAV: On guest: dav://localhost:9843/";;
15451545
esac
15461546

1547-
# 9P
1547+
# virtiofs or 9p depending on host capability
15481548
if [ "${guest_os}" != "windows" ] || [ "${guest_os}" == "windows-server" ]; then
1549-
echo -n " - 9P: On guest: "
1550-
if [ "${guest_os}" == "linux" ]; then
1551-
echo "sudo mount -t 9p -o trans=virtio,version=9p2000.L,msize=104857600 ${PUBLIC_TAG} ~/$(basename "${PUBLIC}")"
1549+
if [ "${guest_os}" == "linux" ] && [ -n "${VIRTIOFSD}" ]; then
1550+
echo " - virtiofs: On guest: sudo mount -t virtiofs ${PUBLIC_TAG} ~/$(basename "${PUBLIC}")"
1551+
elif [ "${guest_os}" == "linux" ]; then
1552+
echo " - 9P: On guest: sudo mount -t 9p -o trans=virtio,version=9p2000.L,msize=104857600 ${PUBLIC_TAG} ~/$(basename "${PUBLIC}")"
15521553
elif [ "${guest_os}" == "macos" ]; then
15531554
# PUBLICSHARE needs to be world writeable for seamless integration with
15541555
# macOS. Test if it is world writeable, and prompt what to do if not.
1555-
echo "sudo mount_9p ${PUBLIC_TAG}"
1556+
echo " - 9P: On guest: sudo mount_9p ${PUBLIC_TAG}"
15561557
if [ "${PUBLIC_PERMS}" != "drwxrwxrwx" ]; then
15571558
echo " - 9P: On host: chmod 777 ${PUBLIC}"
15581559
echo " Required for macOS integration 👆"
@@ -1616,6 +1617,37 @@ function configure_cpu_pinning() {
16161617
echo " - CPU Pinning: Bind guest cores to host cores (${GUEST_CPUS} -> ${CPU_PINNING})"
16171618
}
16181619

1620+
function start_virtiofsd() {
1621+
# Start virtiofsd as a background daemon and record its PID so it can be
1622+
# cleaned up when the VM exits. The socket path is placed alongside other
1623+
# VM runtime files in VMDIR.
1624+
if [ -z "${VIRTIOFSD}" ]; then
1625+
return
1626+
fi
1627+
1628+
VIRTIOFSD_SOCKET="${VMDIR}/${VMNAME}.virtiofsd-sock"
1629+
local virtiofsd_args=(
1630+
--socket-path="${VIRTIOFSD_SOCKET}"
1631+
--shared-dir="${PUBLIC}"
1632+
--announce-submounts
1633+
)
1634+
1635+
echo "${VIRTIOFSD} ${virtiofsd_args[*]} &" >> "${VMDIR}/${VMNAME}.sh"
1636+
${VIRTIOFSD} "${virtiofsd_args[@]}" >> "${VMDIR}/${VMNAME}.log" 2>&1 &
1637+
VIRTIOFSD_PID=$!
1638+
sleep 0.25
1639+
1640+
if ! kill -0 "${VIRTIOFSD_PID}" 2>/dev/null; then
1641+
echo " - WARNING! virtiofsd failed to start; falling back to 9p."
1642+
VIRTIOFSD=""
1643+
VIRTIOFSD_SOCKET=""
1644+
VIRTIOFSD_PID=""
1645+
return
1646+
fi
1647+
1648+
echo " - virtiofsd: ${VIRTIOFSD_SOCKET} (${VIRTIOFSD_PID})"
1649+
}
1650+
16191651
function vm_boot() {
16201652
AUDIO_DEV=""
16211653
BALLOON="-device virtio-balloon"
@@ -2053,12 +2085,23 @@ function vm_boot() {
20532085
fi
20542086
fi
20552087

2088+
# File sharing: prefer virtiofs (shared memory, lower latency) over 9p when
2089+
# virtiofsd is available; virtiofsd must already be running at this point.
20562090
# https://wiki.qemu.org/Documentation/9psetup
20572091
# https://askubuntu.com/questions/772784/9p-libvirt-qemu-share-modes
20582092
if [ "${guest_os}" != "windows" ] || [ "${guest_os}" == "windows-server" ] && [ -n "${PUBLIC}" ]; then
2059-
# shellcheck disable=SC2054
2060-
args+=(-fsdev local,id=fsdev0,path="${PUBLIC}",security_model=mapped-xattr
2061-
-device virtio-9p-pci,fsdev=fsdev0,mount_tag="${PUBLIC_TAG}")
2093+
if [ -n "${VIRTIOFSD_SOCKET}" ]; then
2094+
# virtiofs requires a shared-memory backend; the size mirrors the VM RAM.
2095+
# shellcheck disable=SC2054
2096+
args+=(-object "memory-backend-file,id=mem,size=${RAM_VM},mem-path=/dev/shm,share=on"
2097+
-numa node,memdev=mem
2098+
-chardev "socket,id=char0,path=${VIRTIOFSD_SOCKET}"
2099+
-device "vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=${PUBLIC_TAG}")
2100+
else
2101+
# shellcheck disable=SC2054
2102+
args+=(-fsdev local,id=fsdev0,path="${PUBLIC}",security_model=mapped-xattr
2103+
-device virtio-9p-pci,fsdev=fsdev0,mount_tag="${PUBLIC_TAG}")
2104+
fi
20622105
fi
20632106

20642107
if [ -n "${USB_PASSTHROUGH}" ]; then
@@ -2469,6 +2512,16 @@ function fileshare_param_check() {
24692512
PUBLIC_PERMS=$(${STAT} -c "%A" "${PUBLIC}")
24702513
fi
24712514
fi
2515+
2516+
# Prefer virtiofs over 9p when virtiofsd is available and the guest is Linux.
2517+
# virtiofs uses shared memory rather than a transport protocol, giving much
2518+
# lower latency and higher throughput than 9p.
2519+
if [ -n "${PUBLIC}" ] && [ "${guest_os}" == "linux" ]; then
2520+
VIRTIOFSD=$(command -v virtiofsd 2>/dev/null || echo "/usr/lib/qemu/virtiofsd")
2521+
if [ ! -x "${VIRTIOFSD}" ]; then
2522+
VIRTIOFSD=""
2523+
fi
2524+
fi
24722525
}
24732526

24742527
function parse_ports_from_file {
@@ -2579,6 +2632,9 @@ MONITOR_CMD=""
25792632
PUBLIC=""
25802633
PUBLIC_PERMS=""
25812634
PUBLIC_TAG=""
2635+
VIRTIOFSD=""
2636+
VIRTIOFSD_PID=""
2637+
VIRTIOFSD_SOCKET=""
25822638
SHORTCUT_OPTIONS=""
25832639
SNAPSHOT_ACTION=""
25842640
SNAPSHOT_TAG=""
@@ -2903,6 +2959,7 @@ viewer_param_check
29032959
fileshare_param_check
29042960

29052961
if [ -z "${VM_PID}" ]; then
2962+
start_virtiofsd
29062963
vm_boot
29072964
start_viewer
29082965
# If the VM being started is an uninstalled Windows VM then auto-skip the press-any key prompt.

0 commit comments

Comments
 (0)