Commit Graph
103 Commits
Author SHA1 Message Date
Joachim Wiberg afe0488bf2 Add support for runtime evaluation of if:<condition> statements
The if: statement, introduced in v4.4, allows for discarding run/task/services
that depend on other services, based on that service's name, or condition.
Discarding in this context means unloading from the configuration.

At runtime, however, it has proven quite useful to be able to conditionally
qualify a run/task/service based on a condition.  Consider this example from
the Infix operating system:

run name:startup log:prio:user.notice \
	[S] <pid/sysrepo> confd -b --load startup-config -- Loading startup-config

run name:failure log:prio:user.critical if:<usr/fail-startup> \
	[S] <pid/sysrepo> confd --load failure-config -- Loading failure-config

The two run statements reside in the same .conf file so Finit runs them in true
sequence.  If loading the file `startup-config` fails confd sets the condition
usr/fail-startup, thus allowing the next run statement to load `failure-config`.

Notice the difference between <pid/sysrepo> condition and if:<usr/fail-startup>.
The former is a condition for starting and the latter is a condition to check if
a run/task/service is qualified to even be considerered.  The best comparison is
with the [runlevel] option, it too is used to qualify.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 16:39:46 +02:00
Joachim Wiberg 939ae02a6a Increase MAX command, and arg., length: 64 -> 256
With non-standard paths, e.g., when running `make distcheck`, the
absolute path to some commands become ridiculously long.  However,
this has been a recurring issue for some users in the past, so it
is time to increase the capabilibieies of Finit to cover this.

Yes, a better way is probably to allocate all these strings when they
are used, but that would require a redesign of the initctl API and
likely cause a lot of regressions before everything has stabilized.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-14 09:15:55 +02:00
Joachim Wiberg 51befb492c Allow conflicting services to start when conflict is resolved
These changes add a new svc_block_t type: SVC_BLOCK_CONFLICT so a user
can more clearly see why a run/task/service has not been started by
Finit.  The reason for the block is by default logged, which can be
escaped by using the `nowarn` flag.

Also, when the conflict is resolved, allow the service to start.

With these changes, the system/hotplug.conf should work better and
cause less questions about "strange" log messages.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-15 16:23:40 +02:00
Joachim Wiberg 4fbcd1bbad Update copyright years
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-05 06:00:34 +02:00
Joachim Wiberg 44d0d87ad3 Simplify, drop ifdef: let if: become ifdef
Post audit, concensus is to drop if: and always do post-eval of all
ifdef: statements.  Also, rename ifdef: to if: for completeness.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-06 17:03:37 +01:00
Joachim Wiberg c679b0a93d Cannot be const, we're modifying it
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-05 09:56:54 +01:00
Joachim Wiberg fa71f97dcf Add support for if:[!]ident and ifdef:[!]ident for run/task/services
Conditional loading of stanza depending on ident is already loaded.  The
if: checks as in-band while ifdef: checks out-of-band, i.e., post eval.

The optional leading '!' negates the comparison, if NOT foo then ...

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg ed383eaaa6 Minor refactor, break out new fn svc_find_by_str()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 9cb6a54493 Minor refactor, new fn svc_mark()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 56a89db889 Add support run/task/service 'conflict:foo' handling
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 7c2abf69c4 Add missing (new) service state strings
Also, reorder to match state enum order.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-23 17:54:32 +01:00
Joachim Wiberg 8b9bb1c7ce Fix #314: skip restart if conditions are lost
This change prevents Finit from attempting to continue restarting
crashing services that've lost their conditions.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-15 01:03:10 +01:00
Joachim Wiberg a61c2ceb79 Fix #310: service restart delay not working
Always use the configured restart delay for crashing services.  If no
delay is configured, we default to an initial 2000 msec for forking
daemons and start-stop scripts, and 1 msec for non-forking daemons.

