Introducing easyinit
December 10, 2016 —
BarryK
Quirky Linux is intended mostly as a "full installation", occupying an entire partition, the same as most other distributions.
Unlike most major distributions, such as Debian and Ubuntu, Quirky does not have an initramfs. Instead, there is a kernel boot parameter "root=/dev/<partition>" which boots straight to the installation of Quirky. This makes for faster booting, also, Debian and Ubuntu have enormous initramfs files, consisting of files that are duplicated in the installed partition. This creates a larger .iso file to download.
Note, however, some of the variants of Debian and Ubuntu designed for specialised targets such as the Raspberry Pi, do not have a initramfs, or a very small one.
If Quirky needs to perform a filesystem check, resize the filesystem, or a system rollback (recovery, see the Snapshot Manager in the menu), /sbin/init, the first boot script in the installation detects this need, and creates a ramdisk with a minimal Linux installed into it, then performs a pivot_root into it. Then this minimal Linux is able to perform the required operations upon the partition in which Quirky is installed.
The main problem with this mechanism is the potential lack of robustness. The minimal Linux is created in the ramdisk by copying files from Quirky. However, if Quirky is badly broken, there is a possibility that the ramdisk will be also. Hence a rollback might not work.
To make this mechanism more robust, I have been on a mini-coding-marathon for the last couple of days. There is now a ready-made mini-Linux, called 'easyinit'. This is made of static applications that I compiled in Buildroot, with uClibc. The applications include busybox, coreutils, e2fsprogs, ntfs-3g, xdelta3 and gettext.
The main feature of easyinit is it is very small. Unlike the Debian/Ubuntu initramfs' that have kernel modules, libraries, shared-library executables, and a large array of support files.
easyinit resides in /boot in the Quirky installation, and /sbin/init just copies it into a ramdisk and performs a pivot_root into it.
Most significantly, /sbin/init has been reduced greatly in size. It is now a very small and simple script.
The functionality to perform filesystem check, resize, and rollback (recovery), is done within easyinit, and this is broken into small simple scripts.
In easyinit, there is the frontend, /init, that executes first. This may call /sbin/rollback or /sbin/fscheck.
All of this has been written, not yet tested.
Recovery for a totally broken system
The above mechanism will work if Quirky is able to at least get past the kernel, and the first boot script, /sbin/init, is able to run. Busybox in the Quirky installation is compiled statically, so the script should run even if glibc is broken.
However, if the system is so broken that even /init will not run, I plan to implement a fallback, "Plan B".
easyinit is a cpio archive, and can quite easily become an initramfs. So, in the case of the Raspberry Pi SD-card, if easyinit is copied into the first (vfat) partition, and the "root=" parameter changed to "initrd=easyinit", then easyinit will load into RAM and perform the required recovery.
This needs a bit more coding to implement, but it does mean that even a hopelessly broken installation can be recovered.
It does though, require that there be at least one snapshot of the system, taken by the Snapshot Manager.
Comments
The easyinit cpio archive, uncompressed, is 3034K.Gzip compressed it is 1938K, xz compressed it is 1250K.
I intend to build it into the sd-card image uncompressed, and the final image file will be xz compressed, so the 1250K figure is what will apply.
I don't recall the sizes of typical generic initramfs files in the Debian and Ubuntu distributions. I do vaguely recall a figure about 16MB gzip compressed.
Note, I could reduce the size of easyinit if I took out coreutils. I compiled it as a static 800K single binary. There are only a couple of utilities out of it that I am currently using.
I am currently not using these utilities either.
The reason that I have put in more utilities that I currently use, is to cater for future plans. I won't be restricted with what I can do in easyinit.
On the otherhand, I could chop down the size a bit when building the sd-card image in woofQ, just leave in what I need for now. Could easily get the xz-compressed size below 1MB.
Some utilities that maybe could be removed:
coreutils 800K
mksquashfs 294K
unsquashfs 243K
ntfs-3g 279K
TOTAL: 1616K
The utilities still in it, are busybox, e2fsck, resize2fs, xdelta3 and gettext.
This will be in the upcoming Quirky 8.1.4.
In easyinit, there is the frontend, /init, that executes first. This may call /sbin/rollback or /sbin/fscheck.
The frontend script is now /etc/init.d/rcS.
The pivot_root executes "/bin/busybox init", and as there is no /etc/inittab, busybox defaults to executing /etc/init.d/rcS.
There will then be an offer to open it up, and optionally change its contents.
You will find it at /boot/easyinit
Tags: linux