]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fstab-generator: disable default deps if x-systemd.{wanted,required}-by= is used
authorMike Yuan <me@yhndnzj.com>
Fri, 1 Dec 2023 11:32:45 +0000 (19:32 +0800)
committerMike Yuan <me@yhndnzj.com>
Mon, 11 Dec 2023 16:34:32 +0000 (00:34 +0800)
Fixes #30273

13 files changed:
man/systemd.mount.xml
src/fstab-generator/fstab-generator.c
test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.wants/mnt-wantedby-automount.automount [new symlink]
test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requiredby.mount
test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.automount [new file with mode: 0644]
test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.mount [new file with mode: 0644]
test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby.mount
test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby-automount.automount [new symlink]
test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount
test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.automount [new file with mode: 0644]
test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.mount [new file with mode: 0644]
test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount
test/test-fstab-generator/test-18-options.fstab.input

index 8b7f5be8c46b089bded5fbf5b0c9f4c54ac2ef32..b8d4f372810aa02ae610c867f7460bcc84cab80c 100644 (file)
 
         <listitem><para>Mount units referring to local file systems automatically gain
         an <varname>After=</varname> dependency on <filename>local-fs-pre.target</filename>, and a
-        <varname>Before=</varname> dependency on <filename>local-fs.target</filename> unless
-        <option>nofail</option> mount option is set.</para></listitem>
-
-        <listitem><para>Network mount units
-        automatically acquire <varname>After=</varname> dependencies on <filename>remote-fs-pre.target</filename>,
-        <filename>network.target</filename> and <filename>network-online.target</filename>, and gain a
-        <varname>Before=</varname> dependency on <filename>remote-fs.target</filename> unless
-        <option>nofail</option> mount option is set. Towards the latter a
-        <varname>Wants=</varname> unit is added as well.</para></listitem>
+        <varname>Before=</varname> dependency on <filename>local-fs.target</filename> unless one or more
+        mount options among <option>nofail</option>, <option>x-systemd.wanted-by=</option>,
+        and <option>x-systemd.required-by=</option> is set. See below for detailed information.
+        </para></listitem>
+
+        <listitem><para>Network mount units automatically acquire <varname>After=</varname> dependencies on
+        <filename>remote-fs-pre.target</filename>, <filename>network.target</filename>,
+        plus <varname>After=</varname> and <varname>Wants=</varname> dependencies on <filename>network-online.target</filename>,
+        and a <varname>Before=</varname> dependency on <filename>remote-fs.target</filename>, unless
+        one or more mount options among <option>nofail</option>, <option>x-systemd.wanted-by=</option>,
+        and <option>x-systemd.required-by=</option> is set.</para></listitem>
       </itemizedlist>
 
       <para>Mount units referring to local and network file systems are distinguished by their file system type
         <term><option>x-systemd.wanted-by=</option></term>
         <term><option>x-systemd.required-by=</option></term>
 
-        <listitem><para>In the created mount unit, configures a
-        <varname>WantedBy=</varname> or <varname>RequiredBy=</varname>
-        dependency on another unit.  This option may be
-        specified more than once. If this is specified, the normal
-        automatic dependencies on the created mount unit, e.g.,
-        <filename>local-fs.target</filename>, are not automatically
-        created. See <varname>WantedBy=</varname> and <varname>RequiredBy=</varname> in
+        <listitem><para>In the created mount unit, configures a <varname>WantedBy=</varname> or
+        <varname>RequiredBy=</varname> dependency on another unit. This option may be specified more than once.
+        If this is specified, the default dependencies (see above) other than <filename>umount.target</filename>
+        on the created mount unit, e.g. <filename>local-fs.target</filename>, are not automatically created.
+        Hence it is likely that some ordering dependencies need to be set up manually through
+        <option>x-systemd.before=</option> and <option>x-systemd.after=</option>. See <varname>WantedBy=</varname>
+        and <varname>RequiredBy=</varname> in
         <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         for details.</para>
 
index fd1a78aed2f37847cae190d3603228a78c6730be..3c0b597470a49efe89e216a40286c0a2ad927d14 100644 (file)
@@ -599,13 +599,25 @@ static int add_mount(
                 SET_FLAG(flags, MOUNT_NOFAIL, true);
         }
 
+        if (!strv_isempty(wanted_by) || !strv_isempty(required_by)) {
+                /* If x-systemd.{wanted,required}-by= is specified, target_unit is not used */
+                target_unit = NULL;
+
+                /* Don't set default ordering dependencies on local-fs.target or remote-fs.target, but we
+                 * still need to conflict with umount.target. */
+                fputs("DefaultDependencies=no\n"
+                      "Conflicts=umount.target\n"
+                      "Before=umount.target\n",
+                      f);
+        }
+
         r = write_extra_dependencies(f, opts);
         if (r < 0)
                 return r;
 
         /* Order the mount unit we generate relative to target_unit, so that DefaultDependencies= on the
          * target unit won't affect us. */