We must track the increasing delay in the svc_t because processes can
fail quickly in differing ways.  E.g, the test daemon 'serv' behaves
extra evil by crashing right after having created its pidile (i.e.,
when it's signaled to Finit it is 'ready' and all is dandy ...).  If
we don't track the delay per svc_t we would restart 'serv' after only
1 msec every (other) time.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 13:54:56 +01:00
Joachim Wiberg 5dd1a676ac Fix #282: add support for oncrash:script to call post:script action
This patch adds the oncrash:script option to call the post:script
action, if defined, for a crashing service.  The EXIT_CODE variable
sent to the script is set to `crashed`.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 13:07:10 +01:00
Joachim Wiberg 912a281ee2 Fix #299: add support for service readiness notification
This patch adds service readiness notification to support daemons
employing systemd and s6 notification.  Complementing the native
Finit readiness support using PID files that exist already.

The two have slightly different ways of implementing readiness:

 - https://www.freedesktop.org/software/systemd/man/sd_notify.html
 - https://skarnet.org/software/s6/notifywhenup.html

Finit now provides both a NOTIFY_SOCKET environemnt variable, for
systemd, and a way to start s6 daemons with a descriptor argument.

For details on the syntax, see the `service` documentation.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:06:26 +02:00
Joachim Wiberg 51ade57723 Rename internal run/task/service states => changes condition names
This patch renames the internal states for run/task/services to avoid
any confusion with the introduction of 'ready:scripts'.

 * WAITING -> PAUSED
 * READY   -> WAITING

A service condition that used, e.g., <service/foo/ready> should now
instead use <service/foo/waiting>.

Note: A new condition with the old name <service/foo/ready> will be
      introduced shortly to signify service "readiness", a concept
      used in other PID 1, like systemd and s6.

For details, see issue #299.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-23 15:31:24 +02:00
Joachim Wiberg abcb3ceb67 Fix #300: add ready:script for services, called when daemon is ready
In Finit a daemon can signal its readiness by creating/touching its PID
file.  An ancient UNIX concept -- a daemon creates its PID file when it
has set up signal handlers and is ready to receive IPC (signals), right
before entering its while(1) loop.

Finit took the concept a bit further, adding readiness signalling also
to daemon's by touching their PID file after having processed a SIGHUP.

For both these conditions Finit now supports a ready:script, called when
readiness is detected.  In later commits support for s6 and systemd
style readiness notification will be added that will hook the mechanism
implemented in this commit as well.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-23 09:37:18 +02:00
Joachim Wiberg e589c5b269 Refactor, create svc_find_by_cond() from api.c callback
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-18 14:00:02 +02:00
Joachim Wiberg 96257cc5c7 Let manual:yes run/tasks also end in state 'done'
This is a follow-up to #274, in which Andy pointed out that ending up in
state 'stopped' was a bit confusing for manual:yes run/tasks.

With the following change we let all run/tasks end in state 'done', yet
still allow manual:yes ones to transition to 'ready' when the user calls
`initctl start foo`.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-25 15:41:34 +02:00
Joachim Wiberg fbcd7d2384 Fix #278: enforce conditions also for running pre: scripts
The whole point of pre: scripts is that they run just before the actual
run/task/service process, hence they need to be locked behind the same
conditions as the process.  Otherwise pre: scripts would be nothing more
than plain tasks.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-25 15:05:16 +02:00
Joachim Wiberg 5f908cae49 Fix #274: allow manual:yes on sysv/service/run/task
Prior to this change only service stanzas respected the manual:yes
option, now it (should) work on any svc_t type.  Not tested on ttys.

The initctl tool has been given an extra manual=yes output for these
types of run/task/service entries, shown only when the manual option
is set.

Example:

root@anarchy:~# initctl status foo.sh
     Status : stopped (code=exited, status=0/SUCCESS, manual=yes)
   Identity : foo.sh                                ~~~~~~~~~~~~
Description : Hej foo
     Origin : /etc/finit.d/enabled/foo.conf
Environment :
Condition(s):
    Command : /root/foo.sh
   PID file : none
        PID : 0
       User : root
      Group : root
     Uptime : N/A
     Starts : 1
   Restarts : 0 (0/10)
  Runlevels : [--2345----]

Notice also the new `Starts : 1` which is a counter for the number of
starts in the current runlevel.  On runlevel change it is reset to 0.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-16 17:57:55 +02:00
Joachim Wiberg f8dfcdf024 Fix #279: allow restart:always, restart:-1, of crashing services
This change allows endless restarts, similar to `respawn` but honors
`restart_sec`.  There is no upper limit on the number of times Finit
tries to restart a crashing service.  Same as `restart:-1`

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-12 22:48:12 +02:00
Joachim Wiberg d3c6351ed8 Fix nasty service matcher bug
In some conditions, typically when the same command is used for multiple
services, e.g. the modules-load plugin, the svc_find() function returned
an existing "similar" entry instead of NULL, causing loss of config.

When creating, and searching for, a run/task/service we must follow the
new name:id paradigm to the letter.  Always create based on name:id and
always search for matching name:id.  The name may be derived from the
command, but they cannot be used interchangably.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:08 +02:00
Joachim Wiberg 108bbf56dd Update copyright years
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-19 19:35:49 +02:00
Joachim Wiberg c926160853 Issue #223: add type:forking service option, with updated docs
- Add `type:forking` service option to trigger guessing pidfile to
   watch for, instead of `pid:!foo` option, which is not intuitive.
   This option may likely also survive into the new file format :)
 - Update docs and add examples
 - Update start-stop-serv.sh test case with this new variant

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 19:13:28 +02:00
Ming Liu e1c59a2515 Fix some wrong return values of run tasks
When a run task is started with svc->started = 1, it should be
considered started successfully or failed on the other hand.

