When working with 9p passthrough filesystems in QEMU/KVM environments, you'll notice an interesting permission behavior: while read operations and modifications to existing files work as expected, file/directory creation often fails despite correct permissions. This stems from how the 9p protocol handles metadata operations differently from regular filesystem operations.
For full read/write operations including file creation, you need to configure both the host and guest sides properly. The most critical components are:
<filesystem type='mount' accessmode='mapped'>
<source dir='/path/on/host'/>
<target dir='mount_tag'/>
<readonly/> <!-- Remove this for write access -->
</filesystem>
Here's a complete working configuration that enables full write access:
# Host side libvirt XML configuration
<devices>
<filesystem type='mount' accessmode='passthrough'>
<source dir='/shared/data'/>
<target dir='shared_data'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
</filesystem>
</devices>
# Guest side mount command
mount -t 9p -o trans=virtio,version=9p2000.L,access=client,msize=524288 shared_data /mnt/data
The 9p protocol supports several permission mapping modes:
- passthrough: Preserves exact UID/GID (requires matching user IDs)
- mapped: Translates UID/GID between host and guest
- none: Uses default permissions (usually root:root)
If you're still experiencing problems with file creation, verify these aspects:
# Check host directory permissions
ls -ld /shared/data
# Verify mount options in guest
mount | grep 9p
# Test basic write functionality
echo "test" > /mnt/data/testfile
For better performance with write operations, consider these mount options:
mount -t 9p -o trans=virtio,version=9p2000.L,cache=loose,msize=1048576 shared_data /mnt/data
When working with 9p passthrough filesystems in KVM/QEMU/libvirt environments, many developers encounter a peculiar permission behavior: while read operations work seamlessly and file modifications succeed with proper permissions (o+w), file creation and directory operations fail despite seemingly correct permissions.
The 9p filesystem (Plan 9 filesystem protocol) in QEMU operates through multiple layers:
Guest OS → QEMU 9p server → Host filesystem
↓ ↓ ↓
VirtIO Security context POSIX permissions
The permission issues stem from how these layers interact, particularly regarding write operations.
To enable full read/write access, you need to configure both the libvirt domain XML and the host filesystem properties:
<filesystem type='mount' accessmode='passthrough'>
<source dir='/host/path'/>
<target dir='/guest/mountpoint'/>
<readonly/> <!-- Remove this for write access -->
</filesystem>
1. Security Context Configuration
Modify your libvirt XML to include:
<filesystem type='mount' accessmode='passthrough'>
<source dir='/host/path'/>
<target dir='/guest/mountpoint'/>
<driver type='path' wrpolicy='immediate'/>
</filesystem>
2. Host Filesystem Preparation
On the host system, ensure proper permissions:
# chmod -R a+rwX /host/path
# chcon -R -t virt_content_t /host/path # For SELinux systems
# setfacl -R -m u:qemu:rwx /host/path # For ACL-enabled systems
The mount command in the guest should include specific options for write support:
# mount -t 9p -o trans=virtio,access=any,version=9p2000.L /fs/data /mnt
Key options:
access=any
: Allows all operationsversion=9p2000.L
: Uses the most feature-complete protocol version
If operations still fail, check:
# dmesg | grep 9p
[ 123.456789] 9p: Violation: trying to access file/directory not owned by user
Solutions:
- Add
security_model=none
to mount options (not recommended for production) - Verify UID/GID mapping between host and guest using virtfs remapping
For better write performance, consider these additional mount options:
# mount -t 9p -o trans=virtio,cache=loose,writeback /fs/data /mnt
This configuration reduces synchronization overhead at the cost of potential data loss during crashes.