Skip to content

fstab-generator: support for x-systemd.onfailure#42440

Open
nikhilar2410 wants to merge 1 commit into
systemd:mainfrom
nikhilar2410:x-systemd-onfailure
Open

fstab-generator: support for x-systemd.onfailure#42440
nikhilar2410 wants to merge 1 commit into
systemd:mainfrom
nikhilar2410:x-systemd-onfailure

Conversation

@nikhilar2410

Copy link
Copy Markdown

Add support for the x-systemd.onfailure= fstab option in systemd-fstab-generator.
This allows configuring OnFailure= dependencies for generated mount units directly through /etc/fstab.

For example:
/dev/sda1 /data ext4 defaults,x-systemd.onfailure=emergency.target 0 2

results in the generated mount unit containing:
[Unit]
OnFailure=emergency.target

This makes it possible to attach recovery targets or services to mount failures directly from fstab configuration.

Add documentation and generator tests.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

Claude review of PR #42440 (8d535a7)

This is a small, well-scoped change adding x-systemd.onfailure= to fstab-generator, with docs and tests. A few items below.

Must fix

  • NEWS entry in wrong sectionNEWS:7 — a new opt-in feature is listed under "Announcements of Future Feature Removals and Incompatible Changes:"; move it to "Changes in the system and service manager:".
  • Missing .expected.sysroot fixturestest/test-fstab-generator/test-18-options.fstab.input:19 — new expected units were added only to .expected/; the initrd=no test run diffs the full file list against .expected.sysroot/ and will fail. Likely cause of the failing CI.

Suggestions

  • Validate OnFailure= valuessrc/fstab-generator/fstab-generator.c:451 — an empty x-systemd.onfailure= emits a malformed bare OnFailure= line; skip empties / check unit_name_is_valid(). (Not mangling to .mount is correct here.)
  • Escape % in OnFailure= valuessrc/fstab-generator/fstab-generator.c:452 — the value is written verbatim, so a literal % is reinterpreted by PID1 specifier expansion at load; write_mounts_for() escapes via specifier_escape_strv() for this reason.
  • Test empty x-systemd.onfailure= valuetest/test-fstab-generator/test-18-options.fstab.input:19 — the isempty(*u) skip branch is not exercised by any fixture.
  • Test x-systemd.automount interactiontest/test-fstab-generator/test-18-options.fstab.input:19 — no fixture confirms the documented "applies to the generated mount unit only" behavior when combined with automount.

Nits

  • Redundant isempty(opts) checksrc/fstab-generator/fstab-generator.c:434 — the sole caller already guards this.
  • Missing assert(where)src/fstab-generator/fstab-generator.c:432where is dereferenced in the log message; sibling helpers assert it.
  • Match sibling one-line formattingsrc/fstab-generator/fstab-generator.c:437 — collapse the multi-line fstab_filter_options()/log_error_errno() calls.
  • Blank line before final return 0;src/fstab-generator/fstab-generator.c:454 — sibling helpers separate the trailing return 0; with a blank line.
  • "created mount unit" wordingman/systemd.mount.xml:290 — new entry says "generated mount unit" (lines 290, 296); all sibling options use "created mount unit".
  • Hard-tab indentationman/systemd.mount.xml:291 — line indented with a hard tab while the rest of the file uses spaces.

Workflow run

Comment thread NEWS Outdated
Comment thread src/fstab-generator/fstab-generator.c Outdated
Comment thread src/fstab-generator/fstab-generator.c Outdated
Comment thread src/fstab-generator/fstab-generator.c
if (isempty(opts))
return 0;

