1
0
mirror of https://github.com/systemd/systemd.git synced 2025-02-27 01:57:35 +03:00

fstab-generator: drop unapplicable mount options for / from mount unit Options=

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.
This commit is contained in:
Mike Yuan 2023-10-27 01:29:02 +08:00
parent ba2f3ec832
commit b3ee014879
No known key found for this signature in database
GPG Key ID: 417471C0A40F58B3
3 changed files with 57 additions and 26 deletions

View 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;
}

View File

@ -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

View File

@ -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