Skip to main content.

Runnable Userspace Meta Programs (RUMPs)


About (top)

RUMPs are a loosely defined collection of programs which run unmodified kernel code in userspace. The main purpose is testing and development, but they may be used for other purposes such as to introduce multiple protection domains into the system or circumvent viral licensing restrictions.

Current support is limited to file systems, although networking and some subset of device drivers are planned for the future. This document describes only file systems.

File system are available either as transparently integrated into a running system (i.e. the application notices no difference to the same code running in the kernel), or as standalone programs. Kernel file systems which currently function as RUMPs are:

  • cd9660fs, efs, ext2fs, ffs, hfs, lfs (read-only), msdosfs, ntfs, tmpfs, and udf

RUMPs are available on NetBSD-current and will available in releases starting from NetBSD 5.0.

Components (top)

The file system RUMPs are made up of multiple different components. This section includes a description of each. Also, refer to the diagram.

Figure. ÒUMP components

RUMP components

  • librump provides the kernel environment for programs running in userspace. It is completely independent of file systems, althought currently most of the functionality it provides is directly related to file systems. librump is internally split into two pieces.

    • rumpkern provides the kernel interfaces. Some parts, such as the vfs name cache or the specificdata routines are compiled directly from kernel source code. Other parts such as the page fault routines or special device file system are written specifically for userspace.

      When adding functionality, the first preference should be to compile source modules directly from the kernel. Only when that fails, should functionality be implemented specially for RUMP. This is to keep the maintenance penalty at a minimum.

    • rumpuser provides routines in the regular user program namespace necessary for the kernel counterpart. These include routines such as malloc() and read(), but they are namespaced so that they do not collide with regular symbols - remember that the kernel provides malloc() also, but we wish to execute the libc version here.

  • libp2k is the adaption library which acts as a translator between the puffs(3) interface and the vfs layer. This is used only when mounting the file system via puffs(3) and is supported only on NetBSD. Calls to the file system are driven by the kernel virtual file system layer and ultimately by applications which use the file system like any regular in-kernel file system.

    It is possible to implement a similar translation library for e.g. the FUSE interface found on many systems and gain the ability to mount NetBSD kernel file systems on those platforms.

  • libukfs provides "standalone" access to a kernel file system. In this case, the file system is not mounted, but calls to the file system are controlled by the program using the library. The following gives a few ideas of calls which can be made:

    fs = ukfs_mount("ffs", "/home/pooka/img/ffs.img", "/", 0, &args, sizeof(args));
    ukfs_getdents(fs, "/", 0, buf, sizeof(buf));
    ukfs_read(fs, "/etc/passwd", 0, buf, sizeof(buf));
    ukfs_link(fs, "/hardlink", "/etc/linkfile");
            

    As can be seen, the interface does not attempt to duplicate that of the system call interface (open(), read(), etc.), only provide one to access the file system with.

    The ukfs library can be used to for example implement the makefs(8), as it is completely file system and host system agnostic. The canonical example of usage is the fsconsole program found in src/sys/rump/fs/bin/fsconsole.

It is important to note a crucial difference between the ukfs approach and the mounting approach. While mounting the file system as a userspace file server allows for complete application transparency, it requires mounting priviledges and support from the operating system. Accessing the file system through ukfs requires no priviledges except permission to read/write the file system image and to execute a program. Access through ukfs is also completely OS-independent and the NetBSD kernel file system code has already been run on Linux in this manner.

Using (top)

Building

Currently RUMPs are not installed. Rather they are just compiled and run from their build directories. The build is performed by going to src/sys/rump and typing make.

Mounting (p2k)

To mount a file system RUMP, go to its build directory and run the file server along with any flags you want, e.g. (requires system support for puffs)

pain-rustique> cd src/sys/rump/fs/bin/ffs
pain-rustique> ./ffs -o ro ~/img/ffs.img /mnt

Or if you want to mount a block device instead, the procedure is the same:

pain-rustique> cd src/sys/rump/fs/bin/ffs
pain-rustique> ./ffs /dev/wd0e /mnt2

NOTE: RUMP is considered experimental, so please make sure to backup your system before using it on any real (non-test) file systems. No loss of data has been experienced or reported, but being the first one to do so without backups does not qualify you for a special prize.

After this the file system will show up on the mountlist and you can access it through /mnt like any other mounted file system:

pain-rustique> mount | grep ffs.img
/home/pooka/img/ffs.img on /mnt type puffs|p2k|ffs (read-only, nosuid, nodev, mounted by pooka)
pain-rustique> df /mnt
Filesystem              1K-blocks       Used      Avail %Cap Mounted on
/home/pooka/img/ffs.img    254079      52034     189342  21% /mnt

Using ukfs

To use a file system directly via ukfs, you must write a program which uses the ukfs library in a fashion suitable to your goals. At this stage of development, the ukfs interface is documented only in source form in the src/sys/rump/fs/lib/libukfs/ukfs.h header.

File System Development (top)

To start developing a new file system using RUMP, the following steps must be taken (see existing file systems for clarification):

  1. Create src/sys/rump/fs/lib/libfsname and inside it a Makefile, which builds a regular userspace library out of the kernel file system code. The source modules are typically all the .c files in the file system's source directory, but there might be some variation depending on file system options.

  2. Create src/sys/rump/fs/bin/fsname and in there a regular user program. It should first process command line arguments. After that, the relevant routines are p2k_run_fs() for mounting a file system via p2k or ukfs_mount() for using the file system via ukfs. Naturally the ukfs program should call other ukfs calls after this to accomplish what it desires.

    This program must be linked with at least with the file system libraries it wants to use, librump and libukfs. Additionally, if you wish to mount the file system, libp2k and libpuffs must be included. There is some Makefile magic to handle this. See other file RUMPs for examples and also look into src/sys/rump/fs/Makefile.rumpfs.

  3. Add your file system to RUMPFSLIST in src/sys/rump/fs/Makefile.rumpfs.

  4. If your file system requires kernel support not yet provided by librump, investigate how to add it. The lack of support will present itself either as a linker failure or a runtime panic (core dump) in an unimplemented stub.

After the file system has been compiled, it can be run and debugged like any other userspace program. gdb can be attached to the process, a memory access violation will create a core dump, execution can be stopped and continued independently of the kernel, etc.

A Word About Caches

By default, puffs caches name lookup results (name cache) and file contents (page cache) in the kernel. While this speeds things up, it also changes some file system operation call patterns. Under normal operation this makes no difference, but when tracking down bugs it might make a crucial difference. To force the puffs kernel module to operate uncached, use the -o nocache mount option or embed the PUFFS_KFLAG_NOCACHE flag directly in the source code.

Source Code (top)

You can browse the source code online. See README.dirs in the top level directory for information on what to find where.

History (top)

The initial development for the RUMP framework was done as a Google Summer of Code 2007 project. It has since been developed with funding from the Finnish Cultural Foundation and the Research Foundation of Helsinki University of Technology.