Running OpenBSD off a USB Stick

Introduction

This document describes how OpenBSD (obsd) can be installed and run off a USB stick without the need for a hard drive. Write operations to the USB stick are avoided.

We assume that the USB stick has a capacity of 512MB or more. In this case, the base installation fits well onto the stick and no pruning is required.

Installing

The easiest way to install obsd is to boot the OpenBSD installation CD on any computer with the USB stick plugged in. The installation script will show the available drives and the stick will be shown as sd0. By choosing this drive, the installation can be performed as any regular obsd installation. However, we must be careful not to touch the actual drive of the computer, which will show up as wd0.

The following partition layout should work fairly well:

PartitionMountMB512K
a/4898304
d/var1632768
e/var/log1632768
f/tmp1632768
g/home1632768
h/usr**

On a 512MB stick this should leave enough room in /usr for a basic (non-X) installation. With all non-X sets and the xbase40 set installed the /usr partition will be about 388 MB large. We do not want to swap to the drive and therefore we do not configure a swap partition either.

Mounting file systems

All file systems that reside on the stick shall be mounted read-only. All file systems that must be writable while obsd is running are copied to and mounted as memory file systems. The following file systems must be writable:

/dev  /tmp  /var  /var/log

If a computer running obsd is available then these steps can be performed on the mounted drive. Otherwise, the computer should be booted from the drive.

First, we create a prototypical /dev directory, which we are going to populate with device nodes:

Next, copy the MAKEDEV script from /dev to /proto/dev and run it to create all device nodes. This is accomplished by:

cd /proto/dev ; ./MAKEDEV all

The creation process takes a while. Next, we must adjust the fstab file using vi. This includes the following steps:

The -P option of the mount_mfs command populates the mounted filesystem. This can be done from a directory or from a block device. In our case, we created separate partitions for /tmp, /var and /var/log, which leads to a clean and simple setup for their corresponding memory file systems.

The inode value for the population of the /dev memory file system should be small e.g., 128 since the device nodes are small and therefore many inodes are required. The number of sectors required can be estimated by running:

ls /proto/dev | wc -l

and rounding this number up with a good safety margin added. My rationale is as follows: each device entry will occupy one sector. Additional blocks are needed for inodes.

The final fstab may look as given below:

# cat /etc/fstab
/dev/sd0a / ffs ro,noatime 1 1
/dev/sd0g /home ffs ro,nodev,nosuid,noatime 1 2
/dev/sd0h /usr ffs ro,nodev,noatime 1 2
# /dev/sd0d /var ffs ro,nodev,nosuid,noatime 1 2
# /dev/sd0e /tmp ffs ro,nodev,nosuid,noatime 1 2
# /dev/sd0f /var/log ffs ro,nodev,nosuid,noatime 1 2
swap /var mfs rw,nosuid,noexec,nodev,-P=/dev/sd0d 0 0
swap /tmp mfs rw,nosuid,noexec,nodev,-P=/dev/sd0e 0 0
swap /var/log mfs rw,nosuid,noexec,nodev,-P=/dev/sd0f 0 0
swap /dev mfs rw,nosuid,noexec,-P=/proto/dev,-i=128,-s=2048 0 0

We simply commented out the partitions we wish to move to a memory file system. For each such partition, we added a memory file system entry that populates the file system from the corresponding partition. The only exception is /dev, which we populate from a directory in the root file system of the drive.

Notes

The /var file system is very small and will therefore fill up quickly as obsd sends reports to the root account by e-mail. However, since /var is a separate partition, no harm is done except that the operation fails and an occasional error message appears in the logs.