r = fstab_filter_options(opts,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude: nit: The fstab_filter_options() call (lines 437-442) and the log_error_errno() message (lines 444-446) are each spread over multiple lines, whereas every sibling helper writes them as single lines (e.g. r = fstab_filter_options(opts, filter, NULL, NULL, &paths, NULL); and return log_error_errno(r, "Failed to parse options for '%s': %m", where);). Collapsing them to one-liners would match the file's style.

@nikhilar2410 nikhilar2410 force-pushed the x-systemd-onfailure branch from 50c65ce to 1f09717 Compare June 4, 2026 04:38
Comment thread test/test-fstab-generator/test-18-options.fstab.input
Comment on lines +448 to +452
STRV_FOREACH(u, units) {
if (isempty(*u))
continue;

fprintf(f, "OnFailure=%s\n", *u);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude: suggestion: The x-systemd.onfailure= value is written verbatim with no escaping. When PID1 loads the generated unit, OnFailure= is parsed by config_parse_unit_deps(), which runs each token through unit_name_printf() and therefore expands %-specifiers. The path-writing sibling write_mounts_for() escapes its values via specifier_escape_strv() for exactly this reason. As written, an fstab value containing a literal % (e.g. x-systemd.onfailure=foo-%n.service) will be reinterpreted rather than emitted literally, so the resulting dependency can differ from what the administrator typed. Consider running the values through specifier_escape_strv() before emitting them so the written value stays literal. Low impact (fstab is admin-controlled), hence a suggestion.

@nikhilar2410 nikhilar2410 force-pushed the x-systemd-onfailure branch from 1f09717 to 8ffaeda Compare June 4, 2026 10:46
Comment on lines +453 to +454
}
return 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude: nit: Missing blank line before the final return 0;. The sibling helpers in this file (write_dependency(), write_mounts_for()) separate the emit/loop block from the trailing return 0; with a blank line; matching that here keeps the helpers consistent.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

/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
/dev/sdx18 /mnt/onfailure auto x-systemd.onfailure=foo.service 0 0
/dev/sdx19 /mnt/onfailure-multi auto x-systemd.onfailure=foo.service,x-systemd.onfailure=bar.service 0 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude: suggestion: The generator explicitly handles an empty x-systemd.onfailure= value (the if (isempty(*u)) continue; branch in write_on_failure()), but no test fixture exercises it. Consider adding an fstab entry such as x-systemd.onfailure=foo.service,x-systemd.onfailure= so the empty-value skip path is covered and the expected unit confirms only the non-empty OnFailure= is emitted.

/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
/dev/sdx18 /mnt/onfailure auto x-systemd.onfailure=foo.service 0 0
/dev/sdx19 /mnt/onfailure-multi auto x-systemd.onfailure=foo.service,x-systemd.onfailure=bar.service 0 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude: suggestion: The man page entry documents that x-systemd.onfailure= "always applies to the generated mount unit only, regardless of whether x-systemd.automount has been specified", but no fixture combines x-systemd.onfailure= with x-systemd.automount. Consider adding such an entry and a .automount expected unit to confirm the documented behavior (OnFailure= lands on the .mount unit, not the .automount unit).

Add support for the x-systemd.onfailure fstab option in
fstab-generator.

This allows generated mount units to include the systemd
OnFailure= dependency specified through /etc/fstab.

The implementation parses x-systemd.onfailure entries using
fstab_filter_options() and emits corresponding OnFailure=
directives into generated mount units.

Example:

/dev/sda1 /data ext4
defaults,x-systemd.onfailure=emergency.target 0 2

generates:

OnFailure=emergency.target

This makes it possible to attach recovery targets or services
to mount failures directly from fstab configuration.

Add documentation and generator tests.

Signed-off-by: Nikhil R <[email protected]>
@nikhilar2410 nikhilar2410 force-pushed the x-systemd-onfailure branch from 8ffaeda to 8d535a7 Compare June 8, 2026 12:44
@nikhilar2410 nikhilar2410 marked this pull request as ready for review June 8, 2026 13:04
@github-actions github-actions Bot added the please-review PR is ready for (re-)review by a maintainer label Jun 8, 2026
Comment thread man/systemd.mount.xml
<varlistentry>
<term><option>x-systemd.onfailure=</option></term>

<listitem><para>In the generated mount unit, configures an

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude: nit: Claude: This entry refers to the "generated mount unit" (here, and again at line 296), but every sibling x-systemd.* option on this page says "created mount unit" (e.g. x-systemd.wanted-by=, x-systemd.wants-mounts-for=, and the equivalent automount caveat at lines 248-250). Use "created mount unit" for consistency.

Comment thread man/systemd.mount.xml
<term><option>x-systemd.onfailure=</option></term>

<listitem><para>In the generated mount unit, configures an
<varname>OnFailure=</varname> dependency. The argument should be a unit name.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude: nit: Claude: This line is indented with a hard tab (followed by a space), whereas the rest of systemd.mount.xml, including the surrounding option entries, uses spaces only. Re-indent with spaces to match the file's style.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants