Skip to content

Commit 66ed21a

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 7ea4e95 commit 66ed21a

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
@@ -46,6 +46,7 @@ required to run the virtual machines.
4646
- **Nearly 1000 operating system editions are supported!**
4747
- Full SPICE support including host/guest clipboard sharing
4848
- VirtIO-webdavd file sharing for Linux and Windows guests
49+
- VirtIO-fs file sharing for Linux guests (*automatically preferred over 9p when `virtiofsd` is installed on the host*)
4950
- VirtIO-9p file sharing for Linux and macOS guests
5051
- [QEMU Guest Agent
5152
support](https://wiki.qemu.org/Features/GuestAgent); provides access

quickemu

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

1116-
# 9P
1116+
# virtiofs or 9p depending on host capability
11171117
if [ "${guest_os}" != "windows" ] || [ "${guest_os}" == "windows-server" ]; then
1118-
echo -n " - 9P: On guest: "
1119-
if [ "${guest_os}" == "linux" ]; then
1120-
echo "sudo mount -t 9p -o trans=virtio,version=9p2000.L,msize=104857600 ${PUBLIC_TAG} ~/$(basename "${PUBLIC}")"
1118+
if [ "${guest_os}" == "linux" ] && [ -n "${VIRTIOFSD}" ]; then
1119+
echo " - virtiofs: On guest: sudo mount -t virtiofs ${PUBLIC_TAG} ~/$(basename "${PUBLIC}")"
1120+
elif [ "${guest_os}" == "linux" ]; then
1121+
echo " - 9P: On guest: sudo mount -t 9p -o trans=virtio,version=9p2000.L,msize=104857600 ${PUBLIC_TAG} ~/$(basename "${PUBLIC}")"
11211122
elif [ "${guest_os}" == "macos" ]; then
11221123
# PUBLICSHARE needs to be world writeable for seamless integration with
11231124
# macOS. Test if it is world writeable, and prompt what to do if not.
1124-
echo "sudo mount_9p ${PUBLIC_TAG}"
1125+
echo " - 9P: On guest: sudo mount_9p ${PUBLIC_TAG}"
11251126
if [ "${PUBLIC_PERMS}" != "drwxrwxrwx" ]; then
11261127
echo " - 9P: On host: chmod 777 ${PUBLIC}"
11271128
echo " Required for macOS integration 👆"
@@ -1156,6 +1157,37 @@ function configure_tpm() {
11561157
fi
11571158
}
11581159

1160+
function start_virtiofsd() {
1161+
# Start virtiofsd as a background daemon and record its PID so it can be
1162+
# cleaned up when the VM exits. The socket path is placed alongside other
1163+
# VM runtime files in VMDIR.
1164+
if [ -z "${VIRTIOFSD}" ]; then
1165+
return
1166+
fi
1167+
1168+
VIRTIOFSD_SOCKET="${VMDIR}/${VMNAME}.virtiofsd-sock"
1169+
local virtiofsd_args=(
1170+
--socket-path="${VIRTIOFSD_SOCKET}"
1171+
--shared-dir="${PUBLIC}"
1172+
--announce-submounts
1173+
)
1174+
1175+
echo "${VIRTIOFSD} ${virtiofsd_args[*]} &" >> "${VMDIR}/${VMNAME}.sh"
1176+
${VIRTIOFSD} "${virtiofsd_args[@]}" >> "${VMDIR}/${VMNAME}.log" 2>&1 &
1177+
VIRTIOFSD_PID=$!
1178+
sleep 0.25
1179+
1180+
if ! kill -0 "${VIRTIOFSD_PID}" 2>/dev/null; then
1181+
echo " - WARNING! virtiofsd failed to start; falling back to 9p."
1182+
VIRTIOFSD=""
1183+
VIRTIOFSD_SOCKET=""
1184+
VIRTIOFSD_PID=""
1185+
return
1186+
fi
1187+
1188+
echo " - virtiofsd: ${VIRTIOFSD_SOCKET} (${VIRTIOFSD_PID})"
1189+
}
1190+
11591191
function vm_boot() {
11601192
AUDIO_DEV=""
11611193
BALLOON="-device virtio-balloon"
@@ -1481,12 +1513,23 @@ function vm_boot() {
14811513
-drive id=SystemDisk,if=none,format=${disk_format},file="${disk_img}" ${STATUS_QUO})
14821514
fi
14831515

1516+
# File sharing: prefer virtiofs (shared memory, lower latency) over 9p when
1517+
# virtiofsd is available; virtiofsd must already be running at this point.
14841518
# https://wiki.qemu.org/Documentation/9psetup
14851519
# https://askubuntu.com/questions/772784/9p-libvirt-qemu-share-modes
14861520
if [ "${guest_os}" != "windows" ] || [ "${guest_os}" == "windows-server" ] && [ -n "${PUBLIC}" ]; then
1487-
# shellcheck disable=SC2054
1488-
args+=(-fsdev local,id=fsdev0,path="${PUBLIC}",security_model=mapped-xattr
1489-
-device virtio-9p-pci,fsdev=fsdev0,mount_tag="${PUBLIC_TAG}")
1521+
if [ -n "${VIRTIOFSD_SOCKET}" ]; then
1522+
# virtiofs requires a shared-memory backend; the size mirrors the VM RAM.
1523+
# shellcheck disable=SC2054
1524+
args+=(-object "memory-backend-file,id=mem,size=${RAM_VM},mem-path=/dev/shm,share=on"
1525+
-numa node,memdev=mem
1526+
-chardev "socket,id=char0,path=${VIRTIOFSD_SOCKET}"
1527+
-device "vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=${PUBLIC_TAG}")
1528+
else
1529+
# shellcheck disable=SC2054
1530+
args+=(-fsdev local,id=fsdev0,path="${PUBLIC}",security_model=mapped-xattr
1531+
-device virtio-9p-pci,fsdev=fsdev0,mount_tag="${PUBLIC_TAG}")
1532+
fi
14901533
fi
14911534

14921535
if [ -n "${USB_PASSTHROUGH}" ]; then
@@ -1829,6 +1872,16 @@ function fileshare_param_check() {
18291872
PUBLIC_PERMS=$(${STAT} -c "%A" "${PUBLIC}")
18301873
fi
18311874
fi
1875+
1876+
# Prefer virtiofs over 9p when virtiofsd is available and the guest is Linux.
1877+
# virtiofs uses shared memory rather than a transport protocol, giving much
1878+
# lower latency and higher throughput than 9p.
1879+
if [ -n "${PUBLIC}" ] && [ "${guest_os}" == "linux" ]; then
1880+
VIRTIOFSD=$(command -v virtiofsd 2>/dev/null || echo "/usr/lib/qemu/virtiofsd")
1881+
if [ ! -x "${VIRTIOFSD}" ]; then
1882+
VIRTIOFSD=""
1883+
fi
1884+
fi
18321885
}
18331886

18341887
function parse_ports_from_file {
@@ -1936,6 +1989,9 @@ MONITOR_CMD=""
19361989
PUBLIC=""
19371990
PUBLIC_PERMS=""
19381991
PUBLIC_TAG=""
1992+
VIRTIOFSD=""
1993+
VIRTIOFSD_PID=""
1994+
VIRTIOFSD_SOCKET=""
19391995
SHORTCUT_OPTIONS=""
19401996
SNAPSHOT_ACTION=""
19411997
SNAPSHOT_TAG=""
@@ -2219,6 +2275,7 @@ viewer_param_check
22192275
fileshare_param_check
22202276

22212277
if [ -z "${VM_PID}" ]; then
2278+
start_virtiofsd
22222279
vm_boot
22232280
start_viewer
22242281
# If the VM being started is an uninstalled Windows VM then auto-skip the press-any key prompt.

0 commit comments

Comments
 (0)