Read-only filesystems can be really useful for the deployment of devices that are prone to sudden shutdowns or other failure scenarios. It also makes it really easy to upgrade dependending on the method used.
I recently had to create a small buildroot system with a read-only layer and a write enabled layer using overlayfs. I’m using this setup for x86 boards and armv7 boards. Also, one requirement I set for myself was not to depend on any bootloader specific feature, since I have to support multiple architectures.
In this article, I’ll be describing a bit of this setup.
Overlayfs
From the linux summary of overlayfs:
An overlay filesystem combines two filesystems - an ‘upper’ filesystem and a ’lower’ filesystem. When a name exists in both filesystems, the object in the ‘upper’ filesystem is visible while the object in the ’lower’ filesystem is either hidden or, in the case of directories, merged with the ‘upper’ object.
You can find more documentation on the kernel documentation page. 1
This basically means that we can have a readonly (lower) filesystem merged with a writable (upper) filesystem. And every change made on the filesystem will be persisted on the upper filesystem. With this description you can see how this makes system upgrades and factory resets a dream, and it really does. 2
Boot and Overlayfs mounting process
For this article, I’ll be making the following assumptions:
- The system is already partitioned properly, with a working bootloader and two partitions, the first one bootable.
- We have a working kernel with overlayfs and initramfs supported.
For the boot process, we just need a kernel and a initrd on our boot partition and load that on the bootloader.
All we have to do now is override our /init
so that we can mount the new
overlayed filesystem before our actual init.
So our new /init
will look something like this:
|
|
After this, you should be on your new merged filesystem.
Upgrades and Resets
From the boot process and mounting, you can see how upgrading and reset will be very simple tasks.
To upgrade, just replacing the kernel and rootfs on the boot partition should
do the trick. To reset, just cleaning the /overlay/upper
should bring
everything to default!
And that’s it. It took me a little time to figure all this stuff out. But it’s a really simple process and I haven’t found any weird behavior with this little setup yet.
A huge inspiration for this was the OpenWrt project, they use a setup similar to the one I describe on their distro, and it works very well! ↩︎