Signed-off-by: Sergio Morlans <sergio.morlans@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2022-03-05 11:53:25 +01:00
Jörgen Sigvardsson 4121113688 Added implementation for the new command INIT_CMD_SIGNAL.
The implementation looks up the named service by using
`svc_parse_jobstr`. The callbacks for `svc_parse_jobstr` has been
augmented to accept a user data parameter. For this use case,
a carrier for the actual signal was needed. The address of the
signal parameter is taken and passed on as a `void *`. The
callback then simply deferences it as an int - the signal number.
2022-02-15 12:29:40 +01:00
Joachim Wiberg 222d8d3575 New helper function, resolves svc_t type to string
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-07 06:51:20 +01:00
Joachim Wiberg 95995a45cf Add total restart counter for service & sysv daemons
This patch adds a recent feature request to keep track of the total
number of restarts (including crashes and initctl restart) of both
service and sysv daemons.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-11 17:18:59 +01:00
Joachim Wiberg 184525687c Follow-up to ec2900e: minor cleanup + signed vs unsigned comparison
Minor coding style cleanup.  Also, clang complained of a signed vs
unsigned comparison in service_retry(), max(timeout, svc->restart_tmo)

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 06:52:44 +01:00
Joachim Wiberg b53f2f4a60 Cleanup, drop now unused internal function svc_is_unique()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 05:34:10 +01:00
Joachim Wiberg 280d91b9bf Add support for new libite (-lite) header namespace
Due to an unfortunate name clash with the DirectFB project LiTE, the
libite (-lite) project had to change its header namespace from

   lite/*.h -> libite/*.h

This patch adds support for the new namepace in Finit, triggered by the
define _LIBITE_LITE, from the .pc file read by pkg-config.  This should
only be needed on systems that install libite without the compatibility
symlink lite -> libite/ in the staging include directory.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-12-06 21:38:20 +01:00
Robert Andersson ec2900e4dd service.c: add more parameters when starting services
It would be good if we can control the services more specifically with
the following parameters like:

restart:N   - how many times shall the service to be restarted on
              failures (<10), the default max is 10.
restart_tmo - the timeout of the restarting.
norestart   - dont restart on failures.
oncrash     - once all retrying also fail, how to deal with it,
              rebooting or ignoring the failures.

Signed-off-by: Robert Andersson <robert.m.andersson@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2021-09-21 10:55:29 +02:00
Tim Gates 841b06df37 docs: Fix a few typos
There are small typos in:
- doc/conditions.md
- src/mount.c
- src/svc.h

Fixes:
- Should read `satisfied` rather than `satsifed`.
- Should read `process` rather than `prorcess`.
- Should read `measure` rather than `meausre`.
2021-08-27 06:23:04 +10:00
yangfl fa14ed1649 Fix typo
with the love from codespell
2021-06-25 13:08:14 +08:00
Joachim Wiberg a19b82ea5f Allow tty's to always respawn, no max restart count
This patch adds a `respawn` flag for services and ttys, always set for
ttys, that allows bypassing the crash/restart counter and immediately
restart a 'crashing' service.

For tty type services this is the expected behavior, but for regular
services it is not.  That is why `respawn` flags is not advertised in
the docs.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 06:29:11 +02:00
Joachim Wiberg 679b4df881 Fallback rescue mode handling
Before 4e5d06b the only way to go into rescue mode was to skip certain
steps and then attempt to load /lib/finit/rescue.conf.  After 4e5d06b
we keep the old handling as a fallback in case early sulogin fails.

The new tty option 'rescue' is added, which recue.conf is updated with.
This option implies notty mode and will try sulogin (again) before it
falls back to start /bin/sh as a login shell.

The reason we keep this is to be able to handle all possible use-cases
and also allow sysadmins to set up the behavior that fits their needs.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 22:10:42 +02:00
Joachim Wiberg ba858743e5 Fix #129: add pre:script and post:script action support
This patch updates the service state machine with two new states: SETUP
and CLEANUP.  If an executable pre:/path/to/script is defined for a
service, it is called every time the task goes to READY state.  If an
executable post:/path/to/script is defined for a service, it is called
when the task goes to HALTED state.

Each of these two scripts default to a three (3) second execution time
before they are SIGKILLed.  This can be adjusted with the `kill:SEC`
option for the service.  There are no execution guarantees, nor are
there any way of detecting if the script was killed before completion or
not -- except for running Finit in debug mode and inspecting the result
printed by system_monitor().

Note: the post:script MUST be idempotent since transitions between READY
      and HALTED can take place any number of times before a task goes
      to its RUNNING state.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-18 11:33:38 +02:00
Joachim Wiberg c0368d2b16 Refactor fallback shell handling, run as regular service
This patch re-enables the fallback shell handling after the big TTY
refactor.  We do this by allowing the fallback shell to run as a
regular service.

Note: this also adds the "hidden" support for 'notty' option for
      tty configurations stanzas.  This is just to pick up from
      where the kernel left us, reusing stdin + stdout.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-14 16:29:19 +02:00
Joachim Wiberg 30020263ba Refactor tty handling to use service backend enabling conditions etc.
Initial refactor of the tty implementation to use the service/run/task
general backend.  This enables all the features of services also for
ttys, except logging because it makes no sense.

Work in progress:

 - plugins/tty.c does not work anymore, could possibly be removed in
   favor of usinga (a new) condition instead (if-tty-exists)
 - fallback tty does not work anymore, should we remove it, or can we
   handle it as an optional built-in with (a new) condition?
 - @console does not work anymore, needs to generate N cloned services

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-14 16:29:19 +02:00
Joachim Wiberg 90f7ff1c23 initctl: new command 'reload NAME:ID' and new semantics for restart
This patch corrects a logical glitch, or design flaw, in initctl.  The
'restart FOO' command did not stop+start FOO only send SIGHUP (provided
FOO supports SIGHUP).  Hence, a new command 'reload FOO' is introduced,
which does exactly that, and 'restart FOO' now stops and restarts FOO.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-04 12:35:35 +02:00
Jacques de Laval 10f4c7fa18 Do a full restart rather than HUP if command line of a service has changed
By keeping track of when a full restart is needed, Finit can relieve
the user of having to track modifications to service configuration. This
also makes initctl reload easier to explain and reason about as the effect
of a reload should now be that any configuration updates to services will
be fully "commited" by initctl reload.

Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
2021-04-01 16:18:54 +02:00
Joachim Wiberg 665d212bd6 Add support for configuring cgroups and their settings on services
This patch adds support for modifying settings for the default cgroups;
init, user, and system, as well as adding up to a total of eight groups
for the system.

Services can now be assigned to a cgroup, with optional extra settings
for that particular process group.  The syntax is slightly contrivied
but follows the overall Finit syntax of prop:value,prop':value', e.g.

   cgroup maint cpu.weight:123,mem.max:10000

Starting with the introduction of rlimits, a group of services sharing
the same .conf file can share the same (locally "global") rlimits, and
now also the same cgroup, e.g.

    cgroup.maint
    service foo
    service bar cgroup:mem.max:1000

This puts foo and bar in the same top-level cgroup 'maint', with an
extra memory restriction on bar for max 1000 bytes memory.

NOTE: 'mem.' is a Finit extension, a shorthand for cgroups2 'memory.'

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-03-30 10:21:01 +02:00
Joachim Wiberg 9c4d5341ae No env file, or optional ('-'), are both OK results
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-03-23 16:24:12 +01:00
Jacques de Laval b3fad1077e Store removal status separate from dirty
Having removal status stored in the dirty status resulted in removal
status being forgotten when a service was marked as dirty, for instance
when a dependency was updated. This side effect of marke_dirty seems a bit
unexpected and instead of adding exceptions to the logic for when marking
a service dirty - let's separate the two things (dirty and removed) from each
other.

Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
2021-03-19 16:53:04 +01:00
Joachim Wiberg 8aba63a9e3 Track oldpid of services to fix empty pid in restart message
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-03-12 00:13:15 +01:00
Joachim Wiberg 6b688c4211 Refactor, share env helper fns with initctl
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-03-11 15:10:10 +01:00
Joachim Wiberg 548acf27cf Minor refactor, rename RESPAWN_MAX -> SVC_RESPAWN_MAX
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-03-11 12:48:44 +01:00
Joachim Wiberg 11a3318c02 Properly set status 'missing' for missing binaries and/or env files
When we try to start a service/run/task we call whichp() to see if the
binary exists, either tha absolute path given in the .conf file, or in
the $PATH we run with.  If binary, or the env: file, doesn't exist we
now set svc_missing() state.

On `initctl reload` we unblock the service to be able to check again.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-03-11 11:44:23 +01:00
Joachim Wiberg 4d05bf9359 Mark affected services as dirty if their rdeps are dirty
Provided a configuration that looks like this:

ospfd.conf:
    service [2345] <!pid/zebra> log ospfd -A 127.0.0.1 -u root -g root -- OSPF daemon

zebra.conf:
    service [2345] <!> log zebra -A 127.0.0.1 -u root -g root -- Zebra Routing daemon

If zebra.conf is changed, we restart it when `initctl reload` is issued.

This change ensures that ospfd is also restarted, because ospfd depends
on zebra, we must restart it too.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-03-07 14:52:19 +01:00