]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fstab-generator: add rd.systemd.mount-extra= and friends
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 25 Jul 2023 19:17:27 +0000 (04:17 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 26 Jul 2023 15:50:01 +0000 (00:50 +0900)
Previously, mounts specified in systemd.mount-extra= are equally handled
both in initrd and the main system. So, the mounts for the main system
are also mounted in initrd.

This introduces rd.systemd.mount-extra=, which specifies mounts in initrd.
Then, mounts specified in systemd.mount-extra= are still mounted both in
initrd and the main system, but prefixed with /sysroot/ when running in
initrd.

Fixes #28516.

man/systemd-fstab-generator.xml
src/fstab-generator/fstab-generator.c
test/test-fstab-generator/test-19-mounts-from-cmdline.input
test/test-fstab-generator/test-20-swap-from-cmdline.input

index 46f2390234913af2ac5fc6367c9220ab4f243e5e..9173970bf7d708c201cf1f2edb1968d67ee84db2 100644 (file)
 
       <varlistentry>
         <term><varname>systemd.mount-extra=<replaceable>WHAT</replaceable>:<replaceable>WHERE</replaceable>[:<replaceable>FSTYPE</replaceable>[:<replaceable>OPTIONS</replaceable>]]</varname></term>
+        <term><varname>rd.systemd.mount-extra=<replaceable>WHAT</replaceable>:<replaceable>WHERE</replaceable>[:<replaceable>FSTYPE</replaceable>[:<replaceable>OPTIONS</replaceable>]]</varname></term>
 
         <listitem>
           <para>Specifies the mount unit. Takes at least two and at most four fields separated with a colon
           (<literal>:</literal>). Each field is handled as the corresponding fstab field. This option can be
-          specified multiple times.</para>
+          specified multiple times. <varname>rd.systemd.mount-extra=</varname> is honored only in the initrd,
+          while <varname>systemd.mount-extra=</varname> is honored by both the main system and the initrd.
+          In the initrd, the mount point (and also source path if the mount is bind mount) specified in
+          <varname>systemd.mount-extra=</varname> is prefixed with <filename>/sysroot/</filename>.</para>
           <para>Example:
           <programlisting>
 systemd.mount-extra=/dev/sda1:/mount-point:ext4:rw,noatime</programlisting>
@@ -256,10 +260,13 @@ systemd.mount-extra=/dev/sda1:/mount-point:ext4:rw,noatime</programlisting>
 
       <varlistentry>
         <term><varname>systemd.swap-extra=<replaceable>WHAT</replaceable>[:<replaceable>OPTIONS</replaceable>]</varname></term>
+        <term><varname>rd.systemd.swap-extra=<replaceable>WHAT</replaceable>[:<replaceable>OPTIONS</replaceable>]</varname></term>
 
         <listitem>
           <para>Specifies the swap unit. Takes the block device to be used as a swap device, and optionally
-          takes mount options followed by a colon (<literal>:</literal>).</para>
+          takes mount options followed by a colon (<literal>:</literal>). This option can be specified
+          multiple times. <varname>rd.systemd.swap-extra=</varname> is honored only in the initrd, while
+          <varname>systemd.swap-extra=</varname> is honored by both the main system and the initrd.</para>
           <para>Example:
           <programlisting>
 systemd.swap=/dev/sda2:x-systemd.makefs</programlisting>
index 218c13ad0c9272e662886484d5506b334619bff1..4bb727c0bbe961b3627b07343ef63904da978d5c 100644 (file)
@@ -49,6 +49,7 @@ typedef enum MountPointFlags {
 } MountPointFlags;
 
 typedef struct Mount {
+        bool for_initrd;
         char *what;
         char *where;
         char *fstype;
@@ -102,7 +103,13 @@ static void mount_array_free(Mount *mounts, size_t n) {
         free(mounts);
 }
 
-static int mount_array_add_internal(char *in_what, char *in_where, const char *in_fstype, const char *in_options) {
+static int mount_array_add_internal(
+                bool for_initrd,
+                char *in_what,
+                char *in_where,
+                const char *in_fstype,
+                const char *in_options) {
+
         _cleanup_free_ char *what = NULL, *where = NULL, *fstype = NULL, *options = NULL;
         int r;
 
@@ -135,6 +142,7 @@ static int mount_array_add_internal(char *in_what, char *in_where, const char *i
                 return -ENOMEM;
 
         arg_mounts[arg_n_mounts++] = (Mount) {
+                .for_initrd = for_initrd,
                 .what = TAKE_PTR(what),
                 .where = TAKE_PTR(where),
                 .fstype = TAKE_PTR(fstype),
@@ -144,7 +152,7 @@ static int mount_array_add_internal(char *in_what, char *in_where, const char *i
         return 0;
 }
 
-static int mount_array_add(const char *str) {
+static int mount_array_add(bool for_initrd, const char *str) {
         _cleanup_free_ char *what = NULL, *where = NULL, *fstype = NULL, *options = NULL;
         int r;
 
@@ -159,10 +167,10 @@ static int mount_array_add(const char *str) {
         if (!isempty(str))
                 return -EINVAL;
 
-        return mount_array_add_internal(TAKE_PTR(what), TAKE_PTR(where), fstype, options);
+        return mount_array_add_internal(for_initrd, TAKE_PTR(what), TAKE_PTR(where), fstype, options);
 }
 
-static int mount_array_add_swap(const char *str) {
+static int mount_array_add_swap(bool for_initrd, const char *str) {
         _cleanup_free_ char *what = NULL, *options = NULL;
         int r;
 
@@ -177,7 +185,7 @@ static int mount_array_add_swap(const char *str) {
         if (!isempty(str))
                 return -EINVAL;
 
-        return mount_array_add_internal(TAKE_PTR(what), NULL, "swap", options);
+        return mount_array_add_internal(for_initrd, TAKE_PTR(what), NULL, "swap", options);
 }
 
 static int write_options(FILE *f, const char *options) {
@@ -1282,6 +1290,9 @@ static int add_mounts_from_cmdline(void) {
         /* Handle each entries found in cmdline as a fstab entry. */
 
         FOREACH_ARRAY(m, arg_mounts, arg_n_mounts) {
+                if (m->for_initrd && !in_initrd())
+                        continue;
+
                 r = parse_fstab_one(
                               "/proc/cmdline",
                               m->what,
@@ -1289,7 +1300,7 @@ static int add_mounts_from_cmdline(void) {
                               m->fstype,
                               m->options,
                               /* passno = */ 0,
-                              /* prefix_sysroot = */ false,
+                              /* prefix_sysroot = */ !m->for_initrd && in_initrd(),
                               /* use_swap_enabled = */ false);
                 if (r < 0 && ret >= 0)
                         ret = r;
@@ -1437,21 +1448,21 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                 else
                         arg_verity = r;
 
-        } else if (streq(key, "systemd.mount-extra")) {
+        } else if (STR_IN_SET(key, "systemd.mount-extra", "rd.systemd.mount-extra")) {
 
                 if (proc_cmdline_value_missing(key, value))
                         return 0;
 
-                r = mount_array_add(value);
+                r = mount_array_add(startswith(key, "rd."), value);
                 if (r < 0)
                         log_warning("Failed to parse systemd.mount-extra= option, ignoring: %s", value);
 
-        } else if (streq(key, "systemd.swap-extra")) {
+        } else if (STR_IN_SET(key, "systemd.swap-extra", "rd.systemd.swap-extra")) {
 
                 if (proc_cmdline_value_missing(key, value))
                         return 0;
 
-                r = mount_array_add_swap(value);
+                r = mount_array_add_swap(startswith(key, "rd."), value);
                 if (r < 0)
                         log_warning("Failed to parse systemd.swap-extra= option, ignoring: %s", value);
         }
index 4312d01e529670ae8ba64e1dc078f36b12cf3ea7..f2cc6fc075ae92c96618a80cc6baaaec405e927d 100644 (file)
@@ -1,5 +1,5 @@
-systemd.mount-extra=/dev/sdx1:/sysroot:auto:defaults
-systemd.mount-extra=/dev/sdx2:/hoge/without_options:auto
-systemd.mount-extra=/dev/sdx3:/hoge/without_fstype
-systemd.mount-extra=/dev/sdx4
-systemd.mount-extra=//foo\ufffebar:/hoge/with\x20space:cifs:rw,seclabel
+rd.systemd.mount-extra=/dev/sdx1:/sysroot:auto:defaults
+rd.systemd.mount-extra=/dev/sdx2:/hoge/without_options:auto
+rd.systemd.mount-extra=/dev/sdx3:/hoge/without_fstype
+rd.systemd.mount-extra=/dev/sdx4
+rd.systemd.mount-extra=//foo\ufffebar:/hoge/with\x20space:cifs:rw,seclabel
index 953c09ff104a2d410777dbe144d14e1df415e59e..d92c5300e2d9597cb7b14f941f23edd3ed450f17 100644 (file)
@@ -1,4 +1,4 @@
-systemd.mount-extra=/dev/sdy1:none:swap
-systemd.mount-extra=/dev/sdy2:none:swap:x-systemd.makefs
-systemd.swap-extra=/dev/sdy3:x-systemd.makefs,nofail
-systemd.swap-extra=/dev/sdy4
+rd.systemd.mount-extra=/dev/sdy1:none:swap
+rd.systemd.mount-extra=/dev/sdy2:none:swap:x-systemd.makefs
+rd.systemd.swap-extra=/dev/sdy3:x-systemd.makefs,nofail
+rd.systemd.swap-extra=/dev/sdy4