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