From 39a4c452d2ab1de2779061f2a81c7b5ff59addd0 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Fri, 1 Dec 2023 19:32:45 +0800 Subject: [PATCH] fstab-generator: disable default deps if x-systemd.{wanted,required}-by= is used Fixes #30273 --- man/systemd.mount.xml | 32 +++++---- src/fstab-generator/fstab-generator.c | 69 ++++++++++++------- .../mnt-wantedby-automount.automount | 1 + .../mnt-requiredby.mount | 4 +- .../mnt-wantedby-automount.automount | 8 +++ .../mnt-wantedby-automount.mount | 14 ++++ .../mnt-wantedby.mount | 4 +- .../mnt-wantedby-automount.automount | 1 + .../mnt-requiredby.mount | 4 +- .../mnt-wantedby-automount.automount | 8 +++ .../mnt-wantedby-automount.mount | 14 ++++ .../mnt-wantedby.mount | 4 +- .../test-18-options.fstab.input | 33 ++++----- 13 files changed, 136 insertions(+), 60 deletions(-) create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.wants/mnt-wantedby-automount.automount create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.automount create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.mount create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby-automount.automount create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.automount create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.mount diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index 8b7f5be8c46..b8d4f372810 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -134,15 +134,17 @@ Mount units referring to local file systems automatically gain an After= dependency on local-fs-pre.target, and a - Before= dependency on local-fs.target unless - mount option is set. + Before= dependency on local-fs.target unless one or more + mount options among , , + and is set. See below for detailed information. + - Network mount units - automatically acquire After= dependencies on remote-fs-pre.target, - network.target and network-online.target, and gain a - Before= dependency on remote-fs.target unless - mount option is set. Towards the latter a - Wants= unit is added as well. + Network mount units automatically acquire After= dependencies on + remote-fs-pre.target, network.target, + plus After= and Wants= dependencies on network-online.target, + and a Before= dependency on remote-fs.target, unless + one or more mount options among , , + and is set. Mount units referring to local and network file systems are distinguished by their file system type @@ -240,13 +242,13 @@ - In the created mount unit, configures a - WantedBy= or RequiredBy= - 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., - local-fs.target, are not automatically - created. See WantedBy= and RequiredBy= in + In the created mount unit, configures a WantedBy= or + RequiredBy= dependency on another unit. This option may be specified more than once. + If this is specified, the default dependencies (see above) other than umount.target + on the created mount unit, e.g. local-fs.target, are not automatically created. + Hence it is likely that some ordering dependencies need to be set up manually through + and . See WantedBy= + and RequiredBy= in systemd.unit5 for details. diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index fd1a78aed2f..3c0b597470a 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -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 index 00000000000..14fd3956729 --- /dev/null +++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.wants/mnt-wantedby-automount.automount @@ -0,0 +1 @@ +../mnt-wantedby-automount.automount \ No newline at end of file diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requiredby.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requiredby.mount index 5edc4ddf223..96fd67261f5 100644 --- a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requiredby.mount +++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requiredby.mount @@ -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 index 00000000000..b9f2d285ef6 --- /dev/null +++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.automount @@ -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 index 00000000000..d9094767f22 --- /dev/null +++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby-automount.mount @@ -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 diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby.mount index e12df820d45..ff76a6f9b49 100644 --- a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby.mount +++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby.mount @@ -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 index 00000000000..14fd3956729 --- /dev/null +++ b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby-automount.automount @@ -0,0 +1 @@ +../mnt-wantedby-automount.automount \ No newline at end of file diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount index 5edc4ddf223..96fd67261f5 100644 --- a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount +++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount @@ -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 index 00000000000..b9f2d285ef6 --- /dev/null +++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.automount @@ -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 index 00000000000..d9094767f22 --- /dev/null +++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby-automount.mount @@ -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 diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount index e12df820d45..ff76a6f9b49 100644 --- a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount +++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount @@ -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.input b/test/test-fstab-generator/test-18-options.fstab.input index 98ef0b9fba6..2112d68828b 100644 --- a/test/test-fstab-generator/test-18-options.fstab.input +++ b/test/test-fstab-generator/test-18-options.fstab.input @@ -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