A Date with Squashfs and Aufs
Yesterday I uploaded a testing build of Calf GNU/Linux with the version number “001″ (0.0.1). It uses Squashfs (with linking, like Tiny Core) and Aufs (for a “save file”, like Puppy).
Since yesterday, I’m recompiling the whole thing. I’m trying to find the right packages and right order to build them. For instance, I can compile Coreutils without GMP as a dependency – Coreutils goes first and GMP joins the distro only when it’s really needed (GCC needs it).
I was wondering … what is the most efficient way to get a writeable /, a persistent home directory and a package management system that allows packages to be installed on-the-fly and removed cleanly? The answer is already included in Calf 001.
Until 001, Calf used a tmpfs moutned on / and an image file mounted on the home directory. However, this approach had some limitations. First, it wasn’t very elegant – the home directory had “lost+found”. Second, packages could not contain any files that go to the home directory, for obvious reasons – they’re linked and not copied, so the save file doesn’t contain them. If you want to create a quick backup of your home directory, you’re in trouble. The init scripts were more complicated and did not allow the flexibility of Puppy.
However, 001 has a new init script – the whole thing in one script, it’s more efficient. It uses a file named “distrorc”, which resides in /etc. That file contains 4 variables: distroName, distroFilePrefix, distroReleaseDate and distroArch.
The first variable, distroName, is the user-friendly distribution name. The second one is the prefix for some of its files (for example, if Puppy 5.1.1 uses pup-511.sfs, this variable is the equivalent of the “pup” prefix). The third variable is the release date and the fourth one is the architecture, i486 in this case.
The init process starts when /init creates a tmpfs with the size tag of 80% of the available RAM. Then, it copies everything there and calls the real init, which runs /etc/init.d/rcS. The purpose of /init is the creation of the tmpfs file system, which is writeable and allows the “live” nature of the distro.
Then, the init script scans all partitions (it detects them through /sys) for a file named $distroFilePrefix-$distroVersion.sfs, both on the partition root and sub-directories. If it finds it, the Squashfs image is linked. Then, it does the same with all files that end with “.sfs” in a directory named $distroFilePrefix-extensions that is placed next to the Squashfs file, if there is such.
After the extension linking, the init script checks whether a file named ${distroFilePrefix}save.img exists next to the Squashfs file; that’s the save file. It is mounted and used as a layer above the /root from the Squashfs file system found earlier.
At the moment the initramfs is really big, it’s 16 MB, because it has all kernel modules. Now I’m almost done rebuilding the whole Calf GNU/Linux and this time things that are highly likely to be needed on most machines are part of the kernel. For instance, USB support is something all computers have – if it’s part of the kernel image, the USB support code doesn’t have to be loaded as a kernel module, that saves precious boot time.
Additionally, 002 will have both Aufs and Squashfs compiled in and not as modules, to speed it up even further. The Squashfs loading will be faster and boot times should be shorter.
To conclude, Aufs and Squashfs are two interesting pieces of software that are vital for most mini-distributions and live distributions. Let’s hope Calf GNU/Linux will eventually make a good use of both.