V9FS

V9FS is a remote file system based on the 9P2000.L protocol.

Adding V9FS to the NuttX Configuration

The V9FS client is easy to add to your configuration. Just add CONFIG_FS_V9FS to nuttx/.config.

In order to fully run V9FS, you also need to select a transport layer driver. The two currently available are:

  • VIRTIO -> CONFIG_V9FS_VIRTIO_9P=y

  • SOCKET -> CONFIG_V9FS_SOCKET_9P=y

Owner and Group

With CONFIG_SCHED_USER_IDENTITY, V9FS attaches to the server once for each effective user ID that uses the mount. A new file, directory or symbolic link gets the effective user ID and the effective group ID of the caller. chown() and fchown() send Tsetattr, and stat() shows the owner and the group that the server returns.

The server decides what it does with the owner. In QEMU, the security_model option of -fsdev or -virtfs selects it:

  • mapped-xattr: QEMU keeps the owner, the group and the mode of a file in extended attributes of the host file (user.virtfs.uid, user.virtfs.gid, user.virtfs.mode). Use this model when NuttX needs the owner and the group of its files.

  • mapped-file: the same, in hidden .virtfs_metadata files.

  • passthrough: QEMU changes the owner of the host file. QEMU must run as root, else the creation of a file fails with EPERM.

  • none: QEMU ignores the owner of a new file. stat() shows the owner of the host file, and chown() fails with EPERM unless QEMU runs as root.

V9FS Mount Command

In V9FS, we have some special parameters

  • uname. Used to indicate the user identity of the client

  • aname. Optional, it specifies the file tree that the client requests to access

  • trans. Selects the transport layer (virtio/socket)

  • msize. The maximum size of the message

  • tag. The tag of the mount point

Different transport layers have different requirements for parameter passing. Here are some examples:

Qemu + VIRTIO

mount -t v9fs -o trans=virtio,tag=<mount_tag> /dir

Similarly, we need to bring the corresponding parameters in qemu

-fsdev local,security_model=none,id=fsdev1,path=<share-path> \
-device virtio-9p-device,id=fs1,fsdev=fsdev1,mount_tag=<mount_tag>

Use security_model=mapped-xattr to keep the owner and the group of the files (see Owner and Group).

For how to start virtio-9p in QEMU, please refer to the document:

Socket

mount -t v9fs -o trans=socket,tag=<IP Address>:[Port Default 563],aname=[path] /dir

There are many types of 9P socket servers. Here we use R9-fileserver (a cross-platform 9p server based on Rust https://github.com/crafcat7/R9-fileserver)

sudo ./ya-vm-file-server --network-address <IP Address>:<Server Port> --mount-point <share-path>

Result

NuttShell (NSH)
nsh> mkdir mnt
nsh>
nsh> ls mnt
/mnt:
nsh> mount -t v9fs -o trans=virtio,tag=hostshare /mnt/v9fs
nsh>
nsh> ls /mnt/v9fs
/mnt/v9fs:
sdcard/
mnt/
nsh>
nsh> echo "This is a test" >/mnt/v9fs/testfile.txt
nsh> ls -l /mnt/v9fs
/mnt/v9fs:
drwxrwxrwx    1000    1000        4096 sdcard/
-rw-rw-rw-    1000    1000          15 testfile.txt
drwxrwxrwx    1000    1000        4096 mnt/
nsh>
nsh> cat /mnt/v9fs/testfile.txt
This is a test
nsh>