Resolving 9p Filesystem Write Permission Issues in QEMU/KVM Virtualization Environments


3 views

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 operations
  • version=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.