Exploring the most NetBSD-unique feature: running the kernel and drivers in userspace with rump_server, booting a filesystem in userspace, and using rump kernels for testing without rebooting.

In episode 16 we conquered IPv6 and advanced networking. Now it's time to explore one of the most NetBSD-unique features in the operating system world: in this episode we'll dissect rump kernels and kernel-in-userspace — running kernel drivers and subsystems as ordinary processes with rump_server, booting a filesystem in userspace, and using it for testing without having to reboot.
Imagine being able to try out a filesystem driver, boot a disk image, or test a network stack — all as a normal process you can kill at any time, with zero risk of damaging the machine. That's the power of rump kernels, and few operating systems can do it as cleanly as NetBSD. Let's start with the concept.
rump stands for Runnable Userspace Meta Programs. The concept: the NetBSD kernel is modularized in such a way that its drivers and subsystems can be compiled into a server running in userspace — complete with the filesystem stack, network stack, and device drivers — without needing a machine or a reboot.
Imagine a small kernel "running" as a process: it has a VFS (Virtual File System), can format and mount filesystems, and can handle networking — but runs as an ordinary user. If that process crashes, nothing is destroyed.
| Benefit | Explanation |
|---|---|
| Filesystem testing without rebooting | Format, mount, and destroy disk images to your heart's content |
| Driver debugging | Drivers run as processes that can be debugged with gdb |
| Isolation | A driver failure doesn't drag down the system |
| Automation | Test suites can spin up and tear down small kernels as fast as processes |
The main rump kernels tool is rump_server — a daemon that runs your chosen kernel components in userspace. This tool is part of the NetBSD base system.
rump_server -lrumpvfsrump_server: creating server at unix socket /tmp/rump_serverThe -l option loads a module (here rumpvfs — the virtual file system), and -r creates the socket. Now we have a "mini kernel" living at /tmp/rump_server — ready to accept mount commands.
Here's the most interesting trick: using rump_server to format and mount a filesystem — including a disk image — without touching the system's real filesystems.
truncate -s 64m /tmp/test.imgThen format that image as FFS — using rump, so no global mount is needed:
rump.disk -t ffs /tmp/test.imgrump.disk: image /tmp/test.img contains 131072 sectorsrump.disk wraps the disk device so it can be used by rump components — just like the /dev/sd0 device, but entirely in userspace.
With the rump_server socket running, mount the image onto a host directory:
mount_ffs -o rump /tmp/test.img /mnt/rumpmount | grep rump
/tmp/test.img on /mnt/rump type ffs (rump, local)Notice the (rump, local) flag — this mount is managed by the rump_server, not the main kernel. This means the filesystem is "real" to the processes using it, but doesn't disturb the host system at all.
cp /etc/rc.conf /mnt/rump/
ls -l /mnt/rump-rw-r--r-- 1 root wheel 512 Aug 3 12:00 rc.confNow the real power: create a "broken" filesystem and see whether fsck repairs it — all in userspace:
rump.disk -t ffs -F /tmp/test.img
fsck -o rump -y /tmp/test.img** /tmp/test.img
** Phase 1 - Check Blocks and Sizes
... (repaired automatically)If this were done on a real filesystem, the risk of actual data loss would be real. With rump, everything lives in a single image file — break it a hundred times and it doesn't matter.
Info
Every command used with rump gets a special suffix: mount_ffs -o rump and tools like fsck accept the same option. It's an elegant design — the commands you already know stay the same, they just run through rump.
rumphijack wraps a process so its syscalls are routed to a rump_server instead of the kernel. A classic example: running ping with a rump network stack — as if the process were running on a different machine.
rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet unix:///tmp/rumpsockrump_server: creating server at /tmp/rumpsockThen hijack the ping process:
rumphijack -s /tmp/rumpsock ping -c 3 127.0.0.1PING 127.0.0.1: 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 time=0.041 msThat command looks ordinary, but it's actually running on a userspace network stack. For network testing, this makes it possible to simulate interfaces and topologies without affecting the real kernel stack.
Combining rump with disk images opens up a highly productive workflow:
truncate).rumpvfs (and rumpdev if you need devices).newfs -o rump or rump.disk -t ffs.rump_server -u) and repeat.truncate -s 64m /tmp/test.img
rump_server -lrumpvfs
rump.disk -t ffs /tmp/test.img
mount_ffs -o rump /tmp/test.img /mnt/rump
# ... any operations ...
umount /mnt/rump
rump_server -u| Scenario | Approach |
|---|---|
| Test a new filesystem/tool | rump with a disk image |
| Debug a driver without rebooting | rump_server with the driver module |
| Test a network configuration | rumphijack + rump network stack |
| CI/CD test suites | Spin up/tear down rump servers in scripts |
In this episode 17, you've explored the most NetBSD-unique feature: the rump kernel concept as a kernel running in userspace, using rump_server to run kernel components, booting and managing a filesystem in userspace, and using rumphijack to route a process's syscalls to a rump network stack.
Key takeaways:
rump_server -lrumpvfs builds a "mini kernel" with a socket.-o rump (e.g. mount_ffs -o rump).rumphijack routes a process's syscalls to a rump_server.In the next episode, episode 18, we'll take NetBSD into the world of virtualization: virtualization and cloud with NVMM and Xen — understanding the NVMM hypervisor, integration with QEMU, Xen's role as dom0/domU, and cloud images. See you in episode 18!