]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fstab-generator: drop unapplicable mount options for / from mount unit Options= 29734/head
authorMike Yuan <me@yhndnzj.com>
Thu, 26 Oct 2023 17:29:02 +0000 (01:29 +0800)
committerMike Yuan <me@yhndnzj.com>
Fri, 27 Oct 2023 15:51:01 +0000 (23:51 +0800)
Prompted by #29705

Note that x-systemd.wanted-by= and x-systemd.required-by= are not
dropped, since we ignore them because they are unnecessary rather
than unapplicable.

src/fstab-generator/fstab-generator.c
test/units/generator-utils.sh
test/units/testsuite-81.fstab-generator.sh

index d14dcba8a3fbea76ebc4e39d64fe9e108ad5bd95..016f3baa7f849fe566763ba0e2c83c696601a647 100644 (file)
@@ -466,6 +466,42 @@ static int write_extra_dependencies(FILE *f, const char *opts) {
         return 0;
 }
 
+static int mandatory_mount_drop_unapplicable_options(
+                MountPointFlags *flags,
+                const char *where,
+                const char *options,
+                char **ret_options) {
+
+        int r;
+
+        assert(flags);
+        assert(where);
+        assert(options);
+        assert(ret_options);
+
+        if (!(*flags & (MOUNT_NOAUTO|MOUNT_NOFAIL|MOUNT_AUTOMOUNT))) {
+                _cleanup_free_ char *opts = NULL;
+
+                opts = strdup(options);
+                if (!opts)
+                        return -ENOMEM;
+
+                *ret_options = TAKE_PTR(opts);
+                return 0;
+        }
+
+        log_debug("Mount '%s' is mandatory, ignoring 'noauto', 'nofail', and 'x-systemd.automount' options.",
+                  where);
+
+        *flags &= ~(MOUNT_NOAUTO|MOUNT_NOFAIL|MOUNT_AUTOMOUNT);
+
+        r = fstab_filter_options(options, "noauto\0nofail\0x-systemd.automount\0", NULL, NULL, NULL, ret_options);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 static int add_mount(
                 const char *source,
                 const char *dest,
@@ -478,11 +514,8 @@ static int add_mount(
                 MountPointFlags flags,
                 const char *target_unit) {
 
-        _cleanup_free_ char
-                *name = NULL,
-                *automount_name = NULL,
-                *filtered = NULL,
-                *where_escaped = NULL;
+        _cleanup_free_ char *name = NULL, *automount_name = NULL, *filtered = NULL, *where_escaped = NULL,
+                *opts_root_filtered = NULL;
         _cleanup_strv_free_ char **wanted_by = NULL, **required_by = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         int r;
@@ -519,20 +552,18 @@ static int add_mount(
                 return r;
 
         if (path_equal(where, "/")) {
-                if (flags & MOUNT_NOAUTO)
-                        log_warning("Ignoring \"noauto\" option for root device");
-                if (flags & MOUNT_NOFAIL)
-                        log_warning("Ignoring \"nofail\" option for root device");
-                if (flags & MOUNT_AUTOMOUNT)
-                        log_warning("Ignoring \"automount\" option for root device");
+                r = mandatory_mount_drop_unapplicable_options(&flags, where, opts, &opts_root_filtered);
+                if (r < 0)
+                        return r;
+                opts = opts_root_filtered;
+
                 if (!strv_isempty(wanted_by))
-                        log_warning("Ignoring \"x-systemd.wanted-by=\" option for root device");
+                        log_debug("Ignoring 'x-systemd.wanted-by=' option for root device.");
                 if (!strv_isempty(required_by))
-                        log_warning("Ignoring \"x-systemd.required-by=\" option for root device");
+                        log_debug("Ignoring 'x-systemd.required-by=' option for root device.");
 
                 required_by = strv_free(required_by);
                 wanted_by = strv_free(wanted_by);
-                SET_FLAG(flags, MOUNT_NOAUTO | MOUNT_NOFAIL | MOUNT_AUTOMOUNT, false);
         }
 
         r = unit_name_from_path(where, ".mount", &name);
@@ -936,14 +967,11 @@ static int parse_fstab_one(
                         mount_is_network(fstype, options) ? SPECIAL_REMOTE_FS_TARGET :
                                                             SPECIAL_LOCAL_FS_TARGET;
 
-        /* nofail or noauto don't make sense for critical filesystems we must mount in initrd. */
-        if ((is_sysroot || is_sysroot_usr) && ((flags & (MOUNT_NOFAIL|MOUNT_NOAUTO)) != 0)) {
-                flags &= ~(MOUNT_NOFAIL|MOUNT_NOAUTO);
-                r = fstab_filter_options(options, "noauto\0nofail\0", NULL, NULL, NULL, &opts);
+        /* nofail, noauto and x-systemd.automount don't make sense for critical filesystems we must mount in initrd. */
+        if (is_sysroot || is_sysroot_usr) {
+                r = mandatory_mount_drop_unapplicable_options(&flags, where, options, &opts);
                 if (r < 0)
                         return r;
-
-                log_debug("'noauto' and 'nofail' options are ignored for /sysroot/ and /sysroot/usr/ mounts.");
                 options = opts;
         }
 
index 42c6a773533460f7846fa9e48a470334e1468953..fb62747fa1f209d167df25350792af32b01fca64 100755 (executable)
@@ -31,15 +31,13 @@ in_container() {
     systemd-detect-virt -qc
 }
 
-# Filter out "unwanted" options, i.e. options that the fstab-generator doesn't
-# propagate to the final mount unit
-opt_filter_consumed() {(
+opt_filter() (
     set +x
     local opt split_options filtered_options
 
     IFS="," read -ra split_options <<< "${1:?}"
     for opt in "${split_options[@]}"; do
-        if [[ "$opt" =~ ^x-systemd.device-timeout= ]]; then
+        if [[ "$opt" =~ ${2:?} ]]; then
             continue
         fi
 
@@ -47,7 +45,7 @@ opt_filter_consumed() {(
     done
 
     IFS=","; printf "%s" "${filtered_options[*]}"
-)}
+)
 
 # Run the given generator $1 with target directory $2 - clean the target
 # directory beforehand
index d772f8de0a400503b600bf256d7d346dd1ed2003..50c4b2f47d4a836b55c773e81c209b7a76a254c0 100755 (executable)
@@ -148,7 +148,12 @@ check_fstab_mount_units() {
         fi
         if [[ -n "$opts" ]] && [[ "$opts" != defaults ]]; then
             # Some options are not propagated to the generated unit
-            filtered_options="$(opt_filter_consumed "$opts")"
+            if [[ "$where" == / ]]; then
+                filtered_options="$(opt_filter "$opts" "(noauto|nofail|x-systemd.(wanted-by=|required-by=|automount|device-timeout=))")"
+            else
+                filtered_options="$(opt_filter "$opts" "^x-systemd.device-timeout=")"
+            fi
+
             if [[ "${filtered_options[*]}" != defaults ]]; then
                 grep -qE "^Options=.*$filtered_options.*$" "$out_dir/$unit"
             fi