1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-09 01:18:19 +03:00

Merge pull request #31048 from YHNdnzj/fstab-modernization

fstab-util/generator: a few cleanups/improvements
This commit is contained in:
Daan De Meyer 2024-01-26 09:01:19 +01:00 committed by GitHub
commit 329288613c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 167 additions and 164 deletions

View File

@ -1327,33 +1327,31 @@ int read_timestamp_file(const char *fn, usec_t *ret) {
return 0; return 0;
} }
int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) { int fputs_with_separator(FILE *f, const char *s, const char *separator, bool *space) {
int r;
assert(s); assert(s);
assert(space);
/* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter /* Outputs the specified string with fputs(), but optionally prefixes it with a separator.
* when specified shall initially point to a boolean variable initialized to false. It is set to true after the * The *space parameter when specified shall initially point to a boolean variable initialized
* first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each * to false. It is set to true after the first invocation. This call is supposed to be use in loops,
* element, but not before the first one. */ * where a separator shall be inserted between each element, but not before the first one. */
if (!f) if (!f)
f = stdout; f = stdout;
if (space) { if (!separator)
if (!separator) separator = " ";
separator = " ";
if (*space) { if (*space)
r = fputs(separator, f); if (fputs(separator, f) < 0)
if (r < 0) return -EIO;
return r;
}
*space = true; *space = true;
}
return fputs(s, f); if (fputs(s, f) < 0)
return -EIO;
return 0;
} }
/* A bitmask of the EOL markers we know */ /* A bitmask of the EOL markers we know */

View File