-        if (!FLAGS_SET(flags, MOUNT_NOFAIL))
+        if (target_unit && !FLAGS_SET(flags, MOUNT_NOFAIL))
                 fprintf(f, "Before=%s\n", target_unit);
 
         if (passno != 0) {
@@ -696,26 +708,7 @@ static int add_mount(
                 }
         }
 
-        if (!FLAGS_SET(flags, MOUNT_AUTOMOUNT)) {
-                if (!FLAGS_SET(flags, MOUNT_NOAUTO) && strv_isempty(wanted_by) && strv_isempty(required_by)) {
-                        r = generator_add_symlink(dest, target_unit,
-                                                  (flags & MOUNT_NOFAIL) ? "wants" : "requires", name);
-                        if (r < 0)
-                                return r;
-                } else {
-                        STRV_FOREACH(s, wanted_by) {
-                                r = generator_add_symlink(dest, *s, "wants", name);
-                                if (r < 0)
-                                        return r;
-                        }
-
-                        STRV_FOREACH(s, required_by) {
-                                r = generator_add_symlink(dest, *s, "requires", name);
-                                if (r < 0)
-                                        return r;
-                        }
-                }
-        } else {
+        if (FLAGS_SET(flags, MOUNT_AUTOMOUNT)) {
                 r = unit_name_from_path(where, ".automount", &automount_name);
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate unit name: %m");
@@ -745,11 +738,37 @@ static int add_mount(
                 r = fflush_and_check(f);
                 if (r < 0)
                         return log_error_errno(r, "Failed to write unit file %s: %m", automount_name);
+        }
 
-                r = generator_add_symlink(dest, target_unit,
-                                          (flags & MOUNT_NOFAIL) ? "wants" : "requires", automount_name);
-                if (r < 0)
-                        return r;
+        if (target_unit) {
+                assert(strv_isempty(wanted_by));
+                assert(strv_isempty(required_by));
+
+                /* noauto has no effect if x-systemd.automount is used */
+                if (!FLAGS_SET(flags, MOUNT_NOAUTO) || automount_name) {
+                        r = generator_add_symlink(dest, target_unit,
+                                                  FLAGS_SET(flags, MOUNT_NOFAIL) ? "wants" : "requires",
+                                                  automount_name ?: name);
+                        if (r < 0)
+                                return r;
+                }
+        } else {
+                const char *unit_name = automount_name ?: name;
+
+                STRV_FOREACH(s, wanted_by) {
+                        r = generator_add_symlink(dest, *s, "wants", unit_name);
+                        if (r < 0)
+                                return r;
+                }
+
+                STRV_FOREACH(s, required_by) {
+                        r = generator_add_symlink(dest, *s, "requires", unit_name);
+                        if (r < 0)
+                                return r;
+                }
+
+                if ((flags & (MOUNT_NOAUTO|MOUNT_NOFAIL)) != 0)
+                        log_warning("x-systemd.wanted-by= and/or x-systemd.required-by= specified, 'noauto' and 'nofail' have no effect.");
         }
 
         return true;
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.wants/mnt-wantedby-automount.automount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.wants/mnt-wantedby-automount.automount
new file mode 120000 (symlink)
index 0000000..14fd395
--- /dev/null
@@ -0,0 +1 @@
+../mnt-wantedby-automount.automount
\ No newline at end of file
index 5edc4ddf22388269bfa3e0b6ecb3eee4626f1119..96fd67261f54af27831c2687cb4eefd0f24d2dec 100644 (file)
@@ -3,7 +3,9 @@
 [Unit]
 Documentation=man:fstab(5) man:systemd-fstab-generator(8)
 SourcePath=/etc/fstab
-Before=local-fs.target
+DefaultDependencies=no
+Conflicts=umount.target
+Before=umount.target
 After=blockdev@dev-sdx8.target
 
 [Mount]
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.automount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.automount
new file mode 100644 (file)
index 0000000..b9f2d28
--- /dev/null
@@ -0,0 +1,8 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+SourcePath=/etc/fstab
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+
+[Automount]
+Where=/mnt/wantedby-automount
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.mount
new file mode 100644 (file)
index 0000000..d909476
--- /dev/null
@@ -0,0 +1,14 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+DefaultDependencies=no
+Conflicts=umount.target
+Before=umount.target
+After=blockdev@dev-sdx17.target
+
+[Mount]
+What=/dev/sdx17
+Where=/mnt/wantedby
+Options=x-systemd.wanted-by=foo.service,x-systemd.automount
index e12df820d45db488a41cf2f5b8af7e2d1e07180c..ff76a6f9b49ecd187853c92b72a5a21c327d3f6a 100644 (file)
@@ -3,7 +3,9 @@
 [Unit]
 Documentation=man:fstab(5) man:systemd-fstab-generator(8)
 SourcePath=/etc/fstab
-Before=local-fs.target
+DefaultDependencies=no
+Conflicts=umount.target
+Before=umount.target
 After=blockdev@dev-sdx7.target
 
 [Mount]
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby-automount.automount b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby-automount.automount
new file mode 120000 (symlink)
index 0000000..14fd395
--- /dev/null
@@ -0,0 +1 @@
+../mnt-wantedby-automount.automount
\ No newline at end of file
index 5edc4ddf22388269bfa3e0b6ecb3eee4626f1119..96fd67261f54af27831c2687cb4eefd0f24d2dec 100644 (file)
@@ -3,7 +3,9 @@
 [Unit]
 Documentation=man:fstab(5) man:systemd-fstab-generator(8)
 SourcePath=/etc/fstab
-Before=local-fs.target
+DefaultDependencies=no
+Conflicts=umount.target
+Before=umount.target
 After=blockdev@dev-sdx8.target
 
 [Mount]
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.automount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.automount
new file mode 100644 (file)
index 0000000..b9f2d28
--- /dev/null
@@ -0,0 +1,8 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+SourcePath=/etc/fstab
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+
+[Automount]
+Where=/mnt/wantedby-automount
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.mount
new file mode 100644 (file)
index 0000000..d909476
--- /dev/null
@@ -0,0 +1,14 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+DefaultDependencies=no
+Conflicts=umount.target
+Before=umount.target
+After=blockdev@dev-sdx17.target
+
+[Mount]
+What=/dev/sdx17
+Where=/mnt/wantedby
+Options=x-systemd.wanted-by=foo.service,x-systemd.automount
index e12df820d45db488a41cf2f5b8af7e2d1e07180c..ff76a6f9b49ecd187853c92b72a5a21c327d3f6a 100644 (file)
@@ -3,7 +3,9 @@
 [Unit]
 Documentation=man:fstab(5) man:systemd-fstab-generator(8)
 SourcePath=/etc/fstab
-Before=local-fs.target
+DefaultDependencies=no
+Conflicts=umount.target
+Before=umount.target
 After=blockdev@dev-sdx7.target
 
 [Mount]
index 98ef0b9fba6deb32600e7d04118a0ee54ae64a8b..2112d68828b02add5300f44f9102b094e0c6670c 100644 (file)
@@ -1,16 +1,17 @@
-/dev/sdx1  /sysroot        auto defaults                                       0 1
-/dev/sdx2  /mnt/timeout    auto x-systemd.mount-timeout=10m                    0 0
-/dev/sdx3  /mnt/after      auto x-systemd.after=foo.service                    0 0
-/dev/sdx4  /mnt/before     auto x-systemd.before=foo.service                   0 0
-/dev/sdx5  /mnt/requires   auto x-systemd.requires=foo.service                 0 0
-/dev/sdx6  /mnt/reqmounts  auto x-systemd.requires-mounts-for=/hoge            0 0
-/dev/sdx7  /mnt/wantedby   auto x-systemd.wanted-by=foo.service                0 0
-/dev/sdx8  /mnt/requiredby auto x-systemd.required-by=foo.service              0 0
-/dev/sdx9  /mnt/automount1 auto x-systemd.automount,x-systemd.idle-timeout=30m 0 0
-/dev/sdx10 /mnt/automount2 auto x-systemd.automount,nofail                     0 0
-/dev/sdx11 /mnt/rwonly     auto x-systemd.rw-only                              0 0
-/dev/sdx12 /mnt/mkfs       ext4 x-systemd.makefs                               0 0
-/dev/sdx13 /mnt/growfs     auto x-systemd.growfs                               0 0
-/dev/sdx14 /mnt/pcrfs      auto x-systemd.pcrfs                                0 0
-/dev/sdx15 /mnt/noauto     auto noauto                                         0 0
-/dev/sdx16 /mnt/nofail     auto nofail                                         0 0
+/dev/sdx1  /sysroot                auto defaults                                            0 1
+/dev/sdx2  /mnt/timeout            auto x-systemd.mount-timeout=10m                         0 0
+/dev/sdx3  /mnt/after              auto x-systemd.after=foo.service                         0 0
+/dev/sdx4  /mnt/before             auto x-systemd.before=foo.service                        0 0
+/dev/sdx5  /mnt/requires           auto x-systemd.requires=foo.service                      0 0
+/dev/sdx6  /mnt/reqmounts          auto x-systemd.requires-mounts-for=/hoge                 0 0
+/dev/sdx7  /mnt/wantedby           auto x-systemd.wanted-by=foo.service                     0 0
+/dev/sdx8  /mnt/requiredby         auto x-systemd.required-by=foo.service                   0 0
+/dev/sdx9  /mnt/automount1         auto x-systemd.automount,x-systemd.idle-timeout=30m      0 0
+/dev/sdx10 /mnt/automount2         auto x-systemd.automount,nofail                          0 0
+/dev/sdx11 /mnt/rwonly             auto x-systemd.rw-only                                   0 0
+/dev/sdx12 /mnt/mkfs               ext4 x-systemd.makefs                                    0 0
+/dev/sdx13 /mnt/growfs             auto x-systemd.growfs                                    0 0
+/dev/sdx14 /mnt/pcrfs              auto x-systemd.pcrfs                                     0 0
+/dev/sdx15 /mnt/noauto             auto noauto                                              0 0
+/dev/sdx16 /mnt/nofail             auto nofail                                              0 0
+/dev/sdx17 /mnt/wantedby-automount auto x-systemd.wanted-by=foo.service,x-systemd.automount 0 0