The mini_fo overlay file system
mini_fo is a virtual kernel file system that can make read-only file systems writable. This is done by redirecting modifying operations to a writeable location called "storage directory", and leaving the original data in the "base directory" untouched. When reading, the file system merges the modifed and original data so that only the newest versions will appear. This occurs transparently to the user, who can access the data like on any other read-write file system.
This page discusses how the mini_fo file system can be used in embedded systems. For more general information, please visit the mini_fo project page
What it is good for?
In embedded systems the main use of mini_fo is to overlay the root file system. This means it is mounted on top of the regular root file system, thereby allowing applications or users to transparently make modifications to it but redirecting these to a different location.
Some examples of why this is usefull are explained in the following sections.
Making a read-only root filesystem writeable
Root file systems stored in flash are often read only, such as cramfs
or read only ext2
. While this offers major advantages in terms of speed and flash memory footprint, it nevertheless is often desireable to be able to modify the root file system, for example to
- apply (small) software updates without having to burn a whole new root file system image to flash
- make modifications during developement when frequent changes to the root file system occur.
This can be achieved by mounting mini_fo on top of the root file system and using a small writeable partition as the storage file system. This could be either a small jffs2 flash partition, or during development even an external hard disk. This has the following advantages:
- read-only file systems (fast, small memory footprint) can be used like persistent writable file systems (in contrast to a ramdisk)
- slow flash journalling file systems with large flash memory footprint can be avoided.
Non persistant changes
Ramdisks are often used when the root file system needs to be modified non-persistantly. This works well, but downsides are the large RAM memory footprint and the time costly operation of copying the ramdisk into RAM during startup. These can be avoided by overlaying the root file system as in the previous example but with the difference that the tmpfs file system
is used as storage. Thus only
modified files are stored in RAM, and can even be swapped out if neccessary. This saves boot time and RAM!
Mini_fo can be easily used to implement a "reset to factory defaults" function by overlaying the default root file system. When configuration changes are made, these are automatically directed to the storage file system and take precedence over the original files. Now, to restore the system to factory defaults, all that needs to be done is delete the contents of the storage directory. This will remove all changes made to the root file system and return it to the original state.
Note: Deleting the contents of the storage directory should only be done when the overlay file system is unmounted.
Generally, there are two different ways of overlaying the root file system, which both make sense in different scenarios.
Starting a single application in a chrooted overlayed environment
This is easy. Let's assume "/" is the read-only root file system and /dev/mtdblock5 contains a small jffs2 flash partition that shall be used to store modifications made by application "/usr/bin/autoPilot"
# mount -t jffs2 /dev/mtdblock5 /tmp/sto
# insmod mini_fo.o
# mount -t mini_fo -o base=/,sto=/tmp/sto/ / /mnt/mini_fo/
# cd /mnt/mini_fo/
# chroot . /usr/bin/autoPilot
The mini_fo file system is mounted with "/" as base directory, "/tmp/sto/" as storage directory to the mount point "/mnt/mini_fo". After that
is used to start the application with the new file system root "/mnt/mini_fo". All modifications made by the application will be stored to the jffs2 file system in /tmp/sto.
Starting the whole system system in chrooted overlayed environment
This is more interesting, and a bit trickier, as mounting needs to be done during system startup after
the root file system has been mounted, but before
init is started. The best way to do this is to have a script that mounts the mini_fo file system on top of root and then starts init in the chrooted overlayed environment. For example assume the following script "overlay_init", stored in /sbin/:
# mount mini_fo overlay file system and execute init
# make sure these exist in the read-only file system
# mount tmpfs as storage file system with a maximum size of 32MB
mount -t tmpfs -o rw,size=32M none $STORAGE
mount -t mini_fo -o base=/,sto=$STORAGE / $MOUNT_POINT
exec /usr/sbin/chroot $MOUNT_POINT /sbin/init
echo "exec chroot failed, bad!"
Now its easy to choose between a mini_fo overlayed and the regular non overlayed system just by setting the "init" kernel parameter in the boot loader to "init=/sbin/overlay_init".
pivot_root(1) can be used with chroot if there is need to access the original non overlayed root file system from the chrooted overlayed environment.
The mini_fo file system is inserted as an additional layer between the VFS and the native file system, and thus creates some overhead that varies strongly depending of the operation performed.
1. modifying a regular file for the first time
This results in a copy of the original file beeing created in the storage directory, that is then modified. Overhead depends on the size of the modified file.
2. Reading from files, creating new files, modifying already modified files
These operations are passed directly through to the lower native layer, and only impose an overhead of 1-2%.