Skip to content

conf: optionally load services from available - #519

Open
ForkJoy wants to merge 1 commit into
finit-project:masterfrom
ForkJoy:master
Open

ForkJoy wants to merge 1 commit into
finit-project:masterfrom
ForkJoy:master

Conversation

@ForkJoy

@ForkJoy ForkJoy commented Nov 2, 2026

Copy link
Copy Markdown

The distro layout currently treats finit.d/available as a staging area only. A unit is unknown to Finit until its configuration is linked into enabled, so disabling autostart also removes the unit from runtime control. Using manual-start keeps a unit controllable, but requires changing the unit configuration instead of using the existing enable and disable interface.

Add the top-level load-available setting. When enabled, configuration files in finit.d/available are read before the regular configuration paths and their runnable units are registered with an available-only source state. Such units remain visible to initctl and can be started and stopped explicitly, but are prevented from starting automatically. A later enabled symlink overrides that source state and restores the unit's own manual-start policy; disabling it again leaves a running instance alone while preventing future automatic starts.

Keep loader source state separate from manual-start so an explicit manual-start setting continues to apply after a unit is enabled. Pass the source through both block and legacy parsers, including nested legacy includes, and apply it consistently to service, task, run, sysv, and tty units. Load available files first so normal configuration precedence and same-name overrides remain intact, while ignoring dangling replacement symlinks.

Available files are passive unit definitions, not active system configuration. Ignore their top-level settings until enabled, while retaining file-local resource limits needed by their units. Also keep available-only units from satisfying configuration-time if:name checks or displacing providers from enabled units.

Handle reload transitions without restarting completed tasks, losing a manual start waiting on conditions, or stopping a running unit merely because it was disabled. Guard retry paths against reviving stopped available-only services. A late pidfile from a forking service can otherwise undo an explicit stop during the same transition, so retain the stop request when adopting the discovered PID and let the state machine terminate it.

Document the setting, its precedence and manual-start interaction, and add integration coverage for block and legacy formats, all runnable unit types, enable/disable transitions, conditions, providers, global setting isolation, dangling links, delayed pidfiles, and empty available directories.

The distro layout currently treats finit.d/available as a staging
area only.  A unit is unknown to Finit until its configuration is
linked into enabled, so disabling autostart also removes the unit from
runtime control.  Using manual-start keeps a unit controllable, but
requires changing the unit configuration instead of using the existing
enable and disable interface.

Add the top-level load-available setting.  When enabled, configuration
files in finit.d/available are read before the regular configuration
paths and their runnable units are registered with an available-only
source state.  Such units remain visible to initctl and can be started
and stopped explicitly, but are prevented from starting automatically.
A later enabled symlink overrides that source state and restores the
unit's own manual-start policy; disabling it again leaves a running
instance alone while preventing future automatic starts.

Keep loader source state separate from manual-start so an explicit
manual-start setting continues to apply after a unit is enabled.  Pass
the source through both block and legacy parsers, including nested
legacy includes, and apply it consistently to service, task, run, sysv,
and tty units.  Load available files first so normal configuration
precedence and same-name overrides remain intact, while ignoring
dangling replacement symlinks.

Available files are passive unit definitions, not active system
configuration.  Ignore their top-level settings until enabled, while
retaining file-local resource limits needed by their units.  Also keep
available-only units from satisfying configuration-time if:name checks
or displacing providers from enabled units.

Handle reload transitions without restarting completed tasks, losing a
manual start waiting on conditions, or stopping a running unit merely
because it was disabled.  Guard retry paths against reviving stopped
available-only services.  A late pidfile from a forking service can
otherwise undo an explicit stop during the same transition, so retain
the stop request when adopting the discovered PID and let the state
machine terminate it.

Document the setting, its precedence and manual-start interaction, and
add integration coverage for block and legacy formats, all runnable
unit types, enable/disable transitions, conditions, providers, global
setting isolation, dangling links, delayed pidfiles, and empty
available directories.

@troglobit troglobit left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for the work on this, and for the thorough tests!

Finit was never meant to imitate systemd. The available/ and enabled/ setup is closer to Apache or nginx. Files in available/ can define services that compete for the same role, e.g., rsyslogd and sysklogd both providing syslogd. Loading everything in available/ would break many existing installations, even when it's opt-in, because the same files are used both ways.

I do like the idea of a service that can be controlled with initctl without being enabled. But this PR has too many sweeping behavior changes that don't belong to that feature:

  • the pidfile plugin no longer ignores pidfile events while a service is stopping
  • service_forked() overwrites the const state field directly
  • service_stop() now cleans up and halts every service whose PID is already gone
  • tty stanzas get a new manual-start option
  • cgroup settings are reset for each file

Some of these may be real bugs, but each needs its own PR with its own motivation.

For the feature itself, I'd rather go another way. For example, initctl start foo could load available/foo.conf when foo isn't enabled, and keep it as a manual unit until the next reload. That way nothing is scanned at boot and services that compete for a role never meet. If you'd like to rework the PR in that direction, great. Otherwise I can adopt it and pick out the pieces we can use in the context of #335, which is after pretty much the same thing. Just let me know.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants