Feature #14579


expose virtio 9P transport device

Added by Joshua M. Clulow 4 months ago. Updated 3 months ago.

driver - device drivers
Start date:
Due date:
% Done:


Estimated time:
Gerrit CR:


Some hypervisors (e.g., QEMU and bhyve) provide support for file sharing via the 9P protocol, a descendant of the file sharing protocol from Plan 9. In these hypervisors the protocol does not use the network for transport, but rather a simple VIRTIO device. Though a device ID is set aside in the specification, the operation of the device is not described.

A concrete first step towards providing access to these shared file systems from within illumos guests is to expose the 9P transport device in a way that can be used from processes and file system drivers. This is considerably simpler than a potential file system implementation and will enable continued incremental work on either a file system or user tools to interact with the hypervisor.


lookit.c (15.7 KB) lookit.c Joshua M. Clulow, 2022-03-24 01:24 AM
Actions #1

Updated by Electric Monk 4 months ago

  • Gerrit CR set to 2077
Actions #2

Updated by Joshua M. Clulow 4 months ago

Manual page:

VIO9P(4D)                           Devices                          VIO9P(4D)

     vio9p – Virtio 9P Transport Driver


     The vio9p driver provides access to 9P transport devices commonly used by
     hypervisors and emulators to expose a shared file system.

     The vio9p driver is not a Committed interface, and may change at any

     Each device corresponds to a specific 9P channel.  The device may be
     opened for read(2) and write(2) calls.  Writes represent a 9P request
     message sent to the hypervisor, and reads represent responses to those

     Unlike with other transports like TCP, the channel is not explicitly
     reset when the device is opened or closed.  After a call to open(2), the
     application should use a version message to open a new session.  This
     will explicitly discard any previous session, clunking any active fids in
     the process and negotiating an appropriate protocol version with the
     hypervisor.  It is likely also appropriate to do this as part of closing
     the device, to allow the hypervisor to free any session tracking

     Writes must be well-formed 9P messages.  In particular, they must include
     a minimum of seven bytes, representing the message size[4], type[1], and
     tag[2].  The driver limits request and response size to 8192 bytes, and
     will fail larger writes with ENOSPC.  Applications should, in their
     initial version message, negotiate an msize[4] value less than or equal
     to 8192 bytes.

     Reads are interruptible and will block waiting for a response to a
     request sent in a previous write.  If insufficient buffer space is
     provided to the read call to receive the message, the call will fail with
     EOVERFLOW and the message will remain available for a subsequent read.
     Messages are provided as-is to the application, including the size[4],
     type[1], and tag[2].

     Depending on the 9P server provided by the hypervisor, requests that are
     issued concurrently may result in responses that arrive out of order.
     Applications should develop a strategy for allocating unique tag[2]
     values, so that request and response messages can be correlated.

     The driver provides an ioctl, VIO9P_IOC_MOUNT_TAG, to expose the Mount
     Tag string if one was provided by the hypervisor.  The ioctl is defined
     in <sys/vio9p.h>.  The argument must be a char *, pointing to a buffer of
     VIO9P_MOUNT_TAG_SIZE bytes.  On success, the buffer will contain the
     mount tag string read from the hypervisor; in principle this should be a
     null-terminated C string, but applications should take care to verify
     that it is in the expected format.  Note that even if successfully read,
     the string may be empty.

     /dev/9p/*                         Character device for access to a 9P

     /kernel/drv/amd64/vio9p           Device driver (x86)


     close(2), ioctl(2), open(2), read(2), write(2)

illumos                         March 21, 2022                         illumos
Actions #3

Updated by Joshua M. Clulow 4 months ago

I have attached a C program that demonstrates basic usage of 9P. I shared a directory using 9P into a QEMU guest on my Linux workstation:

$ find /var/tmp/NINE/

You can see the output from inside the guest:

root@unknown:~# ./lookit
MOUNT TAG: "/nine" 

frame size = 21
type = 101
tag = 0xffff
msize = 4096
version = 9P2000.L

frame size = 20
type = 105
tag = 0x3e9
aqid { 80 622BAD00 0000000001CD60FF }

frame size = 88
type = 125
tag = 0x3ea
{ 80 622BAD00 0000000001CD60FF } 800001ed u   1000 g     50 "." 

frame size = 24
type = 13
tag = 0x3eb
root { 80 622BAD00 0000000001CD60FF }
iounit = 0

--- LISTDIR: FID 12340001
READDIR >> TAG 41b OFFSET 0000000000000000
frame size = 122
type = 41
tag = 0x41b
rcount = 111
 ~ ~ ~ start 11
{ 00 00000000 0000000001CC0126 } t 04 o 247C71EC371E9FB0 ".." 
 ~ ~ ~ offset after 0: 26
{ 00 00000000 0000000001CD6100 } t 04 o 61BC295E3D20CEAE "root" 
 ~ ~ ~ offset after 1: 54
{ 00 00000000 0000000001CD60FF } t 04 o 7356807EDC3FD7CB "." 
 ~ ~ ~ offset after 2: 79
{ 00 00000000 0000000001CC20B7 } t 08 o 7FFFFFFFFFFFFFFF "date.txt" 
 ~ ~ ~ offset after 3: 111

frame size = 11
type = 41
tag = 0x41c
rcount = 0
--- END OF LISTDIR: FID 12340001

frame size = 22
type = 111
tag = 0x7d0
nwqid = 1
wsqid { 80 622BAD05 0000000001CD6100 }

frame size = 24
type = 13
tag = 0xbe9
root { 80 622BAD05 0000000001CD6100 }
iounit = 0

--- LISTDIR: FID 90001
READDIR >> TAG beb OFFSET 0000000000000000
frame size = 91
type = 41
tag = 0xbeb
rcount = 80
 ~ ~ ~ start 11
{ 00 00000000 0000000001CC2C4B } t 08 o 13CF57DC35F70D51 "a.txt" 
 ~ ~ ~ offset after 0: 29
{ 00 00000000 0000000001CD60FF } t 04 o 61BC295E3D20CEAE ".." 
 ~ ~ ~ offset after 1: 55
{ 00 00000000 0000000001CD6100 } t 04 o 7FFFFFFFFFFFFFFF "." 
 ~ ~ ~ offset after 2: 80

frame size = 11
type = 41
tag = 0xbec
rcount = 0
Actions #4

Updated by Joshua M. Clulow 3 months ago

For background reading on 9P, there are a number of places one could look. Probably the most important thing to know is that while 9P is a protocol for remote access to a file system, Plan 9 had a somewhat loose definition of what could be in a file system; anything that could be made to look like a UNIX hierarchical file system, whether it was actual file storage or some software control interface like the proc file system, could be made available over 9P. Some documents of interest:

In short: there is, as far as I can see, no objectively best reference -- but much public documentation of subjective relevance!


Also available in: Atom PDF