@ -143,7 +143,7 @@ int fflush_sync_and_check(FILE *f);
int write_timestamp_file_atomic(const char *fn, usec_t n); int write_timestamp_file_atomic(const char *fn, usec_t n);
int read_timestamp_file(const char *fn, usec_t *ret); int read_timestamp_file(const char *fn, usec_t *ret);
int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space); int fputs_with_separator(FILE *f, const char *s, const char *separator, bool *space);
typedef enum ReadLineFlags { typedef enum ReadLineFlags {
READ_LINE_ONLY_NUL = 1 << 0, READ_LINE_ONLY_NUL = 1 << 0,

View File

@ -91,13 +91,16 @@ void ordered_set_print(FILE *f, const char *field, OrderedSet *s) {
bool space = false; bool space = false;
char *p; char *p;
assert(f);
assert(field);
if (ordered_set_isempty(s)) if (ordered_set_isempty(s))
return; return;
fputs(field, f); fputs(field, f);
ORDERED_SET_FOREACH(p, s) ORDERED_SET_FOREACH(p, s)
fputs_with_space(f, p, NULL, &space); fputs_with_separator(f, p, NULL, &space);
fputc('\n', f); fputc('\n', f);
} }

View File

@ -894,13 +894,15 @@ int fputstrv(FILE *f, char * const *l, const char *separator, bool *space) {
bool b = false; bool b = false;
int r; int r;
assert(f);
/* Like fputs(), but for strv, and with a less stupid argument order */ /* Like fputs(), but for strv, and with a less stupid argument order */
if (!space) if (!space)
space = &b; space = &b;
STRV_FOREACH(s, l) { STRV_FOREACH(s, l) {
r = fputs_with_space(f, *s, separator, space); r = fputs_with_separator(f, *s, separator, space);
if (r < 0) if (r < 0)
return r; return r;
} }

View File

@ -191,6 +191,8 @@ static int mount_array_add_swap(bool for_initrd, const char *str) {
static int write_options(FILE *f, const char *options) { static int write_options(FILE *f, const char *options) {
_cleanup_free_ char *o = NULL; _cleanup_free_ char *o = NULL;
assert(f);
if (isempty(options)) if (isempty(options))
return 0; return 0;
@ -208,6 +210,9 @@ static int write_options(FILE *f, const char *options) {
static int write_what(FILE *f, const char *what) { static int write_what(FILE *f, const char *what) {
_cleanup_free_ char *w = NULL; _cleanup_free_ char *w = NULL;
assert(f);
assert(what);
w = specifier_escape(what); w = specifier_escape(what);
if (!w) if (!w)
return log_oom(); return log_oom();
@ -324,25 +329,30 @@ static int write_timeout(
const char *where, const char *where,
const char *opts, const char *opts,
const char *filter, const char *filter,
const char *variable) { const char *unit_setting) {
_cleanup_free_ char *timeout = NULL; _cleanup_free_ char *timeout = NULL;
usec_t u; usec_t u;
int r; int r;
assert(f);
assert(where);
assert(filter);
assert(unit_setting);
r = fstab_filter_options(opts, filter, NULL, &timeout, NULL, NULL); r = fstab_filter_options(opts, filter, NULL, &timeout, NULL, NULL);
if (r < 0) if (r < 0)
return log_warning_errno(r, "Failed to parse options: %m"); return log_error_errno(r, "Failed to parse options for '%s': %m", where);
if (r == 0) if (r == 0)
return 0; return 0;
r = parse_sec_fix_0(timeout, &u); r = parse_sec_fix_0(timeout, &u);
if (r < 0) { if (r < 0) {
log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout); log_warning_errno(r, "Failed to parse timeout '%s' for '%s', ignoring: %m", timeout, where);
return 0; return 0;
} }
fprintf(f, "%s=%s\n", variable, FORMAT_TIMESPAN(u, 0)); fprintf(f, "%s=%s\n", unit_setting, FORMAT_TIMESPAN(u, 0));
return 0; return 0;
} }
@ -359,114 +369,118 @@ static int write_mount_timeout(FILE *f, const char *where, const char *opts) {
static int write_dependency( static int write_dependency(
FILE *f, FILE *f,
const char *where,
const char *opts, const char *opts,
const char *filter, const char *filter,
const char *format) { const char* const *unit_settings) {
_cleanup_strv_free_ char **names = NULL, **units = NULL; _cleanup_strv_free_ char **unit_names = NULL;
_cleanup_free_ char *res = NULL; _cleanup_free_ char *units = NULL;
int r; int r;
assert(f); assert(f);
assert(opts); assert(filter);
assert(unit_settings);
r = fstab_filter_options(opts, filter, NULL, NULL, &names, NULL); r = fstab_filter_options(opts, filter, NULL, NULL, &unit_names, NULL);
if (r < 0) if (r < 0)
return log_warning_errno(r, "Failed to parse options: %m"); return log_error_errno(r, "Failed to parse options for '%s': %m", where);
if (r == 0) if (r == 0)
return 0; return 0;
STRV_FOREACH(s, names) { STRV_FOREACH(s, unit_names) {
char *x; _cleanup_free_ char *mangled = NULL;
r = unit_name_mangle_with_suffix(*s, "as dependency", 0, ".mount", &x); r = unit_name_mangle_with_suffix(*s, "as dependency", 0, ".mount", &mangled);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m"); return log_error_errno(r, "Failed to generate dependency unit name for '%s': %m", where);
r = strv_consume(&units, x); if (!strextend_with_separator(&units, " ", mangled))
if (r < 0)
return log_oom(); return log_oom();
} }
if (units) { STRV_FOREACH(setting, unit_settings)
res = strv_join(units, " "); fprintf(f, "%s=%s\n", *setting, units);
if (!res)
return log_oom();
DISABLE_WARNING_FORMAT_NONLITERAL;
fprintf(f, format, res);
REENABLE_WARNING;
}
return 0; return 0;
} }
static int write_after(FILE *f, const char *opts) { static int write_after(FILE *f, const char *where, const char *opts) {
return write_dependency(f, opts, return write_dependency(f, where, opts,
"x-systemd.after\0", "After=%1$s\n"); "x-systemd.after\0", STRV_MAKE_CONST("After"));
} }
static int write_requires_after(FILE *f, const char *opts) { static int write_requires_after(FILE *f, const char *where, const char *opts) {
return write_dependency(f, opts, return write_dependency(f, where, opts,
"x-systemd.requires\0", "After=%1$s\nRequires=%1$s\n"); "x-systemd.requires\0", STRV_MAKE_CONST("Requires", "After"));
} }
static int write_before(FILE *f, const char *opts) { static int write_before(FILE *f, const char *where, const char *opts) {
return write_dependency(f, opts, return write_dependency(f, where, opts,
"x-systemd.before\0", "Before=%1$s\n"); "x-systemd.before\0", STRV_MAKE_CONST("Before"));
} }
static int write_mounts_for(const char *x_opt, const char *unit_setting, FILE *f, const char *opts) { static int write_mounts_for(
FILE *f,
const char *where,
const char *opts,
const char *filter,
const char *unit_setting) {
_cleanup_strv_free_ char **paths = NULL, **paths_escaped = NULL; _cleanup_strv_free_ char **paths = NULL, **paths_escaped = NULL;
_cleanup_free_ char *res = NULL;
int r; int r;
assert(x_opt);
assert(unit_setting);
assert(f); assert(f);
assert(opts); assert(where);
assert(filter);
assert(unit_setting);
r = fstab_filter_options(opts, x_opt, NULL, NULL, &paths, NULL); r = fstab_filter_options(opts, filter, NULL, NULL, &paths, NULL);
if (r < 0) if (r < 0)
return log_warning_errno(r, "Failed to parse options: %m"); return log_error_errno(r, "Failed to parse options for '%s': %m", where);
if (r == 0) if (r == 0)
return 0; return 0;
r = specifier_escape_strv(paths, &paths_escaped); r = specifier_escape_strv(paths, &paths_escaped);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to escape paths: %m"); return log_error_errno(r, "Failed to escape paths for '%s': %m", where);
res = strv_join(paths_escaped, " "); fprintf(f, "%s=", unit_setting);
if (!res) fputstrv(f, paths_escaped, NULL, NULL);
return log_oom(); fputc('\n', f);
fprintf(f, "%s=%s\n", unit_setting, res);
return 0; return 0;
} }
static int write_extra_dependencies(FILE *f, const char *opts) { static int write_extra_dependencies(FILE *f, const char *where, const char *opts) {
int r; int r;
assert(f); assert(f);
if (opts) { if (isempty(opts))
r = write_after(f, opts); return 0;
if (r < 0)
return r; r = write_after(f, where, opts);
r = write_requires_after(f, opts); if (r < 0)
if (r < 0) return r;
return r;
r = write_before(f, opts); r = write_requires_after(f, where, opts);
if (r < 0) if (r < 0)
return r; return r;
r = write_mounts_for("x-systemd.requires-mounts-for\0", "RequiresMountsFor", f, opts);
if (r < 0) r = write_before(f, where, opts);
return r; if (r < 0)
r = write_mounts_for("x-systemd.wants-mounts-for\0", "WantsMountsFor", f, opts); return r;
if (r < 0)
return r; r = write_mounts_for(f, where, opts,
} "x-systemd.requires-mounts-for\0", "RequiresMountsFor");
if (r < 0)
return r;
r = write_mounts_for(f, where, opts,
"x-systemd.wants-mounts-for\0", "WantsMountsFor");
if (r < 0)
return r;
return 0; return 0;
} }
@ -481,17 +495,13 @@ static int mandatory_mount_drop_unapplicable_options(
assert(flags); assert(flags);
assert(where); assert(where);
assert(options);
assert(ret_options); assert(ret_options);
if (!(*flags & (MOUNT_NOAUTO|MOUNT_NOFAIL|MOUNT_AUTOMOUNT))) { if (!(*flags & (MOUNT_NOAUTO|MOUNT_NOFAIL|MOUNT_AUTOMOUNT))) {
_cleanup_free_ char *opts = NULL; r = strdup_or_null(options, ret_options);
if (r < 0)
return r;
opts = strdup(options);
if (!opts)
return -ENOMEM;
*ret_options = TAKE_PTR(opts);
return 0; return 0;
} }
@ -527,7 +537,6 @@ static int add_mount(
assert(what); assert(what);
assert(where); assert(where);
assert(opts);
assert(target_unit); assert(target_unit);
assert(source); assert(source);
@ -556,16 +565,16 @@ static int add_mount(
if (r < 0) if (r < 0)
return r; return r;
if (path_equal(where, "/")) { if (PATH_IN_SET(where, "/", "/usr")) {
r = mandatory_mount_drop_unapplicable_options(&flags, where, opts, &opts_root_filtered); r = mandatory_mount_drop_unapplicable_options(&flags, where, opts, &opts_root_filtered);
if (r < 0) if (r < 0)
return r; return r;
opts = opts_root_filtered; opts = opts_root_filtered;
if (!strv_isempty(wanted_by)) if (!strv_isempty(wanted_by))
log_debug("Ignoring 'x-systemd.wanted-by=' option for root device."); log_debug("Ignoring 'x-systemd.wanted-by=' option for root/usr device.");
if (!strv_isempty(required_by)) if (!strv_isempty(required_by))
log_debug("Ignoring 'x-systemd.required-by=' option for root device."); log_debug("Ignoring 'x-systemd.required-by=' option for root/usr device.");
required_by = strv_free(required_by); required_by = strv_free(required_by);
wanted_by = strv_free(wanted_by); wanted_by = strv_free(wanted_by);
@ -611,7 +620,7 @@ static int add_mount(
f); f);
} }
r = write_extra_dependencies(f, opts); r = write_extra_dependencies(f, where, opts);
if (r < 0) if (r < 0)
return r; return r;
@ -840,6 +849,9 @@ static int add_sysusr_sysroot_usr_bind_mount(const char *source) {
static MountPointFlags fstab_options_to_flags(const char *options, bool is_swap) { static MountPointFlags fstab_options_to_flags(const char *options, bool is_swap) {
MountPointFlags flags = 0; MountPointFlags flags = 0;
if (isempty(options))
return 0;
if (fstab_test_option(options, "x-systemd.makefs\0")) if (fstab_test_option(options, "x-systemd.makefs\0"))
flags |= MOUNT_MAKEFS; flags |= MOUNT_MAKEFS;
if (fstab_test_option(options, "x-systemd.growfs\0")) if (fstab_test_option(options, "x-systemd.growfs\0"))
@ -915,7 +927,6 @@ static int parse_fstab_one(
assert(what_original); assert(what_original);
assert(fstype); assert(fstype);
assert(options);
if (prefix_sysroot && !mount_in_initrd(where_original, options, accept_root)) if (prefix_sysroot && !mount_in_initrd(where_original, options, accept_root))
return 0; return 0;
@ -1587,7 +1598,7 @@ static int determine_usr(void) {
* with /sysroot/etc/fstab available, and then we can write additional units based * with /sysroot/etc/fstab available, and then we can write additional units based
* on that file. */ * on that file. */
static int run_generator(void) { static int run_generator(void) {
int r = 0; int r;
r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0); r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0) if (r < 0)

View File

@ -537,7 +537,7 @@ static void link_save_domains(Link *link, FILE *f, OrderedSet *static_domains, D
assert(f); assert(f);
ORDERED_SET_FOREACH(p, static_domains) ORDERED_SET_FOREACH(p, static_domains)
fputs_with_space(f, p, NULL, &space); fputs_with_separator(f, p, NULL, &space);
if (use_domains == DHCP_USE_DOMAINS_NO) if (use_domains == DHCP_USE_DOMAINS_NO)
return; return;
@ -547,7 +547,7 @@ static void link_save_domains(Link *link, FILE *f, OrderedSet *static_domains, D
char **domains; char **domains;
if (sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname) >= 0) if (sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname) >= 0)
fputs_with_space(f, domainname, NULL, &space); fputs_with_separator(f, domainname, NULL, &space);
if (sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains) >= 0) if (sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains) >= 0)
fputstrv(f, domains, NULL, &space); fputstrv(f, domains, NULL, &space);
} }
@ -563,7 +563,7 @@ static void link_save_domains(Link *link, FILE *f, OrderedSet *static_domains, D
NDiscDNSSL *dd; NDiscDNSSL *dd;
SET_FOREACH(dd, link->ndisc_dnssl) SET_FOREACH(dd, link->ndisc_dnssl)
fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space); fputs_with_separator(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
} }
} }
@ -652,7 +652,7 @@ static int link_save(Link *link) {
if (!escaped) if (!escaped)
return -ENOMEM; return -ENOMEM;
fputs_with_space(f, escaped, ":", &space); fputs_with_separator(f, escaped, ":", &space);
} }
fputs("\"\n", f); fputs("\"\n", f);
@ -782,7 +782,7 @@ static int link_save(Link *link) {
fputs("DNSSEC_NTA=", f); fputs("DNSSEC_NTA=", f);
space = false; space = false;
SET_FOREACH(n, nta_anchors) SET_FOREACH(n, nta_anchors)
fputs_with_space(f, n, NULL, &space); fputs_with_separator(f, n, NULL, &space);
fputc('\n', f); fputc('\n', f);
} }
} }

View File

@ -148,16 +148,16 @@ int fstab_filter_options(
char ***ret_values, char ***ret_values,
char **ret_filtered) { char **ret_filtered) {
const char *namefound = NULL, *x; _cleanup_strv_free_ char **values = NULL;
_cleanup_strv_free_ char **stor = NULL, **values = NULL; _cleanup_free_ char *value = NULL, *filtered = NULL;
_cleanup_free_ char *value = NULL, **filtered = NULL; const char *namefound = NULL;
int r; int r;
assert(names && *names); assert(!isempty(names));
assert(!(ret_value && ret_values)); assert(!(ret_value && ret_values));
if (!opts) if (!opts)
goto answer; goto finish;
/* Finds any options matching 'names', and returns: /* Finds any options matching 'names', and returns:
* - the last matching option name in ret_namefound, * - the last matching option name in ret_namefound,
@ -169,50 +169,49 @@ int fstab_filter_options(
* *
* Returns negative on error, true if any matching options were found, false otherwise. */ * Returns negative on error, true if any matching options were found, false otherwise. */
if (ret_filtered || ret_value || ret_values) { if (ret_value || ret_values || ret_filtered) {
_cleanup_strv_free_ char **opts_split = NULL;
_cleanup_free_ char **filtered_strv = NULL; /* strings are owned by 'opts_split' */
/* For backwards compatibility, we need to pass-through escape characters. /* For backwards compatibility, we need to pass-through escape characters.
* The only ones we "consume" are the ones used as "\," or "\\". */ * The only ones we "consume" are the ones used as "\," or "\\". */
r = strv_split_full(&stor, opts, ",", EXTRACT_UNESCAPE_SEPARATORS | EXTRACT_UNESCAPE_RELAX); r = strv_split_full(&opts_split, opts, ",", EXTRACT_UNESCAPE_SEPARATORS|EXTRACT_UNESCAPE_RELAX);
if (r < 0) if (r < 0)
return r; return r;
filtered = memdup(stor, sizeof(char*) * (strv_length(stor) + 1)); STRV_FOREACH(opt, opts_split) {
if (!filtered) bool found = false;
return -ENOMEM; const char *x;
char **t = filtered;
for (char **s = t; *s; s++) {
NULSTR_FOREACH(name, names) { NULSTR_FOREACH(name, names) {
x = startswith(*s, name); x = startswith(*opt, name);
if (!x) if (!x)
continue; continue;
/* Match name, but when ret_values, only when followed by assignment. */
/* If ret_values, only accept settings followed by assignment. */
if (*x == '=' || (!ret_values && *x == '\0')) { if (*x == '=' || (!ret_values && *x == '\0')) {
/* Keep the last occurrence found */
namefound = name; namefound = name;
goto found; found = true;
break;
} }
} }
*t = *s; if (found) {
t++; if (ret_value)
continue;
found:
if (ret_value || ret_values) {
assert(IN_SET(*x, '=', '\0'));
if (ret_value) {
r = free_and_strdup(&value, *x == '=' ? x + 1 : NULL); r = free_and_strdup(&value, *x == '=' ? x + 1 : NULL);
if (r < 0) else if (ret_values)
return r;
} else if (*x) {
r = strv_extend(&values, x + 1); r = strv_extend(&values, x + 1);
if (r < 0) else
return r; r = 0;
} } else
} r = strv_push(&filtered_strv, *opt);
if (r < 0)
return r;
} }
*t = NULL;
filtered = strv_join_full(filtered_strv, ",", NULL, /* escape_separator = */ true);
if (!filtered)
return -ENOMEM;
} else } else
for (const char *word = opts;;) { for (const char *word = opts;;) {
const char *end = word; const char *end = word;
@ -232,7 +231,7 @@ int fstab_filter_options(
} }
NULSTR_FOREACH(name, names) { NULSTR_FOREACH(name, names) {
x = startswith(word, name); const char *x = startswith(word, name);
if (!x || x > end) if (!x || x > end)
continue; continue;
@ -249,39 +248,32 @@ int fstab_filter_options(
word = end + 1; word = end + 1;
} }
answer: finish:
if (ret_namefound) if (ret_namefound)
*ret_namefound = namefound; *ret_namefound = namefound; /* owned by 'names' (passed-in) */
if (ret_filtered) {
char *f;
f = strv_join_full(filtered, ",", NULL, true);
if (!f)
return -ENOMEM;
*ret_filtered = f;
}
if (ret_value) if (ret_value)
*ret_value = TAKE_PTR(value); *ret_value = TAKE_PTR(value);
if (ret_values) if (ret_values)
*ret_values = TAKE_PTR(values); *ret_values = TAKE_PTR(values);
if (ret_filtered)
*ret_filtered = TAKE_PTR(filtered);
return !!namefound; return !!namefound;
} }
int fstab_find_pri(const char *options, int *ret) { int fstab_find_pri(const char *opts, int *ret) {
_cleanup_free_ char *opt = NULL; _cleanup_free_ char *v = NULL;
int r, pri; int r, pri;
assert(ret); assert(ret);
r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL, NULL); r = fstab_filter_options(opts, "pri\0", NULL, &v, NULL, NULL);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0 || !opt) if (r == 0 || !v)
return 0; return 0;
r = safe_atoi(opt, &pri); r = safe_atoi(v, &pri);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -32,23 +32,20 @@ int fstab_filter_options(
char **ret_value, char **ret_value,
char ***ret_values, char ***ret_values,
char **ret_filtered); char **ret_filtered);
static inline bool fstab_test_option(const char *opts, const char *names) { static inline bool fstab_test_option(const char *opts, const char *names) {
return !!fstab_filter_options(opts, names, NULL, NULL, NULL, NULL); return fstab_filter_options(opts, names, NULL, NULL, NULL, NULL);
} }
int fstab_find_pri(const char *options, int *ret);
static inline bool fstab_test_yes_no_option(const char *opts, const char *yes_no) { static inline bool fstab_test_yes_no_option(const char *opts, const char *yes_no) {
const char *opt; const char *opt_found;
/* If first name given is last, return 1. /* If first name given is last, return 1.
* If second name given is last or neither is found, return 0. */ * If second name given is last or neither is found, return 0. */
assert_se(fstab_filter_options(opts, yes_no, &opt, NULL, NULL, NULL) >= 0); assert_se(fstab_filter_options(opts, yes_no, &opt_found, NULL, NULL, NULL) >= 0);
return opt == yes_no; return opt_found == yes_no;
} }
int fstab_find_pri(const char *opts, int *ret);
char *fstab_node_to_udev_node(const char *p); char *fstab_node_to_udev_node(const char *p);

View File

@ -116,7 +116,7 @@ TEST(fstab_filter_options) {
do_fstab_filter_options(" opt ", "opt\0x-opt\0", 0, 0, NULL, NULL, "", NULL); do_fstab_filter_options(" opt ", "opt\0x-opt\0", 0, 0, NULL, NULL, "", NULL);
/* check function with NULL args */ /* check function with NULL args */
do_fstab_filter_options(NULL, "opt\0", 0, 0, NULL, NULL, "", ""); do_fstab_filter_options(NULL, "opt\0", 0, 0, NULL, NULL, "", NULL);
do_fstab_filter_options("", "opt\0", 0, 0, NULL, NULL, "", ""); do_fstab_filter_options("", "opt\0", 0, 0, NULL, NULL, "", "");
/* unnecessary comma separators */ /* unnecessary comma separators */

View File

@ -148,7 +148,7 @@ check_fstab_mount_units() {
fi fi
if [[ -n "$opts" ]] && [[ "$opts" != defaults ]]; then if [[ -n "$opts" ]] && [[ "$opts" != defaults ]]; then
# Some options are not propagated to the generated unit # Some options are not propagated to the generated unit
if [[ "$where" == / ]]; then if [[ "$where" == / || "$where" == /usr ]]; then
filtered_options="$(opt_filter "$opts" "(noauto|nofail|x-systemd.(wanted-by=|required-by=|automount|device-timeout=))")" filtered_options="$(opt_filter "$opts" "(noauto|nofail|x-systemd.(wanted-by=|required-by=|automount|device-timeout=))")"
else else
filtered_options="$(opt_filter "$opts" "^x-systemd.device-timeout=")" filtered_options="$(opt_filter "$opts" "^x-systemd.device-timeout=")"