Feature #14579
openexpose virtio 9P transport device
0%
Description
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.
Files
Updated by Joshua M. Clulow 4 months ago
Manual page:
VIO9P(4D) Devices VIO9P(4D) NAME vio9p – Virtio 9P Transport Driver SYNOPSIS /dev/9p/* DESCRIPTION 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 time. APPLICATION PROGRAMMING INTERFACE 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 requests. 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 resources. 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. IOCTLS 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. FILES /dev/9p/* Character device for access to a 9P channel. /kernel/drv/amd64/vio9p Device driver (x86) INTERFACE STABILITY Uncommitted SEE ALSO close(2), ioctl(2), open(2), read(2), write(2) illumos March 21, 2022 illumos
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/ /var/tmp/NINE/ /var/tmp/NINE/root /var/tmp/NINE/root/a.txt /var/tmp/NINE/date.txt
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 READDIR >> TAG 41c OFFSET 7FFFFFFFFFFFFFFF frame size = 11 type = 41 tag = 0x41c rcount = 0 done --- 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 READDIR >> TAG bec OFFSET 7FFFFFFFFFFFFFFF frame size = 11 type = 41 tag = 0xbec rcount = 0 done --- END OF LISTDIR: FID 90001
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:
- For 9P history, the wikipedia page gives some basic background.
- Manual pages from Plan 9 are, today, published at 9p.io -- of particular interest is Section 5: Plan 9 File Protocol, 9P and the intro to section 5 which contain some descriptions of the protocol and the basic request and response messages
- Subsequent RFC-style documents are available in the ericvh/9p-rfc GitHub repository and its associated GitHub pages site which covers the 9P2000 and 9P2000.u revisions and extensions to the original 9P protocol.
- The diod project appears to offer a 9P server, and ostensibly is the place to look for the more Linux-centric 9P2000.L revision of the protocol.
- QEMU also has some 9P documentation that discusses their implementation and how guests are expected to use it
- There is a community-compiled list of known 9P implementations at http://9p.cat-v.org/implementations as well
In short: there is, as far as I can see, no objectively best reference -- but much public documentation of subjective relevance!