Kernel File Systems as Userspace Servers
This chapter describes the symbiosis of background knowledge on them, see the respective web pages.
The integration of the puffs and rump technologies enables mounting kernel file systems as userspace servers. Equivalent functionality to the in-kernel option is maintained, and an application accessing files is unable to tell the difference between the two.
A useful scenario for mounting a kernel file system as a userspace server is accessing untrusted media. As file system code is generally authored assuming a trusted and correct file system image, a corrupt or deliberately modified image can easily cause a kernel crash or security compromise. By using a userspace server, the compromise is limited to the userspace server program, not the whole system.
It also enables the mounting of kernel file systems which are not included as part of the kernel and loading a module is not desired. Additionally, using kernel file systems from different operating system versions is possible, since interfacing with the kernel is done through the puffs protocol, not the kernel binary interface. This is desired for example when wanting to take advantage of new functionality without upgrading the operating system or wanting to do a partial rollback to avoid a regression in a newer version.
The use of kernel file systems as userspace servers requires the support for puffs in the kernel.
To mount the file system, the relevant rump_fs command must be run. These commands share the same suffix as the normal in-kernel mount_fs commands. For instance, the equivalent of mount_msdos is rump_msdos. The usage is also equal, so the manual page of the mount equivalent should be consulted. The only exception is that rump file systems do not require the use of vnconfig to mount regular files. Rather, such images can be mounted directly by using the image as the device file path.
To unmount, umount should be run as normal. While it is possible to violently kill the server process, this does not give the file system an opportunity to flush its caches and cleanly unmount and may result in data loss. In case the server process is violently killed, puffs automatically performs a forced unmount and no further action is necessary.
To mount a file system image as a read-only mount:
pain-rustique> rump_ffs -o ro ~/img/ffs.img /mnt OR pain-rustique> mount -t ffs -o ro,rump ~/img/ffs.img /mnt
If you want to mount a disk device instead, the procedure is the same. This example also instructs the file system to use journalling. Note: for reasons beyond the scope of this document, it is highly recommended you use the raw device instead of the usual block device.
pain-rustique> rump_ffs -o log /dev/rwd0e /mnt2
Mounting nfs works in a similar fashion. The command line flag
-p makes sure a non-root mount is succesful if the
server allows them:
pain-rustique> rump_nfs -p host:/export /mnt3
Finally, the option
rump in fstab signals that
the file system should be mounted using rump instead of the
kernel file service. The following example is for specifying an
nfs share mount from a laptop over wireless:
server:/m/server /m/server nfs rw,noauto,-r=8192,-w=8192,rump
After this the file system will show up on the mountlist and you can access it through the mountpath like any other mounted file system.
Internally, kernel file systems are implemented against the kernel virtual file system layer. This layer defines a protocol which kernel file systems convert to their backend storage protocol to satisfy the operation. The result is then converted back to a format the virtual file system layer understands and passed back to caller (most likely an application, although it can be for example the NFS server).
Analogously, puffs file systems must interpret and convert the
puffs file system interface protocol. While the puffs interface
is very similar to the kernel virtual file system interface,
there are differences in some parameters. For example, the
virtual file system passes information about I/O as a
struct uiomove. In contrast, puffs
passes this as explicit parameters.
Since a userspace kernel file system server attaches itself
as a puffs file system, protocol conversion from puffs to the
kernel virtual file system must happen, if the whole protocol
stack is to work. This conversion of protocols is done by
the p2k, or puffs-to-kernel, component. It is installed
libp2k and linked with all kernel
file system servers.