4

While the linux boots up, initrd is mounted with basic support files and kernel modules, which are needed to help further boot procedure. Later the rootfs is mounted and initrd is unmounted from the Linux OS. My question is if the initrd is unmounted how can a user still see the files mounted by initrd ?

Ex: some files in /etc, /lib etc..

3
  • Opposite question: why do you think the user would not be able to see those mounts? They're only mounted by the initrd – they don't come from the initrd. Apr 1 at 8:23
  • Let me elaborate my question. AFAIK, initrd is a disk image when uncompressed will contain many directories like /etc, /lib, /bin, /usr, .. . When the initrd is mounted in the boot process to the ram, these directories and its contents will be present in the system. During the later stage of boot process, initrd will be unmounted and rootfs will be mounted. My question is when the initrd is unmounted, why the directories /etc, /lib, /bin, /usr,.. and their contents are still present?
    – Franc
    Apr 1 at 8:38
  • It depends on implementation, but at least for busybox-based initramfs using switch_root, it deletes all initramfs files before switching to the real root filesystem and init system (rm -rf, mount --move, chroot, exec init). You can read the source code, it has a very long comment. There are other implementations - once the kernel unpacks initramfs and execs /init for you, it no longer cares what happens afterward Apr 1 at 8:51

1 Answer 1

7

Later the rootfs is mounted and initrd is unmounted from the Linux OS

It is not exactly "unmounted"; most Linux distributions haven't used a mountable initrd for years. Instead, they use an "initramfs" which is an archive that gets extracted into a RAM filesystem (tmpfs) that's initially mounted at "/". Even though it is still specified using the initrd= option, it behaves completely differently from the original initrd mechanism.

My question is when the initrd is unmounted, why the directories /etc, /lib, /bin, /usr,.. and their contents are still present?

Because they are not actually "/etc" or "/lib" from the initramfs point of view. The initramfs doesn't mount "/" directly – the initramfs itself is "/" – instead it mounts the real root filesystem at something like "/mnt" or "/newroot", so those directories start off as "/newroot/lib" and such.

One of the final steps done by the initramfs is to either "pivot_root()" or "mount(MS_MOVE)", an operation that makes "/newroot" become the new "/", essentially exchanging the two mounts (the old "/" which was the initramfs is moved to a sub-mount).

The minimal "/bin" and "/etc" and "/lib" that were unpacked from the initramfs do disappear during this process.

In other words, the process is approximately:

  1. The kernel mounts an empty tmpfs at /.
  2. The kernel unpacks the initramfs.cpio archive into the in-memory /, which contains some minimal files in /bin, /lib, etc.
  3. The kernel runs /init, which is the "core" of the initramfs.
  4. The initramfs /init script reads "root=" from the kernel command line (or uses some other method) and mounts the real root filesystem at /newroot or something similar. At this point, your files are at /newroot/lib, /newroot/home, and so on.
  5. The initramfs optionally mounts other necessary things under /newroot, such as a tmpfs at "/newroot/run", or a NFS-based /usr as "/newroot/usr".
  6. The initramfs /init turns /newroot into / using, I believe, one of two methods:
    • it deletes all files that were unpacked into the initramfs "/", then moves the "/newroot" mount onto "/" (overlaying the now-empty tmpfs which stays there forever) and uses chroot() to make it permanent – this is what's done by Arch Linux's initramfs using the switch_root tool;
    • or it calls pivot_root() to "swap" the initramfs / with /newroot, turning the latter into the new / and moving the initramfs to something like /run/initramfs which can then be unmounted – not sure if this method is still used.
  7. Finally, now that "/" is the real root, /init (still running from memory) executes the real root filesystem's /sbin/init.

Often the initramfs /init is a simple shell script (though not always; it could even be a full copy of systemd). You can take a look at the Arch mkinitcpio /init. This internally uses the "overlay using mount(MS_MOVE)" method; see e.g. switch_root from util-linux.

7
  • Not sure about the delete part :-) Apr 1 at 11:27
  • 1
    It really does delete the contents of the ramfs, as otherwise they would just continue occupying memory (sometimes a whole ~200MB of it) while being inaccessible. See here, here, here, etc. Apr 1 at 12:04
  • Woah, thanks. That looks kinda weird to me, almost like a crutch. Apr 1 at 15:00
  • 2
    A note in the kernel suggests the rootfs cannot be pivot_root'd: git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/…. I.e. an initramfs must do the first bullet under 6 in your list. Rootfs cannot be unmounted, because the VFS mechanism is "naturally" nonempty ("same reason you can't kill the init": git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/…). Rootfs is always attached to /, even if empty or mounted over. This ensures the VFS always works.
    – HTNW
    Apr 1 at 19:14
  • 1
    @HTNW It also ensures that no special semantics are required in the VFS layer for the ‘real’ root filesystem, which greatly simplifies the implementation in a number of ways. Apr 1 at 20:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.