Skip to content

Commit 313c47f

Browse files
committed
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>
1 parent 7416634 commit 313c47f

File tree

4 files changed

+32
-77
lines changed

4 files changed

+32
-77
lines changed

Documentation/filesystems/ramfs-rootfs-initramfs.rst

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,8 @@ What is rootfs?
7676
---------------
7777

7878
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
8681
(tmpfs/ramfs) mounted on top of it. This allows pivot_root() and unmounting
8782
of the initramfs to work normally.
8883

@@ -126,25 +121,14 @@ All this differs from the old initrd in several ways:
126121
program. See the switch_root utility, below.)
127122

128123
- When switching another root device, initrd would pivot_root and then
129-
umount the ramdisk. Traditionally, initramfs is rootfs: you can neither
130-
pivot_root rootfs, nor unmount it. Instead delete everything out of
131-
rootfs to free up the space (find -xdev / -exec rm '{}' ';'), overmount
132-
rootfs with the new root (cd /newmount; mount --move . /; chroot .),
133-
attach stdin/stdout/stderr to the new /dev/console, and exec the new init.
134-
135-
Since this is a remarkably persnickety process (and involves deleting
136-
commands before you can run them), the klibc package introduced a helper
137-
program (utils/run_init.c) to do all this for you. Most other packages
138-
(such as busybox) have named this command "switch_root".
139-
140-
However, if the kernel is booted with "nullfs_rootfs", pivot_root() works
124+
umount the ramdisk. With nullfs as the true root, pivot_root() works
141125
normally from the initramfs. Userspace can simply do::
142126

143127
chdir(new_root);
144128
pivot_root(".", ".");
145129
umount2(".", MNT_DETACH);
146130

147-
This is the preferred method when nullfs_rootfs is enabled.
131+
This is the preferred method for switching root filesystems.
148132

149133
Populating initramfs:
150134
---------------------

fs/namespace.c

Lines changed: 21 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,6 @@ static int __init initramfs_options_setup(char *str)
7575

7676
__setup("initramfs_options=", initramfs_options_setup);
7777

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-
8978
static u64 event;
9079
static DEFINE_XARRAY_FLAGS(mnt_id_xa, XA_FLAGS_ALLOC);
9180
static DEFINE_IDA(mnt_group_ida);
@@ -4593,10 +4582,9 @@ int path_pivot_root(struct path *new, struct path *old)
45934582
* pointed to by put_old must yield the same directory as new_root. No other
45944583
* file system may be mounted on put_old. After all, new_root is a mountpoint.
45954584
*
4596-
* Also, the current root cannot be on the 'rootfs' (initial ramfs) filesystem
4597-
* unless the kernel was booted with "nullfs_rootfs". See
4598-
* Documentation/filesystems/ramfs-rootfs-initramfs.rst for alternatives
4599-
* in this situation.
4585+
* The immutable nullfs filesystem is mounted as the true root of the VFS
4586+
* hierarchy. The mutable rootfs (tmpfs/ramfs) is layered on top of this,
4587+
* allowing pivot_root() to work normally from initramfs.
46004588
*
46014589
* Notes:
46024590
* - we don't move root/cwd if they are not at the root (reason: if something
@@ -5993,49 +5981,39 @@ static void __init init_mount_tree(void)
59935981
struct path root;
59945982

59955983
/*
5996-
* When nullfs is used, we create two mounts:
5984+
* We create two mounts:
59975985
*
59985986
* (1) nullfs with mount id 1
59995987
* (2) mutable rootfs with mount id 2
60005988
*
60015989
* with (2) mounted on top of (1).
60025990
*/
6003-
if (nullfs_rootfs) {
6004-
nullfs_mnt = vfs_kern_mount(&nullfs_fs_type, 0, "nullfs", NULL);
6005-
if (IS_ERR(nullfs_mnt))
6006-
panic("VFS: Failed to create nullfs");
6007-
}
5991+
nullfs_mnt = vfs_kern_mount(&nullfs_fs_type, 0, "nullfs", NULL);
5992+
if (IS_ERR(nullfs_mnt))
5993+
panic("VFS: Failed to create nullfs");
60085994

60095995
mnt = vfs_kern_mount(&rootfs_fs_type, 0, "rootfs", initramfs_options);
60105996
if (IS_ERR(mnt))
60115997
panic("Can't create rootfs");
60125998

6013-
if (nullfs_rootfs) {
6014-
VFS_WARN_ON_ONCE(real_mount(nullfs_mnt)->mnt_id != 1);
6015-
VFS_WARN_ON_ONCE(real_mount(mnt)->mnt_id != 2);
5999+
VFS_WARN_ON_ONCE(real_mount(nullfs_mnt)->mnt_id != 1);
6000+
VFS_WARN_ON_ONCE(real_mount(mnt)->mnt_id != 2);
60166001

6017-
/* The namespace root is the nullfs mnt. */
6018-
mnt_root = real_mount(nullfs_mnt);
6019-
init_mnt_ns.root = mnt_root;
6002+
/* The namespace root is the nullfs mnt. */
6003+
mnt_root = real_mount(nullfs_mnt);
6004+
init_mnt_ns.root = mnt_root;
60206005

6021-
/* Mount mutable rootfs on top of nullfs. */
6022-
root.mnt = nullfs_mnt;
6023-
root.dentry = nullfs_mnt->mnt_root;
6006+
/* Mount mutable rootfs on top of nullfs. */
6007+
root.mnt = nullfs_mnt;
6008+
root.dentry = nullfs_mnt->mnt_root;
60246009

6025-
LOCK_MOUNT_EXACT(mp, &root);
6026-
if (unlikely(IS_ERR(mp.parent)))
6027-
panic("VFS: Failed to mount rootfs on nullfs");
6028-
scoped_guard(mount_writer)
6029-
attach_mnt(real_mount(mnt), mp.parent, mp.mp);
6010+
LOCK_MOUNT_EXACT(mp, &root);
6011+
if (unlikely(IS_ERR(mp.parent)))
6012+
panic("VFS: Failed to mount rootfs on nullfs");
6013+
scoped_guard(mount_writer)
6014+
attach_mnt(real_mount(mnt), mp.parent, mp.mp);
60306015

6031-
pr_info("VFS: Finished mounting rootfs on nullfs\n");
6032-
} else {
6033-
VFS_WARN_ON_ONCE(real_mount(mnt)->mnt_id != 1);
6034-
6035-
/* The namespace root is the mutable rootfs. */
6036-
mnt_root = real_mount(mnt);
6037-
init_mnt_ns.root = mnt_root;
6038-
}
6016+
pr_info("VFS: Finished mounting rootfs on nullfs\n");
60396017

60406018
/*
60416019
* We've dropped all locks here but that's fine. Not just are we

init/do_mounts.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -493,21 +493,15 @@ void __init prepare_namespace(void)
493493
out:
494494
devtmpfs_mount();
495495

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");
506498
return;
507499
}
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");
511505
}
512506

513507
static bool is_tmpfs;

init/do_mounts.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
void mount_root_generic(char *name, char *pretty_name, int flags);
1616
void mount_root(char *root_device_name);
1717
extern int root_mountflags;
18-
extern bool nullfs_rootfs;
1918

2019
static inline __init int create_dev(char *name, dev_t dev)
2120
{

0 commit comments

Comments
 (0)