Merging or Creating Read-Only Filesystems with Unionfs

Recently, I was asked to make an embedded system running Linux completely read-only. To accomplish this, I utilized the unionfs utility. The standard blurb from the man page will shed some light on it:

Unionfs is not a command, but rather a file system. This manual page describes additional mount options that Unionfs supports.
Unionfs is a stackable unification file system, which can appear to merge the contents of several directories (branches), while keeping their physical content separate. Unionfs is useful for unified source tree management, merged contents of split CD-ROM, merged separate software package directories, data grids, and more. Unionfs allows any mix of read-only and read-write branches, as well as insertion and deletion of branches anywhere in the fan-out. To maintain unix semantics, Unionfs handles elimination of duplicates, partial-error conditions, and more.

In a nutshell, Unionfs allows you to layer directories into a single, mounted directory. Once the module has been compiled and inserted, it’s very easy to use. For example, to mount a read-only filesystem, you’ll want to replace any lines in your linuxrc file (if you don’t know what this is, you’ll want to read the article from logicsupply) that mount your filesystem (at /mnt/root, for example) with something like this:

insmod /unionfs.ko
mkdir /mnt/root.ro /mnt/root.rw
mount -o ro /mnt/root.ro
mount -t tmpfs root.rw root.rw
mount -t unionfs -o dirs=/mnt/root.rw=rw:/mnt/root.ro=ro unionfs /mnt/root

In the above example, we insert the unionfs.ko module located in the / directory. We then create the directories for which we will merge. These directories are where we’ve mounted our root filesystem and the tmpfs filesystem. Next, we mount our root filesystem as readonly to the root.ro mount point and then mount a tmpfs filesystem to root.rw which will become our writable layer. Finally, we merge the two together and voila! A read-only filesystem. The next thing to do is to chroot to /mnt/root and you’re done. Keep in mind that any changes made are being written to the tmpfs layer of unionfs and will not be persistent.

Take a look at these great articles on other example usage:

The most difficult part is getting your kernel to support it, but even this isn’t too difficult thanks to good patches on the main project website here:

We’ll run through an example. Say that your embedded system is using the 2.6.24 kernel and you want to use Unionfs. The first things you’ll need to do is find the 2.6.24 patch on the Unionfs main project website, download it, extract it, and then apply it using a command like the following from within the kernel source directory (the same directory with the Makefile):

patch -p1 < unionfs-2.5.4_for_2.6.24.7.diff

When patched, you’ll then need to use make menuconfig to select the Unionfs module. Save the .config changes when prompted to do so and use the make command to compile the kernel and modules. Install the kernel Image and the module into your embedded system and then try to insmod the driver. It should just work. Then, you can use the commands outlined above.

And that’s that! Be sure to check out the links provided. It would be too difficult to include everything there is to know about Unionfs in a single post. I hope I was able to provide you with at least a start in using it. Good luck and have fun!

Feel free to donate if this post prevented any headaches! Another way to show your appreciation is to take a gander at these relative ads that you may be interested in:

There's 1 Comment So Far

  • Manu
    June 29th, 2011 at 8:47 am

    I have some issue to understand the line 4
    Should the line 4: mount -t tmpfs root.rw root.rw be mount -t tmpfs -o rw root.rw instead?

Share your thoughts, leave a comment!