Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fs: use nullfs unconditionally as the real rootfs

Remove the "nullfs_rootfs" boot parameter and simply always use nullfs.
The mutable rootfs will be mounted on top of it. Systems that don't use
pivot_root() to pivot away from the real rootfs will have an additional
mount stick around but that shouldn't be a problem at all. If it is
we'll rever this commit.

This also simplifies the boot process and removes the need for the
traditional switch_root workarounds.

Suggested-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>

+32 -77
+4 -20
Documentation/filesystems/ramfs-rootfs-initramfs.rst
··· 76 76 --------------- 77 77 78 78 Rootfs is a special instance of ramfs (or tmpfs, if that's enabled), which is 79 - always present in 2.6 systems. Traditionally, you can't unmount rootfs for 80 - approximately the same reason you can't kill the init process; rather than 81 - having special code to check for and handle an empty list, it's smaller and 82 - simpler for the kernel to just make sure certain lists can't become empty. 83 - 84 - However, if the kernel is booted with "nullfs_rootfs", an immutable empty 85 - filesystem called nullfs is used as the true root, with the mutable rootfs 79 + always present in Linux systems. The kernel uses an immutable empty filesystem 80 + called nullfs as the true root of the VFS hierarchy, with the mutable rootfs 86 81 (tmpfs/ramfs) mounted on top of it. This allows pivot_root() and unmounting 87 82 of the initramfs to work normally. 88 83 ··· 121 126 program. See the switch_root utility, below.) 122 127 123 128 - When switching another root device, initrd would pivot_root and then 124 - umount the ramdisk. Traditionally, initramfs is rootfs: you can neither 125 - pivot_root rootfs, nor unmount it. Instead delete everything out of 126 - rootfs to free up the space (find -xdev / -exec rm '{}' ';'), overmount 127 - rootfs with the new root (cd /newmount; mount --move . /; chroot .), 128 - attach stdin/stdout/stderr to the new /dev/console, and exec the new init. 129 - 130 - Since this is a remarkably persnickety process (and involves deleting 131 - commands before you can run them), the klibc package introduced a helper 132 - program (utils/run_init.c) to do all this for you. Most other packages 133 - (such as busybox) have named this command "switch_root". 134 - 135 - However, if the kernel is booted with "nullfs_rootfs", pivot_root() works 129 + umount the ramdisk. With nullfs as the true root, pivot_root() works 136 130 normally from the initramfs. Userspace can simply do:: 137 131 138 132 chdir(new_root); 139 133 pivot_root(".", "."); 140 134 umount2(".", MNT_DETACH); 141 135 142 - This is the preferred method when nullfs_rootfs is enabled. 136 + This is the preferred method for switching root filesystems. 143 137 144 138 Populating initramfs: 145 139 ---------------------
+21 -43
fs/namespace.c
··· 75 75 76 76 __setup("initramfs_options=", initramfs_options_setup); 77 77 78 - bool nullfs_rootfs = false; 79 - 80 - static int __init nullfs_rootfs_setup(char *str) 81 - { 82 - if (*str) 83 - return 0; 84 - nullfs_rootfs = true; 85 - return 1; 86 - } 87 - __setup("nullfs_rootfs", nullfs_rootfs_setup); 88 - 89 78 static u64 event; 90 79 static DEFINE_XARRAY_FLAGS(mnt_id_xa, XA_FLAGS_ALLOC); 91 80 static DEFINE_IDA(mnt_group_ida); ··· 4582 4593 * pointed to by put_old must yield the same directory as new_root. No other 4583 4594 * file system may be mounted on put_old. After all, new_root is a mountpoint. 4584 4595 * 4585 - * Also, the current root cannot be on the 'rootfs' (initial ramfs) filesystem 4586 - * unless the kernel was booted with "nullfs_rootfs". See 4587 - * Documentation/filesystems/ramfs-rootfs-initramfs.rst for alternatives 4588 - * in this situation. 4596 + * The immutable nullfs filesystem is mounted as the true root of the VFS 4597 + * hierarchy. The mutable rootfs (tmpfs/ramfs) is layered on top of this, 4598 + * allowing pivot_root() to work normally from initramfs. 4589 4599 * 4590 4600 * Notes: 4591 4601 * - we don't move root/cwd if they are not at the root (reason: if something ··· 5981 5993 struct path root; 5982 5994 5983 5995 /* 5984 - * When nullfs is used, we create two mounts: 5996 + * We create two mounts: 5985 5997 * 5986 5998 * (1) nullfs with mount id 1 5987 5999 * (2) mutable rootfs with mount id 2 5988 6000 * 5989 6001 * with (2) mounted on top of (1). 5990 6002 */ 5991 - if (nullfs_rootfs) { 5992 - nullfs_mnt = vfs_kern_mount(&nullfs_fs_type, 0, "nullfs", NULL); 5993 - if (IS_ERR(nullfs_mnt)) 5994 - panic("VFS: Failed to create nullfs"); 5995 - } 6003 + nullfs_mnt = vfs_kern_mount(&nullfs_fs_type, 0, "nullfs", NULL); 6004 + if (IS_ERR(nullfs_mnt)) 6005 + panic("VFS: Failed to create nullfs"); 5996 6006 5997 6007 mnt = vfs_kern_mount(&rootfs_fs_type, 0, "rootfs", initramfs_options); 5998 6008 if (IS_ERR(mnt)) 5999 6009 panic("Can't create rootfs"); 6000 6010 6001 - if (nullfs_rootfs) { 6002 - VFS_WARN_ON_ONCE(real_mount(nullfs_mnt)->mnt_id != 1); 6003 - VFS_WARN_ON_ONCE(real_mount(mnt)->mnt_id != 2); 6011 + VFS_WARN_ON_ONCE(real_mount(nullfs_mnt)->mnt_id != 1); 6012 + VFS_WARN_ON_ONCE(real_mount(mnt)->mnt_id != 2); 6004 6013 6005 - /* The namespace root is the nullfs mnt. */ 6006 - mnt_root = real_mount(nullfs_mnt); 6007 - init_mnt_ns.root = mnt_root; 6014 + /* The namespace root is the nullfs mnt. */ 6015 + mnt_root = real_mount(nullfs_mnt); 6016 + init_mnt_ns.root = mnt_root; 6008 6017 6009 - /* Mount mutable rootfs on top of nullfs. */ 6010 - root.mnt = nullfs_mnt; 6011 - root.dentry = nullfs_mnt->mnt_root; 6018 + /* Mount mutable rootfs on top of nullfs. */ 6019 + root.mnt = nullfs_mnt; 6020 + root.dentry = nullfs_mnt->mnt_root; 6012 6021 6013 - LOCK_MOUNT_EXACT(mp, &root); 6014 - if (unlikely(IS_ERR(mp.parent))) 6015 - panic("VFS: Failed to mount rootfs on nullfs"); 6016 - scoped_guard(mount_writer) 6017 - attach_mnt(real_mount(mnt), mp.parent, mp.mp); 6022 + LOCK_MOUNT_EXACT(mp, &root); 6023 + if (unlikely(IS_ERR(mp.parent))) 6024 + panic("VFS: Failed to mount rootfs on nullfs"); 6025 + scoped_guard(mount_writer) 6026 + attach_mnt(real_mount(mnt), mp.parent, mp.mp); 6018 6027 6019 - pr_info("VFS: Finished mounting rootfs on nullfs\n"); 6020 - } else { 6021 - VFS_WARN_ON_ONCE(real_mount(mnt)->mnt_id != 1); 6022 - 6023 - /* The namespace root is the mutable rootfs. */ 6024 - mnt_root = real_mount(mnt); 6025 - init_mnt_ns.root = mnt_root; 6026 - } 6028 + pr_info("VFS: Finished mounting rootfs on nullfs\n"); 6027 6029 6028 6030 /* 6029 6031 * We've dropped all locks here but that's fine. Not just are we
+7 -13
init/do_mounts.c
··· 493 493 out: 494 494 devtmpfs_mount(); 495 495 496 - if (nullfs_rootfs) { 497 - if (init_pivot_root(".", ".")) { 498 - pr_err("VFS: Failed to pivot into new rootfs\n"); 499 - return; 500 - } 501 - if (init_umount(".", MNT_DETACH)) { 502 - pr_err("VFS: Failed to unmount old rootfs\n"); 503 - return; 504 - } 505 - pr_info("VFS: Pivoted into new rootfs\n"); 496 + if (init_pivot_root(".", ".")) { 497 + pr_err("VFS: Failed to pivot into new rootfs\n"); 506 498 return; 507 499 } 508 - 509 - init_mount(".", "/", NULL, MS_MOVE, NULL); 510 - init_chroot("."); 500 + if (init_umount(".", MNT_DETACH)) { 501 + pr_err("VFS: Failed to unmount old rootfs\n"); 502 + return; 503 + } 504 + pr_info("VFS: Pivoted into new rootfs\n"); 511 505 } 512 506 513 507 static bool is_tmpfs;
-1
init/do_mounts.h
··· 15 15 void mount_root_generic(char *name, char *pretty_name, int flags); 16 16 void mount_root(char *root_device_name); 17 17 extern int root_mountflags; 18 - extern bool nullfs_rootfs; 19 18 20 19 static inline __init int create_dev(char *name, dev_t dev) 21 20 {