Why does initramfs mount the root filesystem read-only

10,001

The initial ramdisk (initrd) is typically a stripped-down version of the root filesystem containing only that which is needed to mount the actual root filesystem and hand off booting to it.

The initrd exists because in modern systems, the boot loader can't be made smart enough to find the root filesystem reliably. There are just too many possibilities for such a small program as the boot loader to cover. Consider NFS root, nonstandard RAID cards, etc. The boot loader has to do its work using only the BIOS plus whatever code can be crammed into the boot sector.

The initrd gets stored somewhere the boot loader can find, and it's small enough that the extra bit of space it takes doesn't usually bother anyone. (In small embedded systems, there usually is no "real" root, just the initrd.)

The initrd is precious: its contents have to be preserved under all conditions, because if the initrd breaks, the system cannot boot. One design choice its designers made to ensure this is to make the boot loader load the initrd read-only. There are other principles that work toward this, too, such as that in the case of small systems where there is no "real" root, you still mount separate /tmp, /var/cache and such for storing things. Changing the initrd is done only rarely, and then should be done very carefully.

Getting back to the normal case where there is a real root filesystem, it is initially mounted read-only because initrd was. It is then kept read-only as long as possible for much the same reasons. Any writing to the real root that does need to be done is put off until the system is booted up, by preference, or at least until late in the boot process when that preference cannot be satisfied.

The most important thing that happens during this read-only phase is that the root filesystem is checked to see if it was unmounted cleanly. That is something the boot loader could certainly do instead of leaving it to the initrd, but what then happens if the root filesystem wasn't unmounted cleanly? Then it has to call fsck to check and possibly fix it. So, where would initrd get fsck, if it was responsible for this step instead of waiting until the handoff to the "real" root? You could say that you need to copy fsck into the initrd when building it, but now it's bigger. And on top of that, which fsck will you copy? Linux systems regularly use a dozen or so different filesystems. Do you copy only the one needed for the real root at the time the initrd is created? Do you balloon the size of initrd by copying all available fsck.foo programs into it, in case the root filesystem later gets migrated to some other filesystem type, and someone forgets to rebuild the initrd?

The Linux boot system architects wisely chose not to burden the initrd with these problems. They delegated checking of the real root filesystem to the real root filesystem, since it is in a better position to do that than the initrd.

Once the boot process has proceeded far enough that it is safe to do so, the initrd gets swapped out from under the real root with pivot_root(8), and the filesystem is remounted in read-write mode.

Share:
10,001

Related videos on Youtube

Portablejim
Author by

Portablejim

Looking for work: -- Website hosting -- CD/DVD burning, printing & duplication.

Updated on September 18, 2022

Comments

  • Portablejim
    Portablejim almost 2 years

    What is the reason for the root filesystem being mounted ro in the initramfs (and in initrd).

    For example the Gentoo initramfs guide mounts the root filesystem with:

    mount -o ro /dev/sda1 /mnt/root
    

    Why not the following?

    mount -o rw /dev/sda1 /mnt/root
    

    I can see that there is a probably a good reason (and it probably involves switchroot), however it does not seem to be documented anywhere.

  • psusi
    psusi over 12 years
    The initramfs is not mounted read only; the kernel unpacks it into a read/write tmpfs that is mounted as /. Also pivot_root() is used in the now depreciated initrd, but not an initramfs, which most systems use these days ( even though the file is still named initrd ). With the initrd, pivot_root took place before execing /sbin/init, which went on to fsck and remount r/w. With an initramfs, it just deletes all files in the initramfs, then chroots into the real root and execs /sbin/init.