]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fstab-generator: add a flag to accept entry for "/" in initrd
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 26 Jul 2023 00:39:23 +0000 (09:39 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 26 Jul 2023 15:50:15 +0000 (00:50 +0900)
When both prefix_sysroot and accept_root is true, the entry for "/" will
be accepted and converted to "/sysroot/".

Why? If the entry is read from the main system's fstab, then we already
mounted /sysroot/, hence it is not and should not re-add the .mount unit
for /sysroot/. However, if we want to specify the root mount through the
kernel command line or credential, without this change, we need to
specify the same entry in the two options. E.g.
===
systemd.mount-extra=/dev/sda1:/:auto:defaults
rd.systemd.mount-extra=/dev/sda1:/sysroot:auto:defaults
===
That's inconvenient. Of course, we can dedup that by using traditional
options, but cannot when defined in credential.

src/fstab-generator/fstab-generator.c

index e414529ed8664b66c898a655c782967c5f6bfb6d..103c55c7c758436a1036b3bdcea659c76e82e1e2 100644 (file)
@@ -314,9 +314,9 @@ static bool mount_is_network(const char *fstype, const char *options) {
                 (fstype && fstype_is_network(fstype));
 }
 
-static bool mount_in_initrd(const char *where, const char *options) {
+static bool mount_in_initrd(const char *where, const char *options, bool accept_root) {
         return fstab_test_option(options, "x-initrd.mount\0") ||
-                (where && path_equal(where, "/usr"));
+                (where && PATH_IN_SET(where, "/usr", accept_root ? "/" : NULL));
 }
 
 static int write_timeout(
@@ -851,6 +851,7 @@ static int parse_fstab_one(
                 const char *options,
                 int passno,
                 bool prefix_sysroot,
+                bool accept_root, /* This takes an effect only when prefix_sysroot is true. */
                 bool use_swap_enabled) {
 
         _cleanup_free_ char *what = NULL, *where = NULL;
@@ -862,7 +863,7 @@ static int parse_fstab_one(
         assert(fstype);
         assert(options);
 
-        if (prefix_sysroot && !mount_in_initrd(where_original, options))
+        if (prefix_sysroot && !mount_in_initrd(where_original, options, accept_root))
                 return 0;
 
         is_swap = streq_ptr(fstype, "swap");
@@ -982,7 +983,9 @@ static int parse_fstab(bool prefix_sysroot) {
         while ((me = getmntent(f))) {
                 r = parse_fstab_one(fstab,
                                     me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno,
-                                    prefix_sysroot, /* use_swap_enabled = */ true);
+                                    prefix_sysroot,
+                                    /* accept_root = */ false,
+                                    /* use_swap_enabled = */ true);
                 if (r < 0 && ret >= 0)
                         ret = r;
                 if (arg_sysroot_check && r > 0)
@@ -1301,6 +1304,7 @@ static int add_mounts_from_cmdline(void) {
                               m->options,
                               /* passno = */ 0,
                               /* prefix_sysroot = */ !m->for_initrd && in_initrd(),
+                              /* accept_root = */ true,
                               /* use_swap_enabled = */ false);
                 if (r < 0 && ret >= 0)
                         ret = r;
@@ -1337,6 +1341,7 @@ static int add_mounts_from_creds(bool prefix_sysroot) {
                                 me->mnt_opts,
                                 me->mnt_passno,
                                 /* prefix_sysroot = */ prefix_sysroot,
+                                /* accept_root = */ true,
                                 /* use_swap_enabled = */ true);
                 if (r < 0 && ret >= 0)
                         ret = r;