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=ySOCKET ->
CONFIG_V9FS_SOCKET_9P=y
Symbolic Links
With CONFIG_FS_LINKS, V9FS follows the symbolic links on the server,
and supports readlink(), lstat(), symlink() and link(). A
path follows at most SYMLOOP_MAX links, and a loop fails with
ELOOP. open() with O_NOFOLLOW does not follow a link in the
last component of the path. rm of a link removes the link, not its
target. A link with an absolute target is not followed and fails with
ENOTSUP, because the target is a path on the server.
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_metadatafiles.
passthrough: QEMU changes the owner of the host file. QEMU must run as root, else the creation of a file fails withEPERM.
none: QEMU ignores the owner of a new file.stat()shows the owner of the host file, andchown()fails withEPERMunless 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>