Compare commits

..
1134 Commits
Author SHA1 Message Date
Joachim Wiberg 9245869e18 Update ChangeLog and bump version for v4.9 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-15 07:09:58 +01:00
Joachim Wiberg 0f4a487328 .github: tests share same sysroot, must run in sequence
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-14 10:28:16 +01:00
Joachim Wiberg f1b5b42919 test: enable debug logs for global-envs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-14 10:25:30 +01:00
Joachim Wiberg f546129baf test: debug sysvparts
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-14 10:25:30 +01:00
Joachim Wiberg 27451ac3f2 Update ChangeLog and bump version for v4.9-rc1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-14 06:26:27 +01:00
Joachim Wiberg 0a8f3a6250 Fix #425: flush .conf file events before reload and runlevel change
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-13 07:06:13 +01:00
Joachim Wiberg 70c4e7d774 iwatch: ensure adding a new watcher is idempotent
Some subsystems call iwatch_add() without first calling iwatch_del() on
the same path.  E.g., cgroup_config().

Issue #417 but unclear atm. if this is the root cause.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-13 05:53:24 +01:00
Joachim Wiberg 5265eee25d test: slightly more robust checkself.sh
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-11 10:17:35 +01:00
Joachim Wiberg 4b06e1a49f Silence overly verbose debug messages in cond_set/clear/update
These functions call other functions that log more detailed information.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-11 10:17:35 +01:00
Joachim Wiberg 6b9aa21509 Minor cleanup, code (style) and comments
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-11 10:17:35 +01:00
Joachim Wiberg 990307fbc9 Fix kill() on timeout of pre:/post:/ready:scripts
A long running pre/post/ready script must be killed properly, not by
targeting its process group.  Process group cleanup is handled by the
service_monitor() when reaping the script's PID.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-11 10:17:34 +01:00
Joachim Wiberg 9d8a9b7fba Check for pre:- and post:scripts in $PATH
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-11 10:17:34 +01:00
Joachim Wiberg bbc83eaa64 test: new test
New test adds /bin/fail.sh to verify that a failing pre:script (that
also takes too long to run) is detected: exit code and timeout.

Ensure existing test pass full path to /sbin/fail.sh script.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-11 10:17:33 +01:00
Joachim Wiberg 23d034f521 Prevent main process from starting if pre: script fails
Check exit status of `pre:` scripts, on failure drive service/sysv to
`crashed` state.  The exit code of `post:` scripts remain ignored for
now.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-11 09:39:40 +01:00
Joachim Wiberg 9a3148a49d Bump version to v4.9-beta1 and update ChangeLog
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-10 10:43:38 +01:00
Joachim Wiberg 8560103a24 Add individual timeout support for pre/post/ready scripts
Syntax:
    [pre|post|ready]:[0-3600,]/path/to/script

Description:
    Before this patch all pre/post/ready scripts used the global kill
    delay as timeout.  After this patch it is possible to disable the
    timeout as well as set a timeout >60, which is max kill delay.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-10 10:43:37 +01:00
Joachim Wiberg 7a75e34808 Fix initctl touch of template services
Follow-up to 465bc17, which addressed unintended restart of siblings.
This patch fixes a problem where template instantiated services are not
properly reloaded/restarted when marked as "dirty" with `initctl touch`.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-10 10:43:37 +01:00
Joachim Wiberg 4d4fc10d57 plugins: rtc: follow-up to bc8118d
In save() RTC, ensure the RTC_FILE option is actually enabled.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-10 10:43:29 +01:00
Joachim Wiberg 003faae9e9 .github: disable apparmarmor to allow testing in unshare
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-03 10:23:45 +01:00
Joachim Wiberg 01a01d65c0 Merge pull request #424 from aanderse/container/systemd-nspawn
Add systemd-nspawn to the list of container types

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-03 07:13:33 +01:00
Aaron Andersen 048302f06a add systemd-nspawn to the list of container types 2025-02-02 08:58:36 -05:00
Joachim Wiberg 74f0fcfccd Merge pull request #422 from az143/fstab-nofail 2024-12-20 02:18:09 +01:00
az 3cfe0a33b8 fstab with UUID/LABEL: nofail handling for fsck
add support for 'nofail' fstab option. if present, finit's fsck invocation ignores errors for this device.

this is useful if you have an fstab entry for a device with UUID= or LABEL= which isn't always present and which you'd like to not
bail on (so you set nofail). in this case finit leaves the presence-or-not decision to fsck, which exits nonzero.

for block devices that are directly listed in fstab this change isn't important, because for such finit looks for the blockdev's existence and skips the fsck if n/a.
2024-12-20 09:09:24 +10:00
Joachim Wiberg 465bc17ca4 Fix unintended restart of template siblings
Consider the case where container@.conf is an available template.  When
creating a container@foo.conf it will share the same base .conf as an
existing container@bar.conf, but we do not expect to restart bar just
because foo is instantiated.

Up until this change, all template siblings were considered "dirty" if a
new one was created or updated.  Skipping realpath() for all files that
have a '@' works around the problem.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-11-28 11:13:44 +01:00
Joachim Wiberg d4889b435d Merge pull request #419 from troglobit/rtc
RTC plugin fixes and extension

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-11-04 10:48:26 +01:00
Joachim Wiberg 49c0557ced plugins: reduce log level LOG_ERR -> LOG_WARNING
These plugins signal success and failure directly to the console, the
user should inspect syslog for more information.

This change is a follow-up to 340cae4, where kernel logs of LOG_ERR and
higher are allowed to log directly to the console.  Since syslogd has
not been started before these plugins, the log messages would otherwise
leak to the console.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-11-04 10:42:45 +01:00
Joachim Wiberg 6be16f2f6d Fix buggy --with-rtc-date=DATE, introduced in Finit v4.4
In 42ef3d3c, for v4.4-rc1, support for setting a custom RTC restore date
was introduced.  Unfortunately the configure script was wrong and caused
config.h to contain

    #define RTC_TIMESTAMP_CUSTOM "$rtc_date"

instead of

    #define RTC_TIMESTAMP_CUSTOM "2023-04-10 14:35:42"

Furthermore, the error handling for strptime() was wrong, so the restore
date was always reverted to the default.

This patch fixes both issues and extends the DATE of --with-rtc-date to
also include seconds.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-11-04 10:42:45 +01:00
Joachim Wiberg bc8118d515 Fix #418: support systems with a broken RTC
This patch introduces a new configure option --with-rtc-file=FILE.  When
enabled the RTC plugin detects missing RTC device and falls back to save
and restore system time from a file instead.  When --with-rtc-file is
used without an argument the default file is /var/lib/misc/rtc, but the
feature itself is disabled by default.

The usefulness of this feature may not be obvious at first, but some
systems are equipped with an RTC that resets to a random date at power
on.  This can be really bad in the case the date is far in the future,
because an NTP sync would then cause time skips backwards, which shows
up in logs and causes a whole lot of pain in alarm systems.

The solution is to disable the RTC driver or device tree node, and when
Finit starts up, the RTC plugin detects a the device node and instead
restores time from the last save game.  Meaning time will always only
move forwards.

NOTE: when Finit is built --with-rtc-file we always save to disk, but
      only restore from the "save game" if restoring from RTC fails.
      If the system has no RTC we always restore from disk.

      As an added bonus, this change also makes sure to periodically
      sync also the RTC with the system clock.  Useful for systems
      that do not run an NTP client.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-11-04 10:40:35 +01:00
Joachim Wiberg 0c0e880f3f plugins: refactor rtc.so
Factor out time_set() and time_get() for readability and reuse.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-11-03 09:45:27 +01:00
Joachim Wiberg 119e66a7e9 Reset color attributes and clear screen when starting up
Some boot loaders, like GRUB, leave background color artifacts from
their boot menu.  This patch resets the foreground and background
color attributes, and then clears the screen, without clearing the
scrollback buffer.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-10-28 10:58:04 +01:00
Joachim Wiberg 46ffa81f5c Only mark rdeps dirty if main service is nohup
This patch changes a behavior that's been default since Finit 4.0,
introduced in 4d05bf9 with 4.0-rc2.

If service B depends on A and A needs to be reloaded, then B may be
affected.  If A is declared as NOHUP <!>, then A will be stopped and
restarted, during which time the condition it provides is removed,
and B will also be stopped.

However, and as of this patch, if A is declared supporting HUP, then the
condition A provides will only go into flux, during which time B will be
SIGSTOPed instead of needing to be reloaded.

Fix #415

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-10-17 14:33:30 +02:00
Joachim Wiberg 54701422a5 Bump version for v4.8 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-10-13 19:42:44 +02:00
Joachim Wiberg 9d463e3823 Update ChangeLog, added fistmpfs() check and zebra stop fix
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-10-13 19:42:44 +02:00
Joachim Wiberg 56e558c960 initctl: add support for showing template@foo.conf
Fixes #411

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-10-13 19:40:21 +02:00
Joachim Wiberg dfaf351da1 Fix #414: zebra immediately restarts if manually stopped
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-10-13 19:40:21 +02:00
Joachim Wiberg a8433fcb7f test: ignore unreachable shellcheck warning
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-10-12 08:39:30 +02:00
Joachim Wiberg 2daa953bee Merge pull request #409 from liuming50/prevent-nftw-follow-symbolic-links 2024-08-24 14:56:28 +02:00
Ming Liu 3e3e9aadf5 tmpfiles.c: prevent nftw follow symbolic links
When dealing with "L+" and "R", the function call 'nftw' should not
follow symbolic links, otherwise, it would also delete the targets
which is wrong.

For instance, if there is already a symbolic link:
```
/path/to/the/link -> /path/to/some/folder
```

if we set the following in a tmpfile conf:

```
L+ /path/to/the/link -    -    -     - /path/to/the/target
```

the result would be /path/to/some/folder also get deleted, which it
should not.

it could be even worse, when the symbolic link already is pointing to:
/path/to/the/target, the whole /path/to/the/target would be deleted on
next system boot.

Signed-off-by: Mathias Thore <mathias.thore@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2024-08-24 13:29:10 +02:00
Joachim Wiberg dc873c6548 Show expanded prefix and libdir in summary
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-08-19 08:02:12 +02:00
Joachim Wiberg 29bd7a504e Merge pull request #408 from mandelmassa/master
Avoid remounting already mounted /run and /tmp directories

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-08-06 13:13:49 +02:00
Mathias Thore a0685219cf Avoid remounting already mounted /run and /tmp directories
Adds the function fistmpfs to determine if a new tmpfs mount should be
performed on /run and /tmp. The function supports cases where more
complex mount hierarchies are in use, including overlayfs backed mounts.

Signed-off-by: Mathias Thore <mathias.thore@atlascopco.com>
2024-08-05 14:33:43 +02:00
Joachim Wiberg 13b107b7b1 Fix #407: extend initctl poll timeout
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-06-22 09:23:14 +02:00
Joachim Wiberg 409d68d05b Update ChangeLog
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-06-22 09:20:28 +02:00
Joachim Wiberg ab62b5282b runparts: add -b (batch) mode for syslog output
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-06-19 09:20:03 +02:00
Joachim Wiberg d02d65feeb .github: minor, bump action version
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-06-19 09:20:03 +02:00
Ming 9a0dea6aef configure.ac: make cgroup2 configurable (#406) 2024-05-11 14:06:01 +02:00
Joachim Wiberg 7481505b1a plugins: minor refactor
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-28 19:38:03 +02:00
Joachim Wiberg 8251f1a422 Fix derefernce before NULL check
Found by Coverity Scan

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-28 14:40:05 +02:00
Joachim Wiberg e269176a79 plugins: fix possible use of unitialized variable
Found by Coverity Scan

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-28 14:39:30 +02:00
Joachim Wiberg 612f5a9385 Allow building Finit --without-rc-local support
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-28 14:25:53 +02:00
Joachim Wiberg 4a2381eb6f Fix #404: possible undefined behavior --without-fstab
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-28 14:22:57 +02:00
Joachim Wiberg 0cae7d44dd Follow-up to 6a89e60, len may be used unitialized
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-28 14:21:22 +02:00
Joachim Wiberg 340cae4afd Change default behavior, allow kernel logs to console
A Linux system booted with the kernel command line option 'quiet' only
logs error (and above) severity messages to the console.  For embedded
systems, which is the primary target for Finit, this is what you want
to see.

Hence, and after careful consideration, this patch changes the default
behavior of Finit to allow kernel logs to the console.  A build-time
configure flags, --disable-kernel-logging, has been added to restore
legacy behavior.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-24 12:46:59 +02:00
Joachim Wiberg 6a89e60fc8 Fix #405: parsing >1 active consoles in tty @console setups
Systems that have the following tty setup and multiple consoles listed
in /sys/class/tty/console/active misbehave:

    tty [12345789] @console 0 xterm noclear passenv

Only the first listed console is started properly, the remaining ones
were registered using the wrong :ID and no arguments to getty.

This patch fixes the parsing and re-use of the base paramenters for
all consoles listed in the active file.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-24 11:33:35 +02:00
Joachim Wiberg 840d612fc2 plugins: minor, show skipped path in debug
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-03 08:11:50 +02:00
Joachim Wiberg 60c676ab2d test: minor, spelling in comment
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-03 08:11:41 +02:00
Joachim Wiberg deada0fa89 initctl: refactor to use new suffix() function
Reduce code duplication and use suffix() function to check and append a
suffix to a path.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-03 08:10:35 +02:00
Joachim Wiberg 7b501f255b initctl: touch does not support template services
Fixes #403

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-03 07:47:23 +02:00
Joachim Wiberg 052136cb99 initctl: touch does not respect -n switch
Fixes #402

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-02 16:07:01 +02:00
Joachim Wiberg 742b8b72cc Update ChangeLog for v4.8-beta1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-30 12:39:06 +01:00
Joachim Wiberg c37037c015 system: allow udevd to read its arguments from /etc/default/udevd
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-30 12:38:50 +01:00
Joachim Wiberg c32b5a749a Refactor popen()/pclose() logic in ifupdown calls
Currently no code checks the return code of ifupdown at runlevel
changes, but for future reference this code has been refactored
to match the changes made in cbdb949 to fix issue #400.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-30 12:38:50 +01:00
Joachim Wiberg 7701718d7b Fix #400: resolve exit code from pclose() by calling WEXITSTATUS()
This problem affects all calls to run_interactive() that check the
return value of the command.  Causing HOOK_MOUNT_ERROR to *not* run
on mount failure, and sulogin() to *not* be started on fsck error.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-30 12:38:50 +01:00
Joachim Wiberg eb4eca9607 test: verify pre:/post:scripts also for configlets
For a background, see issue #399

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-23 08:55:42 +01:00
Joachim Wiberg cab94b81e8 Bump version for start of 4.8 release cycle
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-23 08:31:53 +01:00
Joachim Wiberg 5913217808 test: add finit.d/available and finit.d/enabled/ dirs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-23 08:17:03 +01:00
Joachim Wiberg b49f55ab3d tmpfiles.d: ignore x/X command, no cleanup at runtime with Finit
Silence log warnings for command x/X (ignore clean for path), because
Finit does not do tmpfiles cleaning at runtime.

x /tmp/podman-run-*
x /tmp/containers-user-*
x /tmp/run-*/libpod
D! /var/lib/containers/storage/tmp 0700 root root
D! /run/podman 0700 root root
D! /var/lib/cni/networks

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-13 12:06:39 +01:00
Joachim Wiberg bf4a584e2e plugins: add support for hwrng and check if seed file is empty
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-13 12:06:32 +01:00
Joachim Wiberg 90a4df8d12 plugins: on error-retry, don't print "Restoring RTC" twice
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-11 18:53:22 +01:00
Joachim Wiberg 146bf55122 Fix #398: display unsupported initctl command (number) in log
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-11 16:01:30 +01:00
Joachim Wiberg c1ed373398 Fix #397: drop ttinit() for PID 1
After reports from the field, see issue #397, of lockups at reboot,
we've decided to drop this code from PID 1.  It was added before the 4.x
series, when the current progress output was introduced.  For the older
style progress it served a purpose since the placement of [OK]/[FAIL]
was on the right hand side.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-11 15:46:38 +01:00
Joachim Wiberg 5998342b3e system: drop debug mode from udevd
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-02-26 08:41:14 +01:00
Joachim Wiberg 9dc7b8a6b0 tmpfiles.d: skip x11.conf unless --enable-x11-common-plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-02-04 15:27:27 +01:00
Joachim Wiberg c221823654 shutdown: use cond_clear_noupdate() to prevent nested service_stop()
When the system shuts down, or user changes runlevels, we don't have to
call cond_clear_update(), because this can lead to nested service_stop()
calls, which in turn lead to out of sync progress updates:

[ .. ] Stopping Foo
[ OK ] Stopping Bar
[ OK ]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-02-03 17:31:37 +01:00
Joachim Wiberg 248f7d3110 Merge pull request #393 from solt87/patch-1
Improve wording.
2024-01-16 08:04:36 +01:00
Solt Budavári fe90ba5781 Improve wording. 2024-01-15 20:56:16 +01:00
Joachim Wiberg 71c87734b7 Add missing ChangeLog for critical issue triggering v4.7 release cycle
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-08 16:46:56 +01:00
Joachim Wiberg cd060e8af3 getty: trigger /etc/issue compat mode for Alpine Linux
The /etc/issue file on Alpine Linux says "Kernel \r on an \m (\l)", so
\r needs to return the uts release rather than os-release VERSION.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 21:18:58 +01:00
Joachim Wiberg 33a7f123d7 contrib/alpine: link to blog post that goes more in-depth
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 21:07:48 +01:00
Joachim Wiberg d15e28ea6b Update ChangeLog and bump version for v4.7 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 19:48:31 +01:00
Joachim Wiberg 836bfff08b .github: update actions
... and try to fix weekly trigger

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 19:47:12 +01:00
Joachim Wiberg 59152b557c keventd: remove runlevels 0 and 6
The responsibility of the kernel event daemon is to relay kernel events
to Finit.  At shutdown and reboot it is too late for more events and the
daemon should just shut down with other services.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 15:18:52 +01:00
Joachim Wiberg 293b0ffa79 tmpfiles.d/var.conf: fix ordering and add legacy /run/lock/subsys
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 13:59:49 +01:00
Joachim Wiberg d5d9cd5645 tmpfiles: fix error message and ignore unremovable dirs (EBUSY)
Fix copy-paste of error message from cond-w.c

A read-only root filesystem may have /var/lock, while we want to remove
it and add a symlink to ../run/lock.  Ignore errors from this since we
cannot do anything about it.  It is up to the user to fix their skeleton
or use an overlay.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 13:56:31 +01:00
Joachim Wiberg 2f281665af Simplify and add links to Infix, br2-finit-demo, and Buildroot
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 02:00:47 +01:00
Joachim Wiberg b00e7394f8 Update ChangeLog and bump version for v4.7-rc1
No more changes or fixes expected.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 01:51:15 +01:00
Joachim Wiberg d5a5fffa52 Update copyright years
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 01:50:50 +01:00
Joachim Wiberg 4d24c34b28 Update screenshot URL to point to HowTo
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 01:39:30 +01:00
Joachim Wiberg 355265651e Retake new screenshot, fix resolution
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 01:32:52 +01:00
Joachim Wiberg 41093df2a9 Attempt 2, scaled
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 01:27:03 +01:00
Joachim Wiberg 0a816d1fa4 Test bump Alpine screenshot
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 01:23:03 +01:00
Joachim Wiberg 3bfc0f0fca contrib/alpine: drop softdog, we are not built with finit-watchdogd
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 00:59:27 +01:00
Joachim Wiberg 0aa6ee895c contrib/alpine: follow-up to 2c340f83
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 00:59:18 +01:00
Joachim Wiberg b1526fb2d6 contrib/alpine: bump version
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 00:56:41 +01:00
Joachim Wiberg b2624ac160 contrib/alpine: fix install script, grep for contrib/alpine
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 00:56:11 +01:00
Joachim Wiberg 2c340f83ce contrib/alpine: fix syslog.conf vs syslogd.conf
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-07 00:26:19 +01:00
Joachim Wiberg 337ee003bb Mount /dev/mqueue if missing and set sticky bit to /dev/shm
Inspired by Alpine Linux, add /dev/mqueue if missing.  We should check
the /proc/filesystems first, but this is quicker.

The sticky bit ensures only the owner of files in /dev/shm can delete or
rename files.  This is also what Alpine Linux use.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 23:50:30 +01:00
Joachim Wiberg 791df0c986 Refactor, ensure basenm() returns a const char pointer of its arg.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 23:46:17 +01:00
Joachim Wiberg f29e92be21 Minor, update
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 20:02:45 +01:00
Joachim Wiberg 379a63fce4 .github: adjust path for cov-build
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 19:55:55 +01:00
Joachim Wiberg b1f9a11809 .github: update actions, sync coverity with latest
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 19:51:37 +01:00
Joachim Wiberg 2d9c63e48e test: actually verify the service asserts ready before continuing
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 16:31:45 +01:00
Joachim Wiberg d66455496a Fix #392: ensure 'ready' condition is cleared on pidfile removal
A service with notify:pid is 'ready' when the pidfile has been created,
the converse also holds true -- when a pidfile is removed the service is
no longer 'ready'.

The state transition for the service has probably already been done, in
svc_set_state(), clearing all <service/foo/*> conditions when the PID
was collected.  The pidfile event may arrive later, so for completeness
we make sure the 'ready' condition is not recreated at least.

Problem introduced in 912a281 with the original supoport for service
readiness notification.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 12:25:41 +01:00
Joachim Wiberg 77cf72cb40 test: regression test to reproduce issue #392
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 12:03:33 +01:00
Joachim Wiberg 6cc587068b Log service identifier, not process name, in debug message
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 11:59:46 +01:00
Joachim Wiberg cc96e8908a Open v4.7 release cycle
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 11:59:33 +01:00
Joachim Wiberg adb25d52cd test: minor, rename test case native -> pid
We now support notify:pid, so let's use it, even though it's the default.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 10:13:13 +01:00
Joachim Wiberg 7d09567ec8 Mention cgroup.root workaround to Linux SCHED_RR limitation
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-05 10:27:03 +01:00
Joachim Wiberg 9130af1c77 Merge pull request #390 from Stargirl-chan/master
Fix compilation on musl by implementing a custom basename

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-12-29 14:57:10 +01:00
Stargirl-chan cbea83b369 Simplified function comment and follow coding style 2023-12-29 13:37:08 +01:00
Stargirl-chan 42cd8d284b Implement custom basename function (basenm)
There exist two possible basename functions, a xpg compliant one in libgen.h
and a GLIBC exclusive one declared in string.h, that was previously also declared by musl libc.
Both implementations are expecting different parameter types (`const char *` for GLIBC and `char *` for xpg)

With the removal of the basename function from string.h in musl libc, we could only rely on the xpg implementation.

Unfortunately, the xpg implementation of basename does modify the contents of whatever you put in it,
even though that there really is no need for it.

This is an issue in some cases, where we might want to get the basename of a read-only variable, e.g. a `const char *`,
as trying to modify something read-only is undefined behavior.

So in order to keep things consistent for us, we implement our own version of basename called `basenm`,
that does not modify the passed argument.
2023-12-29 10:44:40 +01:00
Stargirl-chan 72ebc92622 Fix compilation on musl by using posix basename 2023-12-28 03:41:00 +01:00
Joachim Wiberg 06adecaaea Merge pull request #388 from soggyfries/soggyfries-log-fix
Fix log child exiting with debug disabled
2023-12-19 06:43:24 +01:00
Ryan Rorison efc0592961 Fix log child exiting with debug disabled 2023-12-18 21:00:45 -08:00
Joachim Wiberg ed88469276 Actually silence the log message, missing hunk for previous change
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-12-10 17:32:19 +01:00
Joachim Wiberg cbf96a1de0 Silence 'not available' log messages for nowarn run/task/service
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-12-10 16:42:29 +01:00
Joachim Wiberg cc979f27f1 tmpfiles.d: add missing /var/tmp and /var/lock -> /run/lock
- /var/tmp  https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html
 - /run/lock std Debian

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-22 08:08:24 +01:00
Joachim Wiberg fca5ce57ea Bump version for v4.6 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-13 07:03:30 +01:00
Joachim Wiberg 53aa195ad5 test: update, pid/B is no longer assert by Finit if notify != pid
As of Finit v4.6 we no longer assert the PID condition for services
declaring themselves as notify != pid.  We replace D with a forking
service to catch any future regressions in the pidfile plugin.

No need to check reload PID of D, it is enough to check PID of C.

Also, reduce the number of retries at startup.  If we haven't gone
up within 10 sec with this tiny config something is really wrong.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-13 06:09:35 +01:00
Joachim Wiberg e60211168e Fix type:forking regression in 66020f4, caught by tests
Premise, a service declaring itself 'notify:none' should never assert a
pid condition.  However, forking services still need to be supported and
the only way to do that is if they create a pid file.  Hence, instead of
skipping pidfile_update_conds() completely we need to filter the type.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-13 06:06:58 +01:00
Joachim Wiberg dc3ee9e467 Handle rare warning when registering configuration changes
2023-11-13T04:02:23 [WRN]: conf_change_act():failed registering /etc/finit.conf/ event mask 00000004: Not a directory

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-13 05:05:07 +01:00
Joachim Wiberg 6918f3b711 Update ChangeLog for v4.6
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-13 04:39:08 +01:00
Joachim Wiberg 66020f48ea Do not create PID conditions for services that do not support it
Follow-up to issue #386

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-13 04:37:03 +01:00
Joachim Wiberg 47b0d4cccf Reassert both PID and ready conditions when leaving paused state
Follow-up to issue #386

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-13 04:35:31 +01:00
Joachim Wiberg 92c2efa655 Minor, use svc_ident() instead of incomplete svc->name in debug logs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-13 04:32:30 +01:00
Joachim Wiberg b69aa8a8bd Bump version for 4.6 bug fix release, rc1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-12 19:08:40 +01:00
Joachim Wiberg ca90bbfb04 Fix #387: sanity check environment variables before sourcing
This fixes an issue when finding a global environment variable with
spaces in the variable name:

    set COLORTERM=yes

Literally, 'set COLORTERM' was the name of the variable.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-12 19:07:54 +01:00
Joachim Wiberg 0b5c555c7f Add 'notify:pid' style readiness notifaction and 'readiness none'
This change expands the readiness notification system in Finit with the
native 'pid' style, which will remain the default readiness in Finit 4.x

For systems that want to transition to Finit 5.x early, a global option
to set 'readiness none' in /etc/finit.conf, has been added.  This change
the service default notification mode to 'notify:none', which can also
be set by Finit 4.x ('readiness pid') for select services.

Fixes #386.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-12 19:07:12 +01:00
Joachim Wiberg 6443995fc9 Fix #385: internal conditions are type oneshot, always active
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-12 09:04:35 +01:00
Joachim Wiberg 180faf8a40 test: minor, disable debug as final step in function
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-12 09:04:15 +01:00
Joachim Wiberg 0ebdd32f6b Fix #384: reassemble value fragments after wordexp() before setenv()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-12 08:50:12 +01:00
Joachim Wiberg 60bf858302 test: extend svc-env.sh with more common use-case
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-12 08:37:05 +01:00
Joachim Wiberg 7c86b40190 Fix #383: configure must expand FINIT_RUNPATH_ before define
This fixes an annying buglet that creeped in just before the v4.5 release
causing none of the internal services to be registered properly:

    conf_save_service():Failed creating ${localstatedir}/run/finit/system/dbus.conf: No such file or directory
    plugin_run_hook():Calling modules-load hook n:o 5 (arg: 0x55c4c8133621) ...
    load():Scanning /etc/modules-load.d for config files ...
    cond_set_oneshot():hook/svc/plugin
    cond_set_oneshot_noupdate():hook/svc/plugin => /run/finit/cond/hook/svc/plugin
    cond_update():hook/svc/plugin
    parse_conf():*** Parsing /etc/finit.conf
    conf_save_service():Failed creating ${localstatedir}/run/finit/system/runparts.conf: No such file or directory

The fix, like most, is simple when you find it.  We must expand $runstatedir
before creating the #define in config.h

For convenience, here's the patch for the generated configure script:

&<---------------------------[cut here]---------------------------
--- a/configure	2023-11-05 23:39:51.907334321 +0100
+++ b/configure	2023-11-05 23:39:58.339299795 +0100
@@ -15352,7 +15352,15 @@
 printf "%s\n" "#define FINIT_EXECPATH_ \"$pkglibexecdir\"" >>confdefs.h

-printf "%s\n" "#define FINIT_RUNPATH_ \"$runstatedir/finit/system\"" >>confdefs.h
+	finit_runpath="$runstatedir/finit/system"
+	finit_runpath=`(
+	    test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+	    test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+	    eval echo \""$finit_runpath"\"
+	    )`
+
+
+printf "%s\n" "#define FINIT_RUNPATH_ \"$finit_runpath\"" >>confdefs.h

&<---------------------------[cut here]---------------------------
Ensure you include the three empty lines for context at the end!

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-05 23:46:26 +01:00
Joachim Wiberg 4f3f140a09 Disable Bash completion in 'make distcheck'
We cannot rely on the auto-detection of Bash completion dir during 'make
distcheck' because autotools does not use DESTDIR, only --prefix for the
install check, and pkg-config returns a system path.

Also, show detected path in configure summary for debug.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 22:54:42 +01:00
Joachim Wiberg 10c24b1674 Minor, reorder alphabetically
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 22:53:20 +01:00
Joachim Wiberg 2b4f89ecd1 test: cannot use absolute path to initctl (distcheck)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 22:09:54 +01:00
Joachim Wiberg c42a6f2869 Update ChangeLog and bump version for v4.5 GA
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 21:05:10 +01:00
Joachim Wiberg 89bb609a7e Update Filesystem Layout section slightly, tie in with bootmisc.so
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 21:04:02 +01:00
Joachim Wiberg da6298aecd test: wait for runparts to finish
In Finit v4.5 we've moved the start of rc.local and runparts to the
transtion from bootstrap to multi-user, so we must give it time to
finish.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 21:04:02 +01:00
Joachim Wiberg 576318cc29 Install Bash completion by default, auto-detect install path
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 20:47:11 +01:00
Joachim Wiberg 0d7d331ad4 Fix minor resource leak at boot, found by Coverity Scan
Introduced in release cycle, no need to document.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 20:11:48 +01:00
Joachim Wiberg c886ecb5cc Add support for multiple if:!foo,!bar to skip loading of service
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 19:25:10 +01:00
Joachim Wiberg 304a096877 test: wait for runparts to finish
In Finit v4.5 we've moved the start of rc.local and runparts to the
transtion from bootstrap to multi-user, so we must give it time to
finish.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 18:16:24 +01:00
Joachim Wiberg 064c7682fc Minor, do not append errno message
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 18:15:34 +01:00
Joachim Wiberg 58239b897b Silence Finit progress output for run/tasks stopping
Sync with Starting message in service_start(), should only be shown for
daemons and sysv services.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 18:01:13 +01:00
Joachim Wiberg 5281d82e80 Fix #378: add run/task support for <!> to allow transition from bootstrap
This odd little feature makes it possible to declare run/tasks with a
condition that does not block Finit transitioning from bootstrap to the
next runlevel.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 17:55:39 +01:00
Joachim Wiberg 5ff28c4dc6 system: minor, ignore generated file
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 16:18:11 +01:00
Joachim Wiberg f2218836af Fix #378: warn on console if run/task times out during bootstrap
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 14:52:26 +01:00
Joachim Wiberg fbb3779d17 Fix bootstrap timeout (120 sec), off by a factor 10 (1200 sec)
Regression in v4.5 release cycle, no changelog notice needed.

Reported as part of issue #378 by Alexander Zangerl.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 13:50:43 +01:00
Joachim Wiberg 68f44f7a97 Fix #377: expand service env:file variables
This change allows us to support constructs like this:

    RUNDIR=/var/run/somesvc
    DAEMON_ARGS=--workdir $RUNDIR --other-args...

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 13:32:09 +01:00
Joachim Wiberg 50e587f447 test: new test, verify env:file variable expansion
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 13:31:36 +01:00
Joachim Wiberg fb4c560196 test: shellcheck fixes to new test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 13:31:31 +01:00
Joachim Wiberg 8b5fa5eeaa test: add optional argument to sep() helper function
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 13:31:01 +01:00
Joachim Wiberg 88ec21e9cc plugins: change wording, we don't recreate machine-id every boot
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 10:14:32 +01:00
Joachim Wiberg 84adec4006 Fix #382: do not clear service conditions if only paused
Introduced back in v4.3-rc2, 82cc10be8, the support for automatic
service conditions have had a weird and unintended behavior.  Any
change in state (see doc/svc-machine.png) caused Finit to clear
out *all* previously acquired service conditions.

However, when moving between RUNNING and PAUSED states, a service
should not have its conditions cleared.  The PAUSED state, seen
also by all conditions moving to FLUX, is only temporary while an
`initctl reload` is processed.  If a service has no changes to be
applied it will move back to RUNNING.

Also, we cannot clear the service conditions because other run/task
or services may depend on it and clearing them would cause Finit to
SIGTERM these processes (since they are no longer eligible to run).

This patch not only adds this pre-condition to `cond_clearn()`, it
also clarifies which state (before or after) the particular code
is interested in.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 01:05:25 +01:00
Joachim Wiberg 19b2b2a279 test: follow-up to 2235fb83
Renamed .conf file for udev/mdev etc. caused 'mdev -df' to start in
tests.  This fix closes that again since none of that is needed in
our small namespaced world.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 01:02:33 +01:00
Joachim Wiberg e4163b7221 test: new test, issue #382
Alexander Zangerl reports that <service/foo/STATE> conditions seem to be
removed when calling `initctl reload`, even though no .conf changes have
been made.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 00:58:28 +01:00
Joachim Wiberg eaef302420 Drop doc/bootstrap.md, inaccurate and confusing to users
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-24 23:43:28 +02:00
Joachim Wiberg d5738da307 system: add support for mdevd, preferred over plain mdev
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-22 13:37:13 +02:00
Joachim Wiberg c9f930c7ad Skip registering service when if:!name matches a named svc_t
The delayed matcehd works when all run/task/services provide their own
unique identity, but for replacements this is sometimes not the case.

Example from system/10-hotplug.conf.in:

    run nowarn conflict:udevd,mdev cgroup.init name:coldplug <service/mdevd/ready> \
	[S] mdevd-coldplug -- Cold plugging system

vs

    run nowarn conflict:udevd,mdevd cgroup.init name:coldplug if:!mdevd <service/mdev/running> \
	[S] @pkglibexecdir@/coldplug -- Cold plugging system

Here they both provide the <run/coldplug/*> conditions, and if the first
is loaded, because we found mdevd, then we should not attempt to load
this one.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-22 13:37:13 +02:00
Joachim Wiberg e2ee372b5d Fix #374: describe automount of /run, /tmp and tmpfiles.d support
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-22 12:18:42 +02:00
Joachim Wiberg 7ff7f93364 Fix #376: describe shell limitations with run/task stanzas
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-22 12:17:07 +02:00
Joachim Wiberg d5a95760ef Replace hardcoded /run/finit/system with configured path
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-22 11:49:37 +02:00
Joachim Wiberg 24d1425b74 Disable modprobe plugin by default, udevd and mdev loads modules
The updated 10-hotplug.conf now ensures modules are loaded, so we no
longer need the modprobe.so plugin to be enabled by default.

Also, update the hotplug "plugin" description, it is kept entirely
for backwards compatibility reasons after the plugin was converted
to 10-hotplug.conf.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-22 11:49:37 +02:00
Joachim Wiberg 43d9e25ba7 Fix #367: add support for mdev's netlink daemon mode
This commit replaces the `mdev -s` call to populate the device tree with
the "new" `mdev -df` daemon mode, introduced in BusyBox 1.31.0, 2019.

In daemon mode mdev listens to kernel uevents, replacing the hotplug use
of mdev.  After creating the netlink socket, 'mdev -df' performs the same
initial scan as 'mdev -s' did.

To perform device (re)discovery, module loading and setup, including any
firmware loading, a coldplug operation is typically required.  This is
done by the new /libexec/finit/coldplug script, by Alexander Zangerl.

Unlike 'mdevadm settle', mdev does not offer any mechanism to detect when
the discovery operation is done: on slower systems the triggering side,
the coldplug script, often completes quite a bit earlier than mdev's
uevent processing.  I.e., depending on <run/coldplug/success> is not an
indicator of all devices having been (re)discovered and fully set up.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-22 11:49:29 +02:00
Joachim Wiberg f27998ae4f Assert <int/container> condition if we detect running in container
Useful both for troubleshooting and for triggering if:<int/container> tasks.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-14 08:37:15 +02:00
Joachim Wiberg c8e0b6b9ef Redirect 'log*' output to console when finit.debug is enabled
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-14 08:34:06 +02:00
Joachim Wiberg f7e8fccb2f system: extend final udevadm settle timeout 5 -> 30 sec
On some systems udev may very well take more than five seconds to complete.
Probing modules, loading firmware, etc.  Note, the timeout only sets the
maximum wait time.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-14 08:29:08 +02:00
Joachim Wiberg 7bbccb1213 Silence non-critical failure to remove /run/finit/cond/ at reboot
The directory may hold various custom generated conditions that are not
managed by Finit.  Not being able to remove the directory is not a
critical error.

finit[1]: cond_delpath():Failed removing condition path /var/run/finit/cond/: Directory not empty

Therefore, ignore ENOENT and ENOTEMPTY and log everything/anything else.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-14 08:25:56 +02:00
Joachim Wiberg d38c333e04 Bump version for final candidate, v4.5-rc5
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-05 08:19:24 +02:00
Joachim Wiberg 095f6b645c Update ChangeLog, should be final changes for v4.5 GA
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 19:01:38 +02:00
Joachim Wiberg b4d10cbade Always ensure /run/finit/system exists before saving runtime service
This fixes the regression in the tests, which runs in a very stripped
down world without tmpfiles.d etc.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 18:48:13 +02:00
Joachim Wiberg 5d703fd39e Support delayed load of services from plugins and bundled services
This adds a new function conf_save_service() replacing service_register() for
plugins and bundled services like watchdogd, keventd, runparts, etc.

The benefits to this change are several:

 - Plugin/Bundled services no longer risk starting before udev or other
   critical services/task have started
 - Definitions can be overridden by an administrator (see docs)
 - Increases visibility (user: where are all these services coming from?)
   Previously the origin (file the service was loaded from) was NULL.
 - Adds another level of extensibility to Finit

The most notable change is that dbus is no longer started before udevd.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 18:37:43 +02:00
Joachim Wiberg eaaf8d862e Minor, append _ to PATH constant
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 18:25:09 +02:00
Joachim Wiberg 2468f11cd8 plugins: fix dbus pidfile locator
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 18:20:50 +02:00
Joachim Wiberg f8a6a119ac system: new name for testserv.conf -> 90-testserv.conf
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 17:30:08 +02:00
Joachim Wiberg 1889b88aab Log execution order at bootstrap to /run/finit/exec.order
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 17:21:11 +02:00
Joachim Wiberg 0d70023bfe Log conf file evaluation order at bootstrap to /run/finit/conf.order
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 17:20:15 +02:00
Joachim Wiberg 41648a073b Fix evaluation order of /lib/finit/system/* vs /etc/finit.d/*
See updated documentation and inline comment for details.

Fix #371

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 17:20:15 +02:00
Joachim Wiberg 33cee0ba5f system: fix lost udevadm calls due to overloading
The system/10-hotplug.conf needs to index its calls to udevadm for all
calls to udevadm, not just the trigger calls.  Otherwise the first
udevadm is overloaded with all subseequent (unindexed) udevamd stanzas.

Also, make sure all udevadm calls to settle/reload are hidden.

Fix #372

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 17:19:46 +02:00
Joachim Wiberg 2235fb8352 system: rename *.conf files to ensure proper execution order
At bootstrap we want to start udev as soon as possible (after any
services registered by plugins).

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-04 11:39:39 +02:00
Joachim Wiberg eb9e94935e Failure to open fstab should log to console, reboot if no sulogin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 17:56:49 +02:00
Joachim Wiberg fb230f2137 .github: add makeLatest flag based on non-rc/beta/alpha
Note, the makeLatest flag can also be set to 'legacy', which takes
latest date and version.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 17:42:20 +02:00
Joachim Wiberg 6aa48a8b32 .github: fix pre-release flag input
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 17:41:52 +02:00
Joachim Wiberg 5b9cebbfd3 Update ChangeLog and bump version for v4.5-rc4
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 16:51:03 +02:00
Joachim Wiberg 38791616e0 Add commented-out developer debug for svc_enabled()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 16:39:46 +02:00
Joachim Wiberg fede3fd2e1 Fix #370: document conditional loading and execution config options
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 16:39:46 +02:00
Joachim Wiberg a46a33238d Display 'run' stanza progress only when they've completed
This is a follow-up to 4701ede.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 16:39:46 +02:00
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 ec5e42694d Silence noisy debug messages, useful only to developers
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 15:14:02 +02:00
Joachim Wiberg 2e73563eea Fix #369: allow runlevel change using initctl during bootstrap
This change opens up the runlevel change API from bootstrap.  The twist
is that the change is only queued, i.e., the call `initctl runlevel 9`
during bootstrap only changes the configured runlevel to go to after
bootstrap has completed.

Effectively, this change allows overriding the `runlevel` directive in
/etc/finit.conf without having to change the file.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 15:11:33 +02:00
Joachim Wiberg 338521a748 Update ChangeLog and bump for v4.5-rc3
No more changes are expected after -rc3.  Will be used for testing in
Infix and br2-ext-finit before the final v4.5 GA.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-24 14:04:28 +02:00
Joachim Wiberg 6ae1083c99 Add support for SysV-only scripts in runparts
This patch extens the SysV compatibility support in Finit by adding
support for limiting `runparts` to run only SNNfoo, or KNNfoo, style
scripts from a directory.

Additionally, by default `runparts` now runs entirely in the background
without any progress.  To enable progress, an optional argument has been
added to the runparts command line.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-24 13:25:35 +02:00
Joachim Wiberg 846806747b Fix #366: document fsck.* command line options and simplify code
As pointed out in #366, the configure options --enable-fastboot and
--enable-fsckfix should just alter the default values of the two fsck
command line options.

This commit simplifies the code and makes it possible to override using
the command line regardless of the two build options.

Finally, add the two command line options to doc/cmdline.md

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-24 11:58:07 +02:00
Joachim Wiberg 8904ca993e test: reindent
Standard Emacs shell-mode 4-space indent.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-18 06:38:59 +02:00
Joachim Wiberg efed0db16b test: reindent, don't warn on PID 0
PID 0 for a collected task is not a bug, 1 or < 0 is a bug.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-16 10:28:48 +02:00
Joachim Wiberg 11946f12d3 contrib: disable bundled watchdog for Alpine builds
In the Alpine reference builds we use 'watchdog' from the BusyBox suite.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-16 10:28:48 +02:00
Joachim Wiberg 2ba359ed80 Merge pull request #365 from markand/man-typo 2023-09-15 12:31:14 +02:00
David Demelier fafd524701 doc: fix typo in finit.8 manual page 2023-09-15 10:50:31 +02:00
Joachim Wiberg 1ee6c9f46b watchdogd: drop startup message, leaks to console
We use LOG_CONS to ensure log messages reach the operator, but since
watchdogd starts very early this means non-critical messages like the
initial greeting leaks to console because syslogd has not yet started.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-15 09:47:42 +02:00
Joachim Wiberg a88eb82a68 Simplify overly complex description, drop links to older versions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-14 10:03:49 +02:00
Joachim Wiberg a436a1c8cb .github: speed up release job, and support for setting pre-release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-14 09:40:55 +02:00
Joachim Wiberg 7cb91854b0 Update ChangeLog and bump version for v4.5-rc2
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-14 09:22:11 +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 480d29175c test: minor, clarify
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-14 09:15:40 +02:00
Joachim Wiberg ea68413512 test: add missing scripts to dist for new runparts test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-14 09:15:17 +02:00
Joachim Wiberg 4edfa9859e .github: fix variable sharing between jobs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-14 09:14:28 +02:00
Joachim Wiberg eb6291c943 Update ChangeLog and bump version for v4.5-rc1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-13 13:26:33 +02:00
Joachim Wiberg 756b7c3fb6 Document advanced hooks/plugins to trigger rescue.conf
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-13 13:03:20 +02:00
Joachim Wiberg 263aec292a Support for disabling invocation of rescue mode from kernel cmdline
The rescue mode that can be invoked from the kernel command line is
potentially unsafe.  Many systems lock the root user account, or use
another account for managing, e.g. 'admin'.  The sulogin program(s)
would on such systems give the user a root prompt.

In #357 we added support for setting a custom sulogin user, but for some
systems that is not enough.  On many embedded systems the /etc/passwd
and shadow files are populated at bootstrap and at the time rescue mode
runs, these files will be unpopulated.

The only, truly safe, approach on such systems is to disable rescue mode
completely.  Otherwise intricate Finit plugins have to be used that run
before rescue mode is started -- increasing the complexity of the system
as a whole.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-13 12:45:03 +02:00
Joachim Wiberg 5a946a4ea7 doc: clarify what single user mode does
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-13 12:44:33 +02:00
Joachim Wiberg c90b4d797b doc: clarify eval order of sulogins in traditional rescue mode
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-13 12:44:00 +02:00
Joachim Wiberg 6e7a2fb6d5 Fix #357: allow sulogin with user different from 'root'
In issue #357 there's a proposal for optionally allowing /bin/login, but
after intense discussions we've agreed that would be opening up for all
sorts of potential (security) issues.

it's better to keep things as-is but with the added twist of supporting
a custom user at configure time, e.g., 'admin'.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-13 11:37:15 +02:00
Joachim Wiberg ddedcf77e8 Follow-up to 4701ede: reschedule bootstrap check while not done
Non-trivial systems, like Infix[1], require more than one lap around the
track to warm up.  This is a follow-up to issue #362, commit 4701ede, in
fixing an obvious oversight in the new sm_check_bootstrap() work.  While
there are still outstanding bootstrap tasks or services that have not
yet started, we must reschedule the worker.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-13 09:35:02 +02:00
Joachim Wiberg 924ec2ef80 test: add missing runlevel/ref.log
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 21:18:28 +02:00
Joachim Wiberg a49f27c191 initctl: show runlevel 'N S' instead of 'N 10' during bootstrap
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 14:05:11 +02:00
Joachim Wiberg b41b4ce989 test: new, verify runparts order
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 14:04:26 +02:00
Joachim Wiberg 3d74e93fa2 test: when rc.local is busy, delay test until it's free
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 14:03:43 +02:00
Joachim Wiberg 443700a88e test: new, verify that a run task can call initctl
Follow-up to #362

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:30:57 +02:00
Joachim Wiberg 4701edef4c Fix #362: prevent blocking main loop when starting run tasks
Drop complete() logic, waiting for run tasks to finish, from the
service_start() funciton to the general service_monitor().  This
refactor frees up the main loop and allows us to answer any API
calls from initctl even from the run task itself.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg e6da0a22e7 Helper script for development/test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg 7be2bbbc30 doc: add SysV Init Compatibility section
Minor updates and fixes to other sections as well.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg 3e269c632f Start runparts with -d in debug mode, otherwise -p for progress
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg f2507d9fd7 runparts: fix arg handling and skip backup files
For some specialized forms of runparts, e.g., start-stop scripts in SysV
init replacements, there is a need to append an argument.  Typically
this is 'start' or 'stop'.

This functionality has been broken for quite some time, meaning we
should consider it being unused by current users of Finit.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg e9f403bceb runparts: simplify and adjust log levels
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg c03176c42a doc: relocate text to common TODO file
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg 9707bfb103 TODO: things to fix before release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg 11430f83c8 Use unbuffered stderr for runparts logging result and progress
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg a22a794f55 Clarify usage text slightly
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg 5556501287 dbg(): add missing \n for stderr logginge
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg ab554568b2 test: handle very short tests that exit before reaching runlevel 2
Bootstrap-only tests that just verify basic functionality are often very
short.  This change handles that by retrying SIGUSR2 until Finit has had
the chance to finalize bootstrap and enable signals.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg b39a4498a3 test: enable bootstrap-crash, regression test for #351
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg dead2444e2 doc: 'run' command limitation, blocks Finit completely
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-30 10:21:07 +02:00
Joachim Wiberg a58002588e Refactor initial startup, run runparts and rc.local in background
The code refactored in this commit has long been an eyesore.  The
hand-over, from the sequential main() function, to the event loop
was clumsy at best and was very difficult to debug.

Instead of using a series of workers we now delegate everything to
the big state machine by introducing a new SM_BOOTSRTAP_WAIT_STATE.

Both the runparts and rc.local scripts now run in the background, no
longer blocking the event loop from responding to initctl calls.  To
ensure they run at the same point in time two things have been done:

 1. A new <int/bootstrap> condition has been added which triggers
    runparts, which now is a regular task created by conf_init()
 2. /etc/rc.local is started from SM_RUNLEVEL_WAIT_STATE when we
    transition from runlevel S to any other runlevel.

Fixes #356

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-30 10:09:34 +02:00
Joachim Wiberg 28e101aaae Minor, ensure we can call exec_runtask() with NULL args
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-29 23:22:07 +02:00
Joachim Wiberg 6da8af8136 Minor, add debug logs and clarify comment
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-29 23:21:27 +02:00
Joachim Wiberg 3069e753e1 getty: add missing '-p' in usage text
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-27 13:34:45 +02:00
Joachim Wiberg aafd5c1010 Allow overriding SCREEN_WIDTH
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-27 13:33:57 +02:00
Joachim Wiberg 2f51c8ea0d test: minor, log() -> inf()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-27 13:33:22 +02:00
Joachim Wiberg d1130473fc Follow-up to 1fc0f36, missing %s argument
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-27 13:33:00 +02:00
Joachim Wiberg b682a5e4fe Fix #360: Bash completion for initctl
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-17 07:31:59 +02:00
Joachim Wiberg 1fc0f36c6c initctl: check [enable | disable] for absolute path, not supported
For reference, see issue #359.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-11 08:06:46 +02:00
Joachim Wiberg 5df5b22327 man: update finit.conf(5) with info on enabled and available
This should clarify the messup on the behalf of the mainatiner in not
documenting this properly, including the deviations introduced in v4.4

See issue #359 for a background.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-11 07:57:57 +02:00
Joachim Wiberg 4153c7966d Fix #358: fix modify events for /etc/finit.conf
- iwatch events return filenames in dir field, ignore file for those
 - improve warning message on failure
 - drop bogus "Out of memory" error log message

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-10 14:20:36 +02:00
Joachim Wiberg 458d68533f Update ChangeLog
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-10 13:37:25 +02:00
Joachim Wiberg 63b5db38df Refactor, ensure pre:/post:/ready: scripts run in the same cgroup
Related to issue #361.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-10 13:25:11 +02:00
Joachim Wiberg 2135639508 Update changelog with latest fixes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-10 10:27:29 +02:00
Joachim Wiberg 9c8cd6c024 Improved logging on failure to execvp() in forked child
The execvp() call always fails with -1, so only logging exit code when
collecting the PID is not enough.  When debugging the user needs to see
the errno from execvp(), e.g., "No such file or directory", when the
command was missing the absolute path to the executable.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-10 10:23:20 +02:00
Joachim Wiberg 450f498061 Fix #361: cgroup move fail if starting service as non-root
Regression in v4.4

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-07-10 10:23:20 +02:00
Joachim Wiberg 5769500afe Bump devel version and update ChangeLog for v4.5 release cycle
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-27 12:33:16 +02:00
Joachim Wiberg dc61969164 Check in service_stop() if the process is already dead
Related to 6f0d448 in that we check if the kernel knows about this
process before we try to stop it.  If it's already dead we clean up
and return.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-27 12:22:59 +02:00
Joachim Wiberg 6f0d448765 Fix #227: delayed service_kill() may stall shutdown/reboot
This turns out to be the root-cause of #227.  Finit is waiting forever
for proceeses to stop at shutdown/reboot, while a subreaper has already
collected the PID, or Finit for some reason did not collect the PID.

When the process timeout calls service_kill() we now check if the kernel
actually knows of this process or not.  If it's already been collected,
we can notify Finit of this by calling service_monitor() to clean up the
'svc' and in turn call sm_step() to finalize the state transition.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-27 12:18:09 +02:00
Joachim Wiberg 0c9b7a67e0 doc/plugins.md: fix script hook path
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-27 12:14:26 +02:00
Joachim Wiberg 5db2fb2c32 initctl: let -f force-skip check for built-in service
When calling `initctl -b create` from a start script at bootstrap you
risk blocking the boot since Finit currently cannot reply to IPC during
that period.

This patch allows -f to override this builtin check for the following
initctl commands:

 - touch
 - show
 - edit
 - create
 - delete

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-20 10:25:02 +02:00
Joachim Wiberg f4d3ec1a9f Update ChangeLog and bump version for v4.4 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-15 16:40:56 +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 7850378e15 Fix issue with messed up linewrap in qemu-system-x86_64
Apparently the qemu-system-x86_64 in -nographics mode does all sorts of
crazy things to the terminal.  Most annoying, it disables linewrap.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-15 16:05:59 +02:00
Joachim Wiberg 438d6b4e63 Document fix of regression from Finit v3.2
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-14 09:33:10 +02:00
Joachim Wiberg 712f68f9da Fix #355: regression stopping a process and its group
In 91a9c83 a regression was introduced that affects the way Finit stops
a supervised process and its process group.

Instead of sending SIGTERM to the process, delegating the responsibility
to that process to inform any children it may have, Finit as of 91a9c83
sends SIGTERM to the entire process group.  For SIGKILL this is fine,
SIGKILL only runs as cleanup and as a last ditch effort if the process
doesn't respond to SIGTERM.

This regression, introduced in v3.2, directly affects services like
avahi-autoipd that have forked off children that it needs to tell to
exit cleanly before it returns. With the patch in question these
children are never allowed to complete, which in turn causes lingering
169.254 link-local addresses on interfaces.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-14 09:27:09 +02:00
Joachim Wiberg 8a32ec5c92 Bump version for v4.4-rc2
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-08 09:58:42 +02:00
Joachim Wiberg 081622a085 Enable more features at distcheck for improved coverage
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-08 09:56:25 +02:00
Joachim Wiberg 2526431d8e Allow Finit to inherit PATH and SHELL from env.
When started as a monitor in a container, or for the test suite run from
distcheck, we must allow Finit to find its own tools like initctl.  This
should also be a more generic solution that cover more cases.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-08 09:52:59 +02:00
Joachim Wiberg 47d8a83668 Drop hard coded path limit in glob of *.conf files
A simple distcheck revealed that the local path[] was too small to store
something like /home/jocke/src/finit/finit-4.4-rc1/usr/lib/finit/system/

This refactor should cover all cases.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-08 09:52:21 +02:00
Joachim Wiberg f72f3febf9 Follow-up to e00fda5, allow runlevel 0 for kevent and watchdogd
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-08 09:49:06 +02:00
Joachim Wiberg 138546d008 .github: debug failing tests in release build
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-07 21:06:17 +02:00
Joachim Wiberg cee244d151 Drop TODO, sysv works as well as they can right now
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-07 20:55:00 +02:00
Joachim Wiberg 7af4ad5c24 .github: Release General needs a new uniform!
We've prepared this at one of the finest tailors at Saville Row.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-07 20:53:25 +02:00
Joachim Wiberg c0d3705ed5 Bump version for v4.4-rc1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-07 20:45:03 +02:00
Joachim Wiberg 5cf2b9a283 Massive update of ChangeLog, add missing early changes after v4.3
Finit v4.3 is now almost a year old ... time to get v4.4 out the door!

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-07 20:42:20 +02:00
Joachim Wiberg 0e898da6e5 doc: minor, whitespace
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-07 20:42:11 +02:00
Joachim Wiberg d9f13a1e50 Notable breaking change in runlevels
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-07 11:53:22 +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 b6c5498f43 initctl: refactor serv_enable() for readability and coding style
Also apply the same logic to serv_disable() to drop 40 char limit on
service names.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-05 05:40:26 +02:00
Joachim Wiberg 9a6c68c952 initctl: follow-up to 700c32fd, fix enable regression
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-05 04:32:09 +02:00
Joachim Wiberg e8170e1216 doc: add use-case for runparts scripts
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-04 10:05:40 +02:00
Joachim Wiberg 059a4c8a86 man: document new kernel cmdline options
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-02 00:22:50 +02:00
Joachim Wiberg 0de9db68a3 system: don't warn if neither udev/udevadm or mdev is available
The user may have their own setup of things, by default we should not
cause unnecessary warnings in syslog.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-01 23:53:40 +02:00
Joachim Wiberg aeff68b598 test/rclocal.sh: new test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-01 23:50:57 +02:00
Joachim Wiberg 700c32fd73 Initial support for templating and instantiating services
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-24 20:14:30 +02:00
Joachim Wiberg 334d4a708a Follow-up to e00fda5: skip bootstrap-only services when not in bootstrap
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-24 16:28:49 +02:00
Joachim Wiberg 4d472273e1 .github: debug weekly
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-23 16:47:47 +02:00
Joachim Wiberg 13f1359b3a .github: fix and simplify weekly distcheck job
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-22 15:46:06 +02:00
Joachim Wiberg 2e5b97c8b2 plugins: check explicitly for (time_t)-1 from mktime()
Found by Coverity Scan.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-22 15:30:29 +02:00
Joachim Wiberg 9a962c86c8 Update docs a bit about runlevel 1.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-22 15:11:27 +02:00
Joachim Wiberg f954a4cb92 service_stop: add missing && do_progress for print_result()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-22 15:11:27 +02:00
Joachim Wiberg feb97bc77c Minor, helper function for logging runlevel as a char
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-22 15:11:27 +02:00
Joachim Wiberg e00fda5dc3 Fix #352: separate runlevel S from runlevel 0
Due to an old design decision runlevel S was encoded internally as '0',
meaning it was the same as halt/poweroff.  If you want to run scripts at
system shutdown this was less then ideal since it meant your scripts
also ran at bootstrap.

This change is quite invasive.  It introduces INIT_LEVEL (10) as the
value for runlevel S, meaning all code that parses and/or evaluates
anything for runlevel 0/S was affected and had to be reworked.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-22 15:11:27 +02:00
Joachim Wiberg 80191f2fd5 plugins: allow building with -D_FORTIFY_SOURCE[=1,2]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-22 14:28:08 +02:00
Joachim Wiberg 42ef3d3cf7 plugins: add configure support for overriding RTC fallback datetime
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-10 16:35:42 +02:00
Joachim Wiberg 1f4acb322a m4: simplify and fix issue with AC_PLUGIN() going out of bounds
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-10 16:33:03 +02:00
Joachim Wiberg c3ba15045b plugins: let dbus start as soon as possible
Some services (openresolv) tries to talk to it very early, so lets get
dbus up and running as soon as possible.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-27 14:28:12 +02:00
Joachim Wiberg 8f1d1717f8 initctl: let -n ignore errors from enable/disable as well
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-27 14:27:16 +02:00
Joachim Wiberg 7703d00e82 Fixed TODOs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 16:34:34 +01:00
Joachim Wiberg 3bb826b22b Ensure all a process' children are in the same cgroup
The logger redirection process was sometimes in the init group instead
of the system/<svc>/ group.  This was due to the parent PID being moved
after the logger was forked.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 16:32:28 +01:00
Joachim Wiberg 9ee2be121f Fix in-service cgroup parser regression
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 16:31:43 +01:00
Joachim Wiberg 36c6aa73aa Fix #351: clean run tasks to prevent endless restarts
When we've started a run task, regardless of its exit status, we must
mark it as not dirty to prevent it from being endlessly restarted.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg 13dddb6912 test: new regression test for issue #351
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg bdaf3370d4 test: sectionalize
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg a24077c4af TODO: cond fixes and run/restart-forever test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg 414a49d733 Fix regression in .conf reload when changing runlevel
When the inotify callback is called for a file that has been removed,
the call to realpath() obviously fails (ENOENT).  This fix only takes
the regular case into account, files removed from a symlinked enabled
directory is not handled -- needs more work for that.

Regression introduced in 0a94f3f, PR #347, issue #346.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg be9d54561d Fix WIFEXITED() logic when collecting reaped processes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg 3ce5a2a965 Minor, increased logging on failure to start external logger
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg 1d03e9aa8b Follow-up to a47abfd, fix logged PID reported by external logger tool
Issue #344

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg 5340e47e81 Flush .conf event queue before leaving boostrap
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg 98bbf4a1e5 test: add watchdog to catch runaway tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg d70e2f1ed0 Minor refactor, rgen only needed here
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-19 09:33:33 +01:00
Joachim Wiberg ecb5949679 Follow-up to a613ee9, handle reload as well (existing svc)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-19 09:33:33 +01:00
Joachim Wiberg e55fd19091 Remember to audit sysv services
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-19 08:36:52 +01:00
Joachim Wiberg 19c64e323c Add another log macro, note()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-19 08:35:02 +01:00
Joachim Wiberg 9354221bdd initctl: fix regression in error handling, cmmmit 4542fdb
Issue #339

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-19 08:32:06 +01:00
Joachim Wiberg 1d7048d3ae system: trim delay starting udevd
- Apply dracut[1] and void[] linux lessons
 - Drop udev-finish, not needed anymore (2015)

[1]: https://github.com/dracutdevs/dracut/blob/1ff306a3964840fc548188a8aa4862143b347e8a/modules.d/99base/init.sh#L152-L170
[2]: https://github.com/void-linux/void-runit/blob/master/core-services/02-udev.sh

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-10 18:30:50 +01:00
Joachim Wiberg 8251d713e0 devmon: reduce debug loglevel
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-10 07:52:18 +01: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 571250a9b9 test: drop hotplug.conf system file during tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-05 10:49:14 +01:00
Joachim Wiberg 91540fd793 Issue #351: unable to reproduce
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-05 10:48:45 +01:00
Joachim Wiberg 2566e00ef0 .github: finit -h now require super user privs.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-05 10:12:56 +01:00
Joachim Wiberg 1e5ce38928 Return EX_NOPERM for non-root users calling init/telinit
See issue #301 for future per-user support.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-05 10:05:24 +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 c4dcf568c8 Extend conditional load support with if:<cond> and if:<!cond>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-05 09:47:51 +01:00
Joachim Wiberg b65773d508 Drop logically dead code, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-04 12:09:50 +01:00
Joachim Wiberg e75c1792aa tmpfiles.d: propagate possible error from remove() in mksubsys()
Found by Coverity Scan.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-04 12:02:52 +01:00
Joachim Wiberg 0be4838e01 Fix potential NULL pointer deref, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-04 12:01:24 +01:00
Joachim Wiberg b71605c819 Fix potential NULL pointer deref, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-04 11:59:09 +01:00
Joachim Wiberg 3bb2eb2a8d Fix potential socket leak at bootstrap and shutdown
This is a follow-up to a39ee0b, found by Coverity Scan.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-04 11:44:48 +01:00
Joachim Wiberg 8ce35771c3 initctl: fix potential memory leak
Found by Coverity Scan.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-04 11:43:57 +01:00
Joachim Wiberg 67e80ea989 initctl: ensure the returned plugin buffer data is terminated
Found by Coverity Scan

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-04 11:43:10 +01:00
Joachim Wiberg f4d8ecfb5b getty: fix memory leak in parsing /etc/os-release
Found by Coverity Scan.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-02 21:24:24 +01:00
Joachim Wiberg 2eb3ebb404 test: /var a tmpfs to prevent tests from trampling on each other
Multiple parallel tests writing to the same /var leads to quite
unexpected results.  Let's start fresh in each test instead.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 1e1b3564dd Support for fsck_mode=[auto,skip,force] + fsck_repair=[preen,no,yes]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 7af257cccf Migrate hotplug plugin to a conditional system/hotplug.conf file
This is the first example of the just minted advanced stanza syntax with
if-statements, conflict handling, and nowarn flags.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 84ddac65e5 Migrate testserv plugin to a couple of lines of ASCII .conf files
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 62d6b56fd3 plugins: only run pam_console_apply if available
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +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 f796d59f77 Minor, improve log message slightly
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 97ca450966 Add support for static services in /lib/finit/system/*.conf
Slowly migrating away from hard-coded services in plugins.  This way
it's possible for the user to both inspect and override as needed.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg e0c1c08e68 plugins: remember that bootmisc depends on pidfile plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg c81b722691 tmpfiles.d: add support for 'l' and 'l+', Finit extensions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 11da93b759 Add support for Finit specific tmpfiles.d/
The tmpfilesd() glob sorts files according to name, we could name our
.conf as 00finit.conf to prevent ordering issues with, e.g. dnsmasq,
but this is more elegant and allows for multi-level override.

NOTE: bootmisc depends on the pidfile plugins since the latter need
      to set up its iwatches of /run before bootmisc creates /run.
      Depending on if it's a system with /var/run or /run we need to
      drop /var/run before recreating it.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:49:55 +01:00
Joachim Wiberg 28a90a793d New log macro info() for LOG_INFO level logging
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 a613ee908f If a run/task/service command does not exist, skip registering it
This changes the semantics of Finit a bit by checking for the command to
run when registering it, skipping commands that cannot be found in the
absolute path provided in the command, or in $PATH.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg d3f58b5df0 Minor, add missing else statement
For completeness, never triggered.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg af88b10322 Minor, simplify
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg 966ae9fb0d Rename FINIT_LIBPATH_ -> FINIT_EXECPATH_
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg a69cef0a11 paste(): only add '/' if dir and file are missing a '/'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg b396a018c5 test: install busybox symlinks with relative path
Then it works to run the applets from outside the unshare.  Useful for
testing and test development.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg a4af9ba248 Add limited tmpfiles.d(5) support
This change adds very basic tmpfiles.d/ support to Finit.  Much of the
basic types are supported, but not all, so for now, please check the
code for details on what is working.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg 6942e38413 Relocate ln() helper function
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg e03bd093b5 mksubsys(): if makedir() fails with EEXIST, make sure to chmod()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg d6070a0d10 Drop old now unused /etc/network/run/ifstate
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg bd4efb59ca Refactor, change API for create()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg a90cfd4a75 plugins: fix octal permission on /run/lock and /var/lock
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg ab5a983bf7 test: only run checkself.sh on enabled tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg f7bacf8b1b Add 'set' keyword for environment variables set in /etc/finit.conf
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-22 19:56:29 +01:00
Joachim Wiberg d363501e21 Fix parse/diff of command line args, e.g., nginx -g 'daemon off;'
Starting a service like this works fine:

    service [2345789] env:-/etc/default/nginx nginx -g 'daemon off;'

However, on `initctl reload` the previous argument was lost while
parsing the end of the new one.  So the comparison always resulted
in a 'diff' causing the service to be unnecessarily restarted.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-22 19:46:33 +01:00
Joachim Wiberg 4150fdfe59 Gracefully handle leading 'boot/' in command line conditions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-17 13:14:42 +01:00
Joachim Wiberg 4d2b97e4cc plugins: spellcheck
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-15 19:29:11 +01:00
Joachim Wiberg 21eda9dd1c plugins: create cache dir for nginx and runstatedir for clixon
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-15 19:21:09 +01:00
Joachim Wiberg 4f7e726a3e test: initial regression test for #351 (WIP)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-11 16:48:21 +01:00
Joachim Wiberg 74fc16b832 test: add support for running a bootstrap config
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-11 16:47:03 +01:00
Joachim Wiberg 7393072120 Log exit status of run tasks in debug mode
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-11 16:30:34 +01:00
Joachim Wiberg 96bb3f5c6c Merge pull request #349 from wkz/initctl-cond
initctl: Follow priciple of least surprise for "cond get"

Fixes regression in 4.4 release cycle, commit c3c662f, when support for FLUX condition state was added.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-06 16:13:13 +01:00
Tobias Waldekranz c23a867485 initctl: Follow priciple of least surprise for "cond get"
The accepted standard in Unix is to report successful executions with
exitcode 0. Therefore, map a "initctl cond get" of a condition to the
following exitcodes:

- On: 0
- Off: 1
- Flux: 255

Fixes: c3c662fe64 ("initctl: ensure 'cond get' support flux state")
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
2023-02-06 16:01:18 +01:00
Joachim Wiberg 4f8a5a6531 Follw-up to 4894580, unbreak TTYs
The TTY and log configuration is overloaded using a union in svc_t, so
we cannot "reset" the log attribute on reload.  In fact, a TTY should
never be allowed to have a tty:anything set, so change the parser to
ignore log options for ttys.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-06 15:47:19 +01:00
Joachim Wiberg 48e1a0b17f Another ChangeLog update for the upcoming v4.4 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-06 12:54:54 +01:00
Joachim Wiberg 9c727ed08d test: namespace cleanup, common -> src, tenv -> lib, etc.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 19:04:48 +01:00
Joachim Wiberg 49cd3a441d test: whitespace only
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 18:40:06 +01:00
Joachim Wiberg 8b9258aa73 test: rename tenv-root -> sysroot
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 18:19:23 +01:00
Joachim Wiberg 82c6e4680f Fix issue with pid://../run/foo..pid parser
Unfortunately we cannot use realpath(3) here since the the PID files
usually do not yet exist at this point.

Add and modify my ugly de_dotdot() from Merecat httpd.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 18:16:27 +01:00
Joachim Wiberg a67b2ba9a7 test: new regression test, //run/foo.pid -> /var/run///run/foo.pid
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 18:07:12 +01:00
Joachim Wiberg a96edf0291 test: minor, rename fn
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 17:09:47 +01:00
Joachim Wiberg c26dded49c Further box-in testserv so it doesn't conflict with other serv tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 14:42:32 +01:00
Joachim Wiberg 3bd15a53d6 We take conditions on the kernel command line now
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 14:25:20 +01:00
Joachim Wiberg f0a888c0d1 test: update Makefile.am and build instructions, new testserv plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 12:07:35 +01:00
Joachim Wiberg b6769356b2 test: minor, replace 'texec sh -c' -> 'run'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 11:22:26 +01:00
Joachim Wiberg 5a9cafc2fc Minor issues, as reminders in Magit
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 11:02:25 +01:00
Joachim Wiberg 2e36590bbd plugins/bootmisc: create /run/dnsmasq directory, for resolv.conf
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 11:02:25 +01:00
Joachim Wiberg 33e504b928 Check if WDT_DEVNODE is defined, may not be enabled in configure
When this code was moved from finit.c we rely on WDT_DEVNODE to be
defined in config.h, which is controlled by configure.  Meaning, before
the relocation, Finit did not honor the configure settings.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 02:00:14 +01:00
Joachim Wiberg 6a4f197cc0 .github: enable new testserv plugin, regression testing
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 01:48:57 +01:00
Joachim Wiberg 4894580e8b Fix issue where env:/pre:/post:/etc. is removed from a service stanza
This issue was found when the test pre-post-serv.sh suddnely started
failing, unclear how it could ever have worked before considering the
nature of this patch.

The trick here is when reloading a service like this:

     service env:/etc/env    serv -np -e foo:bar

into this:

     service pre:/bin/pre.sh serv -np

In the second the env: has been removed and pre: added.  But with Finit
prior to this patch, env: was kept leading to unintended behavior.  The
same goes for the other options included in this patch.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 01:46:13 +01:00
Joachim Wiberg 70997fb4c5 Allow Finit watchdogd and keventd to start as early as possible
In particular watchdogd we want to start in runlevel S to ensure we
start kicking the WDT.  (Some HW WDTs are enabled from power on.)

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 01:16:55 +01:00
Joachim Wiberg e9515971ea Refactor, move registration of static services to conf_init()
All services registered in the system rely on conf_init() having been
set up properly, e.g., global_rlimit.  Having conf_init() be responsible
also for registering static services is only logical, and also helps us
clean up main() a bit.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 01:15:49 +01:00
Joachim Wiberg 82dfa002ff Follow-up to c9fe9afa, proper fix for HOOK_BASFFS_UP mess
Instead of the revert in c9fe9afa, we restore HOOK_BASFFS_UP to its
proper place at the end of fs_mount_all().  For this to not cause any
regressions we add a new hook, HOOK_SVC_PLUGIN, and update all plugins
that call service_register() to run at the new hook.

This will cause regressions for external 3rd party plugins that rely on
HOOK_BASEFS_UP to be called at its previous postion.  Nevertheless, this
is the proper fix to the problem.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 01:15:49 +01:00
Joachim Wiberg a664fd7192 Add plugin and test to reproduce failing tests since c9fe9af
With all the change and revert mess of the HOOK_BASEFS_UP tests started
failing due to usr.so and sys.so failed to set up their conditions.  It
then became clear that boomisc.so cleaned up /run ... with the revert
we got service_register() to be called before global_rlimit[] was setup
causing services registered by plugins, before conf_init(), to crash.

This plugin and test is here to ensure we catch this problem in case of
any future refactor.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 01:15:49 +01:00
Joachim Wiberg b62ee0ef6d test/common: add missing newline to usage text
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-04 23:05:05 +01:00
Joachim Wiberg 0cfd867816 plugins: fix memory leak in sys.so
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-04 23:04:41 +01:00
Joachim Wiberg 934a4db7d5 plugins/dbus: adapt to other operating systems
Not all Linux systems are based on Debian, and even if they are inspired
by Debian (Buildroot), they do not necessarily use the same defaults.

This patch probes the current system for:

 - dbus user and group
 - dbus PID file

If the user/group cannot be found we fall back to "root", if the PID
file cannot be determined we ignore PID file readiness.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-25 12:29:08 +01:00
Joachim Wiberg c9fe9afa61 Revert "HOOK_BASEFS_UP must run as soon as all filesystems are mounted"
This reverts commit 5b41c6e since it causes regressions in plugins
adding services to the system.  The proper fix for early bootmisc
is to add a new hook, which will be added in subsequent commits.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-24 10:00:47 +01:00
Joachim Wiberg 320e91653b initctl: add -n,--noerr to return OK(0) if svc doesn't exist
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-19 19:57:25 +01:00
Joachim Wiberg 859d215ca4 Merge pull request #347 from JackNewman12/master
Use realpath in do_change() to ensure symlink directories are correctly reloaded

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-18 07:07:15 +01:00
Jack Newman 0a94f3f303 Use realpath in do_change() to ensure symlink directories are
correctly reloaded.
2023-01-18 15:59:50 +10:00
Joachim Wiberg e83a26b256 Simplify readiness handling for s6 style services
No need for special handling of s6 services, we now have the new
service_notify_reconf() function that is called on init reload.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-17 07:22:59 +01:00
Joachim Wiberg 2508495b8c Fix #343: only mark native services as started in pidfile plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-17 07:22:28 +01:00
Joachim Wiberg 3ef52d9324 test: reproduce pidfile plugin marking systemd services 'started'
Issue #343

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-17 07:22:20 +01:00
Joachim Wiberg 05b72281e6 plugins: minor, fix clang warning
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-16 22:12:03 +01:00
Joachim Wiberg a47abfdc16 Fix #344: check for sysklogd logger tool at runtime, replacing logit
The sysklogd logger is capable of logging the PID of the actual service,
rather than just the logger tool itself (which would be a differet PID
every time).

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 15:45:53 +01:00
Joachim Wiberg 2c9265f8c8 initctl: add 'cat' as alias for 'show'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 14:13:01 +01:00
Joachim Wiberg 56cb6f8613 Fix #343: handle 'initctl reload' of unmodified non-native services
When 'initctl reload' is called new "configuration generation" is
started by Finit.  This mechanism ensures services reaffirm their
readiness and helps distinguish between their ready before reload
and after.

For native services the pidfile plugin handles this.  The s6 style
services are one-shot only, and thus use a static ready condition.

This patch adds support for stepping the configuration generation
of unmodified systemd style services.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:34:05 +01:00
Joachim Wiberg 3dd56ed8af test: minor refactor for readability
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:34:05 +01:00
Joachim Wiberg fddeeb683c test: drop debug
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:34:05 +01:00
Joachim Wiberg 25835b0edf test: clean up properly between tests phases in notify.sh
To reset the crash counter of the 'serv' daemon we need to remove it
from /etc/finit.conf (and reload) between each test phase.

The repeated test phases can now be dropped, since the lack of reset
was the root cause for it failing sometimes in extended runs.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:34:05 +01:00
Joachim Wiberg 27fcfada66 test: add native pid file based daemon to notify.sh for completeness
Correct an obvious oversight, we need to ensure the native pidfile based
daemons also work as intended in the new readiness notification world.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:34:05 +01:00
Joachim Wiberg 2dd5fb0f77 test: s6/systemd style services do not necessarily create a PID file
Ensure the test mimics actual real-world scenario where daemons do not
create a PID file at all.

Issue #343.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:34:05 +01:00
Joachim Wiberg 63044a4b81 test: extend notify.sh with checks for 'restart serv' and 'reload'
Issue #343.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:34:05 +01:00
Joachim Wiberg 4e74f9783a test: minor fix to 'serv' test service
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:34:05 +01:00
Joachim Wiberg c3c662fe64 initctl: ensure 'cond get' support flux state
The 'initctl cond' commands were initiallý added to only manage usr
conditions.  Recently the 'cond get' command was expanded to allow
reading general conditions as well.

However, since general conditions support three states the command
returned 'on' for conditions that were in flux.  This patch fixes
that oversight.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:34:05 +01:00
Joachim Wiberg 7c2764790c Issue #343: READY state lost when service is restarted after crash
The svc_set_state() function not only handles state transitions, it also
makes sure to cancel any outstaing service timeouts.  Before the service
readiness support was added, service conditions were simply a single bit
of information, so clearing its conditions before changing states had no
impact.  With readiness we have multiple bits of information that are
set as conditions.

When restarting a crashing service we set a timeout to retry restarting,
or ensure the service is now running.  This means that the service can
signal READY before RUNNING is reasserted, but the RUNNING state can be
set also by the service state machine, so we need to ensure we do not
re-assert RUNNING if it's already set, and thereby clearing READY.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-15 06:33:55 +01:00
Joachim Wiberg 732d500cf5 Avoid reserved keyword 'new'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-13 07:50:45 +01:00
Joachim Wiberg 4e1ac726ac Minor, update debug message to align PID output
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-13 07:49:17 +01:00
Joachim Wiberg fba58085c6 test: verify readiness notification on crash/restart
Issue #343 reports that readiness notification on crash/restart is lost.
This update to notify.sh reproduces that bug.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-12 09:03:10 +01:00
Joachim Wiberg d1ebb255c6 initctl: add 'kill' alias to 'signal' command
Principle of least surprise.  When no even the maintainer remembers
the correct command, it is time to add an alias.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-12 09:00:57 +01:00
Joachim Wiberg a39ee0b44d Fix #342: prevent certain commands at bootstrap and shutdown
Over the years there have been multiple cases of invalid and/or unsafe
uses of signals and initctl commands at bootstrap and shutdown.  These
cases cannot be safely supported.  This commit locks down finit a bit
to avoid the most common cases.

If you run into this, please open a new discussion at GitHub and we'll
talk about it.  Maybe I've been overzealous or you have another use-case
that warrants opening up some or parts of the API.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-10 17:18:50 +01:00
Joachim Wiberg 947d91acd5 Minor, whitespace only
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 10:51:12 +01:00
Joachim Wiberg 8c206d52e5 Fix imlicit declaration build warning
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 10:49:32 +01:00
Joachim Wiberg 0f445dc9f4 doc: add missing /etc/finit.d and fix indendation (untabify)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 10:38:14 +01:00
Joachim Wiberg c71b35e61a doc: document recommended filesystem layout + automounter
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 10:00:43 +01:00
Joachim Wiberg d20308b7d7 Follow-up to e4e54a8: spellcheck hook name
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 09:08:33 +01:00
Joachim Wiberg e4e54a88d9 Adjust boundaries for when conditions are allowed
Not until fs_mount_all() has completed do we have /run, or /var/run, and
never after shutdown has been initiated.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 09:00:35 +01:00
Joachim Wiberg 308b7c5197 Follow-up to #338: return early if conditions are not available
As pointed out by Jack Newman in issue #338, when conditions are not
available (at boot before cond_init(), or shutdown when /var or /var/run
have been unmounted) we should not try to create any conditions.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 08:17:09 +01:00
Joachim Wiberg 89772bf6c0 Merge pull request #338 from JackNewman12/shutdown-hook-fix
Fix shutdown hooks not running

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 08:08:32 +01:00
Joachim Wiberg 077002e647 doc: follow-up to 02a110e, rename new section, add list of runlevels
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 07:07:18 +01:00
Joachim Wiberg 988cdf9878 Merge pull request #341 from troglobit/reboot-delay
Add support for optional reboot delay

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-09 06:25:45 +01:00
Joachim Wiberg 97db2078f5 Follow-up, spell check
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-08 14:19:09 +01:00
Joachim Wiberg 02a110e6c2 Fix #336: update main config.md Introduction with new .conf overview
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-08 14:18:30 +01:00
Joachim Wiberg 681ef8de6f doc: minor, styling
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-08 14:18:30 +01:00
Joachim Wiberg 0147e0e64f Minor, ensure pointer is legit in --enable-static mode
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-08 14:18:30 +01:00
Joachim Wiberg 311c6be9aa Add support for optional reboot delay
Slightly different take on issue #334 making it optional, possible to
enable per system.

    reboot-delay <0-60>           # default: 0 (disabled)

When enabled (non-zero), runs after filesystems have been unmounted,
the root filesystems has been remounted read-only, and sync(2) has
been called, twice.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-08 09:37:19 +01:00
Joachim Wiberg c22d123ab0 plugins: sys.so and usr.so must run after bootmisc
The bootmisc plugin sets up the base path for finit and figures out if
the system has /run or /var/run -- needed by the other plugins.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 18:07:40 +01:00
Joachim Wiberg 96b5991355 .github: ::set-output is deprecated
https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 18:04:45 +01:00
Joachim Wiberg 06bd352863 .github: fix missing quote
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 17:59:47 +01:00
Joachim Wiberg a918f7497a .github: revise weekly check
For details, see https://stackoverflow.com/a/67527144/1708249

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 17:56:42 +01:00
Joachim Wiberg 8bbae3d414 plugins: ensure /var/run/finit/cond exists
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 17:42:49 +01:00
Joachim Wiberg bfd1f36fdd .github: spellcheck yaml
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 17:26:08 +01:00
Joachim Wiberg 6fc702a560 .github: enable manual trigger as well
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 17:24:45 +01:00
Joachim Wiberg 40dcc5541b .github: split build in a regular build+test and weekly distcheck
This to save time during regular pushes and pull requests, the tests
run from distcheck take a long time, and they're not getting fewer.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 17:19:33 +01:00
Joachim Wiberg 5b41c6e327 HOOK_BASEFS_UP must run as soon as all filesystems are mounted
At this hook point the bootmisc.so plugin runs and creates all relevant
system directories.  Much of the rest of system bootstrap relies on this
so it should be called together with the other FS hooks as soon as all
the filesystems have been mounted.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 15:09:50 +01:00
Joachim Wiberg 4bd81b4d4c conf_saverc: enaure /var/run/finit exists first
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 15:08:58 +01:00
Joachim Wiberg c29589c2ca initctl: add support for --json to list command
This allows for easy access to the *disabled* services:

    root@anarchy:~# initctl ls --json |jq '.available - .enabled'
    [
      "chronyd.conf",
      "dnsmasq.conf",
      "gdbserver.conf",
      "inadyn.conf",
      "inetd.conf",
      "isisd.conf",
      "lldpd.conf",
      "mstpd.conf",
      "ntpd.conf",
      "ospf6d.conf",
      "ospfd.conf",
      "querierd.conf",
      "ripd.conf",
      "ripng.conf",
      "sshd.conf",
      "syslogd.conf",
      "telnetd.conf",
      "uftpd.conf",
      "wpa_supplicant.conf",
      "zebra.conf"
    ]

As discussed in PR issue #335

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 14:00:28 +01:00
Joachim Wiberg 73b89430e4 Fix #340: Finit ignores deleted/moved .conf files in /etc/finit.d
Works locally with/without this patch, but I cannot understand why it
would ever be needed in the first place, so removing.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 14:00:28 +01:00
Joachim Wiberg 2a62fa3d85 Fix #329: add support for multiple args to initctl cond set/clr
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 14:00:16 +01:00
Joachim Wiberg 4542fdb5bb Fix #339: use absolute path in enabled symlinks
When the /etc/finit.d/enabled directory is a symlink elsehwere, e.g.,
/var/finit.d/enabled, a relative symlink will not work.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 11:30:46 +01:00
Joachim Wiberg 525aaf1f66 plugins: s/Initializing/Seeding/ better choice of words
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 09:43:27 +01:00
Joachim Wiberg 910dac5f3a Merge pull request #337 from JackNewman12/autoreload-fix
Fix AUTO_RELOAD #define typo

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-07 09:31:57 +01:00
Jack Newman 2a5c319084 Fix shutdown hooks not running
sig.c was calling plugin_run_hooks for the shutdown hooks, but the
shutdown hooks do not have registered callbacks in hook-scripts.c

Instead directly call plugin_script_run()
2023-01-06 10:29:58 +10:00
Jack 612f4fe288 Merge branch 'troglobit:master' into autoreload-fix 2023-01-06 10:00:03 +10:00
Jack Newman c058c05651 Fix AUTO_RELOAD typo 2023-01-05 09:00:51 +10:00
Joachim Wiberg 0de4578e50 Merge pull request #333 from JackNewman12/config-reload
Mark service dirty if the command line args have changed

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-04 17:00:29 +01:00
Jack Newman b9e94e4695 Consider a service dirty if the command line args have changed
This fixes `initctl reload` correctly restarting all daemons that have new
command line arguments.

Previously command line arguments changes were only acted upon if the
service was explicitly reloaded `initctl reload myservice`.
2023-01-04 13:31:41 +10:00
Joachim Wiberg 9887003b25 doc: clarify and fix confusing pid:/run/bar.pid example
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-01-02 00:30:19 +01:00
Joachim Wiberg f6bfbc86e9 Drop mdevd plugin, not needed since notify:s6 support was added
For an example how to set it up, see the finit-skel repository:

https://github.com/troglobit/finit-skel/blob/main/skel/etc/finit.d/available/mdevd.conf

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-21 11:57:48 +01:00
Joachim Wiberg 4c90b51d80 doc: update conditions wrt new devmon plugin
Issue #185

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-20 14:08:03 +01:00
Joachim Wiberg 48cfbfe5ed Follow-up to 685e0a80, drop extra snprintf() args
Issue #332

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-20 13:35:19 +01:00
Joachim Wiberg f98be8540f test/devmon.sh: new test
Issue #185

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-19 17:20:21 +01:00
Joachim Wiberg 17c69fef3d Fix #185: add devmon support, <dev/foo> condition provider
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-18 22:21:15 +01:00
Joachim Wiberg c586204fc1 New API, iwatch_add1() with no preset mask
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-18 22:21:15 +01:00
Joachim Wiberg ff5e3219be Optional debug support of actual execve() args
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-18 14:43:51 +01:00
Joachim Wiberg 07c52f1566 Improve logging of modified command args, show parsed args as well
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-18 14:43:51 +01:00
Joachim Wiberg 0e04ffd68f service_register(): guard against loss of command args
We use strtok() quite extensively in .conf parser.  Parsing of a service
line is split in two, with the command arguments being parsed very late.

Adding a new sub-option parser, based on strtok(), risk losing command
arguments.  Thus, change to use strtok_r() so that we always know where
the arg parser is.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-18 14:43:51 +01:00
Joachim Wiberg 8b5435908c Simplify, conds[] need not be static
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-17 15:19:08 +01:00
Joachim Wiberg 3a74310aa6 Drop deprecated autoconf statements
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-16 15:45:36 +01:00
Joachim Wiberg 180859a429 plugins: update mdevd to use new notification framework
Last update of plugin before dropping it in favor of an equivalent .conf
snippet.  (Pending new finit-conf repository).

Issue #327

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-16 13:54:46 +01:00
Joachim Wiberg 1d92819d92 Add more progress messages at shutdown/reboot
This patch changes the way progress for unmounting filesystems is
displayed.  To see each filesystem being unmounted Finit now must
be in debug mode.

A general "Unmounting filesystems ..." have been added instead as well
as progress for last hook script and finall call to reboot().

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-16 13:27:24 +01:00
Joachim Wiberg cfa871c548 doc: update with some of the latest changes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-16 13:09:47 +01:00
Joachim Wiberg 685e0a80a4 Fix #332: silence confusing [ OK ] status progress from modules-load
This change drops the confusing status progress output, which was always
OK since the actual modprobe operation runs in the background.  No need
to show status of the "added a task to finit, found modprobe" command.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-11 10:05:53 +01:00
Joachim Wiberg 19847d2997 plugins/modules-load: change default, load modules in runlevel S
Instead of waiting until runlevel 2, 3, 4, or 5 to load modules with
this plugin, we should load modules as soon as possible, i.e., in
runlevel S.  This also means that Finit will clean up all the tasks
so we don't have to see them in `initctl status`.

To allow users to revert to the old behavior, we add a new setting

    set runlevel 2345

that per modules-load.d/file changes the runlevel for all modprobe
commands.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-10 13:29:53 +01:00
Joachim Wiberg 7108b0e789 test: disable shell exit on error during shutdown phase (after test)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-07 10:30:35 +01:00
Joachim Wiberg 7eac0b0341 test: dump shell options to debug 'exit status: 143'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-07 09:09:04 +01:00
Joachim Wiberg 33ec4e7d19 test: instrument shutdown to debug failing tests on GitHub
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-07 08:07:40 +01:00
Joachim Wiberg 1b78f2b364 .github: test with libite and libuev from distro (new!)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-07 07:40:04 +01:00
Joachim Wiberg 119363ff75 .github: attempt to split configure line
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-07 07:32:54 +01:00
Joachim Wiberg f89b508c01 .github: don't fail because tree returns non-zero ...
Has it always been like this, or have they "recently" changed the
behavior of the tree command?

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-07 07:32:02 +01:00
Joachim Wiberg dda8c7c3ac .github: split install & inspect into separate steps to debug
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-07 07:26:20 +01:00
Joachim Wiberg e2d9aab70d .github: step libuEv and libite versions
GitHub have now stepped their 'ubuntu-latest' image to Ubuntu 22.04.
With that comes the GLIBC bump to >= 2.34 which require aligning the
time bits and file offset bits to 64 bits.  This is libuev v2.4.0.

We also make sure to align libite to the same version between the
workflows to avoid any nasty surprises.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-07 07:00:51 +01:00
Joachim Wiberg 3df154b798 Fix #325: allow custom modprobe command in modules-load.d plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-06 14:01:20 +01:00
Joachim Wiberg 3d9cbaf040 fgetval(): handle extra separators betwee key and value
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-06 14:00:31 +01:00
Joachim Wiberg 70c2939596 Fix #315: add environment variables to hook scripts
All hook scripts are called with at least one environment variable set,
FINIT_HOOK_NAME, useful when reusing the same hook script for multiple
hook points.  It is set to the string name, also used by the path, e.g.,
hook/net/up.

For all hook points from hook/sys/shutdown and later, FINIT_SHUTDOWN is
also set, to one of:  halt, poweroff, reboot.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-23 22:51:40 +01:00
Joachim Wiberg d4ee44e27f doc: minor, fix spelling
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-23 22:51:06 +01:00
Joachim Wiberg 0498326962 Fix #318: only show "[ OK ] Calling foo" progress for runparts ...
For all other run_parts() use-cases we just give the script control over
stdout/stderr to prevent clobbering ANSI color escape codes.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-23 21:49:30 +01:00
Joachim Wiberg c84ababbd4 Fix #317: make sure hook scripts don't run twice
Also fixes #316

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-23 21:44:31 +01:00
Joachim Wiberg 67ea42c87b Reduce debug noise from run_parts() slightly
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-23 21:12:30 +01:00
Joachim Wiberg a2ab45cad7 network: log output from ifup without trailing newline
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-23 21:08:50 +01:00
Joachim Wiberg f3fcca6150 Revert "Refactor, enter main event loop earlier"
This reverts commit 03c08d3970 due to it
breaking handling of bootstrap tasks, causing endless boot loop.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-23 17:54:32 +01:00
Joachim Wiberg 2b65d8f1e9 Follow-up to 9046b6f, don't warn() on empty lines, drop line debug
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-23 17:54:32 +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 457c0a246f Fix #320: close API/IPC socket immediately in shutdown/reboot
This protects against any hook scripts or services calling initctl when
we're going down.  There's no way to service these requests anyway, so
no point in keeping the socket open.  This way initctl can check for
the existence of the socket before attempting any IPC command.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-22 08:10:49 +01:00
Joachim Wiberg 1a439baf68 Further improve runparts/hook script docs, add limitations
Issue #320

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-22 08:06:26 +01:00
Joachim Wiberg 68ce78b3fe Fix #319: add missing HOOK_NETWORK_DN
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-21 20:04:32 +01:00
Joachim Wiberg 72e27e99e5 .github: run tests as recommended in test/README.md
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-21 20:04:32 +01:00
Joachim Wiberg a436382886 Improve documentation for runparts and hook scripts
Issue #315.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-21 18:11:58 +01:00
Joachim Wiberg 6bbfc7b1f1 getty: extend issue parser with /etc/os-release support
Add support for /etC/os-release, with fallback to /usr/lib/os-release,
overriding some traditional modifiers with the os-release variant.  The
traditional values for these modifiers are taken from uname, which on
Linux systems are pretty useless since they always return the kernel
name and version instead of the distro/OS values.

E.g., \s becomes PRETTY_NAME instead of 'Linux' and \v becomes the
pretty VERSION, while \r becomes VERSION_ID.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-20 10:44:30 +01:00
Joachim Wiberg 006dd12b09 initctl: recactor, share fgetval() with rest of Finit
Note: this highly useful function should probably migrate to libite.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-20 10:43:30 +01:00
Joachim Wiberg d3a0631390 Add references to service-per-conf and link to finit.conf(5)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-19 10:11:18 +01:00
Joachim Wiberg 9046b6fe2b Fix #186: allow continuation character in .conf files
This change makes it possible to use the standard continuation character
in .conf files.  For example:

    service [23456]     \
         log:stderr     \
         <!pid/foo>     \
         bar            \
         -- This is the bar service, it depends on foo # comment that's dropped

Notice the additional support for comments on .conf lines.  If you use
the comment character today you must change to escape it.  Like this:

    service :2 foo -- Foo \#2

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-19 10:11:11 +01:00
Joachim Wiberg f217794773 Fix #314: call cond_update() also when removing all service/foo/*
When removing a whole tree of conditions we need to walk through each
and call cond_update() to ensure that all dependant tasks are stopped
and put back in waiting.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-15 09:24:54 +01:00
Joachim Wiberg 11e02fabb3 test: update test to detect all corner cases of bug #314
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-15 09:24:28 +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 2a7abf1db0 test: enable new depserv test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-15 00:56:03 +01:00
Joachim Wiberg 34b8c5a3ba test: check for spice on Arrakis, I hear it's good
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-14 23:45:37 +01:00
Joachim Wiberg 8e056422fc test: new shell helper function run()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-14 23:45:17 +01:00
Joachim Wiberg 94e8b185b4 test: add some spice to serv
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-14 23:45:04 +01:00
Joachim Wiberg 996d3960e1 test: touch pidfile on SIGHUP, the default Finit notify mechanism
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-14 18:53:24 +01:00
Joachim Wiberg 3b19734f63 test: new regression test, verify dependency vs restart handling
Bug #314

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-14 08:39:10 +01:00
Joachim Wiberg 64e7c0cd9e test: -P implies -p
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-14 08:18:18 +01:00
Joachim Wiberg 4d0c88bd7a man: add missing period at end of sentences
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-14 07:33:44 +01:00
Joachim Wiberg 9e8c601507 man: rewrite status command description
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-14 07:28:59 +01:00
Joachim Wiberg b26104466a Overdue version bump into v4.4-dev release cycle
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 21:54:22 +01:00
Joachim Wiberg bd25bf65ce test: ensure /run is a unique ramdisk for each test instance
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 21:54:01 +01:00
Joachim Wiberg edd3b41adf .github: only archive .log files
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 18:20:17 +01:00
Joachim Wiberg 28ca3fcc5c .github: restore -j1 for distcheck
Hopefully prevent spurious failures, dunno why atm., parallel checks
should work now. (Works locally with make -j20 check)

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 16:50:45 +01:00
Joachim Wiberg 3b601d0115 Fix issue with services suddenly converting to 'forking' type
When a service starts up the pidfile.so plugin automatically detects any
new pidfiles that show up in the system.  If it finds a matching service
which does not have a custom configured pidfile, it auto-assigns the
detected pidfile to the service.

However, when the user later calls `initctl reload` to update the
running configuration set, Finit service_register() mistakenly will
set the service to forking since it now suddenly has a pidfile ...

The new style way of configuring a forking service is to set the

     type:forking

option.  The old compat way was to set `pid:!/path/to/pidfile`, so
in service_register() we must be very careful not to interpret the
registered pidfile as confiugred by the user -- i.e., check the pid
option.

Bug #313

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 16:35:58 +01:00
Joachim Wiberg 1ef9a9f128 Cancel pending restart timer on initctl stop/start/restart/reload
When a service crashes Finit launches a restart timer that periodically
will try restart the service.  If a user calls `initctl stop foo` finit
must cancel this timer callback, otherwise we may end up with a weird
state where Finit thinkgs the service is running, but pid: 0, i.e., not
started.

Note: this fix has been expanded upon from the proof of concept
      submitted by Jack Newman.

Bug #313

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 16:34:50 +01:00
Joachim Wiberg d612a86c3b test. drop fozza dependency
Obvious dev. test :-)

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 16:19:54 +01:00
Joachim Wiberg 5d3cd05202 .github: split distcheck into separate check + distcheck steps
- We want log files from check archived
 - We want to verify that checks can run from tarball

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 16:13:32 +01:00
Joachim Wiberg 726f7ba229 test: new regression test for bug #313
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 15:53:48 +01:00
Joachim Wiberg 61dab8bd75 test: add support for new helper functions, skip/fail/check_dep
Also, make sure to exit each test with the correct exit status.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 15:52:37 +01:00
Joachim Wiberg a7e81f45c6 test: slay must cache oldpid to an instance specific ramdisk
Running tests in massive parallel causes failing startk-kill-service.sh.
This in turn was caused by the shared test tool 'slay' that cached its
"oldpid" file to a shared area of the rootfs (tenv-root).  It must use a
test instance-specific ramdisk.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 12:38:14 +01:00
Joachim Wiberg be4062f019 test: log service.sh output to stderr
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 12:37:57 +01:00
Joachim Wiberg 035f06e137 initctl: dump svc type and forking in JSON output
First set of svc_t properties not possible to debug otherwise.  See
issue #313 for a background.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 12:11:24 +01:00
Joachim Wiberg 2f91ab5eac Fix #235: support for overriding /etc/finit.conf and /etc/finit.d
This change adds support for a new command line option finit.config=PATH
which can be used to tell Finit to start with /etc/factory.conf instead
of /etc/finit.conf.

For the complete experience a new top-level configuration file directive
`rcsd PATH` has aslo been added.  It in turn can be used by factory.conf
as follows to override /etc/finit.d:

    rcsd /etc/factory.d

Manually verified in myLinux

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-10 17:21:33 +01:00
Joachim Wiberg f6b5b0260b Fix #312: restart services with respawn set, e.g. ttys, immediately
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-09 20:27:16 +01:00
Joachim Wiberg bb9bd7e0b0 Fix #311: document how to combine device tree with conditions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-09 18:20:57 +01:00
Joachim Wiberg 287abd5c7c Fix #254: document limitations in rc.local and runparts
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-09 18:05:21 +01:00
Joachim Wiberg d27f114742 Document new -j,--json output option in initctl
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-09 16:43:11 +01:00
Joachim Wiberg 505c370898 Follow-up to 912a281: let s6 services use oneshot 'ready' condition
Since the s6 readiness notification mechanism closes the notification
socket to Finit (as per s6 spec.) the 'ready' condition should then
always be asserted, even across system reconfiguration events.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-09 14:27:38 +01:00
Joachim Wiberg f26009ec3e Follow-up to 912a281: reassert 'ready' condition on reload
Services that have not been changed, or otherwise needed to be reloaded,
need to have their 'ready' condition reasserted on 'initctl reload',
otherwise it will remain in 'flux'.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-09 14:25:49 +01:00
Joachim Wiberg 8425bc313b initctl: add --json support for condition status and dump
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-09 14:11:46 +01:00
Joachim Wiberg f4d3cf2835 Fix #273: add JSON output option to initctl status [foo]
This change adds support for JSON output to `initctl status` using a
`-j` or `--json` command line option.

Example:

    root@anarchy:~# initctl status -j mdevd
    {
      "identity": "mdevd",
      "description": "MDEVD Extended Hotplug Daemon",
      "status": "crashed",
      "exit": { "code": 100 },
      "origin": "built-in",
      "command": "/bin/mdevd -C -O 4",
      "restarts": 10,
      "pidfile": "/run/mdevd.pid",
      "pid": 0,
      "user": "root",
      "group": "root",
      "uptime": 0,
      "runlevels": [ "S", 1, 2, 3, 4, 5, 7, 8, 9 ]
    }

The excellent tool `jq` can be used to extract certain parts of the
output for further scripting.  E.g. `initctl status -j foo | jq .exit`

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-09 13:49:03 +01:00
Joachim Wiberg bd5cf7c9eb Drop confusing leading / in sig2str() and code2str()
This was added for the benefit of `initctl status foo`, but we have
other users of these functions that don't expect a leading slash.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-08 22:37:13 +01:00
Joachim Wiberg 4709394ae6 .github: bump actions to fix Node.js 12 warnings
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-08 21:49:17 +01:00
Joachim Wiberg 729002ef82 Fix regression introduced in d810ac0: drop 'return;' statement
The condition subsystem starts very late, this should not affect running
callbacks in plugins.  In d810ac0 an extra return statement was included
in a new if() statement block that run plugins hooks.  This caused a
massive regression in how Finit starts up and runs.

 - drop return; statement that causes regression
 - move #ifdefs to surround if() statement

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-08 21:32:07 +01:00
Joachim Wiberg 58b075dbf2 Follow-up to 7cfbca6, remove extra , that disables all plugins
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-08 19:49:23 +01:00
Joachim Wiberg d679840fa3 m4: minor, whistespace cleanup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-08 19:48:56 +01:00
Joachim Wiberg 0e70bdbf6a Handle if building with hook script but no script path
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-07 19:04:59 +01:00
Joachim Wiberg d810ac00bc Fix #302: add support for running scripts at shutdown
This change adds support for running hook scripts at two new hook points
during the shutdown process:

 - HOOK_SVC_DN: after all services and non-reserved processes have been
   killed (and collected)
 - HOOK_SYS_DN: after all file systems have been unmounted, *just prior*
   to Finit calling reboot() to shut down or reboot the system

See doc/plugins.md for details and an example.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-07 07:01:21 +01:00
Joachim Wiberg 5f74adad06 Take down condition subsystem at shutdown/reboot
Leave the system as it was when we found it.  Also, we'll build things
on top of cond_is_available() to handle pre bootstrap and pre shutdown
tasks.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-07 06:44:21 +01:00
Joachim Wiberg 585ac51f45 Refactor local helper function, change readdir() to recursive nftw()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-07 06:43:02 +01:00
Joachim Wiberg ce36797506 doc: update documentation for hook-scripts and all hook points
Follow-up to b62c975.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 14:46:17 +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 383339dc4a Add timestamp to log messages when in fallback and logging to stderr
When there is no log daemon, and we are running in a container, or we
cannot log to the kernel ring buffer, then we log to stderr.  This patch
improves the log output by prefixing each message with a timestamp.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 13:54:55 +01:00
Joachim Wiberg 36b46ba134 Improve and increase debug messages for dying services and scripts
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 13:54:55 +01:00
Joachim Wiberg a2d0859bf1 test: serv: die immediately (no sleep) if started with -c
We want to stress test Finit as much as possible.  We add a small log
though (which admittedly gives us a little bit of a delay) just to see
what happens when debugging failing tests.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 13:54:55 +01:00
Joachim Wiberg d5f542dcca test: slay must wait up to five seconds before giving up
Default max delay before restarting a crashing service is five seconds.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 13:54:55 +01:00
Joachim Wiberg fb86042cb3 test: add crashing.sh, verify oncrash:script support
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 13:07:10 +01:00
Joachim Wiberg 359fb8530e Minor, spelling
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 13:07:10 +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 278994781b Follow-up to c9f1bff, only allow daemons to reach 'READY' state
By definition, the readiness notification is reserved for daemons.  May
possibly be extended also to sysv services later.  If you arrive hare
with that request, please file an issue with the project.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 23:52:32 +02:00
Joachim Wiberg c9f1bff419 Refactor ready:script to support new notify framework
Follow-up to abcb3ce, calling the service ready:script when readiness
has been signaled to or detected by Finit.

Issue #300

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 22:11:12 +02:00
Joachim Wiberg 1f9621cf4b Fix #288: enable built-in sulogin in Alpine and Void Linux builds
Always better to have at least one sulogin available, if the system
provided sulogin isn't available we fall back to the built-in one.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 21:08:44 +02:00
Joachim Wiberg 9458e4e66b Update docs with new readiness notification support
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:36:15 +02:00
Joachim Wiberg ff08038bdc test: add notify.sh to distribution
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:13:04 +02:00
Joachim Wiberg ce330e8bf1 Minor, whitespace
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:12:12 +02:00
Joachim Wiberg 47d837bf6a test: new test, notify.sh, systemd and s6 readiness notification
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:06:26 +02: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 6e863a7872 client_connect(): ensure socket is also reset to -1 on error
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:01:29 +02:00
Joachim Wiberg 488e6c2adf Follow-up to d82d1197: ensure PID file doesn't exist
Before we clear all conditions for a service, ensure pid_file_read()
didn't fail due to the PID file not (yet) containing a valid number.

If the process dies while starting up, and subsequently removes its
PID file, then the file shouldn't exist.  However, if we get inotify
before the process has finished writing the PID, then we just return
and wait for the next event.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:01:29 +02:00
Joachim Wiberg e177b866a9 initctl: follow-up to e1c59a25, simplify
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:01:29 +02:00
Joachim Wiberg 15dcebd0f1 .globalrc: skip tenv-root/ in gtags indexing
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:01:29 +02:00
Joachim Wiberg af60d8d3ec initctl: fix off-by-one in column width when dumping conditions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:01:29 +02:00
Joachim Wiberg 5a32fdb309 Simplify error message, same style as other log messages in module
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:01:29 +02:00
Joachim Wiberg 19f5cb1d01 logit: fall back to package name if $LOGNAME and $USER are unset
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:01:29 +02:00
Joachim Wiberg c5bca5f80a Add 'function():' prefix to new log macros, like the old ones
Also, mark old log macros as DEPRECATED.  Will be removed in a later release.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-09 12:52:49 +02:00
Joachim Wiberg d22dea74e3 Finalize refactor to new log macros, following-up to 37e3be9
This possible also mitigates the issue tracked in #307.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-09 12:52:40 +02:00
Joachim Wiberg dc547317c9 .github: drop setup-root.log from failed builds, no longer a test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-25 11:45:27 +02:00
Joachim Wiberg 6bf5d98569 test: fix distcheck BusyBox downloader for users with ~/.cache
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-25 07:48:36 +02:00
Joachim Wiberg 29dea38f50 test: fix path to setup-root.sh in distcheck mode
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-25 05:53:57 +02:00
Joachim Wiberg 34567dd244 Use new log macros also in keventd and iwatch.c
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-25 05:49:39 +02:00
Joachim Wiberg a3584c6ca3 .github: enable parallel distcheck
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-25 05:06:28 +02:00
Joachim Wiberg 165d0633f6 test: add support for make -j17 check massive parallel testing
This was a tough nut to crack.  Spent 3-4 calendar weeks (getting blurry
now) to try and figure it all out.  In the end, the following changes
were necessary:

 - Ensure setup-root.sh is guaranteed to run before any of the tests
 - Give all tests their unique /etc, /tmp, and /run inside the chroot.
   Turns out tmpfs+overlayfs can be used unprivileged inside an unshare
 - A static BusyBox binary with support for mount helpers so we can
   do the mkdir magic in skel/etc/fstab for the /etc overlay

The last item turned out to be a bit of a roller coaster ride of its
own.  First of all, the original binary we used was from the upstream
BusyBox project[1].  I was sure it couldn't be that hard to enable the
CONFIG_FEATURE_MOUNT_HELPERS ... oh boy was I wrong.  To make long and
tedious story short; two new projects on GitHub were created for this
task: 1) troglobit/misc[2] to house a mirror of https://musl.cc
toolchains and 2) troglobit/busybox-builder[3] to download, patch, and
build the thing using a .config from the myLinux[4] project.  Patching
this .config was necessary, however, since musl libc is strict POSIX
and does not have any of the BSD extensions, e.g. REG_STARTEND that is
in GLIBC regex(3).

[1]: https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/
[2]: https://github.com/troglobit/misc/releases/tag/11-20211120
[3]: https://github.com/troglobit/busybox-builder/releases/tag/1_35_0
[4]: https://github.com/troglobit/myLinux

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-25 04:38:24 +02:00
Joachim Wiberg 9f7ba1ba79 test: upgrade BusyBox binary to v1.35.0 w/ mount helpers
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-25 04:37:16 +02:00
Joachim Wiberg 03c08d3970 Refactor, enter main event loop earlier
This delays the start of the .conf monitor and service initialization
slightly to allow the event loop to run earlier to process any events
from the initial setup.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-05 13:47:08 +02:00
Joachim Wiberg 37e3be9a0d Refactor to share err/warn log API between daemon and client code
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-05 09:57:45 +02:00
Joachim Wiberg 10437887fc Minor, staticify local function
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-29 07:49:40 +02:00
Joachim Wiberg faf1c6233d doc: document new auto-conditions from run/task/service states
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-24 19:55:13 +02:00
Joachim Wiberg c36960350c doc: minor, update table of contents
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-24 19:54:35 +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 9d79673cea Follow-up #278: update documentation for pre:script
The pre:scripts no longer have to be idempotent.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-23 15:23:02 +02:00
Joachim Wiberg 762bf5f031 test: minor shellcheck fix of chrootsetup.sh
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-23 09:44: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 0ae5071f94 API for associtative list of svc_t and pre/post/ready support scripts
This support API is for running things like pre:script, post:script and
the upcoming ready:script for services.  A ready:script will be called
when a service notifies Finit of its readyness.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-18 14:06:43 +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 12e341fe73 doc: script actions *must terminate* or they will be killed
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-18 11:04:13 +02:00
Joachim Wiberg 9be3c4cb9a .github: change to ubuntu-latest, 18.04 deprecated
For details, see https://github.com/actions/runner-images/issues/6002

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-17 07:52:34 +02:00
Joachim Wiberg 433f3ce17e .github: update libite version in release build
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-17 07:52:22 +02:00
Joachim Wiberg 2c29ede0da .github: sync with changes in finit-plugins
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-17 07:52:07 +02:00
Joachim Wiberg 7cfbca6d74 Add --enable-all-plugins configure flag
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-17 07:49:11 +02:00
Joachim Wiberg b30621bb3b Minor, coding style
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-16 14:00:57 +02:00
Joachim Wiberg d6f35903d6 Fix #195: add mdevd plugin as complement to hotplug.sh
This patch adds the mdevd[1] plugin from Andy's fork of Finit, only
minor whitespace adjustment and group fix introduced, along with
updates to configure.ac and the documentation.

Currently the hotplug.sh calls mdevd-coldplug (instad of mdev -s), but
since mdevd is not guaranteed to have started and be ready, it is also
started with mdevd -C.  A better solution is to use the s6 notify code
to synchronize the start of mdevd-coldplug.  Support for this is coming
soon to Finit.

[1]: https://github.com/hongkongkiwi/finit/blob/master/plugins/mdevd.c

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-16 14:00:57 +02:00
Joachim Wiberg a61a8015d7 initctl: new command, list installed plugins
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-15 11:00:39 +02:00
Joachim Wiberg e2f070649d Fix wrong path to command in service after reload, may have changed
Service/task/run are today identified by name:id this means the path to
a command is not necessarily the basis for the identity.  Hence, an
svc_t can now be updated with new the correct path to a command.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-12 15:08:14 +02:00
Joachim Wiberg f08d375c36 Fix lingering cond in service after reload with no cond
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-12 15:08:14 +02:00
Joachim Wiberg 1c4bad5b73 initctl: only show log if PID != 0
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-12 15:08:14 +02:00
Joachim Wiberg 6c874895dc Fix #295: add reboot/shutdown/poweroff timeout -t SEC to initctl
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-12 15:06:54 +02:00
Joachim Wiberg ef1a05425d Minor, reduce scope
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-08-12 08:16:50 +02:00
Joachim Wiberg fc3bad2160 Fix #284: search for plugins in /usr and /usr/local
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-07-17 22:08:05 +02:00
Joachim Wiberg 31ac933d64 Fix #294: shutdown --help mistakenly shuts down system
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-29 08:13:33 +02:00
Joachim Wiberg caa398816d Fix #250: support finit.cond=foo for cmdline <boot/foo> conditions
As a real life example, this can be useful for a mfgtest mode for the
device, wherein the bootloader can be set to finit.cond=test_mode or
finit.cond=user_mode and then specific services can start up in test
mode which wouldn't normally start.

Or even custom firmware update mode such as finit.cond=fw_update_mode
which performs some specific firmware update steps and doesn't launch
normal processes.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-26 21:55:50 +02:00
Joachim Wiberg 0d57a507f3 doc: update SVC state machine with latest changes
In fbcd7d2 and 96257cc the state machine transitions were changed to
ensure that pre:scripts only run when conditions have been asserted, and
that manual:yes run/tasks end properly in 'DONE' as their siblilngs.

Also include SVG in repo for reference since that's the best export from
the original at draw.io

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-26 20:43:28 +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 d9dbfa23c7 plugins: minor whitespace and coding style cleanup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-25 13:42:53 +02:00
Joachim Wiberg 91f077bd08 Merge pull request #293 from wkz/modprobe-uevent
Support for coldplugging more devices

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-23 16:55:06 +02:00
Tobias Waldekranz 5fb4a6ae8f plugins: modprobe: Support for coldplugging more devices
As it turns out, not all buses in Linux will add `modalias` attributes
to their devices in sysfs. One notable exception are MDIO buses. The
plugin's scan routine would thus not pick them up.

Fortunately, the information is always available in the device's
`uevent` attribute.

Therefore, default to looking for modaliases in the device's `uevent`
attribute instead, falling back to `modalias` only if `uevent` is not
availble (this should never happen).
2022-06-23 14:23:04 +02:00
Tobias Waldekranz e84333662e plugins: hotplug: Run after modprobe plugin, if available
Since the modprobe plugin (unsurpricingly) may cause new modules to be
loaded, it makes sense to to delay the initial device node scan until
we know that no mode nodes will show up within the next few
microseconds.
2022-06-23 14:19:30 +02:00
Joachim Wiberg ddb42fda70 Fix #289: minor spelling issue in build.md
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-21 22:28:00 +02:00
Joachim Wiberg 621eb21b42 test: regression test for issue #275
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-19 15:43:46 +02:00
Joachim Wiberg 6cc44a87c9 Fix #275: 'initctl status foo' should list all instances
This is a fix to a regression introduced in e51587c.  The idea is to
have 'initctl status foo' show all instances of foo, provided there are
more than one. E.g.

    root@anarchy:~# initctl -t status foo
    0    foo:1        stopped  [--234-----] hej knekt
    0    foo:2        stopped  [--234-----] hej snigel
    0    foo:3        stopped  [--234-----] hej kalas

And not foobar:

    0    foo:1        stopped  [--234-----] hej knekt
    0    foo:2        stopped  [--234-----] hej snigel
    0    foo:3        stopped  [--234-----] hej kalas
    0    foobar       stopped  [--234-----] hej foobar

If you type an exact match you can drill down like so:

    root@anarchy:~# initctl status foo:1
         Status : stopped (code=exited, status=0/SUCCESS, manual=yes)
       Identity : foo:1
    Description : hej knekt
    ...

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-19 15:39:01 +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 6de67ed107 Fix #268: Merge branch 'dbus-fixes'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-15 06:35:30 +02:00
Andy Savage c129f06195 plugins: create missing d-bus directories
- Prefix plugin defines with DBUS_ to allow overriding at build-time
 - Create missing directories for modern d-bus

Signed-off-by: Andy Savage <andy@savage.hk>
2022-06-15 06:33:12 +02:00
Joachim Wiberg d11dc63bc2 Fix #269: add compulsory kernel symlinks in /dev
Add missing symlinks for compulsory and recommended /dev symlinks, as
specified in the Linux Administrator's Guide, section Linux Allocated
devices.

https://github.com/torvalds/linux/blob/v5.18/Documentation/admin-guide/devices.rst#compulsory-links

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-14 21:49:19 +02:00
Joachim Wiberg d904ec1602 tty: add support for 'passenv' flag to /bin/login
This change makes it possible tell the bundled/built-in getty to call
/bin/login with the '-p' flag, to preserve any environment set in the
Finit .conf files.

Issue #286

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-13 21:20:16 +02:00
Joachim Wiberg 2a98b2f055 Minor, fix shadowing of variable in outer scope
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-13 21:18:22 +02:00
Joachim Wiberg 6286ede985 initctl: add optional TYPE argument to 'cond dump' command
Allow filtering of conditions in raw dump, i.e., the possibility to show
only conditions of a certain type.  The TYPE argument is not validated
in any way, so any prefix match is allowed, e.g.

   initctl cond dump service/s

Shows all conditions for services starting with 's'.

Fixes issue #272

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-12 23:37:03 +02:00
Joachim Wiberg 4a8ca787d3 Minor refactor, reuse MATCH_CMD() from conf.c in service_register()
When adding a new service option recently, I copy-pasted and forgot to
update the length argument to strncasecmp(), so it was time to fix that
once and for all.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-12 23:13:50 +02:00
Joachim Wiberg 561c88a868 Allow changing restart + oncrash settings of existing services
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-12 22:48:12 +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 f50b5a4ac6 Fix #285: initctl restart should start crashed service
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-12 22:24:27 +02:00
Joachim Wiberg 59525b80e3 Export finit/conf.h and finit/service.h for external plugins
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-06 10:38:19 +02:00
Joachim Wiberg 0ce028add1 Fix #283: too quick timeout at bootstrap of lingering tasks
This seemed odd at first, but it turns out we seem to have adjusted the
time scale for the bootstrap worker, so we were off by ... a factor 10.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-06-03 03:45:10 +02:00
Joachim Wiberg 75c5c85f07 test: new regression test for initctl restart self
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-30 06:59:14 +02:00
Joachim Wiberg ccb84ced2e Fix #280: allow calling initctl restart foo from within foo
Move the stop+start from initctl to the state machine by allowing
stopped tasks to restart once it has been collected.  This should
prevent finit from blocking, allowing it to handle other requests
while waiting for the service's PID to be collected.

Effectively, this will allow a service to call initctl to restart
itself, as reported in issue #280.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-30 06:54:27 +02:00
Joachim Wiberg 5ef669fb6c test: fix use-after-free by switching to strdupa()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-30 06:53:37 +02:00
Joachim Wiberg 96ff9c115c Follow-up to 9304024: skip . and ..
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-18 07:25:39 +02:00
Joachim Wiberg 83aa6abb1c Fix potential NULL ptr dereference, found by Coverity
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-17 14:37:06 +02:00
Joachim Wiberg 9304024841 Check return value of remove() when deleting full condition path
Found by Coverity.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-17 14:35:42 +02:00
Joachim Wiberg 0de5981948 initctl: minor, fix invalid format string for print_header()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-17 14:33:45 +02:00
Joachim Wiberg c39106906d Check return value from iwatch_init(), found by Coverity
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-17 14:28:04 +02:00
Joachim Wiberg 929a6e7aac test: fix minor memory leak in test daemon, found by Coverity
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-17 14:26:48 +02:00
Joachim Wiberg ceb4d04d23 Fix potential array overrun, found by Coverity
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-17 14:22:36 +02:00
Joachim Wiberg f483a8aeaa Update ChangeLog and bump version for v4.3 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 21:57:32 +02:00
Joachim Wiberg e3e220ce8e Fix links and update with info on new/existing features
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 21:55:38 +02:00
Joachim Wiberg fc653e4293 man: document initctl cond get
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 20:45:00 +02:00
Joachim Wiberg 94d55cb7dd initctl: allow 'cond get' read any type of condition
Fixes #265

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 11:52:02 +02:00
Joachim Wiberg 0e84ecf143 Minor refactor
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 11:44:24 +02:00
Joachim Wiberg 0e93dfd640 initctl: use standardized exit codes for all fatal errors
This change diversifies the exit codes used by initctl on fatal errors.
Previously only Std C codes 0 and 1 were used, with the initctl specific
255 for some cases.

Both the LSB init script codes and BSD sysexits.h codes are used.  See
util.c exitcodes[] for the full list.  The idea is to complement the
change in 9a76f08, issue #266, so that initctl can be used silently for
scripting purposes.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 11:32:06 +02:00
Joachim Wiberg 4dff8237f1 initctl: fix fallback handling in log command
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 11:01:58 +02:00
Joachim Wiberg 35400f2a8b Minor, drop unused header file
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 10:36:47 +02:00
Joachim Wiberg 9a76f0862c initctl: let -q silence all commands
This patch introduces ERR(), ERRX(), WARN(), and WARNX() as replacements
to their lower case counterparts.  These log macros respect the 'quiet'
flag to initctl, leaving only the return code as indicator to user.

Fixes #266

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 10:34:36 +02:00
Joachim Wiberg fb8a7caa99 initctl: simplify error output of start/stop/restart/signal
No need for the verbose output on error, simply state the cause of the
problem.  The user can issue `initctl -h` to check the syntax of the
command.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 10:30:49 +02:00
Joachim Wiberg f8bed5c7af Minor, fix local shadowing of scope global variable
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 09:38:05 +02:00
Joachim Wiberg da6fa482e7 Follow-up to 195155a, drop unused variable from refactor
... and it's obviously spelled "unlimited", *sigh*

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 09:38:05 +02:00
Joachim Wiberg fdf8e48c99 Minor, reduce scope of local variable
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-15 09:21:48 +02:00
Joachim Wiberg 195155a7f5 initctl: make log command unlimented
Drop `| tail -10` from 'log foo' command.  Let user call tail themselves
and only limit with tail on status command.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-13 13:53:38 +02:00
Joachim Wiberg 6934ba4dbc initctl: improve log digger in 'status foo' command
Grep in /var/log/syslog, or messages, for both the service identity (not
just svc->cmd) and also try to find [PID] for more relevant information.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-13 13:38:26 +02:00
Joachim Wiberg fdbd25c1b5 Use svc_ident() for more cases
- Drop basename() of svc->cmd from remaining code
  - Replace uses of svc->cmd with svc_ident(svc)
  - Use svc_ident() as default log tag

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-13 13:36:33 +02:00
Joachim Wiberg 467f1cca81 initctl: options alphabetically in usage text
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-10 08:11:37 +02:00
Joachim Wiberg d6fdf4a806 README: update initctl usage text
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-10 08:11:37 +02:00
Joachim Wiberg 4be9d97e61 README: make sure to mention auto-disable of cgroups
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-10 08:11:37 +02:00
Joachim Wiberg 021d011493 man: mention the UNIX pipe at least once in every man page
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-10 08:11:37 +02:00
Joachim Wiberg e988d38f71 initctl: minor, fix indentation in usage text
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-10 08:06:13 +02:00
Joachim Wiberg 8690fc732b Fix #263: document confusing initctl reload foo command
What a ride, apparently we support restarting run/tasks in the same
runlevel they have already started once in.  Still unsure if adding
support for reloading a particular Finit .conf file for a service
should be in the context of this command (it isn't now).  Maybe it
is better left as a future expansion when we switch to the new .conf
format?

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-10 08:03:36 +02:00
Joachim Wiberg ceb2945da9 Update ChangeLog and bump version for v4.3-rc2
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-09 06:55:21 +02:00
Joachim Wiberg 1b8a0951f5 initctl: update usage text with missing initctl cond get <COND>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-08 14:09:27 +02:00
Joachim Wiberg a27b8462d1 Fix #260: drop limit on device name in "Checking filesystem" output
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-08 09:59:51 +02:00
Joachim Wiberg edc2d53923 cgroup: reduce loglevel for missing/disallowed cgroup support
A user with no cgroup support in kernel does not know what they are
missing, and a user running in a container has someone else managing
cgroups.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-08 09:57:18 +02:00
Joachim Wiberg 4aae3403f5 test: new test, verify default runlevel from command line
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-08 09:57:18 +02:00
Joachim Wiberg 73423699fd test: add support for overriding default runlevel
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-08 09:57:18 +02:00
Joachim Wiberg 0cce69892a Fix #261: support for overriding default runlevel from command line
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-08 09:57:18 +02:00
Joachim Wiberg 3ca6256f87 doc: update modules-load plugin description, recommend .conf files
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-07 16:29:18 +02:00
Joachim Wiberg eca3098c0e plugins: refactor modules-load to read files in lexicographic order
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-07 16:29:18 +02:00
Joachim Wiberg 7af3461e3c Merge pull request #262 from wkz/hook-scripts
plugins: hook-scripts: new plugin for run-parts scripts on hooks

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 15:04:27 +02:00
Tobias Waldekranz b62c975dc4 plugins: hook-scripts: Add
Add a plugin that will allow the user to trigger the execution of
scripts from plugin hook points. This is particularly useful for early
boot debugging that needs to take place before regular services are
available.

For example, let's say that you want to enable some kernel tracing
before modules are loaded. With hook-scripts, you can just drop in a
shell script in /libexec/finit/hook/mount/all/ that will poke the
right control files in tracefs.
2022-05-06 10:36:37 +02:00
Joachim Wiberg b368bd1420 Document hidden HOOK_BANNER
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 08:22:01 +02:00
Joachim Wiberg 060e97d64e test: minor, drop comment within comment confusing shellcheck
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 08:07:44 +02:00
Joachim Wiberg 9b17ce0b7c Fix restart logic of sysv start/stop scripts and forking services
Init script return pretty quickly after launch, so we cannot use that to
detect if they, or the daemon they launched, have crashed.  So we start
the service_retry() with a 2 sec delay, which should be ample time to
allow the pidfile plugin to detect a forking service's new PID.

In release-cycle regression, no public issue needed.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:08 +02:00
Joachim Wiberg 50f2cbf600 Export service timeout APIs, for pidfile plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:08 +02:00
Joachim Wiberg 837bca3947 test: new test, verify sysv services are restarted properly
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:08 +02:00
Joachim Wiberg 16180675db test: minor coding style fixups
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:08 +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 7e37ac348e Refactor service name: parser slightly
This change makes it possible to see the new service's resulting name
and id before we create it with svc_new().  We extend the debug output
slightly to see what's going on and why we sometimes lose modules from
the modules-load plugin ...

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:07 +02:00
Joachim Wiberg 30e68658ae Use name:id instead consistently in debug messages
For many usecases, e.g. the modules-load plugin, the same command can be
used to create multple run/task/services makeing it real difficult to
debug such systems when Finit does not show the correct task name.  It
also hides nasty bugs, as will be shown in a later commit.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:07 +02:00
Joachim Wiberg a179308819 Simplify, tabstospaces() have already been called
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:07 +02:00
Joachim Wiberg 4cdd5f8ccc Export tabstospaces() from conf.c to helpers.[ch]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:07 +02:00
Joachim Wiberg 7f19474d8d plugins: skip backup files in modules-load plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:07 +02:00
Joachim Wiberg a5941165a0 plugins: add support for 'set noindex' to modules-load plugin
This adds support for a `set` directive in the modules-load plugin.
Currently only `set noindex` and `set index = NUM` are supported and
either disable indexing (:ID) of modules, or reset the index to NUM,
for the given file.  For each new file read the index is reset to
the value it would have had.  E.g.

01-foo.conf:          => name:id
   esp4.ko            => modprobe.esp4.ko:1
   set noindex
   deflate.ko         => modprobe.deflate.ko
02-bar.conf:
   nls_iso8859-15.ko  => modprobe.nls_iso8859-15.ko:3
   nls_utf8.ko        => modprobe.nls_utf8.ko:4

Fixes issue #257

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-06 07:57:07 +02:00
Joachim Wiberg 181d9556a1 Drop config.h include from helpers.h, exported header file
Drop the config.h include from helpers.h after a report from a colleague
trying to build an external plugin from the latest GIT sources.

Instead, make sure config.h is included, and properly commented, in all
.c files that have configure #ifdefs and other deps.  Also, move more
ot the includes from helpers.h to their respective .c file instead to
reduce the amount of headers an external plugin pulls in.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-05 14:48:30 +02:00
Joachim Wiberg bf72e6b9c8 Make bundled sulogin optional, use ./configure --with-sulogin
The bundled sulogin could be considered insecure, so leave it up to the
administrator, or system integrator, to decide which sulogin(8) is best
suited.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-03 05:58:57 +02:00
Joachim Wiberg 8db521d379 Fix minor memory leak in sulogin() handling
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-03 05:58:24 +02:00
Joachim Wiberg f46ac20fb0 doc: document support for global environment variables
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-02 00:16:04 +02:00
Joachim Wiberg d70d86e9fe test: new test, verify behavior of global environment variables
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-02 00:03:07 +02:00
Joachim Wiberg 38db52aa4e Add support for setting environment variables from finit.conf
Finit can now track and set environment variables from finit.conf.  The
syntax is pretty much what you'd expect:

    foo=bar
    baz="qux"

On reload of .conf files, all tracked environment variables are cleared
so if `foo=bar` is removed from finit.conf, or any finit.d/*.conf file,
it will no longer be used by Finit or any new (!) started run/tasks or
services.

The only variables reset to sane defaults on .conf reload are:

    PATH=_PATH_STDPATH
    SHELL=_PATH_BSHELL
    LOGNAME=root
    USER=root

It is entirely possible to override these as well from the .conf files,
but be careful.  Changing SHELL changes the behavior of system() and a
lot of other commands as well.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-02 00:02:44 +02:00
Joachim Wiberg bf62bee440 Update project homepage
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-01 22:43:39 +02:00
Joachim Wiberg e50fe3b060 plugins: use reentrant API getmntent_r()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-01 22:12:02 +02:00
Joachim Wiberg d6c55282ef Fix #253: use reentrant getmntent_r() API
When iterating over the system fstab file to call fsck, Finit calls the
helper function ismnt(), which opens /proc/mounts to make sure mounted
file systems are not fsck'ed.  Both the main function and ismnt() used
the same non-reentrant getmntent() API which caused ismnt() to set the
fstab pointer for the first out of whack.

This change replaces getmntent() in the two critical functions with the
getmntent_r() API instead.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-01 21:43:13 +02:00
Joachim Wiberg 1015124530 Use sys/sysmacros.h, if available, for minor() and major()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-01 20:50:17 +02:00
Joachim Wiberg 38885aaa67 Issue #253: handle fsck of magic /dev/root device
Some systems have /dev/root declared in their /etc/fastb as /.  This is
as special device node created by the kernel based on the root=, and a
few other variables.  This may be a symlink, and if so, and on a mdev
system, the symlink may point to the wrong device node ... so we must
try to figure out the major:minor from / and then traverse /sys/block
to find our root device.

Note: this commit also does a bit of refactoring for readability and
      also adds a few debug lines that may be dropped before release.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-01 19:31:51 +02:00
Joachim Wiberg a685b698c2 Follow-up to 5593372f, regression in remounting read-write at boot
A subtle regression was introduced in 5593372f, when moving to get
getmntent() family of APIs.  Finding the 'ro' flag (or not) in the
system fstab broke and Finit never tried to remount / read-write.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-05-01 19:28:50 +02:00
Joachim Wiberg 9bce8f9584 initctl: add cond get foo, supports -v option
Fix issue #255

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-30 10:28:47 +02:00
Joachim Wiberg d04b04d73a Follow-up to 7212543, fix args to svc_ident()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-30 10:20:53 +02:00
Joachim Wiberg 72125430e6 Fix #252: run/task success+failure conditions do not use :ID
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-30 08:50:14 +02:00
Joachim Wiberg 561387ce57 test: new test, verify pre:post: scripts with optional env:file
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-30 08:46:05 +02:00
Joachim Wiberg e2d1930e6c Fix #248: source env:file also in pre:post: scripts
This change basically add this for pre/post scripts:

    sh -ac '. /path/to/env; exec ./pre-post.sh'

Meaning the env file can be a simple foo=bar file, which Finit reads and
call setenv() on all variables, and the user do not need to call export
on all variables -- additionally, any functions defined in an env file
can be used by the pre-post scripts, but are ignored by Finit.  I.e.,
the service only gets the variables set, no functions.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-30 08:43:44 +02:00
Joachim Wiberg 6f2a124240 doc: update documentation for modules-load plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-27 07:50:21 +02:00
Joachim Wiberg 10392e9639 plugins: modules-load: skip lines starting with '#'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-27 07:46:03 +02:00
Joachim Wiberg 605c489937 Follow-up to 57c97d8, issue #224: add swapon/swapoff fstab wrappers
The swapon and swapoff commands do not support a custom fstab, they
assume /etc/fstab is the only true source of swap devices and files.

This change adds rudimentary (!) support for figuring out any swap
device or file to use from any finit.fstab.  Please note, options are
not supported at the moment.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-26 22:57:22 +02:00
Joachim Wiberg 26409bc860 Follow-up to 57c97d8, issue #224: fsck needs FSTAB_FILE env. set
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-26 21:59:11 +02:00
Joachim Wiberg b01f9f38f2 Improve logging of forking services having started and stopped
Since a forking service, e.g. a sysv init script, will exit very early
we cannot log the same as for regular services "Starting foo[123]", so
instead we log "Started bar[321]" when we get the pidfile update and
the same when stopping a forking service, log "Stopped bar[321]" when
we collect the PID.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-26 20:58:57 +02:00
Joachim Wiberg 2ddbb805ca Improve logging of sysv start/stop scripts, include full command
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-26 20:58:57 +02:00
Joachim Wiberg ed999d9a80 Fix log regression introduced in 82cc10be
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-26 20:58:57 +02:00
Joachim Wiberg 82cc10be88 Fix #246: conditions for running/halted services
This change adds the following service conditions, which can be used to
synchronize other stanzas:

  - service/foo/running
  - service/foo/halted
  - service/foo/missing
  - service/foo/crashed
  - service/foo/stopped
  - service/foo/busy
  - service/foo/restart

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-26 00:07:44 +02:00
Joachim Wiberg 30fb9780d7 initctl: slight improvement to status output for sysv services
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-26 00:07:44 +02:00
Joachim Wiberg 09f46f62b4 Support args to sysv-like scripts, e.g. bridge-stp br0 start
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-26 00:07:44 +02:00
Joachim Wiberg bc4e7a8d8d Revert "Fix starting and stopping of SysV init scripts"
This reverts commit c63279630b which
clearly was not needed to fix the problem.  After this revert the
test(s) still pass, but now we can also start bridge-stp, e.g.

     bridge-stp br0 start

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-25 23:38:52 +02:00
Joachim Wiberg e2753d75f8 plugins: silence netlink developer debug messages
Default debug level for the netlink plugin is just too noisy.  Let's
drop debug messages (mostly) intended for developers.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-25 23:35:02 +02:00
Joachim Wiberg addb8c4019 Fix #247: fall back to reboot -f in sulogin mode
When logged in from sulogin we cannot send IPC to Finit, not even
signals, to delegate reboot.  For usability, attempt to tell reboot that
it's in sulogin mode -- provided the bundled sulogin is used -- to let
reboot trigger over to forced reboot.

We cannot do much about initctl, just document this as a limitation.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-25 21:44:33 +02:00
Joachim Wiberg 0c4a9b62c2 initctl: allow client_connect() to return error
This lets any callers of client_connect() decide what to do wrt. error
recovery and fallback mechanisms.  E.g., reboot may want to check if
it's in sulogin mode, or fall back to sending signals to PID 1.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-25 21:44:33 +02:00
Joachim Wiberg 57c97d8190 Fix #224: support for cmdline -- finit.fstab=/etc/fstab.secondary
This adds support for bringing up the system with an alternate fstab at
boot.  E.g., when using a primary/secondary setup for boot partitions.

By default /etc/fstab is read, like before, this can now be changed
using configure --with-fstab=/path/to/fstab.primary, which sets the
default that can be overridden using finit.fstab=/etc/fstab.secondary

If mounting, or fsck, fails in any way, Finit calls its own bundled
sulogin, or the system sulogin(8), to let the user handle the issue.
If there is no sulogin available, Finit will try to start up in its
rescue.conf boot mode.

Please note, in either of these rescue modes, use `reboot -f` to get the
system to reboot.  Finit is on pause in the background in rescue mode
and cannot be relied on (since there may not be any writable filesystems
available.).

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-25 21:44:33 +02:00
Joachim Wiberg b0d0ca76cf Minor, coding style
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-25 21:37:59 +02:00
Joachim Wiberg 5240c0cf19 Follow-up to a91e197: allow umount fail on EBUSY, skip error message
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-25 18:52:16 +02:00
Joachim Wiberg a02f369a89 Minor, rename local variable
The iterator works on any fstab like file, but to keep confusion to a
minimum, rename local variable.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-25 18:51:17 +02:00
Joachim Wiberg fa2a113cbf test: fix path to Finit rcs.d in distcheck
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 15:22:35 +02:00
Joachim Wiberg 4c5ac38e2c test: attempt to use /etc/finit.conf instead, azure 5/N
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 14:42:49 +02:00
Joachim Wiberg f89ebb91a8 test: even more azure debug 4/N
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 14:39:03 +02:00
Joachim Wiberg 477bc064d5 test: more debug azure 3/N
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 14:28:57 +02:00
Joachim Wiberg 96376126b3 test: debug azure 2/N
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 14:21:58 +02:00
Joachim Wiberg 1c150928cb test: debug cond test in azure
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 14:14:35 +02:00
Joachim Wiberg 7a8d4e2c6b test: wait for Finit to reach runlevel 2 before starting tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 13:19:10 +02:00
Joachim Wiberg fb956fd2f5 test: silence Hint:, does not work anymore, need to debug it
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 13:18:41 +02:00
Joachim Wiberg e6e4d814f3 test: extend initial wait for azure env.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 12:55:37 +02:00
Joachim Wiberg 544d44886a test: let Finit start up properly before starting tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-24 11:36:30 +02:00
Joachim Wiberg cec2d5a4db test: add missing sbin/task.sh to skeleton dist.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-22 18:21:19 +02:00
Joachim Wiberg 539d215d0e test: add missing finit.d to skeleton rootfs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-22 17:51:04 +02:00
Joachim Wiberg 10ef0e7de6 doc: document previously secret service option respawn
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-22 07:21:19 +02:00
Joachim Wiberg 05e6b3e752 test: new test, verify task behavior with conditions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-21 20:52:34 +02:00
Joachim Wiberg 3e4be9a122 man: document command line options, complementing bootparam(7)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-20 07:51:58 +02:00
Joachim Wiberg 5593372ffb Refactor, replace deprecated setfsent() & C:o with setmntent()
The setfsent() family of APIs was never standardized and on Linux only
GLIBC implement them.  We've tried to overcome this limitation, and to
support uClibc/uClibc-ng and musl libc, by providing replacements APIs
in helpers.c.

However, and since we want to support alternative /etc/fstab files, the
setmntent() family of APIs is more widespread and supports reading from
any fstab or mtab file.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-20 07:20:33 +02:00
Joachim Wiberg 05be281301 Rely on (now working) fstab.h check in configure
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-19 20:04:03 +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 a61aa73419 configure: check for fstab.h, no fstaby.h
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-19 19:29:01 +02:00
Joachim Wiberg f39626f132 Minor, fix format string to systemf()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 14:25:32 +02:00
Joachim Wiberg c0b6f3af08 .github: build with latest libite version
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 14:22:09 +02:00
Joachim Wiberg 5d8fcfdf13 .github: allow release builds for -rcN
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 12:06:10 +02:00
Joachim Wiberg e4830c5614 Don't try to restart forking daemons
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:43:33 +02:00
Joachim Wiberg f33261af6b Fix fnread() string fmt, no format args.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:30:43 +02:00
Joachim Wiberg e7516f2b63 Bump version for v4.3-rc1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:08:15 +02:00
Joachim Wiberg d18167fe1d Update ChangeLog, ref cmdline.doc and fix libuEv linking
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:07:13 +02:00
Joachim Wiberg 7d3f95c0a9 doc: minor, emphasize 'debug' like all other kernel cmdline keywords
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:06:31 +02:00
Joachim Wiberg 86c5bbb03d doc: fix markdown syntax
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:06:07 +02:00
Joachim Wiberg 7530bb74f6 Update ChangeLog for upcoming v4.3 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 00:56:54 +02:00
Joachim Wiberg 54dd726d16 Follow-up to bd9bb92, missing API change
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 00:01:10 +02:00
Joachim Wiberg bd9bb92ca0 Replace reboot(RB_SW_SUSPEND) w/ internal /sys/power/state API
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-16 23:59:32 +02:00
Joachim Wiberg 01cb088e51 Fix initctl debug toggle regression introduced in ae09272b
Calling `initctl debug` is supposed to toggle Finit debug messages on
the boot console.  This broke in ae09272b when improving support for
running Finit in containers.

Part of this change is a slight refactor of who calles log_init() when
starting up, and when to call ttinit().  We now call ttinit() every time
we toggle debug.

Also, toggling back to normal logging had a bug.  The new default log
level for Finit is LOG_INFO, but toggling back set it to LOG_NOTICE.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 11:55:17 +02:00
Joachim Wiberg 3d91112e0d Rename finit command line option finit.show_status -> finit.status
Usability.

Remains backwards compatible for now, but finit.show_status is as of 4.3
deprecated.  Likely to be removed int 5.0

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 10:55:48 +02:00
Joachim Wiberg 16aef80682 Silence Coverity Scan NULL ptr deref warning
Explicitly set arg to non-NULL value.  The call to conf() later will
steer up the value to point to the full path of the user's finit.conf

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 10:02:11 +02:00
Joachim Wiberg fd34914936 Fix unchecked return value, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 09:57:04 +02:00
Joachim Wiberg 21a890a04e Fix NULL ptr deref, introduced in 8e2d0060 for issue #189
Found by Coverity Scan.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 09:53:58 +02:00
Joachim Wiberg 7f5f7e8ef6 Fix resource leak in shutdown, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 09:48:42 +02:00
Joachim Wiberg ff937576ea Fix possible NULL deref in run() error handling
When we added support for using popen() to run(), to log the output, we
forgot to update the error handling path.  Found by Coverity Scan.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 09:45:41 +02:00
Joachim Wiberg 7d831170ae plugins: close/exit iwatch *after* event loop has been detached
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 08:33:24 +02:00
Joachim Wiberg 6a21ac55ad Enable more printf format attributes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 08:32:18 +02:00
Joachim Wiberg a0820c7f20 Fix printf format specifier and formatting issues in use of log fns
Almost all related to and (less likely) possible causes of issue #236.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 00:26:14 +02:00
Joachim Wiberg 6d58c9ed0b Enable printf format attributes to logit() and flog()
We don't want repeats of issue #236, so let's start by tracking down any
bugs hidden in logging functions.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 00:17:15 +02:00
Joachim Wiberg bc2ffbc767 Fix printf style function missing argument to %s
This is very likely the root cause of issue #236, let's see.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 00:10:30 +02:00
Joachim Wiberg 4c1fc2410e Show progress output also for unmount
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:41:12 +02:00
Joachim Wiberg 70e1aa889a Ignore errors from the first two remount,ro they are just decoys
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:28:10 +02:00
Joachim Wiberg c8c5e4e88a Revert "Simplify shutdown, no need for workarounds to remount / read-only"
This reverts commit 7c42986800 since we
seem to still need this werid thing on some systems.  The key seems
to use 'any' device at remount[1].  Anyway, the key issue before was
the noisy output, but like Debian we'll just redirect to /dev/null.

[1]: https://bugs.launchpad.net/ubuntu/+source/util-linux/+bug/29187

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:22:18 +02:00
Joachim Wiberg 86c1398778 Run swapoff interactively, let user know what's happening.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:21:52 +02:00
Joachim Wiberg b37fa2b417 Silence process killer at shutdown, too noisy on regular systems
On regular desktop systems, like Debian, the dbus-daemon forks off a
dbus-launch process to start up things like your desktop for you.  This
process is not known to Finit and lingers in the background since it's
been reparented to init, and to top things off it seems to ignore any
SIGTERMs send to it.

Obviously this makes a shutdown on such systems very noisy, so this
patch changes the print() to a _d() so anyone debugging a system can see
it with `-- finit.debug` on the kernel command line, or `initctl debug`.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:16:57 +02:00
Joachim Wiberg a91e197553 Avoid looping forever trying to unmount busy tmpfs
This split unmount is a bit crude, unfortunately.  A user may have set
up a bind or overlayfs mount on top of a tmpfs -- so unmounting tmpfs
first will then always result in EBUSY.

Avoid logging busy errors and fake OK.  We'll catch it later in the
second stage unmount.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:57:14 +02:00
Joachim Wiberg 5adb92ca1b Catch and print any errors when unmounting filesystems at reboot
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:45:37 +02:00
Joachim Wiberg cfc99c4e8b Follow-up to ef9e9ec, run ifdown also in background, with --force
Turns out that on Debian `ifdown -a` can block for quite a while at
shutdown/reboot.  So we'd like to use the --force option.  However,
the BusyBox ifdown tool doesn't support --force, only -f, which in
turn the regular ifdown tool doesn't support.

Regardless, we can allow network shutdown to run in the background
like bring-up, at reboot we want to reboot quickly and don't care
so much, and on runlevel change to single-user mode we can allow
for some lagging behind in the background.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:45:37 +02:00
Joachim Wiberg 3e51ed1c55 Run swapon interactively, let user know what's happening.
Let's try this, should be OK for all types of systems.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:45:37 +02:00
Joachim Wiberg b5df0a6274 Fix swapoff at shutdown, does not support -e flag
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:33:54 +02:00
Joachim Wiberg cbe8d56042 Mention lack of mainline distro testing on non-x86 archs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 08:35:13 +02:00
Joachim Wiberg a3ec792b44 doc: minor updates to build script, again
- Mention why configure script is missing from GIT
  - Adjust command line for enabling Finit debug
  - Plus some minor formatting issues

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 08:33:50 +02:00
Joachim Wiberg c24855d4d5 keventd: add support for toggling debug messages w/ SIGUSR1
Useful to debug system events after the system has started up and you
don't want to rebuild Finit to add the `-d` command line flag.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 22:38:35 +02:00
Joachim Wiberg 014e457fda doc: note which plugins are enabled by default
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 21:35:16 +02:00
Joachim Wiberg 21d89c7e24 doc: mention kernel command line option loglevel=7
This is needed since 5ff27c4f when support for debugging Finit and the
kernel independently was added.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 21:32:28 +02:00
Joachim Wiberg 639fb76f5a doc: update build ref, add "or later" to required libraries
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 21:14:35 +02:00
Joachim Wiberg 30c189b116 initctl: add helpful hint when showing/editing built-in services
Built-in services, like keventd, do not have a .conf file to edit.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 20:51:46 +02:00
Joachim Wiberg e2a8803f7a test: minor, extend log message a bit
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-10 22:46:45 +02:00
Joachim Wiberg 209e140ddd test: let Finit's bootmisc plugin create the /var/run symlink
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-10 22:46:15 +02:00
Joachim Wiberg 2e3fa72924 Revert "plugins: bootmisc: use relative symlink for /var/run"
This reverts commit f0e328edc9.
2022-04-10 22:38:27 +02:00
Joachim Wiberg 1502838a0d Fix regression in _pe() log macro, introduced in 685f332
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-10 12:39:20 +02:00
Joachim Wiberg 377c8bce8c test: fix dist and tenv-root/ regression from refactor
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-09 17:52:48 +02:00
Joachim Wiberg a39d958d25 Follow-up to 7dc7f9a, protect against stalling on non-existing pids
A forking service, e.g. a SysV init script, that returns is no longer
running, even though the monitored service may still be starting.  We
must mark the svc->pid as terminated until we know more -- otherwise
we may stall on a shutdown at that exact point.

Also, when shutting down, and stopping all services, ensure we do not
start the carousel for non-existing PIDs.  This might also cause our
stalling at shutdown.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-08 07:27:42 +02:00
Joachim Wiberg 7f8a96a73e test: refactor test framework to use a rootfs skeleton
Instead of having to create files, and copying them in place for each
test, we move all static test files to a skeleton rootfs.  This makes
it a lot easier to get an overview of how things and how they work.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-08 07:22:33 +02:00
Joachim Wiberg 5c2577214d test: ask BusyBox its tools and recommended paths
Note: we need to add /usr/bin and /usr/sbin to the standard PATH
      for tests and the test environment itself.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-06 22:42:49 +02:00
Joachim Wiberg f03206a694 .github: due to regression in ubuntu-latest, use older ubuntu runner
In https://github.com/actions/virtual-environments/commit/12fa229 the
ubuntu-latest runner was updated to Ubuntu 20.04.4, with Linux kernel
version: 5.13.0-1014-azure.  This broke the Finit tests completely
and the only possible solution, for now, seems to be reverting back
to the ubuntu-18.04 runner instead.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-06 21:16:46 +02:00
Joachim Wiberg f0e328edc9 plugins: bootmisc: use relative symlink for /var/run
In an upside world, much like the Finit test cases, the root may be
relocated.  This make /var/run relative to /var, instead of /.  Which
hopefully is safer and covers more use-cases.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-06 21:13:43 +02:00
Joachim Wiberg 13342f2bd9 .github: debug failing tests again, see what setup-root does
All tests except the first two now suddenly started failing.  Might be
the new caching support for the busybox binary, but that works on other
clean clones -- working theory now is that there's something subtle
with the setup-root.sh test -- which PASSes ...

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 19:43:43 +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
Joachim Wiberg 462d5b22b4 Fix parse bug, always set service's respawn flag
Before this fix, a service declared with respawn could not be changed at
runtime to remove the respawn flag.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 18:06:35 +02:00
Joachim Wiberg b1bfab08f3 Coding style, reverse Christmas tree ordering
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 08:26:13 +02:00
Joachim Wiberg aeb48ef04b test: add support for caching busybox-x86_64 binary in ~/.cache
While without a working Internet connection today I ran into the issue
of not being able to run the tests.  This adds a basic caching mechanism
to setup-root.sh which saves busybox-x86_64 in ~/.cache, if available.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 08:20:48 +02:00
Joachim Wiberg b8b200ad75 doc: move state machine to inside its section
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-03 12:13:42 +02:00
Joachim Wiberg c148d8d783 doc: document supported types of forking/non-forking daemon's
Issue #223

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-03 12:03:21 +02:00
Joachim Wiberg 27ba3b27f5 test: extend start-stop-serv test w/ all supported combinations
serv: add support for foregrounding, running with and without PID file,
      including custom PID filename.

test: verify Finit can start & monitor services that:
      1) Fork and creates a PID file in a known location
      2) Don't fork and don't create a PID file, but Finit does
      3) Don't fork but create a PID file
      4) Don't fork and create custom named PID file

Note: Finit cannot support a service that forks and doesn't create a PID
      file.  This combination is impossible to support without tracking
      all processes created in /proc -- which Finit does not do atm.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-03 11:56:42 +02:00
Joachim Wiberg b4af86255d test: rename fserv -> serv, more features to be added
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-03 11:55:11 +02:00
Joachim Wiberg 01a007b388 .github: detect Finit version and figure out build dir on failure
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-02 12:38:44 +02:00
Joachim Wiberg 0e28741dcb test: fserv is built in another directory
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-02 12:38:20 +02:00
Joachim Wiberg c993feeb44 .github: dump start-stop-fserv.log on make check error
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-02 12:21:01 +02:00
Joachim Wiberg ec17f0aa23 test: add new test to dist, fixes CI build
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-02 12:14:32 +02:00
Joachim Wiberg 6baf2990e8 test: new test to verify support for forking services
Issue #223

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-02 12:08:10 +02:00
Joachim Wiberg 6416e2a1a4 test: minor refactor in build system
Add Makefile.am in tenv and common for EXTRA_DIST.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-02 12:07:34 +02:00
Joachim Wiberg 7c42986800 Simplify shutdown, no need for workarounds to remount / read-only
Calling sync is not needed, remount does this for us.

Remount with 'dummydev' causes warnings and is not needed.  It appears
sysvinit used this to try and fix a sparc related bug.  Instead, use the
rootfs keyword to ensure we don't accidentally remount a bind mounted /.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-02 11:09:29 +02:00
Joachim Wiberg 6f802a7ff1 test: whitespace changes only
Coding style for shell scripts:

  - Tabs for indent (change in Emacs needed)
  - Braces on their own line, like C functions

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-02 10:45:30 +02:00
Joachim Wiberg 879721839e test: slight formatting change in log() output
Encase (stripped) test name in [] and use decreased intensity ANSI coloring.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-02 10:26:07 +02:00
Joachim Wiberg 20290a4166 Clear any outstanding restart timer when svc reaches running state
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 16:32:42 +02:00
Joachim Wiberg ba77e4f217 Ensure we clear the 'starting' flag when cleaning up an svc_t
Prevent crashing/restarting tasks from winding up in the wrong state.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 16:31:19 +02:00
Joachim Wiberg e7b18feca5 Don't block PID 1 waiting for start/stop scripts, fork and forget
No point waiting for SysV start/stop scripts to finish, PID 1 should not
risk getting blocked forever by broken scripts. Instead we fork them off
and forget about them until they terminate. If they are buggy and don't
finish, it's the problem of the admin.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 16:27:46 +02:00
Joachim Wiberg 4a90a3e8ef test: drop plugins we don't need in test
E.g., a failing urandom.so does no good for ppl reading test results.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 16:22:20 +02:00
Joachim Wiberg 6d14ff84d3 test: add missing script helpers to dist archive
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 15:41:24 +02:00
Joachim Wiberg 89cc6017df .github: distcheck runs in another subdir, fix test logs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 14:51:36 +02:00
Joachim Wiberg f6fafdbd23 .github: show individual test logs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 14:28:51 +02:00
Joachim Wiberg 3480e42687 .github: 2nd test-suite.log debug attempt
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 14:23:02 +02:00
Joachim Wiberg 053c1643a7 .github: debug test-suite.log
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 14:09:22 +02:00
Joachim Wiberg 2018cac050 test: at first run, oldpid doesn't exist
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 13:47:11 +02:00
Joachim Wiberg f9090f535d test: drop cat $tty, seems to not be needed
I'll have to ask Jacques what this was for, because it doesn't seem to
be needed to run and monitor the test.  Also, it lingers at shutdown,
causing some unintended side effects in Finit.

Commenting out for now, as a reminder to myself.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-27 13:46:54 +02:00
Joachim Wiberg 10577f3e48 Allow matching of svc_t and pid file, prefer PID over file lookup
When a SysV init script starts a daemon, Finit knows nothing of the PID
it should monitor.  The PID is written, by start-stop-daemon or the
daemon itself, to the PID file.  Finit monitors for new PID files and
can match the PID in such files with an svc_t.

For the regular use-case, we prefer first looking up the matching svc_t
based on the PID -- assuming we start and monitor the service.  As a
fallback we resort to mathching the svc_t's declared PID file with the
new file we just discovered.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-25 06:53:59 +01:00
Joachim Wiberg 07f7caef0d Allow setting custom pid: file for SysV init scripts
We want to find the PID of the daemon the init script starts, so we need
a way to declare this to Finit.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-25 06:52:03 +01:00
Joachim Wiberg 093b3ba467 Fix problem with restarting stopped SysV init scripts
SysV init scripts should not go to "done" state but "halted" so we can
do: `initctl stop foo; initctl start foo`, like we do for our regular
monitored services.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-25 06:50:40 +01:00
Joachim Wiberg c63279630b Fix starting and stopping of SysV init scripts
Due to lack of tests the SysV start/stop script stopped working.
Unclear when.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-25 06:45:55 +01:00
Joachim Wiberg 4755e5206b test: new test, verify SysV start/stop daemon support
Install start-stop-daemon in test root.  Add S01-service.sh, which uses
start-stop-daemon to start service.sh.  Modify service.sh to respect
signals, and not exit immediately when sleep exits due to SIGTERM.
Remove PID file in signal callback and make sure to exit OK

The test itself is basically a copy of the start-stop-service.sh test.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-24 22:11:24 +01:00
Joachim Wiberg 2002157032 Simplify shutdown in container, call _exit()
Calling _exit(2) lets libc do most of the cleanup we want when shutting
down while in a container.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-24 21:56:47 +01:00
Joachim Wiberg 094e00d405 test: update test to use kill(1) replacement slay.sh
The slay script checks for common errors and gives some logs and status
of Finit when something goes wrong.  Helps detect issue #226 when the
start-kill-service.sh test runs at 100000 laps.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-23 07:02:10 +01:00
Joachim Wiberg e01836c506 Clarify debug messages for respawning daemons/ttys
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-23 06:36:46 +01:00
Joachim Wiberg 685f332c6e logit(): avoid extra \n when logging to stderr
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-23 06:33:21 +01:00
Joachim Wiberg ae09272bcc logit(): detect running in container to use stderr for logging
When running in a container we still want to use any syslog daemon
available for our logging needs.  However, the time between the first
logit() in Finit and any such daemon having started can be long.  In a
normal (non-containerized) setup we log to the kernel ring buffer, but
that's not available in a container scenario.  At least not for
unprivileged containers.  So we need to detect all these cases and be
prepared to fall back to log to the console, either using these LOG_CONS
flag to openlog(), or by simply calling vfprintf() to stderr.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-23 06:29:40 +01:00
Joachim Wiberg d16f7e0c88 test: help finit know its under test
This trick can also be used by others who want to run Finit in an
unshare.  Set the container environment variable to 'unshare',
like lxc and docker do for their products.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-23 06:27:33 +01:00
Joachim Wiberg 063d645d95 in_container(): cache positive results
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-23 06:25:43 +01:00
Joachim Wiberg f87e9d8880 Follow-up to 6fa3aa4, log cmd not args[0] which may be NULL
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-22 22:30:59 +01:00
Joachim Wiberg e8099f1bfa The kill(2) syscall returns ENOENT, not ESRCH on missing PIDs
Turns out the kill(2) syscall returns ENOENT, not ESRCH, in our test
suite.  Don't know why, the man page never mentions ENOENT, only the
ESRCH code.  Let's check for both, either way ithe PID is not there.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-22 07:22:15 +01:00
Joachim Wiberg 7dc7f9a968 Fix #227: set svc state late when stopping services, nay be dead
A service may have unexpectedly died, and we never got the signal, so
when stopping services we must set the new state after we've tried to
stop the service.  Otherwise the svc_set_state() function starts a
background timer for the SIGKILL job, which may block a reboot.

The kill() syscall tells us if the service was there or not, if not we
must clean up and go to HALTED state.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-22 07:18:37 +01:00
Joachim Wiberg 996ab8c6c6 Minor, fix local var shadowing outer var
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-21 22:04:09 +01:00
Joachim Wiberg 16c2198304 .github: dump test-suite.log on failure
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-20 15:45:12 +01:00
Joachim Wiberg ecca01dea0 Fix GitHub action status links
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-20 15:37:29 +01:00
Joachim Wiberg bda3cdd3ad Increase inotify socket receive buffer size
At startup (and reconf) of systems with lots of services there is a risk
of losing inotify events, e.g., PID file creation/delete events.  This
patch increase the receive buffer (doubles it).

On Linux the getsockopt() for SO_RCVBUF returns double the set size, due
to housekeeping in the kernel.  So we don't have to do any adjustments
when setting it.

Issue #226

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-20 15:33:56 +01:00
Joachim Wiberg 4811f76294 test: refactor service kill/respawn test
- Allow service to be respawned immediately (hidden option)
 - Stress test by killing 1000 times

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-07 15:50:23 +01:00
Joachim Wiberg 0aba704312 test: install awk, grep, and tail busybox tools as well
We may need them in test scripts.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-07 15:49:45 +01:00
Joachim Wiberg 57329832d0 initctl: skip cgroup in status output pid_cgruop() fails
In some (error) cases the PID known to Finit may no longer exist, or may
not have been added to a cgroup (yet).  Handle this case by skipping the
output of cgroup info in such conditions.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-07 15:48:15 +01:00
Joachim Wiberg 078a1d0c95 initctl: if the system doesn't have logs, skip it in status output
On, e.g., a container based system logs may not be available so check
also that the messages fallback exists instead of causing confusing
error in the status output for the service.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-07 15:43:58 +01:00
Joachim Wiberg 0e695aa0c7 Only run swapon/swapoff if they exist
To silence warnings at startup/shutdown, check for existance of swapon
and swapoff before calling them.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-07 14:01:25 +01:00
Joachim Wiberg f7a1514131 test: update with info on running a single/few tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-07 11:26:17 +01:00
Joachim Wiberg 11bc87ecc3 Merge pull request #233 from liuming50/fix-a-return-value-of-initctl-status
initctl: fix return status of run tasks

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-05 11:59:57 +01: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
Joachim Wiberg 2faefd44a2 Simplify shutdown/reboot when running in a container
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-01 20:46:01 +01:00
Joachim Wiberg 6fa3aa41df run(): add support for logging/redirect
This patch adds support for optional logging of output from all run()
commands.  For run_interactive() we've opted to log instead of just
redirect, meaning output on error is till on console but also in log.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-01 20:46:01 +01:00
Joachim Wiberg ef9e9ec786 networking: log output from 'ifup -a', run 'ifdown -a' interactively
We've been discussing, over the years, that we'd like to have an easier
way to debug bringup with Finit.  Network bringup is one such case where
it's hard to debug if/what you've misspelled in /etc/network/interfaces

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-01 20:46:01 +01:00
Joachim Wiberg d77e3a6113 networking: when ifup is missing, fall back to bring up loopback
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-01 20:46:01 +01:00
Joachim Wiberg 0b1258b44c Add very basic in_container() function, from sysklogd project
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-01 20:46:01 +01:00
Joachim Wiberg 62dad82ba8 Bring networking down also in runlevel 6, reboot
This fixes a seemingly long-running bug; we only brought down networking
in shutdown/halt and for runlevel 1, single-user mode -- not reboot.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-01 20:46:01 +01:00
Joachim Wiberg 5423b5b0a2 Merge pull request #232 from liuming50/tweak-done-conditions
service.c: create conditions according to runtask exit status

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-03-01 16:27:52 +01:00
Ming Liu 6b10174bcb service.c: create conditions according to runtask exit status
In commit f0f358a13:
[ service.c: set/clear condition 'done' for run tasks ]

a runtask done condition would be set/cleared when entering DONE/HALTED
states, but it did not cover all the user cases, for instance, sometimes
an end user may want to know if a runtask has finished sucessfully or
to decide what to do on its failures.

So we now change the conditions to: tsktype/tskname/success and
tsktype/tskname/failure.

And this change not only applies to run/task types, but also applies to
sysv type, in case it fails, a sysv/tskname/failure condition would be
set.

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2022-02-26 14:05:49 +01:00
Joachim Wiberg ec94f4d321 Fix sig.c build warning
Refactor new kill/shutdown implementation from 3e0063e to fix the
regression in compiler output:

sig.c: In function ‘kill_callback’:
sig.c:222:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  222 |  kill(pid, (int)context);
      |            ^

Also, some minor renames and simplificactions to match project style.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-25 07:52:42 +01:00
Joachim Wiberg 69800537f2 Minor, rename local variable for consistency
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-25 07:18:54 +01:00
Joachim Wiberg 61faedb0b5 Minor refactor
- Reversed christmas tree
  - Avoid assignments inside if/while
  - Use established nomenclature

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-25 07:16:19 +01:00
Joachim Wiberg 61014431aa Minor refactor
- Simplify, no need for additional local variable
  - Use established nomenclature

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-25 07:15:43 +01:00
Joachim Wiberg 49bd63994c Minor refactor
- Check all pointers
  - Declaratons always at top of func/scope
  - Use established variable nomenclature
  - Skip useless if() stmt

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-25 07:15:03 +01:00
Joachim Wiberg 85b29d9407 Minor whitespace and comment cleanup
- Comments preferably at beginning of func/sect
  - Reorder code slightly, add whitespace for readability
  - Drop useless comment

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-25 07:15:03 +01:00
Joachim Wiberg b83fdea49b Merge pull request #229 from jorgensigvardsson/issue/255/initctl-signal
Fix #225: add support for initctl signal

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-20 09:50:21 +01:00
Jörgen Sigvardsson beec0ee590 Test case for initctl signal
This commit implements a test for the signal feature of initctl. The
existing service used in tests (`common/service.sh`) has been extended
with a signal trap handler. When SIGUSR1 is received, it will write the
string `'USR1'` to `/tmp/usr1.log`. The test will run `initctl signal
service.sh SIGUSR1` and assert that the contents of the file
`/tmp/usr1.log` really is `USR1`.
2022-02-15 12:43:07 +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
Jörgen Sigvardsson 62da379472 initctl signal command parsing: done 2022-02-15 12:29:40 +01:00
Joachim Wiberg 3c9053b055 Merge pull request #231 from jorgensigvardsson/fix/absolute-var-lock-symlink-breaks-tests
Remove test code that may break tests

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-15 10:47:47 +01:00
Jörgen Sigvardsson 71b07ce2bd Remove test code that may break tests
In the test framework for finit, a set of shell scripts are used to
setup a test harness, run tests, and finalize tests. In the setup, a
file system is created for the virtualized/containerized environment in
which all tests are run, located at `$FINIT_SRC/test/tenv-root`. In the
tear down phase of each test, the file `/var/lock` is made readable
using `chmod +r`. It is not clear _why_ the teardown code does this, as
there are no references in the test framework to this path anywhere
else. It is conceivable that the teardown phase attempted to "reset the
state" for next test.

The code that that this commit removes does not always work. When
`/var/lock` is a symlink, and resolves to an absolute path, the test
framework does not function properly. The teardown code is run in the
context of the host computer, and touching files outside of the
virtualized environment is not ok.

The removal of the offending code does not seem to affect tests: all
tests pass without it, so its existence is questionable.

Signed-off-by: Jörgen Sigvardsson <jorgen.sigvardsson@gmail.com>
2022-02-15 10:30:04 +01:00
Joachim Wiberg ebea3d273e test: mention need for proper configure first
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-13 22:45:47 +01:00
Joachim Wiberg f3a76b8a63 Clarify debug message slightly
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-13 22:45:47 +01:00
Joachim Wiberg ba93791077 Revert 5cdbd57, causes prolonged delays at shutdown/reboot
Blocking SIGTERM means Finit will wait another two seconds before it
sends SIGKILL, which casues a delayed [WARN] Killing ... before we can
proceed to shutdown/reboot -- not OK.  Don't know what I was smoking
back in 2017, but it must've been good.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-13 22:45:47 +01:00
Joachim Wiberg b994858907 initctl: exit immediately on signal (from Finit)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-13 22:45:47 +01:00
Joachim Wiberg 74ad34a0c5 Another case for when we need to silently disable cgroups
When running in a container we might not have the necessary privileges
to mount cgroups.  Don't cause error in this case, just log it.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-13 22:45:47 +01:00
Joachim Wiberg 1b5b37c06b plugin: allow modprobe and tty plugins to be disabled
This patch allows disabling (enabled by default) the modprobe and tty
plugins.  They are not particularly useful in container use-cases.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-13 22:45:47 +01:00
Joachim Wiberg c8e1bd0e9a test: add new kill test to dist
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-12 13:37:55 +01:00
Joachim Wiberg e9c8d3d740 test: verify finit restarts crashing services & registers new PID
We extend the service.sh to emulate a well behaving service that creates
and removes its own PID file.

The new test emulates a crash by sending SIGKILL to service.sh.  We then
verify that Finit restarts it, and eventually registers the new PID when
the services recreates the PID file.

Issue #226

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-12 13:30:05 +01:00
Joachim Wiberg f567b866a0 test: drop plugins we don't want in tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-12 13:29:27 +01:00
Joachim Wiberg 3471d3ee2d test: add service descriptions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-12 12:51:28 +01:00
Joachim Wiberg 6e197f5751 test: add /var and /run to rootfs, add empty fstab
- We need a working /var and /run for some features, e.g. PID
   monitoring and status files for urandom.so
 - Add empty fstab to silence mount errors from finit

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-12 12:49:34 +01:00
Joachim Wiberg b568c18346 initctl: fix usage text for -V,--version
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-12 12:32:53 +01:00
Joachim Wiberg 1b29876ba8 initctl: adjust indentation in usage
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-12 12:32:44 +01:00
Joachim Wiberg 4c6f3d2d69 Minor markdown syntax fixes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-11 17:30:09 +01:00
Joachim Wiberg 8d3f7eded2 contrib/patches: publish inotify IN_MASK_CREATE patch for Linux 4.9
Issue #196.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-11 17:30:09 +01:00
Joachim Wiberg 0222feeda1 Prepare ChangeLog for 4.3 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-08 09:22:00 +01:00
Joachim Wiberg f10cf1a9a0 Merge pull request #220 from liuming50/fix-a-regression
service.c: fix a regression
2022-02-07 12:18:41 +01:00
Ming Liu 85b2089fd3 initctl.c: fix a incosistent coding sytle
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2022-02-07 11:37:56 +01:00
Ming Liu 885808c64c service.c: fix a regression
A regression was introduced by commit f0f358a1:
[ service.c: set/clear condition 'done' for run tasks ]

svc->type is a integer but mistakenly being used as string, which will
cause crash.

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2022-02-07 11:15:47 +01:00
Joachim Wiberg 78069b42e7 Merge pull request #219 from liuming50/fix-filesystems-not-unmounted-at-shutdown
Fix filesystems not unmounted at shutdown
2022-02-07 10:27:45 +01:00
Ming Liu 3e0063e874 Fix filesystems not unmounted at shutdown
Instead of unconditionally waiting 2 seconds for processes to die,
check continuously for remaining processes, and break the loop when
none remain.

Turn PID 1 to a RT process with highest priority 99 during shutdown,
this ensures it would not be preempted by other RT processes.

Signed-off-by: Robert Andersson <robert.m.andersson@atlascopco.com>
Signed-off-by: Mathias Thore <mathias.thore@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2022-02-07 10:06:36 +01:00
Joachim Wiberg 6ec1ab3d4f Merge pull request #218 from liuming50/fix-some-string-comparing-issues
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-07 07:04:10 +01:00
Joachim Wiberg 33b4540ad9 Merge pull request #207 from liuming50/set-condition-done-for-oneshot-tasks
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-07 06:59:28 +01:00
Joachim Wiberg a434b51653 Follow-up to #189: change SERVICE_TYPE, add SERVICE_SCRIPT_TYPE
- SERVICE_TYPE for svc->type
 - SERVICE_SCRIPT_TYPE for pre/post

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-07 06:53:34 +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 8e2d006048 Fix #189: add type/env/exist envs to pre/post scripts
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-07 06:29:05 +01:00
Joachim Wiberg fd9f204b6d Minor refactor, split out pre/post envs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-07 06:12:37 +01:00
Ming Liu f0f358a138 service.c: set/clear condition 'done' for run tasks
We like to know when a runtask (run/task/sysv)is done, so as to start
the services that depending on it, set a oneshot condition 'done' for
that case and clear it when runtask services enter HALTED state.

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2022-02-05 18:18:53 +01:00
Ming Liu cfffcd4513 svc.c: change strncmp to string_compare
strncmp can not handle the case when name is a substring of cmd.

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2022-02-05 13:54:54 +01:00
Ming Liu e51587c66e initctl.c: change string_match to string_compare
It should not use relaxed comparison in some places, otherwise it mess
up with scenarios like:
```
$ initctl status ntpdpre
$ initctl status ntpd
```

the output might be same for both of the above commands without this
fix.

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2022-02-05 13:54:15 +01:00
Joachim Wiberg f930953e6a Fix #214: change WARN color in progress to yellow
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-02-01 08:54:12 +01:00
Joachim Wiberg ebdc10d1c5 Bump version for 4.3 development cycle
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-30 11:03:10 +01:00
Joachim Wiberg d12370568f initctl: add -v,--version command line option
This patch adds the -v,--version option to initctl, which acts as an
alias to the 'version' command.  For now they end up in the same old
function, printing the program version.  However, in time this will be
changed so that the 'version' command asks a running Finit for its
version instead of assuming the daemon is of the same version.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-30 11:02:38 +01:00
Joachim Wiberg 176125deca Strip module args from progress output
A 'module foo args ...' line in finit.conf can be looooooong.  This
patch drops the module args from the progress output for brevity.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-30 10:37:14 +01:00
Joachim Wiberg cb934ca39f Fix issue with "reboot doesn't work on 32-bit targets"
With the introduction of GLIBC v2.34, all 32-bit devices running Linux
get the option of having a 64-bit time_t to survice the UNIX 2038
apocalypse.

Support for 64-bit time_t was added to libuev in v2.4.0.  The build
flags for linking against libuev are defined in the library's .pc
files, which basically gives you -D_TIME_BITS=64 for your CPPFLAGS.

However, it turns out the $(uev_CFLAGS) from pkg-config were only used
when building the main finit binary -- not for the plugins, causing
some really wacky behavior as a result.  All plugins and Finit itself
had some very different opinions on what `struct plugin` looked like,
including offsets and size.  This led to all I/O plugins initializing
their sockets at the wrong offset -- little-endian 32-bit targets set
the HOOK_SHUTDOWN callback hook to address 0x1 -- which the reboot
code then tried to execute, of course leading to a segfault.

This is quite possibly the root cause of issue #216

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-27 18:50:46 +01:00
Joachim Wiberg 4fd95fdcbe Fix #215: disable cgroup support when cpu controller is missing
Previous patches only checked if cgroups v2 support was available in
the kernel.  If mounting failed cgroups support was disabled.

However, much of the core logic to cgroups in Finit revolve around the
CPU controller.  This patch adds checks to ensure that the kernel has
basic controller support as well.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-27 18:50:46 +01:00
Joachim Wiberg cb62349054 plugins/bootmisc: only ignore EEXIST errors in ln()
This patch prevents bogus error messages from Finit for when
directories or symlinks already exist.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-27 18:45:00 +01:00
Joachim Wiberg 1b72119673 Merge pull request #217 from liuming50/fix-a-iwatcher-initializing-issue
cgroup.c: fix a iwatcher initializing issue
2022-01-27 11:02:08 +01:00
Ming Liu add474e825 cgroup.c: fix a iwatcher initializing issue
iwatcher of cgroup needs to be initialized earlier before any
cgroup_add functions being called.

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2022-01-27 10:16:14 +01:00
Joachim Wiberg f32e4d4b30 Update changelog and bump version for v4.2 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-16 05:01:03 +01:00
Joachim Wiberg eff87b3dc5 .github: add basic release general
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-16 05:00:31 +01:00
Joachim Wiberg ea4821fd18 plugins/urandom: fix resource leak, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-16 04:56:34 +01:00
Joachim Wiberg 6285668dcd .github: action for running coverity scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-16 04:47:51 +01:00
Joachim Wiberg 449bc7d12b Follow-up to 10b72f1: periodically age service crash counter
Traditionally we've reset the service restart counter on two occasions:

  1) when a service reaches its max crash count (default 10), and
  2) when a service somehow "stabilizes"

In the second case the service is restored to normal running state and
we "forget" its bad previous behavior.  Meaning we cannot catch daemons
that act in an unstable manner outside the "rage quit" scenario.

This patch allows for slowing aging (decrementing) the restart counter
once every five minutes.  Meaning we still catch rage quitters but now
are also able catch other types of misbehavior.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-13 23:13:26 +01:00
Joachim Wiberg ee867e7f3b Update ChangeLog
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-13 12:03:12 +01:00
Joachim Wiberg b4c7ae9c8c plugins/bootmisc: check return value from symlink() log on error
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-11 17:20:22 +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 823bb82b8c initctl: display number of restarts and max restarts in job status
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-11 16:19:25 +01:00
Joachim Wiberg 9a5bb46f78 Fix #212: service PID file lost after initctl reload
Clearing of the svc->pidfile was introduced in e1b87d70 for a
restriction that has now been removed.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-11 15:54:53 +01:00
Joachim Wiberg 950ca953f5 Fix #211: drop hard-coded getty limit of 32 characters for usernames
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-11 13:40:07 +01:00
Joachim Wiberg 495c8c9eac Update changelog and bump version for v4.2-rc1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-10 21:49:24 +01:00
Joachim Wiberg 2887795586 initctl: minor, coding style cleanup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-10 21:49:01 +01:00
Joachim Wiberg 6a893f50ae initctl: refactor has_utmp() capability check to use new cmd conds
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-10 21:46:22 +01:00
Joachim Wiberg 5d08353284 initctl: minor, fix shadowing of global variable
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-10 21:38:19 +01:00
Joachim Wiberg a37037ded4 Fix #188: support without cgroups v2 support
This patch adds support for detecting if the Linux kernel Fint runs on
has support for cgroups v2.  The probe is done very early, in runlevel
S, when attempting to mount /sys/fs/cgroup.  Meaning, the log message
may be lost on systems that do not run sysklogd[1].

Here's the relevant logs from a system running myLinux on a kernel
that has cgroups v2 support disabled:

    Jan 10 20:19:40 anarchy finit[1]: myLinux 2021.11-696-g8fddaf36ed, entering runlevel S
    Jan 10 20:19:40 anarchy finit[1]: Kernel does not support cgroups v2, disabling.
    Jan 10 20:19:41 anarchy finit[1]: myLinux 2021.11-696-g8fddaf36ed, entering runlevel 2

All code paths that attempt to set or query kernel cgroups config has
been short circuited when this happens.  However, this does not apply
to any cgroup related config in the Finit .conf files -- which may of
course be omitted.  Yet, if configuration directives exist, they will
be parsed and may cause error.

Also, the initctl tool checks if /sys/fs/cgroup is mounted at runtime
and disables all status output and commands that rely on the feature.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-10 21:21:35 +01:00
Joachim Wiberg d331b72dfd Relocate ismnt() and fismnt() to util.c, for sharing with initctl
initctl cannot link with helpers.c, so let's relocate these helper
functions to util.c instead.  Need them to probe for cgroup support.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-10 20:26:37 +01:00
Joachim Wiberg 3b21d35f23 Fix arrow in service desciption ASCII
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-10 13:48:46 +01:00
Joachim Wiberg 62a694b8b7 Prepare ChangeLog for upcoming v4.2 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 08:22:15 +01:00
Joachim Wiberg eeba2960f9 Document new per-service options controlling automatic respawn
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 07:35:33 +01:00
Joachim Wiberg 91550c926b Follow-up to ec2900e: use restart_sec:SEC as canonical option name
A timeout is not the same as a restart delay, which this option really
controls, but the name restart_delay is a bit too long.  Hence, this
obvious name so there's no ambiguity what unit we're dealing with.

Keeping restarttmo:SEC as a compatibility setting for the benefit of
the original authors, for now.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 07:13:06 +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 cdede817fd initctl: new command 'ident [NAME]' shows ids of all/named services
As suggested in issue #197, this new command: 'initctl id [NAME]'
lists identities of all, or named, services.  E.g,

    # initctl id telnetd
    telnetd:23
    telnetd:2323

The NAME argument is optional, when omitted it lists all enabled
run/task/sysv/service in the system, with their full name, and any
optional identitty.  E.g.

    # initctl id
    dropbear
    tty:console
    mdnsd
    mini-snmpd
    smcrouted
    sntpd
    ssdpd
    sysklogd
    watchdogd
    httpd
    telnetd:23
    telnetd:2323

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 06:14:42 +01:00
Joachim Wiberg df42c2f6fe Fix #197: initctl status foo should show overview of foo:1, foo:2 ..
When the system has multiple services 'foo' the initctl command
'status foo' should give a focused overview of all matching foo:*,
whereas a 'status foo:2' should show the detailed view of that
particular instance.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 06:11:57 +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 5ff27c4fe2 Allow kernel log messages to console with loglevel=7
Since Finit v4.0 kernel console output has been silenced just prior to
the banner being printed, unless finit.debug mode was enabled.  This
patch makes sure to check the kernel loglevel, if it's >= 7, finit no
longer disables kernel console ouput.

Consequently, you now need 'quiet' on your kernel command line, or a
loglevel < 7 for a quiet boot, at least until a syslogd takes over.

This means that you now can debug the kernel and finit independently,
which should be a great comfort to anyone doing bringup or any form of
kernel debugging.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 01:34:49 +01:00
Joachim Wiberg e5fff5117d Minor, simplify internal API
Cleanup of old cruft.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 01:34:19 +01:00
Joachim Wiberg 615cd5aac3 plugins/urandom: use RNDADDENTROPY ioctl to seed kernel rng
This patch switches from "cp /var/lib/misc/random-seed /dev/urandom"
to use the kernel RNDADDENTROPY ioctl, which actually increments the
entropy count.

Also, the amount of random data saved at reboot is increased from the
fairly low 512 to 32768 bytes.

All in all, this should greatly improve the stability of most systems
during, or close to, bootstrap.  In particular embedded systems with
limited or no HWRNG.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-02 01:04:07 +01:00
Joachim Wiberg 621d95a89e Minor, fix clang warning 'bootstrap shadows local variable'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-01 22:55:07 +01:00
Joachim Wiberg cd383167f9 plugins/rtc: instead of bailing, reset invalid RTC to kernel default
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-01 22:51:45 +01:00
Joachim Wiberg cb2969002c Fix #210: simplify escape code to clear line
Since we just want to clear the complete line, and are already a the
beginning of the line, we can use the simpler \e[K which also seems
to fix the display resize bug in #210.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-01 18:20:47 +01:00
Joachim Wiberg 1cf204e23d Fix #187: fix typos, including slight clean up
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-01-01 16:37:06 +01:00
Joachim Wiberg 393834b253 Follow-up to 4ca8256: ordering mishap
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-12-07 00:13:54 +01:00
Joachim Wiberg 4ca8256e18 Follow-up to 280d91b, fix conio.h namespace
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-12-07 00:05:47 +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
Joachim Wiberg 980152fd53 Add support for non-root users to use initctl, e.g. group wheel
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-30 11:44:22 +01:00
Joachim Wiberg d994420d4d plugins: minor coding style cleanup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-10 10:18:02 +01:00
Joachim Wiberg 38f3ecf01f .github: run tests from distcheck
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 12:44:31 +02:00
Joachim Wiberg 5cd0d05b31 .github: install libite and libuev to /usr
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 12:27:33 +02:00
Joachim Wiberg 62519c3638 .github: avoid running tests in parallel
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 10:01:45 +02:00
Joachim Wiberg 27bb2deb1a .github: sudo do what I mean
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 09:56:19 +02:00
Joachim Wiberg a2c8e71f14 .github: update dynamic linker cache after installing library deps
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 09:53:26 +02:00
Joachim Wiberg d1f56e7c2e .github: adjust path for showing finit & intictl usage text
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 09:46:19 +02:00
Joachim Wiberg a9fd0cbf02 .github: simplify and fix install path
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 09:32:38 +02:00
Joachim Wiberg be8c89ec00 Bump version for v4.2 release cycle
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 09:28:44 +02:00
Joachim Wiberg 4f53752693 .github: install support libs to /usr/local
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 09:26:54 +02:00
Joachim Wiberg 393673222d Replace Travis-CI with GitHub Actions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-23 09:05:38 +02:00
Joachim Wiberg a88f4524d5 Merge pull request #208 from liuming50/support-more-specific-control-of-services
service.c: add more parameters when starting services
2021-09-23 08:46:42 +02:00
Joachim Wiberg 3a02066a66 Merge pull request #206 from liuming50/dont-hard-code-dbus-user-pidfile
dbus: dont hard-code daemon user/pidfile
2021-09-23 08:31:19 +02:00
Joachim Wiberg 7e3981d1a3 Merge pull request #205 from liuming50/fix-a-wrong-header-include
Fix a header including syntax
2021-09-23 08:30:20 +02: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
Ming Liu d718a27abf dbus: dont hard-code daemon user/pidfile
Both DBUS user and pidfile is configurable in DBUS compilation, by
passing "--with-dbus-user=" and "--with-system-pid-file=", let's avoid
hard-coding them here, use macros instead.

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2021-09-21 10:48:25 +02:00
Ming Liu db8027911c Fix a header including syntax
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2021-09-21 10:47:15 +02:00
Joachim Wiberg aef3b4117d Merge pull request #200 from liuming50/dont-hard-code-nologins-file
Dont hard-code nologin file
2021-09-18 09:48:43 +02:00
Ming Liu 6728b77aca Dont hard-code nologin file
It's configurable in /etc/login.defs as NOLOGINS_FILE, avoid to hard
coding it here, introduce a macro FINIT_NOLOGIN_PATH instead which is
configurable from compiler flags, it's not defined, then back to
_PATH_NOLOGIN from /usr/include/paths.h.

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2021-09-17 13:10:01 +02:00
Ming Liu a7c0b42965 configure.ac: add fastboo/fsckfix to config summary output
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2021-09-10 11:35:45 +02:00
Joachim Wiberg 667b6ecbbd Merge branch 'liuming50-introduce-two-more-config-options' 2021-09-09 09:10:46 +02:00
Joachim Wiberg b852878a4a Follow-up, coding style fixes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-09 09:10:16 +02:00
Ming Liu 940f1f7486 Introduce two more configure options
fastboot: once enabled, fsck would be skipped on filesystems listed in
          /etc/fstab.
fsckfix: once enabled, 'fsck -ys' would be run instead of 'fsck -a',
         and check the return value larger than 1 as a failure and goes
         to login console.

They are both disabled by default, no functional changes unless an end
user choose to enable them.

The idea derives from Sysvinit's "FASTBOOT" and "FSCKFIX".

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2021-09-09 09:08:14 +02:00
Joachim Wiberg 49c705b5ad Merge pull request #201 from liuming50/fix-a-memleak
Fix a memleak.
2021-09-09 09:04:42 +02:00
Joachim Wiberg 5163e8a433 Merge pull request #198 from timgates42/bugfix_typos
docs: Fix a few typos
2021-09-09 08:56:07 +02:00
Joachim Wiberg 71e9603e4e Merge pull request #199 from liuming50/drop-c++-key-word
Avoid using C++ key words
2021-09-09 08:55:39 +02:00
Joachim Wiberg c71102f44e Merge branch 'liuming50-fix-a-unmount-issue' 2021-09-09 08:51:41 +02:00
Joachim Wiberg 9b9158a765 Follow-up, coding style and drop extra print()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-09-09 08:51:26 +02:00
Robert Andersson 595e2b4e81 Ensure all filesystems listed in /proc/mounts are unmounted
The iterator function getmntent() is not stable. It may skip
entries if the contents of the iterated file changes, which
is the case with /proc/mounts when filesystems are unmounted.
As a result, some filesystems were never unmounted.

To fix this, iteratation is now restarted after every
sucessful unmount.

Signed-off-by: Robert Andersson <robert.m.andersson@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2021-08-30 10:16:00 +02:00
Ming Liu ae8e205343 Fix a memleak.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2021-08-29 14:02:04 +02:00
Ming Liu 00b33fbd42 Avoid using C++ key words
"protected" is a C++ key word, replace it with "is_protected" avoid
compiling failures with C++ compiler.

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
2021-08-29 10:35:08 +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
Joachim Wiberg 522a06f864 Merge pull request #181 from yangfl/typo
Fix typo
2021-06-25 07:43:08 +02:00
yangfl fa14ed1649 Fix typo
with the love from codespell
2021-06-25 13:08:14 +08:00
Joachim Wiberg 64e41e066b Change default loglevel to LOG_INFO from LOG_NOTICE
We've had several logit() messages of LOG_INFO level that never
really made it to syslog because we classified it as "debug".

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-22 17:20:17 +02:00
Joachim Wiberg 2a71f35005 Reduce log level of watchdog handover, this is not an error condition
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-22 17:20:17 +02:00
Joachim Wiberg 961a337a5e Minor, we no longer know if it's an external or bundled getty
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-22 17:20:17 +02:00
Joachim Wiberg f0622a692e Minor, format style change of comment block
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-22 17:20:17 +02:00
Joachim Wiberg ef7042dd9d finit: early log, "entering runlevel S", just after printing banner
This patch adds "the missing" first runlevel log entry when Finit has
printed the console banner and begins its bootstrap phase.

At this point we know syslogd hasn't been started yet, so we rely on
logit() to redirect this to /dev/kmsg in the meantime.  Later syslogd
will pick this up, see that it's not from the kernel, and log it to
the proper log file.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-22 17:20:17 +02:00
Joachim Wiberg 046ecfa329 Fix #180: user managed services started by initctl reload
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-14 13:16:14 +02:00
Joachim Wiberg 47fbe49861 Wrap all mount(2) calls so we at least get an error message
If any of these mount() calls fail, not counting EBUSY because that
would mean sth is already mounted, there really isn't much we can do.
So the least we should do is warn on console if it happens.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-14 11:20:08 +02:00
Joachim Wiberg 2f34315634 fnread(): make sure to NUL terminate buffer
Note, this is dead code, currently unsused in Finit.  Possibly an
external plugin makes use of it, but even that is highly unlikely.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-14 11:19:57 +02:00
Joachim Wiberg c8d6ad6546 Bump version for v4.1 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 17:30:48 +02:00
Joachim Wiberg 3dfae3074e Revert "Travis-CI: disable clang for Coverity run"
This reverts commit 8e1845f57b.
2021-06-06 17:05:09 +02:00
Joachim Wiberg 97bebe52c9 Fix logic expression in release_heading(), found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 16:57:52 +02:00
Joachim Wiberg 8e1845f57b Travis-CI: disable clang for Coverity run
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 16:50:51 +02:00
Joachim Wiberg 6cd6769997 Update ChangeLog and drop man page TODO
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 16:46:59 +02:00
Joachim Wiberg 03884d3566 doc: fix minor issues, drop 'simply', nothing's simple ..
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 16:35:57 +02:00
Joachim Wiberg 899925e249 man: initial manual page for finit.conf
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 16:35:37 +02:00
Joachim Wiberg efefa398ce man: initial manual page for initctl
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 12:57:21 +02:00
Joachim Wiberg 1ee24c69bc Sync with man page
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 12:50:03 +02:00
Joachim Wiberg b16a36980c man: initial manual page for finit
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 12:50:03 +02:00
Joachim Wiberg c1b52bbc04 contrib: debian: depending on the setup, a user may not need elogind
I'm writing this in X started on a system running Finit v4.1-pre that
does not have elogind installed.  It does, however, still have systemd
installed, so systemd-logind is available.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 09:05:13 +02:00
Joachim Wiberg 9461ad4d4d doc: add reminders about limitations to sys conditions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 09:04:45 +02:00
Joachim Wiberg e2ef6e9c34 plugins: sys: drop conditions not affecting any svc_t
- Fix bug when calling sys_update_conds() when dir already exists
  and we're not being called from the scandir() handler.  I.e.,
  every time but the first for each new condition sub-family

- Drop sys conditions that don't affect any svc_t.  This may seem
  counterintuitive, and we should probably not use oneshot conds,
  but if we leave these conds asserted they may cause inadvertent
  trigger if a finit.conf is loaded which ha this sys cond.  E.g.,
  if ctrlaltdel is asserted and we enable a task in finit.conf and
  call `initctl reload`, the task would start immediately, even
  though ctrl-alt-del may have been pressed a week ago

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 00:34:11 +02:00
Joachim Wiberg cdc8873f5b Let cond_update() return if any svc_t was affected
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-06 00:33:36 +02:00
Joachim Wiberg b82b205d92 contrib: debian: install available python-quit.conf
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-05 23:35:26 +02:00
Joachim Wiberg 39d879f240 Add support for auto-detetcing OS heading for progress
This patch removes the cognitive overhead of having to manually set your
OS heading, --with-heading="Foo OS vX.YY".  As of this patch, Finit by
default extracts PRETTY_NAME from /etc/os-release.  It is now possible
to also disable the heading entirely using --without-heading

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-05 14:28:49 +02:00
Joachim Wiberg 9c1db9cab3 contrib: drop os marker files, check Makefile instead
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-05 14:28:49 +02:00
Jacques de Laval 2f5c00f2bd Also accept \n for "Please press Enter to activate ..."
Shouldn't be needed for real cases, but we have seen automated scripts send
'\n' instead of '\r', or '\r' + '\n'.

Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
2021-06-04 13:20:14 +02:00
Joachim Wiberg dc36b313ff getty: attempt to steal ctty if don't already have it
This fixes the following classic problem

    login: root
    -sh: can't access tty; job control turned off

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-04 08:39:48 +02:00
Joachim Wiberg 093fa0107a getty: skip 5 sec delay introduced in 94c0d1b refactor
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-04 08:33:58 +02:00
Joachim Wiberg e8f5ec2579 Simplify, drop SYNC_SHUTDOWN state file, not needed anymore
Similar to 6224166 (previous commit), this old code is a remnant of a
bygone era and not needed anymore.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-03 12:51:59 +02:00
Joachim Wiberg 62241668df Drop SIGSTOP/TSTP/CONT handlers, not needed anymore
Once upon a time, SIGSTOP was used to pause Finit during flashing (MTD)
of a system image.  This to prevent Finit from accidentally starting any
programs, i.e., reading from flash disk during or after upgrade.

This was quite intrusive, and has possible nasty side effects, e.g., any
process with root access sends SIGSTOP prevents TTY login.  So this patch
now removes the functionality and recommends using a dedcicated runlevel
for such critical tasks instead.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-03 12:18:08 +02:00
Jacques de Laval ee67c08b64 Reset the starting flag of a service when stopping it
When a service is started and then stopped before it has created it's pid file,
it could be left forever in the "stopping" state, if we don't reset the
starting flag.

Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
2021-06-02 17:01:01 +02:00
Joachim Wiberg 41a14391a2 Refactor sigchld_cb(), handle EINTR properly, restart waitpid()
The waitpid() function can return -1 due to EINTR (signal), so we should
restart it to make sure we collect all zombies.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-02 16:34:24 +02:00
Joachim Wiberg 6eccca31b9 contrib: debian: task to stop any running plymouth boot screen
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-02 08:57:36 +02:00
Joachim Wiberg d497942a9f contrib: debian: speling error demon vs daemon
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-02 08:55:29 +02:00
Joachim Wiberg 68c7352108 Update ChangeLog and bump version for 4.1-rc2
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 16:16:00 +02:00
Joachim Wiberg 0d40e43c4b Update ChangeLog with fixes for containers
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 13:33:35 +02:00
Joachim Wiberg 9867fd82df Check correct struct member to determine if / has 'ro' flag
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 12:50:48 +02:00
Joachim Wiberg 1c941fdfbb plugins: add support for disabling RTC and urandom plugins
Some systems may want to handle RTC and /dev/urandom by themselves, or
not at all as in the case of containers where the host does all this.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 11:43:58 +02:00
Joachim Wiberg 0ba67a72f8 plugins: add missing x11-common plugin to static libplug.la
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 11:43:26 +02:00
Joachim Wiberg 09b9e26b2d fs_init(): skip mounting proc/dev/sys if already mounted
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 17:35:07 +02:00
Joachim Wiberg d25c1d5564 logit: avoid modifying argv[] strings
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 17:03:10 +02:00
Joachim Wiberg d4358ed3f7 Drop nasty hide_args() hack, should not be needed anymore
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 16:51:08 +02:00
Joachim Wiberg cc6ffa35fc Drop parsing of /proc/cmdline by default, instead use argc + argv[]
For most use-cases the kernel will give Finit its arguments as proper
command line args in argc + argv[], like any other program.  However,
for some users, most notably Alpine Linux, there is a slightly broken
initramfs that cannot forward more than one argument using init_args,
for such systems you can re-enable the old behavior with a configure
switch --enable-kernel-cmdline -- it's not ideal but what can you do.

The main reason for removing this feature by default is to support
use-cases where Finit runs as the init for container apps that can read
/proc -- we do not want them to use the init args from the host.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 16:51:08 +02:00
Joachim Wiberg 55e9cb2f58 Update with info on dropped multiple consoles
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 13:59:21 +02:00
Joachim Wiberg 2641256254 plugins: sys: no need to compose path, name is already absolute path
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 13:58:30 +02:00
Joachim Wiberg 473116f603 Drop experimental multiple console output support
It has barely worked and only caused more problems than solved annoying
issues.  We have one console for output, /dev/console, which the kernel
sets up for us.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 10:48:37 +02:00
Joachim Wiberg e18d63df4a Always make sure to not acquire controlling TTY for output redirect
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 10:48:04 +02:00
Joachim Wiberg 4b1b3f6913 Update ChangeLog with latest changes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 09:35:20 +02:00
Joachim Wiberg f6da5e4136 Revert "Travis-CI: disable clang temporarily for Coverity Scan run"
This reverts commit 754358113f.
2021-05-31 07:48:49 +02:00
Joachim Wiberg d1d5d39144 Fix possible NULL ptr deref, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 07:43:29 +02:00
Joachim Wiberg 754358113f Travis-CI: disable clang temporarily for Coverity Scan run
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 07:27:12 +02:00
Joachim Wiberg c24207516d keventd: properly zero terminate buffer, found by Coverity Scan
Also, fix default: case in error handling, must always continue back to
poll() on any recv() error.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 07:22:50 +02:00
Joachim Wiberg 2a23bce78d Hide progress output also on stop/shutdown for services w/o -- descr
Progress at startup has been hidden for services w/o -- description, but
for some reason this check was not added to service_stop().  This patch
rectifies the situation, finally.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 07:17:48 +02: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 ed9590aef1 Fix tty default :ID => tty:S0 instead of tty:ttyS0
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 06:27:59 +02:00
Joachim Wiberg 25683221cc Set default envs like sysvinit and busybox does; TERM, LOGNAME, USER
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 13:22:50 +02:00
Joachim Wiberg 9cc9e3ddbb getty: if we cannot execute /bin/login, try sulogin before /bin/sh
Basic security measure, don't bail to shell if we cannot find/exec
login, instead try sulogin before falling back to plain shell.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 12:42:48 +02:00
Joachim Wiberg 654f8aeb19 getty: handle variable number of arguments, only tty required
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:55:21 +02:00
Joachim Wiberg e349abb897 stty: allow utf8 input characters
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 3027a6755f Adjust logic in finding system consoles for progress/debug output
By default, Linux gives us /dev/console for output.  This is a pseudo
device that uses the same actual device as the last console=foo listed
in /proc/cmdline.  The last one listed is the main console, which is
also the *first* one listed in /sys/class/tty/console/active, so we skip
that when we check for system consoles to avoid duplicating output.

The getty code in tty.c currently has its own handling of @console,
which we keep for now.  Ideally, however, the code should be merged.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 5404aa6037 Refactor run_getty() and run_getty2() into one
By moving the built-in getty to a stand-alone bundled getty we can now
refactor the old run_getty() functions into a single one.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg a319e32438 Clean up prepare_tty()
When TTYs became first class citizens in Finit 4.0 much of the
boilerplate setup is now down by service_start().  Also, the calls to
TIOCSCTTY, VINTR, and SIGINT ignore is not necessary to do here, it
should be done by the getty used, if any.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 2eaf57fc67 stty: simplify and ignore BREAK/SIGINT
It is up to /bin/login, sulogin, or plain shells to unblock SIGINT.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 88ec4a55cb Call setsid() before redirecting stdio or unblocking signals
We must detach from the controlling TTY before enabling signals and
setting up new stdio.  TTYs have their own handling of stdio.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 0acbc60ec1 initctl: drop confusing 'errno 0' from "Timed out" message
errno is not set when we timeout waiting for a reply from Finit.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 4362971c6a run(): Drop extra sig_unblock()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 94c0d1b833 Refactor built-in getty into a standalone getty in /libexec
This patch moves the built-in getty out of Finit into /libexec/finit/,
reducing the size of the Finit binary and simplifying the code.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 1e795d4e16 Fix #175: Ensure finit does not acquire 'dev' as controlling TTY
When starting a getty Finit checks first that the configured TTY device
actually exists and is a TTY.  This patch, by Tobias Waldekranz, ensures
Finit (PID 1) doesn't acquire the TTY device as a controlling TTY.  If
that happens PID 1 will get all signals sent to the process actually
started with the device as its controlling TTY.

Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 00:33:31 +02:00
Joachim Wiberg 93a027ca23 plugins: netlink: fix gcc signed vs unsigned comparsion warning
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-27 11:18:06 +02:00
Joachim Wiberg 5f3958fab4 getty: max username is 32 chars, according to useradd(1)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-27 11:18:06 +02:00
Joachim Wiberg 1351b708fe Fix parse error for detecting external getty
When an external getty is used, and an absolute path is not given, the
parser tried to use access() to determine built-in vs external getty.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-27 11:18:06 +02:00
Joachim Wiberg e867e039bb Follow-up, document SIGINT/SIGPWR in comment, add missing include
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-27 11:18:06 +02:00
Joachim Wiberg 1d1087a3b3 Merge pull request #174 from troglobit/fix-kmsg-log-level
logging: Disregard logging facility when comparing log levels
2021-05-20 19:00:08 +02:00
Jacques de Laval e91f1ea1b2 logging: Disregard logging facility when comparing log levels
If we don't extract the level (disregarding facility), statements such as
"logit(LOG_CONSOLE | LOG_NOTICE, ...)" would never reach the kernel log.

Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
2021-05-20 17:19:53 +02:00
Joachim Wiberg 55d16edadc contrib: update /etc/finit.conf examples
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-18 09:02:58 +02:00
Joachim Wiberg b79245ddb3 Add support for sys/pwr/fail and sys/key/ctrlaltdel conditions
This patch drops the default signal handlers for SIGPWR and SIGINT with
optional tasks in /etc/finit.conf, triggered by two new conditions:
sys/pwr/fail and sys/key/ctrlaltdel, respectively.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-18 08:58:11 +02:00
Joachim Wiberg e706300b6d keventd: rename fgetln() -> fgetline()
Apparently fgetln() is available in musl libc, but not glibc.  This is a
funciton that first appeared in 4.4BSD.  We take a risk that fgetline()
is free in all libc's, getline() is not.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:44:39 +02:00
Joachim Wiberg d08cbd77aa keventd: use poll.h, not sys/poll.h, fix warning on musl libc
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:41:35 +02:00
Joachim Wiberg b070ae73a4 Revert "Travis-CI: disable clang temporarily for Coverity Scan run"
This reverts commit f52c141062.
2021-05-17 00:33:30 +02:00
Joachim Wiberg 2c30eef9a1 Update changelog for v4.1 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:32:43 +02:00
Joachim Wiberg 31cdc113fc doc: update build instructions and examples
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:32:21 +02:00
Joachim Wiberg f6f813498b doc: add some info about keventd, what it does
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:32:11 +02:00
Joachim Wiberg 4c8baaf7c0 Make kevent a configure option, disbled by default
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:26:57 +02:00
Joachim Wiberg 57ca937f27 New function to create onshot conds without updating
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-16 23:37:41 +02:00
Joachim Wiberg d13e39e345 keventd ftbfs: add missing include path to libite
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-16 23:35:39 +02:00
Joachim Wiberg f52c141062 Travis-CI: disable clang temporarily for Coverity Scan run
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-16 23:21:31 +02:00
Joachim Wiberg 40042da8ff contrib: debian: add anacron and cron services
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-15 10:36:05 +02:00
Joachim Wiberg c251304146 Refactor sys condition plugin into a standalone keventd
This patch is a refactor of the prototype sys condition plugin.  It
moves most of the logic to monitor kernel events into a keventd that,
currently only, sets and clears the sys/pwr/ac condition.  The sys
plugin itself is now only a monitor of conditions and ensures Finit
follows them.  This is a lot more secure and moves (at least one piece
of) netlink processing out from PID 1.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-15 10:31:08 +02:00
Joachim Wiberg c047e37a79 cgroup: ensure all services in init group remain as leaf nodes
The top-level cgroup init is a leaf group and should be treated as such,
even for user setup tasks/services.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-15 10:29:29 +02:00
Joachim Wiberg d2c57447f0 initctl: no error if failing to remove non-existing usr condition
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-15 10:29:01 +02:00
Joachim Wiberg 79e9dabc11 Fix bug: re-registering a former service as task does not work
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-15 10:28:29 +02:00
Joachim Wiberg b04dc4d457 Ensure services in plugins and from finit.c belong to a cgroup
The udevd, dbus, bundled watchdog, and others were started without a
valid cgroup.  This is a workaround to ensure they are assigned one.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-15 10:27:59 +02:00
Joachim Wiberg f86e7810be sig.c: disable kernel default ctrl-alt-delete handler
This fixes a long-standanding issue with finit not controlling the
reboot when the user presses ctrl-alt-delete (PC systems).

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-14 10:34:54 +02:00
Joachim Wiberg 2018c82ea1 plugins: sys: watch uevent to prevent feedback loop
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-13 21:20:08 +02:00
Joachim Wiberg c27f3603e6 plugins: sys: use counting semaphores to handle >1 AC supply
- Track number of ac and ac online
 - Use systemd logic to assert sys/pwr/ac also when no supply

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-13 08:45:49 +02:00
Joachim Wiberg 6f82b806ad plugins: new sys condition event monitor (wip)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-11 07:02:49 +02:00
Joachim Wiberg cbb8935660 New functions: fnread() and fngetint(), companions to fnwrite()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-11 07:02:30 +02:00
Joachim Wiberg 21ebbb942f plugins: bootmisc: minor, whitespace
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-09 14:38:16 +02:00
Joachim Wiberg 988ecd95e3 plugins: bootmisc: only create /run/lock if missing
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-09 14:38:16 +02:00
Joachim Wiberg 3f3e70c686 Mount /dev/pts with gid of tty group and set nosuid, noexec flags
Note, this code only runs if /dev/pts was not mounted in /etc/fstab

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-09 14:38:16 +02:00
Joachim Wiberg 073b040981 Prevent user DoS by mounting /run/lock as separate tmpfs
This patch does several things related to /run and system reliability.

 - Mount /run with MAX 10% of usable RAM
 - Create and mount /run/lock as a separate tmpfs with max 5 MiB

As a spin-off, this patch also fixes permisions on /run/lock to 0777
so regular users can create lock files.

Note: none of this code runs if /run is mounted alread in /etc/fstab

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-09 14:38:16 +02:00
Joachim Wiberg b1a058ccdd doc: update TODO a bit, remember -s for initctl
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-09 14:38:16 +02:00
Joachim Wiberg cbc7b8c3c7 plugins: bootmisc: add S02sudo setup for Debian systems
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-09 14:38:16 +02:00
Joachim Wiberg 13340e4200 contrib: debian: start tty's on tty1-tty6 clear 2-6
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-09 14:38:16 +02:00
Joachim Wiberg 0076c1f218 contrib: debian: add apparmor, avahi, and bluetooth services
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-09 14:38:16 +02:00
Joachim Wiberg 6fc71b7528 Follow-up to a1af8e8: mount /tmp with perms for all users
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-09 14:38:16 +02:00
Joachim Wiberg b42f1e99e2 README: use absolute path in sshd example, it requires that
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-07 22:29:23 +02:00
Joachim Wiberg afd6ad06a6 README: drop urls from initctl help text to sync with app
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-07 22:28:50 +02:00
Joachim Wiberg ea0bfaa2f3 Revert "Travis-CI: disable clang temporarily for Coverity Scan run"
This reverts commit 40425ee9ec.
2021-05-07 21:15:37 +02:00
Joachim Wiberg 5c3ec176c2 Update changelog, issue #173
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-07 20:19:31 +02:00
Joachim Wiberg 40425ee9ec Travis-CI: disable clang temporarily for Coverity Scan run
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-07 19:45:28 +02:00
Joachim Wiberg 424db825a3 plugins: netlink: error handling fixes
Handle EAGAIN properly, for both regular and resync flow, on any error
in the regular flow (unless ENOBUFS) we want to check for nl_ifdown on
any of the successfully parsed messages.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-07 17:02:09 +02:00
Joachim Wiberg b9cc4cd629 Revert "plugins: fix #173, increase size of netlink socket receive buffer"
This reverts commit add55cfc2a.
2021-05-07 16:50:04 +02:00
Joachim Wiberg 243b8f025b plugins: netlink: refactor and reduce recv() buffer
This patch adds support for calling recv() repeatedly to get the netlink
response from the kernel.  As a result, the recv() buffer can be reduced
down to 4k again.

Both the regular flow and the resync flow now follow the exact same code
path, except for the ENOBUFS handling.  If we get ENOBUFS in resync, we
are screwed anyway.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-07 16:42:42 +02:00
Joachim Wiberg 6c60b67588 plugins: netlink: fix resync request size alignment with kernel
For RTM_GETLINK we need a `struct ifinfomsg`, not `struct rtmsg`,
otherwise the kernel will get 8 extra bytes and complain about it.

This patch makes sure to set the correct iface change mask as well, and
increases the debug logs a bit to get a fix on sizes used.  We increase
the recv() buffer 8k -> 64k to make sure we can get all data in one big
swoop.  Plan is to refactor this mess in a later commit.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-07 15:20:25 +02:00
Joachim Wiberg 910bb13711 plugins: netlink: redesign to handle ENOBUFS with kernel resync
This is a major redesign of the netlink plugin to be able to handle
ENOBUFS¹ properly.  Pending verification, this change replaces the patch
to increase socket buffer size, which in real life turned out to be
insufficient.

When nl_callback() calls recv() and it fails with ENOBUFS, we consider
our cache of the kernel state invalid and thus:

  1. deassert all net/ conditions
  2. open a new (temporary) netlink socket
  3. send RTM_GETLINK  and re-assert all interfaces using nl_link()
  4. send RTM_GETROUTE and re-assert all routes with nl_route()

Like before, the kernel will not send us a RTM_DELROUTE when it removes
the default route, so we still have to track this ourselves.  This patch
also refactors that functionality to only resync routes when the ifindex
associated previosly with the default route goes down or is removed.

The previous change that added nl_default() to recheck, has been dropped
to instead reuse the standard nl_route() callback.
___
¹ see netlink(7) for details.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-07 13:06:47 +02:00
Joachim Wiberg add55cfc2a plugins: fix #173, increase size of netlink socket receive buffer
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-04 13:19:54 +02:00
Joachim Wiberg 565820325b Follow-up to a1af8e8: nodev is a mount flag as well
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-04 07:36:41 +02:00
Joachim Wiberg 6bb4d67d92 Follow-up to a1af8e8: fix mount options vs mount flags
The nosuid, noexec, and relatime arguments are not mount options, but flags.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-04 07:34:39 +02:00
Joachim Wiberg 534d50c03a Fix diff link
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-03 16:09:27 +02:00
Joachim Wiberg 9a42883a96 Bump version to 4.1-rc1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-03 16:09:21 +02:00
Joachim Wiberg 7c77e2c2b6 Update with major bug fixes for 4.1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-03 15:25:03 +02:00
Joachim Wiberg ea8c46cd30 Fix #170: check for loss of default route when interfaces go down
This patch fixes the problem with Linux not sending netlink route change
notifications when interfaces for these routes goes down.  When an iface
goes down we now send a route request to the kernel and check the return
message, if no default route is found we deassert net/default/route.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-03 15:18:25 +02:00
Joachim Wiberg fead3b0671 configure.ac: drop grub Makefile.in generation
Not needed anymore.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-03 09:34:27 +02:00
Joachim Wiberg 081990b49e Update for upcoming v4.1 bug fix release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-03 03:50:12 +02:00
Joachim Wiberg 6b89f8c6db contrib: debian: update README with new grub setup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-03 03:39:08 +02:00
Joachim Wiberg 373097040a contrib: debian: update install legend
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-03 03:03:30 +02:00
Joachim Wiberg a4ab75172c contrib: debian: use SUPPORTED_INITS instead of custom entry
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-03 01:53:09 +02:00
Joachim Wiberg 5cf9958957 contrib: debian: read parameters from /etc/default/grub
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-02 15:43:27 +02:00
Joachim Wiberg b137e08e84 contrib: fix install script to be able to run from tarball
The file autogen.sh is not included in tarballs.  Use configure.ac
instead to detect topdir.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-02 15:30:13 +02:00
Joachim Wiberg a1af8e8687 Follow-up to 4febd28: restore mount of /dev/shm et al for Debian
This patch restores parts of 4febd28, but in a more orderly fashion, in
order to get a standard Debian system to boot properly with X and tools.

The patch adds fs_finalize() which checks if /dev/sh/, /dev/pts, /run,
and /tmp have been mounted properly from /etc/fstab.  If not, then the
function makes sure to mount tmfps (or devpts) file systems as expected
by most modern systems.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-02 15:21:50 +02:00
Joachim Wiberg 53c7ddcb22 Change SIGUSR1 to be compatible with systemd and SysV init
This patch changes the behavior of SIGUSR1.  Previously USR1 could be
used to halt a running Finit system, similar to BusyBox init.  However,
compatibility with sysvinit and systemd has been deemed more important.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-02 14:48:49 +02:00
Joachim Wiberg 3872077ff1 plugins: netlink: stricter interface name validation
Coverity suggests validating against only a set of known characters.
However, the kernel allows just about all characters in an interface
name.  This version of valdiate_ifname() is blatantly stolen, more
or less, from linux/net/core/dev.c

 https://code.woboq.org/linux/linux/net/core/dev.c.html#1020

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-29 17:19:19 +02:00
Joachim Wiberg 9e85c4f3d1 Bump version for v4.0 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-26 01:01:20 +02:00
Joachim Wiberg 2531102623 sulogin: ensure Ctrl-D returns OK(0) also for pwd login prompt
sulogin should return OK (exit code 0) when the user presses Ctrl-D,
regardless of the prompt shown.  Otherwise Finit may look for another
sulogin to run straight after this one.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-26 00:59:01 +02:00
Joachim Wiberg 33deada6f0 README: mention new rescue mode in feature list overview
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-26 00:52:40 +02:00
Joachim Wiberg 9d1506bb7e Revert "Travis-CI: disable clang for coverity scan run"
This reverts commit e011dac98b.
2021-04-26 00:45:57 +02:00
Joachim Wiberg c3f115c9ec sulogin: fix build issue
Keyboard suddenly lost CapsLock -> Ctrl remapping ...

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-26 00:39:39 +02:00
Joachim Wiberg 430d402b14 sulogin: check for Ctrl-D also if no pwd to abort and continue boot
Signed-off-by: Joachim Wiberg <joachim.nilsson@westermo.se>
2021-04-26 00:25:24 +02:00
Joachim Wiberg e011dac98b Travis-CI: disable clang for coverity scan run
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 23:57:41 +02:00
Joachim Wiberg 42b84d1ccb Update ChangeLog for v4.0 GA
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 23:57:02 +02:00
Joachim Wiberg 288105eac7 sulogin: must fflush() prompt on Alpine Linux (musl libc)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 23:14:05 +02:00
Joachim Wiberg 842b522e68 Drop --disable-logit configure option, no longer in $PATH
Simplify build system.

The logit tool is, as of v4.0, installed into /libexec/finit/logit and
thus not part of the system $PATH.  If a sysadmin or distro wants to
remove it from the system it's entirely possible since Finit always
checks for logit availability before attempting to use it.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 22:53:34 +02:00
Joachim Wiberg e6f36974c8 Document all facets of rescue mode; traditional and fallback
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 22:46:43 +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 666cae6f49 service_start(): allow notty TTYs without device to start
A notty TTY can be declared with or without a device, it requires none.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 22:09:07 +02:00
Joachim Wiberg be2ac1d1b1 sulogin: handle no password and locked account (treated as no pwd)
This patch does two things:

 1. A system with a root account that has no password is now
    allowed to login without password, as one expects.
 2. A systems with a locked root account, is treated as (1).

The latter of the two may very well turn out to be a really bad idea.
Much angst have been poured into it, yet the end decision is to allow
access.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 21:43:39 +02:00
Joachim Wiberg 266e5b30eb Drop all mention of old fallback shell from comments
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 21:43:16 +02:00
Joachim Wiberg 4e5d06b580 Replace experimental emergency shell with actual rescue mode
Most major init systems have a way to start a rescue shell.  This is
usally started when the string `rescue` is read from the kernel's
command line.

The traditional Finit way of handling this has been to skip certain
phases of the standard boot, skip /etc/finit.conf et al, and go for a
/lib/finit/rescue.conf instead.  This pratice has been imroved over
the last few commits with a sulogin.  However, there was no way to
resume boot, like most other init systems offer.

This patch implements a very simple rescue mode, utilizing the new
sulogin, replacing the old (and experimental) emergency shell.  If
Ctrl-D is pressed at the maintenance login prompt the boot is now
resumed.  The same goes for exit/Ctrl-D from the maintenace shell.

The preferred sulogin is the bundled /libexec/finit/sulogin, but
if that isn't installed, the first one in $PATH is used.  If no
sulogin at all is found, Finit proceeds as before this patch, to
skip certains steps and go for a /lib/finit/rescue.conf.  Hence,
al steps can be controlled by an administrator.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 21:32:35 +02:00
Joachim Wiberg fe334135ce Fix small memory leak, use whichp() to query, not which()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 19:47:15 +02:00
Joachim Wiberg aef10fb5e7 Revert "Travis-CI: disable clang for coverity scan run"
This reverts commit 550ae9c784.
2021-04-25 19:47:04 +02:00
Joachim Wiberg 86707c1f0b sulogin: minor refactor, splice out sh() as separate function
- splice out sh() as a separate function
 - make sh() session leader and set controlling TTY (TIOCSCTTY)
   to make it a proper login shell with Ctrl-C functionality
 - simplify call to execl()

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 19:28:03 +02:00
Joachim Wiberg a28d5b3c09 sulogin: fix minor issue found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-25 19:27:42 +02:00
Joachim Wiberg 550ae9c784 Travis-CI: disable clang for coverity scan run
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 20:45:44 +02:00
Joachim Wiberg cd5b91680a sulogin: home cooked version, can be built -static
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 20:43:54 +02:00
Joachim Wiberg 221ab20898 tty: add basic security, call sulogin in rescue mode (notty)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 20:27:26 +02:00
Joachim Wiberg 96534789db Minor, rename LOGIT_PATH -> _PATH_LOGIT for consistency
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 20:26:52 +02:00
Joachim Wiberg 26128dd788 plugins: skip plugin in rescue mode
These plugins should not run in rescue mode, because the system may be
in a very bad state and we do not want to make the situation any worse
than it already is.

Essentially, only services in rescue.conf should run in rescue mode.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 19:46:43 +02:00
Joachim Wiberg 799e992542 tty: minor, rename local variables for consistency
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 10:33:58 +02:00
Joachim Wiberg fa524eec60 contrib: debian: add elogind.conf and update recommendations
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 10:33:57 +02:00
Joachim Wiberg 6dced29b49 Add another constraint for the built-in watchdog, device exists
- Check if watchdogd *and* `WDT_DEVNODE` exists before registering the
   built-in watchdogd at boot
 - Update bootstrap.md with this additional constraint
 - Update config.md with references to bootstrap and the new constraint

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 10:33:57 +02:00
Joachim Wiberg 2ea613a42b Make sure built-in watchdog is disabled by default
Omitting --without-watchdog caused the watchdog to be enabled.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 09:43:27 +02:00
Joachim Wiberg 985df20519 cgroup: don't warn on cgroup.events EINVAL for top-level groups
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 07:42:31 +02:00
Joachim Wiberg f6161b9be9 doc: Add blurb on bundled vs external watchdog, handover and reset
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-24 07:41:46 +02:00
Joachim Wiberg 25c5014d3c Also check env: file for changes to detect svc->args_dirty
This patch fixes an issue where services that support SIGHUP are not
properly stop/started on changes to their command line arguments.

A change to a service's env: file, e.g. /etc/default/foo for service
foo, must also be counted as a change to the foo args.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-23 17:12:59 +02:00
Joachim Wiberg b8b7b53d96 External plugins require exporting cgroup.h, svc.h needs it
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-20 01:48:03 +02:00
Joachim Wiberg 7707c4b8e6 initctl: only show key capture in debug mode
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-04-19 15:56:39 +02:00
284 changed files with 18059 additions and 3746 deletions
+3 -4
View File
@@ -9,9 +9,9 @@ For email questions/requests/alerts there is always the risk of memory
exhaustion on the part of the maintainer(s).
If you are unsure of what to do, or how to implement an idea or bugfix,
open an issue with `"[RFC: Unsure if this is a bug ... ?"`, or similar,
so we can discuss it. Talking about the code first is the best way to
get started before submitting a pull request.
open an issue with `"[RFC: Unsure if this is a bug ... ?"`, or use the
GitHub discussions forum, so we can discuss it. Talking about the code
first is the best way to get started before submitting a pull request.
Either way, when sending an email, patch, or pull request, start by
stating the version the change is made against, what it does, and why.
@@ -73,7 +73,6 @@ It is expected of everyone engaging in the project to, in the words of
Bill & Ted; [be excellent to each other][conduct].
[github]: https://github.com/troglobit/finit/
[KNF]: https://en.wikipedia.org/wiki/Kernel_Normal_Form
[gitbook]: https://git-scm.com/book/ch5-2.html
[conduct]: CODE-OF-CONDUCT.md
+69
View File
@@ -0,0 +1,69 @@
name: Bob the Builder
# Run on all branches, including all pull requests, except the 'dev'
# branch since that's where we run Coverity Scan (limited tokens/day)
on:
push:
branches:
- '**'
- '!dev'
pull_request:
branches:
- '**'
jobs:
build:
# Verify we can build on latest Ubuntu with both gcc and clang
name: ${{ matrix.compiler }}
runs-on: ubuntu-latest
strategy:
matrix:
compiler: [gcc, clang]
fail-fast: false
env:
CC: ${{ matrix.compiler }}
steps:
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config tree jq libuev-dev libite-dev
- uses: actions/checkout@v4
- name: Static Finit
run: |
./autogen.sh
./configure --prefix= --enable-static
make -j3 V=1
- name: Regular Finit
run: |
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var \
--enable-x11-common-plugin --enable-testserv-plugin --with-watchdog \
--with-keventd
make -j3 clean
make -j3 V=1
- name: Install to /tmp
run: |
DESTDIR=/tmp make install-strip
tree /tmp || true
- name: Check dependencies
run: |
ldd /tmp/sbin/finit
size /tmp/sbin/finit
ldd /tmp/sbin/initctl
size /tmp/sbin/initctl
ldd /tmp/sbin/reboot
size /tmp/sbin/reboot
- name: Verify starting and showing usage text
run: |
sudo /tmp/sbin/finit -h
sudo /tmp/sbin/initctl -h
- name: Enable unprivileged userns (unshare)
run: |
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
- name: Run Unit Tests
run: |
make check || (cat test/test-suite.log; false)
- name: Upload Test Results
uses: actions/upload-artifact@v4
with:
name: finit-test-${{ matrix.compiler }}
path: test/*.log
+87
View File
@@ -0,0 +1,87 @@
name: Coverity Scan
on:
push:
branches:
- 'dev'
env:
PROJECT_NAME: finit
CONTACT_EMAIL: troglobit@gmail.com
COVERITY_NAME: troglobit-finit
COVERITY_PROJ: troglobit%2Ffinit
jobs:
coverity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fetch latest Coverity Scan MD5
id: var
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
wget -q https://scan.coverity.com/download/cxx/linux64 \
--post-data "token=$TOKEN&project=${COVERITY_PROJ}&md5=1" \
-O coverity-latest.tar.gz.md5
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
- uses: actions/cache@v4
id: cache
with:
path: coverity-latest.tar.gz
key: ${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
restore-keys: |
${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
${{ runner.os }}-coverity-
${{ runner.os }}-coverity
- name: Download Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
if [ ! -f coverity-latest.tar.gz ]; then
wget -q https://scan.coverity.com/download/cxx/linux64 \
--post-data "token=$TOKEN&project=${COVERITY_PROJ}" \
-O coverity-latest.tar.gz
else
echo "Latest Coverity Scan available from cache :-)"
md5sum coverity-latest.tar.gz
fi
mkdir coverity
tar xzf coverity-latest.tar.gz --strip 1 -C coverity
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config
wget https://github.com/troglobit/libuev/releases/download/v2.4.0/libuev-2.4.0.tar.xz
wget https://github.com/troglobit/libite/releases/download/v2.5.2/libite-2.5.2.tar.gz
tar xf libuev-2.4.0.tar.xz
tar xf libite-2.5.2.tar.gz
(cd libuev-2.4.0 && ./configure --prefix=/usr && make && sudo make install-strip)
(cd libite-2.5.2 && ./configure --prefix=/usr && make && sudo make install-strip)
sudo ldconfig
- name: Configure
run: |
./autogen.sh
./configure --prefix= --enable-x11-common-plugin --with-watchdog --with-keventd
- name: Build
run: |
export PATH=`pwd`/coverity/bin:$PATH
cov-build --dir cov-int make
- name: Submit results to Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
tar czvf ${PROJECT_NAME}.tgz cov-int
curl \
--form project=${COVERITY_NAME} \
--form token=$TOKEN \
--form email=${CONTACT_EMAIL} \
--form file=@${PROJECT_NAME}.tgz \
--form version=trunk \
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
https://scan.coverity.com/builds?project=${COVERITY_PROJ}
- name: Upload build.log
uses: actions/upload-artifact@v4
with:
name: coverity-build.log
path: cov-int/build-log.txt
+62
View File
@@ -0,0 +1,62 @@
name: Release General
on:
push:
tags:
- '[0-9]+.[0-9]+*'
jobs:
release:
name: Build and upload release tarball
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
env:
MAKEFLAGS: -j3
steps:
- uses: actions/checkout@v4
- name: Installing dependencies ...
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config jq libuev-dev libite-dev
- name: Setting release variables ...
id: build
run: |
ver=${GITHUB_REF#refs/tags/}
echo "ver=${ver}" >> $GITHUB_OUTPUT
if echo $ver | grep -qE '^[0-9]+\.[0-9]+(\.[0-9]+)?(-alpha|-beta|-rc)[0-9]*$'; then
echo "pre=true" >> $GITHUB_OUTPUT
else
echo "pre=false" >> $GITHUB_OUTPUT
fi
if echo $ver | grep -qE '^[0-9.]+\.[0-9.]+(\.[0-9]+)?$'; then
echo "latest=true" >> $GITHUB_OUTPUT
else
echo "latest=false" >> $GITHUB_OUTPUT
fi
- name: Creating Makefiles ...
run: |
./autogen.sh
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var \
--enable-x11-common-plugin --enable-testserv-plugin --with-watchdog \
--with-keventd
- name: Enable unprivileged userns (unshare)
run: |
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
- name: Build release ...
run: |
make release || (cat test/test-suite.log; false)
ls -lF ../
mkdir -p artifacts/
mv ../*.tar.* artifacts/
- name: Extract ChangeLog entry ...
run: |
awk '/-----*/{if (x == 1) exit; x=1;next}x' ChangeLog.md \
|head -n -1 > release.md
cat release.md
- uses: ncipollo/release-action@v1
with:
name: Finit v${{ github.ref_name }}
prerelease: ${{ steps.build.outputs.pre }}
makeLatest: ${{ steps.build.outputs.latest }}
bodyFile: "release.md"
artifacts: "artifacts/*"
+51
View File
@@ -0,0 +1,51 @@
name: Weekly Distcheck
# Verify that `make distcheck` works as intended: all tests pass, and
# any new files are distributed in the tarballs
on:
schedule:
- cron: '0 0 * * 0'
workflow_dispatch:
jobs:
schedule:
runs-on: ubuntu-latest
outputs:
run: ${{ steps.check.outputs.run }}
steps:
- uses: actions/checkout@v4
- name: Check for any commits since last week
id: schedule
run: |
commits="$(git log --format=%H --since='1 week ago')"
if [ -n "$commits" ]; then
echo "run=true" >> $GITHUB_OUTPUT
else
echo "run=false" >> $GITHUB_OUTPUT
fi
distcheck:
needs: schedule
if: ${{ needs.schedule.outputs.run == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config jq libuev-dev libite-dev
- uses: actions/checkout@v4
- name: Base run
run: |
./autogen.sh
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var
make -j9 V=1
- name: Install to /tmp
run: |
DESTDIR=/tmp make install-strip
- name: Enable unprivileged userns (unshare)
run: |
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
- name: Check dist tarball
run: |
ver=$(/tmp/sbin/initctl -V | awk '/Finit.*/ {print $2;}')
dir=finit-$ver/_build/sub
make -j1 distcheck || (cat $dir/test/test-suite.log; false)
+7
View File
@@ -14,6 +14,7 @@ GTAGS
/autom4te.cache
/aclocal.m4
/ar-lib
/backup/
/compile
/config.cache
/config.h
@@ -36,6 +37,9 @@ GTAGS
/test-driver
/test-suite.log
# Misc
/.gdb_history
# TroglOS build system
/.config
/.stamp
@@ -45,3 +49,6 @@ GTAGS
/.autoconf
/.automake
/.built
# VS Code user settings
.vscode
+7
View File
@@ -0,0 +1,7 @@
# GNU Global .conf file, see /etc/gtags/gtags.conf for details.
default:\
:tc=default@/etc/gtags/gtags.conf:\
:tc=common:
common:\
:skip=tags,TAGS,ID,y.tab.c,y.tab.h,gtags.files,cscope.files,cscope.out,cscope.po.out,cscope.in.out,,{arch}/,autom4te.cache/,*.orig,*.rej,*.bak,*~,#*#,*.swp,*.tmp,*_flymake.*,*_flymake,*.o,*.a,*.so,*.lo,*.zip,*.gz,*.bz2,*.xz,*.lzh,*.Z,*.tgz,*.min.js,*min.css,sysroot/:
-62
View File
@@ -1,62 +0,0 @@
# Travis CI integration -- https://travis-ci.org/troglobit/finit
# Defaults to GNU GCC and autotools: ./configure && make && make test
language: c
# Use docker for quicker builds, it now allows https://docs.travis-ci.com/user/apt/
sudo: false
# Test build with both GCC and Clang (LLVM)
compiler:
- gcc
- clang
# The secure: declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
env:
global:
- PKG_CONFIG_PATH=/tmp/lib/pkgconfig
- CFLAGS="-W -Wall -Wextra"
- secure: "eOiuHs02lG2Uv146K9dMqucGTWUJFEhpz1oAtwe+kPrRXsXWc20hYMO+DSpMgD05vSvNeQA6p7h7LdRFQ+/g/Obj27TsOE+RKkUvRAtdwzxnKVyii9C/nmML8cFw7rIA0VS8O9mAkVYeyDxNDupBp3e9DPCibhKPvqCvioTnyy4="
addons:
apt:
packages:
- tree
coverity_scan:
project:
name: "troglobit/finit"
description: "finit | Fast & Extensible init for Linux"
notification_email: troglobit@gmail.com
build_command_prepend: "./autogen.sh && ./configure --prefix= --disable-doc --disable-contrib --with-watchdog"
build_command: "make"
branch_pattern: dev
install:
- wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
- wget https://github.com/troglobit/libite/releases/download/v2.3.1/libite-2.3.1.tar.gz
- tar xf libuev-2.3.2.tar.xz
- tar xf libite-2.3.1.tar.gz
- (cd libuev-2.3.2 && ./configure --prefix=/tmp && make && make install-strip)
- (cd libite-2.3.1 && ./configure --prefix=/tmp && make && make install-strip)
# Custom build script for the time being, no "make test" yet
script:
- ./autogen.sh
- ./configure --prefix= --enable-static
- make clean
- make V=1 -j5
- ./configure --prefix= --enable-x11-common-plugin --with-watchdog
- cat config.log
- make clean
- make V=1 -j5
- make install-strip DESTDIR=/tmp/finit
- tree /tmp/finit
- ldd /tmp/finit/sbin/finit
- size /tmp/finit/sbin/finit
- size /tmp/finit/sbin/initctl
- size /tmp/finit/sbin/reboot
- LD_LIBRARY_PATH=/tmp/lib /tmp/finit/sbin/initctl -h
- unshare -V
- nsenter -V
- chroot --version
- 'LD_LIBRARY_PATH=/tmp/lib make distcheck || (cat finit-4.0-beta1/_build/sub/test/test-suite.log; exit 1)'
+925 -29
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,5 +1,5 @@
Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
Copyright (c) 2008-2024 Joachim Wiberg <troglobit@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+10 -1
View File
@@ -1,5 +1,5 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = plugins src test
SUBDIRS = man plugins src system test tmpfiles.d
doc_DATA = README.md LICENSE contrib/finit.conf
EXTRA_DIST = README.md LICENSE ChangeLog.md contrib/finit.conf
@@ -10,6 +10,10 @@ if DOC
SUBDIRS += doc
endif
if BASH
bashdir = $(BASH_DIR)
dist_bash_DATA = initctl
endif
# Compat hook
install-dev:
@make -C src install-pkgincludeHEADERS
@@ -29,3 +33,8 @@ release: distcheck
printf "$$file.md5\t"; cat ../$$file.md5 | cut -f1 -d' '; \
printf "$$file.sha256\t"; cat ../$$file.sha256 | cut -f1 -d' '; \
done
DISTCHECK_CONFIGURE_FLAGS = --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
--enable-testserv-plugin --enable-x11-common-plugin \
--with-watchdog --with-keventd --with-fstab=/etc/fstab \
--with-bash-completion-dir=no
+178 -67
View File
@@ -1,9 +1,8 @@
[![License Badge][]][License] [![Travis Status]][Travis] [![Coverity Status]][Coverity Scan]
[![License Badge][]][License] [![GitHub Status][]][GitHub] [![Coverity Status][]][Coverity Scan]
<img align="right" src="img/finit3.png" alt="Finit: Fast Init">
* [Introduction](#introduction)
* [Features](#features)
* [Bootstrap](doc/bootstrap.md#bootstrap)
* [Runlevels](#runlevels)
* [Syntax](doc/config.md#syntax)
* [Runparts & /etc/rc.local](#runparts--etcrclocal)
@@ -22,36 +21,52 @@
Introduction
------------
Finit is a simple alternative to [SysV init][4] and [systemd][6]. It
was reverse engineered from the [EeePC fastinit][] over ten years ago
by [Claudio Matsuoka][] — "gaps filled with frog DNA …"
Fast init for Linux systems. Reverse engineered from the [EeePC
fastinit][] by [Claudio Matsuoka][] — "gaps filled with frog DNA …"
![Alpine screenshot](img/finit4-screenshot.png)
*Figure 1: Screenshot showing Finit booting [Alpine Linux](https://www.alpinelinux.org/).*
![Alpine screenshot](img/alpine-screenshot2.png)
*Figure 1: Screenshot of Finit booting [Alpine Linux (HowTo)](https://github.com/troglobit/finit/tree/master/contrib/alpine).*
Features include:
* Runlevels
* One-shot tasks, daemons, or SysV init scripts
* Runparts and rc.local
* Process supervision
* Runlevels, defined per service
* One-shot tasks, services (daemons), or [SysV init][4] start/stop scripts
* Runparts and `/etc/rc.local` support
* Process supervision similar to [systemd][]
* Sourcing environment files
* Conditions for network/process/custom dependencies
* Readiness notification; PID files (native) for synchronizing system
startup, support for systemd [sd_notify()][], or [s6 style][] too
* Limited support for [tmpfiles.d(5)][] (no aging, attributes, or subvolumes)
* Pre/Post script actions
* Rudimentary [templating support](doc/config.md#templating)
* Tooling to enable/disable services
* Built-in getty
* Built-in watchdog, with support for hand-over to [watchdogd](https://troglobit.com/watchdogd.html)
* Built-in support for Debian/BusyBox `/etc/network/interfaces`
* Cgroups v2, both configuration and monitoring in `initctl top`
* Plugin support for customization
* Proper rescue mode with bundled `sulogin` for protected maintenance shell
* Integration with [watchdogd][] for full system supervision
* Logging to kernel ring buffer before `syslogd` has started, see the
recommended [sysklogd][] project for complete logging integration
and how to log to the kernel ring buffer from scripts using `logger`
Focus is on small and embedded systems, although Finit is fully usable
on server and desktop systems as well. For working examples, see the
[contrib/](contrib/) section with tutorials for:
[contrib/](contrib/) section with tutorials for the following Linux
distributions:
* [Void Linux](contrib/void/),
* [Alpine Linux](contrib/alpine/), and
* [Debian GNU/Linux](contrib/debian/)
* [Debian GNU/Linux](contrib/debian/), also works on Ubuntu/Linux Mint
> **Note:** support for various Linux distributions does not mean Finit
> installs easily on all architectures. The bundled install scripts are
> examples for standard installations, tested on amd64 (x86_64) systems.
> Custom setups, e.g., for embedded systems, can be found in any of the
> following [Buildroot][] based examples: [myLinux][], [Infix][], or the
> plain [br2-finit-demo](https://github.com/troglobit/br2-finit-demo).
Example
@@ -60,14 +75,25 @@ Example
This example `/etc/finit.conf` can also be split up in multiple `.conf`
files in `/etc/finit.d`. Available, but not yet enabled, services can
be placed in `/etc/finit.d/available` and enabled by an operator using
the [initctl](#commands--status) tool.
the [initctl](#commands--status) tool. See the above mentioned Linux
distributions, or [myLinux][].
> **Note:** as of Finit v4.4, .conf lines can be broken up using the
> standard UNIX continuation character (`\`), also trailing comments are
> now supported. The latter means you need to escape any hashes used in
> directives and descriptions (`\#`). For more on this and examples,
> see the [finit.conf(5)][] manual or [doc/config.md](doc/config.md).
```ApacheConf
# Fallback if /etc/hostname is missing
host default
# Runlevel to start after bootstrap, 'S', default: 2
runlevel 2
#runlevel 2
# Support for setting global environment variables, using foo=bar syntax
# be careful though with variables like PATH, SHELL, LOGNAME, etc.
#PATH=/usr/bin:/bin:/usr/sbin:/sbin
# Max file size for each log file: 100 kiB, rotate max 4 copies:
# log => log.1 => log.2.gz => log.3.gz => log.4.gz
@@ -96,6 +122,11 @@ service :8080 [2345] merecat -n -p 8080 /var/www -- Old web server
#sysv [S] /etc/init.d/acpid -- Starting ACPI Daemon
#task [S] /etc/init.d/kbd -- Preparing console
# Hidden from boot progress, using empty `--` description
#sysv [S] /etc/init.d/keyboard-setup --
#sysv [S] /etc/init.d/acpid --
#task [S] /etc/init.d/kbd --
# Run start scripts from this directory
# runparts /etc/start.d
@@ -118,10 +149,10 @@ some of the most common components needed to start a UNIX daemon:
```
service [LVLS] <COND> log env:[-]/etc/default/daemon daemon ARGS -- Daemon daemon
^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | `-- Optional description
| | | | | | `----------- Daemon arguments
| | | | | `-------------------------- Path to daemon
^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | `---------- Optional description
| | | | | | `------------------ Daemon arguments
| | | | | `------------------------- Path to daemon
| | | | `---------------------------------------------------- Optional env. file
| | | `-------------------------------------------------------- Redirect output to log
| | `--------------------------------------------------------------- Optional conditions
@@ -133,13 +164,13 @@ Some components are optional: runlevel(s), condition(s) and description,
making it easy to create simple start scripts and still possible for more
advanced uses as well:
service sshd -D
service /usr/sbin/sshd -D
Dependencies are handled using [conditions](doc/conditions.md). One of
the most common conditions is to wait for basic networking to become
available:
service <net/route/default> nginx -- High performace HTTP server
service <net/route/default> nginx -- High performance HTTP server
Here is another example where we instruct Finit to not start BusyBox
`ntpd` until `syslogd` has started properly. Finit waits for `syslogd`
@@ -214,13 +245,50 @@ networking here. The configured `runlevel NUM` from `/etc/finit.conf`
is what Finit changes to after bootstrap, unless 'single' (or 'S') is
given on the kernel cmdline, in which case runlevel 1 is started.
All services in runlevel S(0) are started first, followed by the desired
All services in runlevel S) are started first, followed by the desired
run-time runlevel. Run tasks in runlevel S can be started in sequence
by using `run [S] cmd`. Changing runlevels at runtime is done like any
other init, e.g. <kbd>init 4</kbd>, but also using the more advanced
`intictl` tool.
**Conditions**
As mentioned previously, Finit has an advanced dependency system to
handle synchronization, called [conditions](doc/conditions.md). It can
be used in many ways; depend on another service, network availability,
etc.
One *really cool* example useful for embedded systems is to run certain
scripts if a board has a certain feature encoded in its device tree. At
bootstrap we run the following `ident` script:
```sh
#!/bin/sh
conddir=/var/run/finit/cond/hw/model
dtmodel=/sys/firmware/devicetree/base/model
if ! test -e $dtmodel; then
exit 0
fi
model=$(cat $dtmodel | tr "[A-Z] " "[a-z]-")
mkdir -p $conddir && ln -s ../../reconf $conddir/$model
```
Provided the device tree node exists, and is a string, we can then use
the condition `<hw/model/foo>` when starting other scripts. Here is an
example:
```
run [S] /path/to/ident --
task [2] <hw/model/foo> /path/to/foo-init -- Initializing Foo board
```
> Notice the trick with an empty description to hide the call to `ident`
> in the Finit progress output.
**Plugins**
Plugins can *extend* the functionality of Finit and *hook into* the
@@ -262,8 +330,8 @@ unnecessary overhead, which can be removed at build-time using:
**Cgroups**
Finit supports cgroups v2 and comes with the following default groups
in which services and user sessions are placed in:
Finit supports cgroups v2 and comes with the following default groups in
which services and user sessions are placed in:
/sys/fs/cgroup
|-- init/ # cpu.weight:100
@@ -299,6 +367,10 @@ The `initctl` tool has three commands to help debug and optimize the
setup and monitoring of cgroups. See the `ps`, `top`, and `cgroup`
commands for details.
> **Note:** systems that do not support cgroups, specifically version 2,
> are automatically detected. On such systems the above functionality
> is disabled early at boot.
Runparts & /etc/rc.local
------------------------
@@ -319,8 +391,33 @@ Right after the runlevel change when all services have started properly,
No configuration stanza in `/etc/finit.conf` is required for `rc.local`.
If it exists and is an executable shell script Finit calls it at the very
end of the boot, before calling the `HOOK_SYSTEM_UP`. See more on hooks
in [doc/plugins.md](doc/plugins.md#hooks), and about the system bootstrap
in [doc/bootstrap.md](doc/bootstrap.md).
in [doc/plugins.md](doc/plugins.md#hooks).
### Limitations
It is not possible to call Finit via signals or use `initctl` in any
runparts or `/etc/rc.local` script. This because Finit is single
threaded and is calling these scripts in a blocking fashion at the end
of runlevel S, at which point the event loop has not yet been started.
The event loop is the whole thing which Finit is built around, except
for runlevel S, which remains a slow procession through a lot of set up,
with a few hooks and blocking call outs to external scripts.
However, not all `initctl` commands are prohibited. Supported commands:
- `inictl cond`: only operate of files in `/run/finit/cond`
- `initctl enable/disable`: enabled run/task/service is activated on
the runlevel change from S to 2
- `initctl touch/show/create/delete/list`: `create`, provided the
non-interactive mode is used, again changes take effect in the
runlevel change directly after bootstrap
- `initctl -f reboot/poweroff/halt`: provided the `-f` flag is used to
force direct kernel commands
**Example:** you can set a `usr/` condition in `/etc/rc.local` and have
a service/task in runlevel 2 depend on it to execute.
Runlevels
@@ -408,24 +505,25 @@ services, called `initctl`. Unlike `telinit` the `initctl` tool does
not return until the given command has fully completed.
```
alpine:~# initctl help
Usage: initctl [OPTIONS] [COMMAND]
Options:
-b, --batch Batch mode, no screen size probing
-c, --create Create missing paths (and files) as needed
-f, --force Ignore missing files and arguments, never prompt
-h, --help This help text
-j, --json JSON output in 'status' and 'cond' commands
-1, --once Only one lap in commands like 'top'
-p, --plain Use plain table headings, no ctrl chars
-q, --quiet Silent, only return status of command
-t, --no-heading Skip table headings
-v, --verbose Verbose output
-h, --help This help text
-V, --version Show program version
Commands:
debug Toggle Finit (daemon) debug
help This help text
version Show Finit version
version Show program version
ls | list List all .conf in /etc/finit.d
create <CONF> Create .conf in /etc/finit.d/available
@@ -437,16 +535,21 @@ Commands:
disable <CONF> Disable .conf in /etc/finit.d/enabled
reload Reload *.conf in /etc/finit.d (activate changes)
cond set <COND> Set (assert) user-defined condition +usr/COND
cond clear <COND> Clear (deassert) user-defined condition -usr/COND
cond set <COND> Set (assert) user-defined conditions +usr/COND
cond get <COND> Get status of user-defined condition, see $? and -v
cond clear <COND> Clear (deassert) user-defined conditions -usr/COND
cond status Show condition status, default cond command
cond dump Dump all conditions and their status
cond dump [TYPE] Dump all, or a type of, conditions and their status
log [NAME] Show ten last Finit, or NAME, messages from syslog
start <NAME>[:ID] Start service by name, with optional ID
stop <NAME>[:ID] Stop/Pause a running service by name
reload <NAME>[:ID] Reload service by name (SIGHUP or restart)
reload <NAME>[:ID] Reload service as if .conf changed (SIGHUP or restart)
This allows restart of run/tasks that have already run
Note: Finit .conf file(s) are *not* reloaded!
restart <NAME>[:ID] Restart (stop/start) service by name
signal <NAME>[:ID] <S> Send signal S to service by name, with optional ID
ident [NAME] Show matching identities for NAME, or all
status <NAME>[:ID] Show service status, by name
status Show status of services, default command
@@ -454,14 +557,15 @@ Commands:
ps List processes based on cgroups
top Show top-like listing based on cgroups
plugins List installed plugins
runlevel [0-9] Show or set runlevel: 0 halt, 6 reboot
reboot Reboot system
halt Halt system
poweroff Halt and power off system
suspend Suspend system
Bug report address: https://github.com/troglobit/finit/issues
Project homepage: https://troglobit.com/finit.html
utmp show Raw dump of UTMP/WTMP db
```
For services *not* supporting `SIGHUP` the `<!>` notation in the .conf
@@ -480,24 +584,24 @@ scripting and documentation:
```
alpine:~# initctl -p
PID IDENT STATUS RUNLEVELS DESCRIPTION
PID IDENT STATUS RUNLEVELS DESCRIPTION
======================================================================
1506 acpid running [--2345----] ACPI daemon
1509 crond running [--2345----] Cron daemon
1489 dropbear running [--2345----] Dropbear SSH daemon
1511 klogd running [S12345----] Kernel log daemon
1512 ntpd running [--2345----] NTP daemon
1473 syslogd running [S12345----] Syslog daemon
1506 acpid running [---2345----] ACPI daemon
1509 crond running [---2345----] Cron daemon
1489 dropbear running [---2345----] Dropbear SSH daemon
1511 klogd running [S-12345----] Kernel log daemon
1512 ntpd running [---2345----] NTP daemon
1473 syslogd running [S-12345----] Syslog daemon
alpine:~# initctl -pv
PID IDENT STATUS RUNLEVELS COMMAND
PID IDENT STATUS RUNLEVELS COMMAND
======================================================================
1506 acpid running [--2345----] acpid -f
1509 crond running [--2345----] crond -f -S $CRON_OPTS
1489 dropbear running [--2345----] dropbear -R -F $DROPBEAR_OPTS
1511 klogd running [S12345----] klogd -n $KLOGD_OPTS
1512 ntpd running [--2345----] ntpd -n $NTPD_OPTS
1473 syslogd running [S12345----] syslogd -n
1506 acpid running [---2345----] acpid -f
1509 crond running [---2345----] crond -f -S $CRON_OPTS
1489 dropbear running [---2345----] dropbear -R -F $DROPBEAR_OPTS
1511 klogd running [S-12345----] klogd -n $KLOGD_OPTS
1512 ntpd running [---2345----] ntpd -n $NTPD_OPTS
1473 syslogd running [S-12345----] syslogd -n
```
The environment variables to each of the services above are read from,
@@ -522,7 +626,7 @@ Condition(s):
User : root
Group : root
Uptime : 2 hour 46 min 56 sec
Runlevels : [--2345----]
Runlevels : [---2345----]
Memory : 1.2M
CGroup : /system/dropbear cpu 0 [100, max] mem [--.--, max]
|- 1485 dropbear -R -F
@@ -573,36 +677,43 @@ This project is based on the [original finit][] by [Claudio Matsuoka][]
which was reverse engineered from syscalls of the [EeePC fastinit][] —
"gaps filled with frog DNA …"
Finit is developed and maintained by [Joachim Wiberg][] at [GitHub][].
Finit is developed and maintained by [Joachim Wiberg][] at [GitHub][6].
Please file bug reports, clone it, or send pull requests for bug fixes
and proposed extensions.
[1]: https://en.wikipedia.org/wiki/Process_supervision
[2]: http://cr.yp.to/daemontools.html
[3]: http://smarden.org/runit/
[4]: http://en.wikipedia.org/wiki/Init
[5]: http://en.wikipedia.org/wiki/Runlevel
[6]: https://www.freedesktop.org/wiki/Software/systemd/
[9]: https://github.com/troglobit/troglos
[1]: https://en.wikipedia.org/wiki/Process_supervision
[2]: https://cr.yp.to/daemontools.html
[3]: https://smarden.org/runit/
[4]: https://en.wikipedia.org/wiki/Init
[5]: https://en.wikipedia.org/wiki/Runlevel
[6]: https://github.com/troglobit/finit
[RFC862]: https://tools.ietf.org/html/rfc862
[RFC863]: https://tools.ietf.org/html/rfc863
[RFC864]: https://tools.ietf.org/html/rfc864
[RFC867]: https://tools.ietf.org/html/rfc867
[RFC868]: https://tools.ietf.org/html/rfc868
[init]: http://en.wikipedia.org/wiki/Init
[upstart]: http://upstart.ubuntu.com/
[systemd]: http://www.freedesktop.org/wiki/Software/systemd/
[openrc]: http://www.gentoo.org/proj/en/base/openrc/
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
[init]: https://en.wikipedia.org/wiki/Init
[upstart]: https://upstart.ubuntu.com/
[systemd]: https://www.freedesktop.org/wiki/Software/systemd/
[openrc]: https://www.gentoo.org/proj/en/base/openrc/
[sd_notify()]: https://www.freedesktop.org/software/systemd/man/sd_notify.html
[s6 style]: https://skarnet.org/software/s6/notifywhenup.html
[run-parts(8)]: https://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
[tmpfiles.d(5)]: https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html
[original finit]: http://helllabs.org/finit/
[EeePC fastinit]: https://web.archive.org/web/20071208212450/http://wiki.eeeuser.com/boot_process:the_boot_process
[Claudio Matsuoka]: https://github.com/cmatsuoka
[Joachim Wiberg]: http://troglobit.com
[GitHub]: https://github.com/troglobit/finit
[Joachim Wiberg]: https://troglobit.com
[Buildroot]: https://buildroot.org
[Infix]: https://kernelkit.github.io
[finit.conf(5)]: https://man.troglobit.com/man5/finit.conf.5.html
[License]: https://en.wikipedia.org/wiki/MIT_License
[License Badge]: https://img.shields.io/badge/License-MIT-teal.svg
[Travis]: https://travis-ci.org/troglobit/finit
[Travis Status]: https://travis-ci.org/troglobit/finit.svg?branch=master
[myLinux]: https://github.com/troglobit/myLinux/
[watchdogd]: https://github.com/troglobit/watchdogd/
[sysklogd]: https://github.com/troglobit/sysklogd/
[GitHub]: https://github.com/troglobit/finit/actions/workflows/build.yml/
[GitHub Status]: https://github.com/troglobit/finit/actions/workflows/build.yml/badge.svg
[Coverity Scan]: https://scan.coverity.com/projects/3545
[Coverity Status]: https://scan.coverity.com/projects/3545/badge.svg
Executable
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
# Run test suite with the correct configure params
make distclean
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var \
--enable-x11-common-plugin --with-watchdog --with-keventd
make -j17 clean check
+211 -49
View File
@@ -1,20 +1,24 @@
AC_INIT(Finit, 4.0-rc4, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
AC_INIT([Finit], [4.9], [https://github.com/troglobit/finit/issues],
[finit], [https://troglobit.com/projects/finit/])
AC_CONFIG_AUX_DIR(aux)
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR([src/finit.c])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile
contrib/Makefile
contrib/alpine/Makefile contrib/alpine/finit.d/Makefile contrib/alpine/finit.d/available/Makefile
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile contrib/debian/grub.d/Makefile
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
doc/Makefile
man/Makefile
plugins/Makefile
src/Makefile
test/test.env
test/Makefile])
system/Makefile system/10-hotplug.conf
test/test.env test/Makefile
test/lib/Makefile test/src/Makefile
tmpfiles.d/Makefile])
# Older versions of autoconf (<2.58) do not have AC_CONFIG_MACRO_DIR()
#m4_include([m4/plugin.m4])
@@ -31,9 +35,8 @@ AC_PROG_INSTALL
AC_PROG_MKDIR_P
# Configuration.
AC_HEADER_STDC
AC_CHECK_HEADERS([fstaby.h termios.h sys/ioctl.h])
AC_CHECK_FUNCS([strstr getopt getfsenty])
AC_CHECK_HEADERS([termios.h sys/ioctl.h mntent.h sys/sysmacros.h])
AC_CHECK_FUNCS([strstr getopt getmntent getmntent_r])
# Check for uint[8,16,32]_t
AC_TYPE_UINT8_T
@@ -48,25 +51,36 @@ PKG_CHECK_MODULES([uev], [libuev >= 2.2.0])
PKG_CHECK_MODULES([lite], [libite >= 2.2.0])
# Check for configured Finit features
AC_ARG_ENABLE(emergency_shell,
AS_HELP_STRING([--enable-emergency-shell], [Experimental emergency fallback at boot.
Use only for debugging very early boot problems with Finit]),,[
enable_emergency_shell=no])
AC_ARG_ENABLE(auto_reload,
AS_HELP_STRING([--enable-auto-reload], [Automatic reload on any .conf change]),,[
enable_auto_reload=no])
AC_ARG_ENABLE(kernel_cmdline,
AS_HELP_STRING([--enable-kernel-cmdline], [Parse init args from /proc/cmdline (don't use!)]),,[
enable_kernel_cmdline=no])
AC_ARG_ENABLE(fastboot,
AS_HELP_STRING([--enable-fastboot], [Skip fsck check on filesystems listed in /etc/fstab]),,[
enable_fastboot=no])
AC_ARG_ENABLE(fsckfix,
AS_HELP_STRING([--enable-fsckfix], [Run fsck fix mode (options: -yf) on filesystems listed in /etc/fstab]),,[
enable_fsckfix=no])
AC_ARG_ENABLE(cgroup,
AS_HELP_STRING([--disable-cgroup], [Disable cgroup v2 support, default: autodetect from /sys/fs/cgroup]),,[
enable_cgroup=yes])
AC_ARG_ENABLE(redirect,
AS_HELP_STRING([--disable-redirect], [Disable redirection of service output to /dev/null]),,[
enable_redirect=yes])
AC_ARG_ENABLE(logit,
AS_HELP_STRING([--disable-logit], [Disable logit, used for log redirection, default: enable]),,[
enable_logit=yes])
AC_ARG_ENABLE(kernel_logging,
AS_HELP_STRING([--disable-kernel-logging], [Disable kernel logging to console (use 'quiet' instead!]),,[
enable_kernel_logging=yes])
AC_ARG_ENABLE(logrotate,
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp, default enabled]),,[
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp]),,[
enable_logrotate=yes])
AC_ARG_ENABLE(doc,
@@ -77,19 +91,39 @@ AC_ARG_ENABLE(contrib,
AS_HELP_STRING([--disable-contrib], [Disable build and install of contrib section]),,[
enable_contrib=yes])
AC_ARG_ENABLE([rescue],
AS_HELP_STRING([--disable-rescue], [Disable potentially unsafe rescue mode]),,
[enable_rescue=yes])
# Check for extra plugins to enable
enable_all_plugins=auto
AC_ARG_ENABLE(all_plugins,
AS_HELP_STRING([--enable-all-plugins], [Enable all plugins, default: auto]),
enable_all_plugins=$enableval, enable_all_plugins=auto)
AC_PLUGIN([alsa-utils], [no], [Save and restore ALSA sound settings using alsactl])
AC_PLUGIN([dbus], [no], [Setup and start system message bus, D-Bus])
AC_PLUGIN([modules-load], [no], [Scans /etc/modules-load.d for modules to load])
AC_PLUGIN([modprobe], [no], [Coldplug modules using modalias magic])
AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
AC_PLUGIN([x11-common], [no], [Console setup (for X)])
AC_PLUGIN([netlink], [yes], [Basic netlink plugin for IFUP/IFDN and GW events. Can be replaced with externally built plugin that links with libnl or similar.])
AC_PLUGIN([hotplug], [yes], [Setup and start udev or mdev hotplug daemon])
AC_PLUGIN([hook-scripts], [no], [Trigger script execution from hook points])
AC_PLUGIN([hotplug], [yes], [Start udevd or mdev kernel event datamon])
AC_PLUGIN([rtc], [yes], [Save and restore RTC using hwclock])
AC_PLUGIN([tty], [yes], [Automatically activate new TTYs, e.g. USB-to-serial])
AC_PLUGIN([urandom], [yes], [Setup and save random seed at boot/shutdown])
AC_PLUGIN([testserv], [no], [Test plugin to start test serv daemon])
# Check for extra arguments or packages
AC_ARG_WITH([bash-completion-dir],
AS_HELP_STRING([--with-bash-completion-dir[=PATH]], [Directory to install Bash completion, default: auto]),
[bash_dir=$withval], [bash_dir=yes])
AC_ARG_WITH(fstab,
AS_HELP_STRING([--with-fstab=FILE], [System default fstab, default $sysconfdir/fstab]),
[fstab=$withval], [fstab=yes])
AC_ARG_WITH(heading,
AS_HELP_STRING([--with-heading=GREET], [Display GREET instead of Finit version at boot]),
AS_HELP_STRING([--with-heading=GREET], [Heading for boot progress. Default: PRETTY_NAME from /etc/os-release, fallback to "Finit vX.YY"]),
[heading=$withval], [heading=yes])
AC_ARG_WITH(config,
@@ -108,44 +142,94 @@ AC_ARG_WITH(sysconfig,
AS_HELP_STRING([--with-sysconfig=DIR], [System environment directory, sourced by .conf files, default /etc/default & /etc/conf.d]),
[sysconfig=$withval], [sysconfig=default])
AC_ARG_WITH(group,
AS_HELP_STRING([--with-group=NAME], [Group for /run/finit/socket (initctl), default: root]),
[group=$withval], [group=root])
AC_ARG_WITH(hostname,
AS_HELP_STRING([--with-hostname=NAME], [If /etc/hostname is missing, default: noname]),
[hostname=$withval], [hostname=yes])
AC_ARG_WITH(runlevel,
AS_HELP_STRING([--with-runlevel=N], [Runlevel to switch to after bootstrap, default: 2]),
AS_HELP_STRING([--with-runlevel=N], [Runlevel to switch to after bootstrap [1-9], default: 2]),
[runlevel=$withval], [runlevel=yes])
AC_ARG_WITH(random-seed,
AS_HELP_STRING([--with-random-seed=FILE], [Save a random seed for /dev/urandom across reboots, default /var/lib/misc/random-seed]),
[random_seed=$withval], [random_seed=yes])
AC_ARG_WITH(keventd,
AS_HELP_STRING([--with-keventd], [Enable built-in keventd, default: no]),, [with_keventd=no])
AC_ARG_WITH(sulogin,
AS_HELP_STRING([--with-sulogin@<:@=USER@:>@], [Enable built-in sulogin, optional USER to request password for (default root), default: no.]),[sulogin=$withval],[with_sulogin=no])
AC_ARG_WITH(watchdog,
AS_HELP_STRING([--with-watchdog=[DEV]], [Enable built-in watchdog, default: /dev/watchdog]),
[watchdog=$withval],[watchdog=])
AS_HELP_STRING([--with-watchdog@<:@=DEV@:>@], [Enable built-in watchdog, default: /dev/watchdog]),
[watchdog=$withval], [with_watchdog=no watchdog=])
AC_ARG_WITH(hook-scripts-path,
AS_HELP_STRING([--with-hook-scripts-path=DIR], [Base directory for hook scripts, default $libexecdir/finit/hook]),
[hook_scripts_path=$withval], [hook_scripts_path=yes])
AC_ARG_WITH(plugin-path,
AS_HELP_STRING([--with-plugin-path=DIR], [Search path for external plugins, default /usr/lib/finit/plugins:/usr/local/lib/finit/plugins]),
[plugin_path=$withval], [plugin_path=yes])
AC_ARG_WITH(rtc-date,
AS_HELP_STRING([--with-rtc-date=DATE], [If RTC date/time is too old, restore to DATE, format "YYYY-MM-DD HH:MM:SS", default "2000-01-01 00:00:00"]),
[rtc_date=$withval], [rtc_date=no])
AC_ARG_WITH(rtc-file,
AS_HELP_STRING([--with-rtc-file=FILE], [If RTC is missing, save and restore system clock from this file, default: no]),
[rtc_file=$withval], [rtc_file=no])
### Enable features ###########################################################################
# Create config.h from selected features and fallback defaults
AS_IF([test "x$enable_emergency_shell" = "xyes"], [
AC_DEFINE(EMERGENCY_SHELL, 1, [Fork off init and let PID 1 wait and start /bin/sh if init crashes.])])
AS_IF([test "x$enable_auto_reload" = "xyes"], [
AC_DEFINE(AUTO_RELOAD, 1, [Finit automatically does `initctl reload` on any .conf change])])
AS_IF([test "x$enable_kernel_cmdline" = "xyes"], [
AC_DEFINE(KERNEL_CMDLINE, 1, [Dumpster diving after init args from /proc/cmdline])])
AS_IF([test "x$enable_kernel_logging" = "xyes"], [
AC_DEFINE(KERNEL_LOGGING, 1, [Keep kernel warn/err logs to console])])
AS_IF([test "x$enable_cgroup" = "xyes"], [
AC_DEFINE(CGROUP2_ENABLED, 1, [Autodetect cgroup v2 support from /sys/fs/cgroup])])
AS_IF([test "x$enable_fastboot" = "xyes"], [
AC_DEFINE(FAST_BOOT, 1, [Skip fsck check on filesystems listed in /etc/fstab])])
AS_IF([test "x$enable_fsckfix" = "xyes"], [
AC_DEFINE(FSCK_FIX, 1, [Run fsck fix mode (options: -yf) on filesystems listed in /etc/fstab])])
AS_IF([test "x$enable_redirect" = "xyes"], [
AC_DEFINE(REDIRECT_OUTPUT, 1, [Enable redirection of service output to /dev/null])])
### Disable features ###########################################################################
AS_IF([test "x$enable_logit" != "xno"], [
AC_DEFINE(LOGIT_ENABLED, 1, [Enable logit tool, used for log redirection by Finit])])
AS_IF([test "x$enable_logrotate" != "xno"], [
AC_DEFINE(LOGROTATE_ENABLED, 1, [Enable built-in rotation of /var/log/wtmp et al.])])
AS_IF([test "x$enable_rescue" != "xno"], [
AC_DEFINE([RESCUE_MODE], 1, [Define to enable support for rescue mode.])])
AM_CONDITIONAL(LOGROTATE, [test "x$enable_logrotate" = "xyes"])
### With features ##############################################################################
AS_IF([test "x$bash_dir" = "xyes"], [
PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0],
[BASH_DIR="$(pkg-config --variable=completionsdir bash-completion)"],
[BASH_DIR="$datadir/bash-completion/completions"])], [
BASH_DIR="$bash_dir"])
AS_IF([test "x$with_fstab" != "xno"], [
AS_IF([test "x$fstab" = "xyes"], [fstab=$sysconfdir/fstab])
AC_EXPAND_DIR(fstab_path, "$fstab")
AC_DEFINE_UNQUOTED(FINIT_FSTAB, "$fstab_path", [Built-in default: /etc/fstab])],[
AC_DEFINE_UNQUOTED(FINIT_FSTAB, NULL, [No built-in default fstab])])
AS_IF([test "x$with_config" != "xno"], [
AS_IF([test "x$conf" = "xyes"], [
conf=$sysconfdir/finit.conf])])
@@ -161,10 +245,9 @@ AC_DEFINE_UNQUOTED(FINIT_RCSD, "$rcsd_path", [Finit rcS.d/, default /etc/finit.d
AC_SUBST(FINIT_RCSD, "$rcsd_path")
AS_IF([test "x$with_rc_local" != "xno"], [
AS_IF([test "x$rclocal" = "xyes"], [
rclocal=$sysconfdir/rc.local])])
AC_EXPAND_DIR(rclocal_path, "$rclocal")
AC_DEFINE_UNQUOTED(FINIT_RC_LOCAL, "$rclocal_path", [Compat SysV /etc/rc.local file to run last at boot.])
AS_IF([test "x$rclocal" = "xyes"], [rclocal=$sysconfdir/rc.local])
AC_EXPAND_DIR(rclocal_path, "$rclocal")
AC_DEFINE_UNQUOTED(FINIT_RC_LOCAL, "$rclocal_path", [Compat SysV /etc/rc.local file to run last at boot.])])
AS_IF([test "x$with_sysconfig" != "xno"], [
AS_IF([test "x$sysconfig" != "xdefault"], [
@@ -173,9 +256,13 @@ AS_IF([test "x$with_sysconfig" != "xno"], [
[System environment, default /etc/default & /etc/conf.d])])])
AS_IF([test "x$with_heading" != "xno"], [
AS_IF([test "x$heading" = "xyes"], [
heading="$PACKAGE_NAME v$PACKAGE_VERSION"])])
AC_DEFINE_UNQUOTED(INIT_HEADING, "$heading", [Displayed by Finit at boot])
AS_IF([test "x$heading" = "xyes"], [heading=""])
AC_DEFINE_UNQUOTED(INIT_OSHEADING, "$heading", [Displayed by Finit at boot, defaults to /etc/os-release PRETTY_NAME])])
AS_IF([test "x$with_group" != "xno"], [
AS_IF([test "x$group" = "xyes"], [
group=root])])
AC_DEFINE_UNQUOTED(DEFGROUP, "$group", [For /run/finit/socket])
AS_IF([test "x$with_hostname" != "xno"], [
AS_IF([test "x$hostname" = "xyes"], [
@@ -194,34 +281,97 @@ AS_IF([test "x$with_random_seed" != "xno"], [
AC_EXPAND_DIR(random_path, "$random_seed")
AC_DEFINE_UNQUOTED(RANDOMSEED, "$random_path", [Improve random at boot by seeding it with sth from before.])])
AS_IF([test "x$rtc_date" != "xno"], [
AC_DEFINE_UNQUOTED(RTC_TIMESTAMP_CUSTOM, "$rtc_date", [Custom RTC restore date, default: 2000-01-01 00:00])], [
rtc_date=""])
AS_IF([test "x$rtc_file" != "xno"], [
AS_IF([test "x$rtc_file" = "xyes"], [
rtc_file=/var/lib/misc/rtc])
AC_EXPAND_DIR(rtcfile_path, "$rtc_file")
AC_DEFINE_UNQUOTED(RTC_FILE, "$rtcfile_path", [Save and restore system time from this file if /dev/rtc is missing.])],[
AC_DEFINE_UNQUOTED(RTC_FILE, NULL)])
AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes])
AS_IF([test "x$with_sulogin" != "xno"], [
AS_IF([test "x$sulogin" = "xyes"], [
sulogin=root])
with_sulogin=yes
AC_DEFINE_UNQUOTED(SULOGIN_USER, "$sulogin", [Built-in sulogin user, default: root])], [
sulogin=])
AS_IF([test "x$with_watchdog" != "xno"], [
AS_IF([test "x$watchdog" = "xyes"], [
watchdog=/dev/watchdog])
with_watchdog=yes
AC_DEFINE_UNQUOTED(WDT_DEVNODE, "$watchdog", [Built-in watchdog device node])])
AC_DEFINE_UNQUOTED(WDT_DEVNODE, "$watchdog", [Built-in watchdog device node])], [
watchdog=])
AS_IF([test "x$enable_hook_scripts_plugin" != "xno"], [
AS_IF([test "x$hook_scripts_path" = "xyes"], [hook_scripts_path=$libexecdir/finit/hook])
AC_EXPAND_DIR(hook_scripts_path, "$hook_scripts_path")
AC_DEFINE_UNQUOTED(PLUGIN_HOOK_SCRIPTS_PATH, "$hook_scripts_path", [Built-in default: $libexecdir/finit])])
AS_IF([test "x$with_plugin_path" != "xno"], [
AS_IF([test "x$plugin_path" = "xyes"], [plugin_path=/usr/lib/finit/plugins:/usr/local/lib/finit/plugins])
AC_EXPAND_DIR(plugin_path, "$plugin_path")
AC_DEFINE_UNQUOTED(EXTERNAL_PLUGIN_PATH, "$plugin_path", [Built-in default: /usr/lib/finit/plugins:/usr/local/lib/finit/plugins])])
# Control build with automake flags
AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"])
AM_CONDITIONAL(BASH, [test "x$bash_dir" != "xno"])
AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"])
AM_CONDITIONAL(KEVENTD, [test "x$with_keventd" != "xno"])
AM_CONDITIONAL(SULOGIN, [test "x$with_sulogin" != "xno"])
AM_CONDITIONAL(WATCHDOGD, [test "x$with_watchdog" != "xno"])
AM_CONDITIONAL(LOGIT, [test "x$enable_logit" = "xyes"])
AM_CONDITIONAL(DOC, [test "x$enable_doc" = "xyes"])
AM_CONDITIONAL(DOC, [test "x$enable_doc" = "xyes"])
AM_CONDITIONAL(CONTRIB, [test "x$enable_contrib" = "xyes"])
AM_CONDITIONAL(TESTSERV, [test "x$enable_testserv_plugin" = "xyes"])
# Workaround for as-of-yet unreleased runstatedir support, planned for
# autoconf 2.70, which some major distros have backported.
AS_IF([test -z "$runstatedir"], runstatedir="$localstatedir/run")
AC_SUBST(runstatedir)
# Override default libdir, used for plugins and rescue.conf
pkglibdir=$libdir/finit
AC_SUBST(pkglibexecdir)
AC_EXPAND_DIR(pkglibexecdir, "$libexecdir/finit")
AC_DEFINE_UNQUOTED(FINIT_LIBPATH_, "$pkglibexecdir", [Finit libexec path])
AC_DEFINE_UNQUOTED(FINIT_EXECPATH_, "$pkglibexecdir", [Finit libexec path])
AC_EXPAND_DIR(finit_runpath, "$runstatedir/finit/system")
AC_DEFINE_UNQUOTED(FINIT_RUNPATH_, "$finit_runpath", [Finit runtime dynamic system services])
AC_EXPAND_DIR(plugin_path, "$libdir/finit/plugins")
AC_EXPAND_DIR(plugin_path, "$pkglibdir/plugins")
AC_SUBST(plugin_path)
AC_DEFINE_UNQUOTED(PLUGIN_PATH, "$plugin_path", [Finit plugin path])
AC_EXPAND_DIR(rescue_conf, "$libdir/finit/rescue.conf")
AC_EXPAND_DIR(tmpfiles_path, "$libdir/tmpfiles.d")
AC_SUBST(tmpfiles_path)
AC_DEFINE_UNQUOTED(TMPFILES_PATH_, "$tmpfiles_path", [Main tmpfiles.d/, override in /etc])
AC_EXPAND_DIR(finit_tmpfiles, "$pkglibdir/tmpfiles.d")
AC_SUBST(finit_tmpfiles)
AC_DEFINE_UNQUOTED(FINIT_TMPFILES, "$finit_tmpfiles", [Finit tmpfiles.d/ .conf path])
AC_EXPAND_DIR(system_path, "$pkglibdir/system")
AC_SUBST(system_path)
AC_DEFINE_UNQUOTED(FINIT_SYSPATH_, "$system_path", [Static services, previously generated at runtime by plugins])
AC_EXPAND_DIR(rescue_conf, "$pkglibdir/rescue.conf")
AC_DEFINE_UNQUOTED(RESCUE_CONF, "$rescue_conf", [Finit rescue mode .conf])
AC_EXPAND_DIR(sample_conf, "$libdir/finit/sample.conf")
AC_EXPAND_DIR(sample_conf, "$pkglibdir/sample.conf")
AC_DEFINE_UNQUOTED(SAMPLE_CONF, "$sample_conf", [Finit sameple.conf for initctl create])
AC_EXPAND_DIR(bash_completion_dir, "$BASH_DIR")
AC_SUBST(BASH_DIR, "$bash_completion_dir")
AS_IF([test "$heading" = ""], [heading="<DEFAULT>"])
AS_IF([test "$heading" = "no"], [heading="<NONE>"])
RTC_DATE=$rtc_date
AS_IF([test "$rtc_date" = ""], [RTC_DATE="<DEFAULT>"])
AS_IF([test "$rtc_date" = "no"], [RTC_DATE="<DEFAULT>"])
# Generate all files
AC_OUTPUT
@@ -229,14 +379,16 @@ cat <<EOF
------------------ Summary ------------------
$PACKAGE_NAME version $PACKAGE_VERSION
Prefix................: $prefix
Exec prefix...........: $eprefix
Prefix................: $(eval echo $prefix)
Exec prefix...........: $(eval echo $exec_prefix)
Libdir................: $(eval echo $libdir)
Sysconfdir............: `eval echo $sysconfdir`
Localstatedir.........: `eval echo $localstatedir`
Default fstab.........: `eval echo $fstab`
Finit config file.....: $conf_path
Finit config.d path...: $rcsd_path
Finit plugin path.....: $plugin_path
Compat rc.local path..: $rclocal_path
Compat rc.local path..: `eval echo $rclocal`
System environment....: ${sysconfig_path:-${sysconfig}}
Random seed path......: $random_path
C Compiler............: $CC $CFLAGS $CPPFLAGS $LDFLAGS $LIBS
@@ -245,16 +397,26 @@ cat <<EOF
Behavior:
Boot heading..........: $heading
Plugins...............: $plugins
RTC restore date......: $RTC_DATE
RTC fallback file.....: $rtc_file
Optional features:
Install doc/..........: $enable_doc
Install contrib/......: $enable_contrib
Bash completion.......: $bash_completion_dir
Built-in keventd......: $with_keventd
Built-in sulogin......: $with_sulogin $sulogin
Built-in watchdogd....: $with_watchdog $watchdog
Built-in logrotate....: $enable_logrotate
Scripting tool logit..: $enable_logit
Emergency shell.......: $enable_emergency_shell
Use cgroup v2.........: $enable_cgroup
Parse kernel cmdline..: $enable_kernel_cmdline
Keep kernel logging...: $enable_kernel_logging
Skip fsck check.......: $enable_fastboot
Run fsck fix mode.....: $enable_fsckfix
Redirect output.......: $enable_redirect
Rescue mode...........: $enable_rescue
Default hostname......: $hostname
Default group.........: $group
Default runlevel......: $runlevel
------------- Compiler version --------------
+1 -1
View File
@@ -1,5 +1,5 @@
SUBDIRS = finit.d
docsdir := @docdir@/contrib/alpine
docs_DATA = README.md finit.conf alpine-release build.sh install.sh rc.local
docs_DATA = README.md finit.conf build.sh install.sh rc.local
EXTRA_DIST = $(docs_DATA)
+4 -2
View File
@@ -1,5 +1,7 @@
HowTo: Finit on Alpine Linux 3.4-3.6
====================================
HowTo: Finit on Alpine Linux 3.4...3.19
=======================================
> **Blog** https://troglobit.com/post/2021-02-12-alpine-linux-with-finit/
HowTo use Finit to boot an [Alpine Linux][] system. It is assumed that
the user has already installed make, a compiler, C library header files,
-1
View File
@@ -1 +0,0 @@
3.6.2
+2 -3
View File
@@ -17,8 +17,8 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
--prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--enable-dbus-plugin --enable-x11-common-plugin \
--enable-alsa-utils-plugin --with-watchdog \
--with-heading="Alpine Linux 3.13"
--enable-alsa-utils-plugin --without-watchdog \
--with-keventd --with-sulogin
echo
echo "*** Building ..."
@@ -35,4 +35,3 @@ fi
echo
echo "*** Done"
echo
+17 -1
View File
@@ -5,6 +5,22 @@
# Default is 2
#runlevel 2
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
#cgroup init cpu.weight:100
#cgroup user cpu.weight:100
#cgroup system cpu.weight:9700
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
#task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
#task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
## Bootstrap services and tasks
# Can be listed here or in /etc/finit.d/*.conf
+1 -2
View File
@@ -1,8 +1,7 @@
SUBDIRS = available
docsdir := @docdir@/contrib/alpine/finit.d
d_LINKS = acpid.conf crond.conf dropbear.conf getty.conf \
keymap.conf modules.conf ntpd.conf \
klogd.conf syslogd.conf
keymap.conf modules.conf ntpd.conf syslogd.conf
install-exec-hook:
@$(MKDIR_P) $(DESTDIR)$(docsdir)/available
+1 -1
View File
@@ -1,4 +1,4 @@
docsdir := @docdir@/contrib/alpine/finit.d/available
docs_DATA = acpid.conf crond.conf dropbear.conf getty.conf keymap.conf \
lxdm.conf modules.conf ntpd.conf syslog.conf watchdog.conf
lxdm.conf modules.conf ntpd.conf syslogd.conf watchdog.conf
EXTRA_DIST = $(docs_DATA)
@@ -4,4 +4,4 @@
#module evdev
#module mousedev
#module 8139cp
module softdog
#module softdog
+35 -28
View File
@@ -1,44 +1,53 @@
#!/bin/sh
if [ "x`id -u`" != "x0" ]; then
echo
echo "*** This script must run as root"
echo
if [ "$(id -u)" != "0" ]; then
printf "\n\e[1m*** This script must run as root\e[0m\n\n"
exit 1
fi
# shellcheck disable=SC3037,SC3045,SC2154
yorn()
{
printf "\e[1m> %s (y/N)?\e[0m " "$*"
read -rn1 yorn
echo
if [ "$yorn" = "y" ] || [ "$yorn" = "Y" ]; then
return 0
fi
return 1
}
# Adjust base directory
if [ -e alpine-release ]; then
if grep -q contrib/alpine Makefile 2>/dev/null; then
cd ../..
elif [ ! -e autogen.sh ]; then
echo "*** Please run this script from the Finit base directory."
fi
if [ ! -e configure.ac ]; then
printf "\n\e[1m*** Please run this script from the Finit base directory.\e[0m\n"
exit 1
fi
echo
echo "*** Install Finit on Alpine Linux"
echo "========================================================================"
echo "/sbin/finit - PID 1"
echo "/lib/finit/plugins/* - All enabled Finit plugins"
echo "/etc/finit.conf - Finit configuration file"
echo "/etc/finit.d/ - Finit services"
echo
read -p "Do you want to continue (y/N)? " yorn
printf "\n\e[1mInstall Finit on Alpine Linux\n"
printf "========================================================================\e[0m\n"
printf "/sbin/finit - PID 1\n"
printf "/lib/finit/plugins/* - All enabled Finit plugins\n"
printf "/etc/finit.conf - Finit configuration file\n"
printf "/etc/finit.d/ - Finit services\n"
if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
echo
echo "*** Installing Finit files ..."
if yorn "Do you want to continue"; then
printf "\n\e[1m*** Installing Finit files ...\e[0m\n"
make install
cd /usr/share/doc/finit/contrib/alpine
cd /usr/share/doc/finit/contrib/alpine || exit 1
for file in finit.conf rc.local; do
install -vbD $file /etc/$file
done
cp -va finit.d /etc/
read -p "*** Install Finit as the system default Init (y/N)? " yorn
if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
echo "*** Updating /sbin/init symlink --> finit ..."
cd /sbin
if yorn "Install Finit as the system default Init"; then
printf "\e[1m*** Updating /sbin/init symlink --> finit ...\e[0m\n"
cd /sbin || exit 1
rm init
ln -s finit init
@@ -47,10 +56,8 @@ if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
ln -s reboot shutdown
ln -s reboot suspend
fi
echo "*** Done"
printf "\n\e[1m*** Done\e[0m\n"
echo
else
echo
echo "*** Aborting install."
echo
printf "\n\e[1m*** Aborting install.\e[0m\n\n"
fi
+1 -1
View File
@@ -4,5 +4,5 @@
#
# Each line is run in sequence.
#
# NOTE: Remeber to set the executable bit!
# NOTE: Remember to set the executable bit!
#
+2 -2
View File
@@ -1,4 +1,4 @@
SUBDIRS = finit.d grub.d
SUBDIRS = finit.d
docsdir := @docdir@/contrib/debian
docs_DATA = README.md finit.conf os-release build.sh install.sh
docs_DATA = README.md finit.conf build.sh install.sh
EXTRA_DIST = $(docs_DATA)
+20 -7
View File
@@ -20,29 +20,42 @@ tools pre-systemd work as intended.
root@debian:~# apt install initscripts console-setup
> **Note:** as of Debian 11 (Bullseye), libuev and libite are part of
> the main section of Debian. So just install the -dev packages :)
The following script can then be used to configure, build, install and
set up your system to run Finit:
user@debian:~/finit$ contrib/debian/build.sh
However, since `/sbin/init` already exists on your system, the script
creates another entry in your GRUB config, in `/etc/grub.d/40_custom`,
where `init=/sbin/finit` is added to your kernel line. It is of course
also possible to change the default init to Finit, if you do you can
remove the custom Grub entry:
creates another entry in your GRUB config by updating `$SUPPORTED_INITS`
in `/etc/grub.d/10_inux` and run `update-grub`. On reboot you will find
a (finit) entry in the "Advanced options for Debian GNU/Linux" section.
It is of course also possible to change the default init to Finit:
user@debian:~/finit# cd /sbin
user@debian:/sbin# sudo rm init
user@debian:/sbin# sudo mv init oldinit
user@debian:/sbin# sudo ln -s finit init
Before rebooting, check the default [/etc/finit.conf](finit.conf) and
`/etc/finit.d/*.conf` files. The build + install script above provides
a few sample `.conf` files. See `initctl list` after boot for a list of
enabled and available services.
a few sample `.conf` files. See `initctl ls` after boot for a list of
enabled and available services, you can then use `enable` and `disable`
comands to `initctl`, followed by `reload` to activate your changes.
You can also use a standard [/etc/rc.local](rc.local) for one-shot tasks
and initialization like keyboard language etc.
> **NOTE:** X Window system, you may need to `sudo apt install elogind`
> (Bullseye and later), followed by `initctl reload` to activate it (it
> is enabled by default), and logout/login again. The elogind daemon
> ensures a regular non-root user can start and interact with an X
> session, otherwise keyboard and mouse won't work. When you're happy,
> you can enable the lightdm.conf, change the default runlevel to 3, and
> presto! you have a desktop again.
Have fun!
/Joachim ツ
+2 -6
View File
@@ -25,9 +25,8 @@ echo
--prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--enable-dbus-plugin --enable-x11-common-plugin \
--enable-alsa-utils-plugin \
--with-random-seed=/var/lib/urandom/random-seed \
--with-heading="Debian GNU/Linux"
--enable-alsa-utils-plugin --with-keventd \
--with-random-seed=/var/lib/urandom/random-seed
if [ $? -ne 0 ]; then
echo
@@ -60,6 +59,3 @@ else
echo "*** Use 'sudo contrib/debian/install.sh' later to install Finit"
echo
fi
+17 -1
View File
@@ -5,6 +5,22 @@
# Default is 2
#runlevel 2
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
#cgroup init cpu.weight:100
#cgroup user cpu.weight:100
#cgroup system cpu.weight:9700
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
#task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
#task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
## Bootstrap services and tasks
# Can be listed here or in /etc/finit.d/*.conf
+4 -2
View File
@@ -1,7 +1,9 @@
SUBDIRS = available
docsdir := @docdir@/contrib/debian/finit.d
d_LINKS = console-setup.conf getty.conf keyboard-setup.conf \
modules.conf rsyslogd.conf sshd.conf
d_LINKS = acpid.conf apparmor.conf avahi-daemon.conf \
bluetooth.conf console-setup.conf elogind.conf \
getty.conf keyboard-setup.conf modules.conf \
plymouth-quit.conf rsyslogd.conf sshd.conf
install-exec-hook:
@$(MKDIR_P) $(DESTDIR)$(docsdir)/available
+6 -3
View File
@@ -1,5 +1,8 @@
docsdir := @docdir@/contrib/debian/finit.d/available
docs_DATA = acpid.conf console-setup.conf getty.conf keyboard-setup.conf \
lightdm.conf modules.conf rsyslogd.conf sntpd.conf \
sshd.conf syslogd.conf xdm.conf
docs_DATA = acpid.conf apparmor.conf avahi-daemon.conf bluetooth.conf \
console-setup.conf elogind.conf getty.conf \
keyboard-setup.conf lightdm.conf modules.conf sntpd.conf \
plymouth-quit.conf rsyslogd.conf sshd.conf syslogd.conf \
xdm.conf
EXTRA_DIST = $(docs_DATA)
@@ -0,0 +1 @@
task [2345] <sys/pwr/ac,pid/syslogd> halt:usr1 env:-/etc/default/anacron anacron -d -q $ANACRON_ARGS -- Anacron jobs
@@ -0,0 +1,2 @@
sysv [S] /etc/init.d/apparmor -- AppArmor initialization
@@ -0,0 +1 @@
service [2345] env:-/etc/default/avahi-daemon avahi-daemon -s $AVAHI_DAEMON_OPTS -- Avahi mDNS/DNS-SD Stack
@@ -0,0 +1,3 @@
# To ignore errors like "org.freedesktop.hostname1", update the env file with
# "--noplugin=hostname", i.e. append to BLUETOOTHD_OPTS
service [2345] log:null env:-/etc/default/bluetooth /usr/libexec/bluetooth/bluetoothd -n $BLUETOOTHD_OPTS -- Bluetooth service
@@ -0,0 +1 @@
service [2345] <sys/pwr/ac,pid/syslogd> env:-/etc/default/cron cron -f $EXTRA_OPTS -- Background job processing daemon
@@ -0,0 +1,4 @@
# On some systems, bootstrap can be really quick and cause elogind
# to not start before a user has managed to log in. To prevent
# this, add <pid/elogind> as condition to your TTYs in getty.conf
service [2345] <pid/syslogd> /lib/elogind/elogind -- Login manager
+5 -2
View File
@@ -1,4 +1,7 @@
# Consoles to start getty on when system is up
tty [12345] /dev/tty1 linux noclear nowait
tty [2345] /dev/tty2 linux noclear nowait
tty [2345] /dev/tty3 linux noclear nowait
tty [2345] /dev/tty2 linux nowait
tty [2345] /dev/tty3 linux nowait
tty [2345] /dev/tty4 linux nowait
tty [2345] /dev/tty5 linux nowait
tty [2345] /dev/tty6 linux nowait
@@ -0,0 +1,2 @@
# Need to stop plymouth, or it'll block stdin on tty1
task [S] /usr/bin/plymouth quit -- Stopping Plymouth Boot Screen
-14
View File
@@ -1,14 +0,0 @@
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry '$MENU with Finit' --class $TYPE --class gnu-linux --class gnu --class os --user {
insmod gzio
insmod part_msdos
insmod ext2
search --no-floppy --fs-uuid --set=root $BOOT
linux /vmlinuz root=UUID=$ROOT ro quiet init=/sbin/finit
initrd /initrd.img
}
-3
View File
@@ -1,3 +0,0 @@
docsdir := @docdir@/contrib/debian/grub.d
docs_DATA = 40_custom
EXTRA_DIST = $(docs_DATA)
+15 -9
View File
@@ -8,10 +8,10 @@ if [ "x`id -u`" != "x0" ]; then
fi
# Adjust base directory
grep -q Debian os-release 2>/dev/null
grep -q debian Makefile 2>/dev/null
if [ $? -eq 0 ]; then
cd ../..
elif [ ! -e autogen.sh ]; then
elif [ ! -e configure.ac ]; then
echo "*** Please run this script from the Finit base directory."
exit 1
fi
@@ -23,7 +23,7 @@ echo "/sbin/finit - PID 1"
echo "/lib/finit/plugins/* - All enabled Finit plugins"
echo "/etc/finit.conf - Finit configuration file"
echo "/etc/finit.d/ - Finit services"
echo "/etc/grub.d/40_custom - Add menu entry to the Grub boot loader"
echo "/etc/grub.d/10_linux - Add Finit to Grub's SUPPORTED_INITS"
echo
read -p "Do you want to continue (y/N)? " yorn
echo
@@ -38,12 +38,18 @@ if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
cp -va finit.d /etc/
echo "*** Setting up a GRUB boot entry ..."
MENU=`grep gnu-linux /boot/grub/grub.cfg |head -1 |sed "s/menuentry '\([^']*\).*/\1/"`
TYPE=`grep gnu-linux /boot/grub/grub.cfg |head -1 |sed "s/.*' --class \([a-z]*\).*/\1/"`
BOOT=`grep set=root /boot/grub/grub.cfg |head -1 |sed 's/.* \([a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*\).*/\1/'`
ROOT=`grep root=UUID /boot/grub/grub.cfg |head -1 |sed 's/.*UUID=\([a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*\).*/\1/'`
cat grub.d/40_custom | sed "s,\$BOOT,$BOOT,;s,\$ROOT,$ROOT,;s,\$TYPE,$TYPE,;s,\$MENU,$MENU," >/etc/grub.d/40_custom
update-grub
fn=/etc/grub.d/10_linux
if [ -e $fn ]; then
if `grep SUPPORTED_INITS $fn |head -1 |grep -q finit`; then
echo "Already installed, done."
else
echo "Adding Finit to list of SUPPORTED_INITS ..."
sed -i 's/SUPPORTED_INITS="[^"]*/& finit:\/sbin\/finit/' $fn
update-grub
fi
else
echo "Cannot find $fn, you'll have to set up your bootloader on your own."
fi
echo
echo "*** Done"
-8
View File
@@ -1,8 +0,0 @@
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=debian
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
+8
View File
@@ -35,6 +35,14 @@ tty /dev/tty1
tty /dev/tty2
tty /dev/tty3
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
# Alternative method instead of runparts
#task [S] /etc/init.d/keyboard-setup start -- Setting up preliminary keymap
#task [S] /etc/init.d/acpid start -- Starting ACPI Daemon
@@ -0,0 +1,75 @@
In Finit issue #196 we were reminded [1] of a missing inotify flag in
Linux older kernels, IN_MASK_CREATE. Finit makes use of this internally
for monitoring PID conditions, and more. This is a central mechanism to
synchronize services at boot and reload at runtime.
The following patch for Linux 4.9.0, was provided by Andy Savage for
other people that may want to run Finit on slightly older kernels.
[1]: https://github.com/troglobit/finit/issues/196
Index: fs/notify/inotify/inotify_user.c
===================================================================
--- fs.orig/notify/inotify/inotify_user.c
+++ fs/notify/inotify/inotify_user.c
@@ -522,6 +522,7 @@ static int inotify_update_existing_watch
__u32 old_mask, new_mask;
__u32 mask;
int add = (arg & IN_MASK_ADD);
+ int create = (arg & IN_MASK_CREATE);
int ret;
mask = inotify_arg_to_mask(arg);
@@ -529,6 +530,8 @@ static int inotify_update_existing_watch
fsn_mark = fsnotify_find_inode_mark(group, inode);
if (!fsn_mark)
return -ENOENT;
+ else if (create)
+ return -EEXIST;
i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
@@ -726,6 +729,10 @@ SYSCALL_DEFINE3(inotify_add_watch, int,
if (unlikely(!f.file))
return -EBADF;
+ /* IN_MASK_ADD and IN_MASK_CREATE don't make sense together */
+ if (unlikely((mask & IN_MASK_ADD) && (mask & IN_MASK_CREATE)))
+ return -EINVAL;
+
/* verify that this is indeed an inotify instance */
if (unlikely(f.file->f_op != &inotify_fops)) {
ret = -EINVAL;
@@ -814,7 +821,7 @@ static int __init inotify_user_setup(voi
BUILD_BUG_ON(IN_ISDIR != FS_ISDIR);
BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT);
- BUG_ON(hweight32(ALL_INOTIFY_BITS) != 21);
+ BUG_ON(hweight32(ALL_INOTIFY_BITS) != 22);
inotify_inode_mark_cachep = KMEM_CACHE(inotify_inode_mark, SLAB_PANIC);
Index: include/linux/inotify.h
===================================================================
--- include.orig/linux/inotify.h
+++ include/linux/inotify.h
@@ -17,6 +17,6 @@ extern struct ctl_table inotify_table[];
IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | \
IN_Q_OVERFLOW | IN_IGNORED | IN_ONLYDIR | \
IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD | \
- IN_ISDIR | IN_ONESHOT)
+ IN_MASK_CREATE | IN_ISDIR | IN_ONESHOT)
#endif /* _LINUX_INOTIFY_H */
Index: include/uapi/linux/inotify.h
===================================================================
--- include.orig/uapi/linux/inotify.h
+++ include/uapi/linux/inotify.h
@@ -52,6 +52,7 @@ struct inotify_event {
#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
#define IN_EXCL_UNLINK 0x04000000 /* exclude events on unlinked objects */
+#define IN_MASK_CREATE 0x10000000 /* only create watches */
#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */
#define IN_ISDIR 0x40000000 /* event occurred against dir */
#define IN_ONESHOT 0x80000000 /* only send event once */
+1 -1
View File
@@ -1,4 +1,4 @@
SUBDIRS = finit.d
docsdir := @docdir@/contrib/void
docs_DATA = README.md finit.conf build.sh install.sh rc.local xbps
docs_DATA = README.md finit.conf build.sh install.sh rc.local
EXTRA_DIST = $(docs_DATA)
+1 -2
View File
@@ -18,7 +18,7 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
--sysconfdir=/etc --localstatedir=/var \
--enable-dbus-plugin --enable-x11-common-plugin \
--enable-alsa-utils-plugin --with-watchdog \
--with-heading="Void Linux"
--with-keventd --with-sulogin
echo
echo "*** Building ..."
@@ -35,4 +35,3 @@ fi
echo
echo "*** Done"
echo
+17
View File
@@ -5,5 +5,22 @@
# Default is 2
#runlevel 2
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
#cgroup init cpu.weight:100
#cgroup user cpu.weight:100
#cgroup system cpu.weight:9700
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
#task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
#task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
## Bootstrap services and tasks
# Can be listed here or in /etc/finit.d/*.conf
+3 -2
View File
@@ -8,9 +8,10 @@ if [ "x`id -u`" != "x0" ]; then
fi
# Adjust base directory
if [ -e xbps ]; then
grep -q void Makefile 2>/dev/null
if [ $? -eq 0 ]; then
cd ../..
elif [ ! -e autogen.sh ]; then
elif [ ! -e configure.ac ]; then
echo "*** Please run this script from the Finit base directory."
exit 1
fi
+1 -1
View File
@@ -4,4 +4,4 @@
#
# Each line is run in sequence.
#
# NOTE: Remeber to set the executable bit!
# NOTE: Remember to set the executable bit!
+14 -2
View File
@@ -21,17 +21,29 @@ Some of these are also registered in the issue tracker on GitHub.
* Allow running as non-pid1 => read .conf and RCSD form cmdline
* Add `finit.conf` support for UPS notification (SIGPWR) to start a task
using, e.g. <sys/power/{ok,fail,low}> conditions. More info in sig.c
As of Finit v4.1 SIGPWR generates <sys/power/fail> condition and it
is up to a task to check why and take appropriate action.
* Add `finit.conf` support for ctrl-alt-delete (SIGINT) and kbrequest,
i.e. KeyboardSignal, (SIGWINCH) behavior. Using conditions to a task,
e.g, <sys/key/ctrlaltdel> and <sys/key/signal> like SIGPWR handling.
* Write man pages for finit and `finit.conf`, steal from the excellent
`pimd` man pages ...
As of Finit v4.1 SIGINT generates <sys/key/ctrlaltdel>, but there is
no check if the signal actually originates from the kernel. To get
this verification, a new libuEv release is needed. As of June 6 -21
that functionality is not yet released.
Initctl
-------
* Add support for timed shutdown in Finit, including cancelled shutdown:
shutdown -h 03:35 "foobar was here"
* Add support for JSON output, or similar, from `initctl show`, e.g.
`initctl show --json`
* Add support for `-s` to redirect all output to syslog, for scripting
Init
-56
View File
@@ -1,56 +0,0 @@
Bootstrap
=========
1. Prepare emergency shell, if enabled
2. Set up initial signal handlers
3. Set up default $PATH early
4. Mount `/proc` and `/sys`
5. Check kernel command line for `debug` to figure out log level
6. Load all `.so` plugins
7. Call `fsck` on file systems listed in `/etc/fstab`
8. Populate `/dev` using either udev or mdev, depending on system type
9. Parse `/etc/finit.conf` and all `/etc/finit.d/*.conf` files
10. Start built-in watchdog, if enabled
11. Set hostname
12. Remount `/` read-write if `/` is listed in `/etc/fstab` without `ro`
13. Call 1st level hooks, `HOOK_ROOTFS_UP`
14. Mount all file systems listed in `/etc/fstab` and swap, if available
15. Enable SysV init signals
16. Call 2nd level hooks, `HOOK_BASEFS_UP`
17. Cleanup stale files from `/tmp/*` et al, handled by `bootmisc` plugin
18. Load kernel params from `/etc/sysctl.d/*.conf`, `/etc/sysctl.conf`
et al. (Supports all locations that SysV init does.), handled by
`procps` plugin
19. Start all 'S' runlevel tasks and services
20. Bring up loopback interface and all `/etc/network/interfaces`, if
the `.conf` setting `network <SCRIPT>` is set, it is called instead
21. Call 3rd level hooks, `HOOK_NETWORK_UP`
22. If `runparts <DIR>` is set, [run-parts(8)][] is called on `<DIR>`
23. Switch to the configured runlevel from `/etc/finit.conf`, default 2.
At every runlevel change all `*.conf` files in `/etc/finit.d/` are
(re)loaded and new services, tasks, and blocking run commands are
started. Provided they are allowed in the new runlevel and all of
their conditions, if any, are set.
24. Call 4th level hooks, `HOOK_SVC_UP`
25. Call `/etc/rc.local`, if it exists and is an executable shell script
26. Call 5th level (last) hooks, `HOOK_SYSTEM_UP`
27. Start all configured TTYs
In (19) and (22) tasks and services defined in `/etc/finit.conf` and
`/etc/sysctl.d/*.conf` are started. Remember, all `service` and `task`
stanzas are started in parallel and `run` in sequence, and in the order
listed. Hence, to emulate a SysV `/etc/init.d/rcS` one could write a
long `finit.conf` with only `run` statements.
Notice the five hook points that are called at various point in the
bootstrap process. This is where plugins can extend the boot in any way
they please. There are other hook points, e.g. `HOOK_MOUNT_ERROR`, for
more on this see [plugins.md](plugins.md).
For instance, at `HOOK_BASEFS_UP` a plugin could read an XML file from a
USB stick, convert/copy its contents to the system's `/etc/` directory,
well before all 'S' runlevel tasks are started. This could be used with
system images that are created read-only and all configuration is stored
on external media.
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
+33 -13
View File
@@ -27,10 +27,10 @@ optional plugins to enable. It depends on two external libraries:
PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure
The configure script checks for all dependencies, including the correct
version of the above mentioned libraries. Currently requried versions:
version of the above mentioned libraries. Currently required versions:
- libite v2.2.0
- libuEv v2.2.0
- libite v2.2.0, or later
- libuEv v2.2.0, or later
Configure
@@ -53,6 +53,10 @@ Below are a few of the main switches to configure:
built-ins (.o files) and all external libraries, except the C library
will be linked statically.
* `--enable-kernel-cmdline`: Enable Finit pre-4.1 parsing of init args from
`/proc/cmdline`, this is *not recommended* since Finit may be running as the
init for container apps that can see the host's `/proc` filesystem
* `--enable-alsa-utils-plugin`: Enable the optional `alsa-utils.so` sound plugin.
* `--enable-dbus-plugin`: Enable the optional D-Bus `dbus.so` plugin.
@@ -61,8 +65,19 @@ Below are a few of the main switches to configure:
* `--enable-x11-common-plugin`: Enable the optional X Window `x11-common.so` plugin.
* `--with-sulogin`: Enable bundled `sulogin` program. Default is to use the
system `sulogin(8)`. The sulogin shipped with Finit *allows password-less*
login if the `root` user is disabled or has no password at all.
For more configure flags, see <kbd>./configure --help</kbd>
> **Note:** the configure script is not available in the GIT sources. It is
> however included in (officially supported) released tarballs. The
> idea is that you should not need GNU autotools to build, only the
> above mentioned dependencies, a POSIX shell, a C compiler and make.
> Any contributing to Finit can generate it from `configure.ac` using
> the `autogen.sh` script.
Example
-------
@@ -70,16 +85,16 @@ Example
First, unpack the archive:
```shell
$ tar xf finit-3.0.tar.xz
$ cd finit-3.0/
$ tar xf finit-4.3.tar.gz
$ cd finit-4.3/
```
Then configure, build and install:
```shell
$ ./configure --prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--with-heading="Alpine Linux 3.13" --with-hostname=alpine
$ ./configure --prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--with-keventd --with-watchdog
$ make
.
.
@@ -87,13 +102,13 @@ $ make
$ DESTDIR=/tmp/finit make install
```
In this example the [finit-3.0.tar.xz][1] archive is unpacked to the
In this example the [finit-4.3.tar.gz][1] archive is unpacked to the
user's home directory, configured, built and installed to a temporary
staging directory. The environment variable `DESTDIR` controls the
destination directory when installing, very useful for building binary
standalone packages.
Finit 3.0 and later can detect if it runs on an embedded system, or a
Finit 4.1 and later can detect if it runs on an embedded system, or a
system that use BusyBox tools instead of udev & C:o. On such systems
`mdev` instead of `udev` is used. However, remember to also change the
Linux config to:
@@ -142,17 +157,22 @@ enabled. The default Finit rescue mode configuration is installed into
By default the a root shell, without login, is started.
> **Note:** in this mode `initctl` will not work. Use the `-f` flag to
> force `reboot`, `shutdown`, or `poweroff`.
Debugging
---------
Edit, or append to, the kernel command line: remove `quiet` to enable
kernel messages and add `debug` to enable Finit debug messages.
kernel messages and add `finit.debug` to enable Finit debug messages.
```shell
append="init=/sbin/finit debug"
append="init=/sbin/finit -- finit.debug"
```
Notice the `--` separator.
To debug startup issues, in particular issues with getty/login, add
the following to your Finit .conf file:
@@ -171,6 +191,6 @@ it only for debugging start up issues when Finit crashes.
systems since they can potentially give a user root access.
[1]: ftp://troglobit.com/finit/finit-3.0.tar.xz
[1]: ftp://troglobit.com/finit/finit-4.3.tar.gz
[libuEv]: https://github.com/troglobit/libuev
[libite]: https://github.com/troglobit/libite
+86 -14
View File
@@ -6,15 +6,66 @@ passed on the Linux kernel command line. Not limited to Finit.
The `bool` setting is one of `on, off, true false, 1, 0`.
> **NOTE:** remember to use `--` to separate kernel parameters from
> parameters to init. E.g., `init=/sbin/finit -- finit.debug rescue`
* `debug`: Enable kernel debug. Debug messages are printed to the
console until Finit starts up.
console until Finit starts up, unless `loglevel=7` (below) is used.
* `fsck.mode=<auto,force,skip>`, default: `auto`, unless built with
`configure --enable-fastboot`, in which case the default is `skip`
* `fsck.repair=<preen,yes,no>`, default: `preen`, unless built with
`configure --enable-fsckfix`, in which case the default is `yes`.
This configure option also sets `fsck.mode=force`, unless fastboot
is selected at the same time. I.e., the `--enable-fastboot` build
option overrides the `fsck.mode` default value.
* `finit.cond=foo[,bar[,baz]]`: set `<boot/foo>` condition, optionally
multiple conditions can be set using the same option, separated with a
comma. Alternatively, multiple `foo.cond=arg` can be given. Each will
result in a `<boot/arg>` condition being set to control the rest of the
system bootstrap.
Very useful for selecting different boot modes, e.g. manufacturing test,
firmware upgrade, or rescue mode.
> Note: `<boot/...>` conditions cannot be cleared with `initctl`!
* `finit.config=/path/to/alternative/finit.conf`: override the
compile-time bootstrap config file, default:
./configure --with-config=/etc/finit.conf
Useful when starting up in various rescue mode, factory, or
production test setups. Use the top-level configuration file
directive `rcsd /path/to/finit.d` to override the default
rcS.d directory.
* `finit.debug[=bool]`: Enable finit debug. This is operated
independently of the kernel debug setting. New as of Finit v4.
independently of the kernel `debug` setting. New as of Finit v4.
* `finit.show_status[=bool]`: Control finit boot progress, including
banner.
* `finit.fstab=</path/to/etc/fstab.alternative>`: Tell Finit to use an
alternate `fstab` to mount the file system from. Remember, this file
must be on the `root=...` file system provided to Finit from the
kernel. By default the built-in fstab is used, which itself defaults
to `/etc/fstab`, but can be changed at build time with:
./configure --with-fstab=/path/to/fstab
It is even possible to disable a built-in default using:
./configure --without-fstab
Making `finit.fstab=/path/to/fstab` a *mandatory* command line option.
Note, if the command line fstab is missing, Finit falls back to the
built-in fstab, and if both are missing, the system treats this as a
bad `fsck` and thus calls `sulogin`. If, in turn, `sulogin` is not
available on the system, Finit calls reboot, which is also what will
happen when a user exits from `sulogin`.
* `finit.status[=bool]`: Control finit boot progress, including banner.
(Used to be `finit.show_status`, which works but is deprecated.)
* `finit.status_style=<classic,modern>`: Set Finit boot progress style,
when enabled.
@@ -24,23 +75,44 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
signals and has no job control. Recommend using, and modifying,
`rescue` mode instead.
* `loglevel=<0-7>`, sets the kernel's log level, which is more granular
than `debug`. Also, when `loglevel=7`, Finit will *not disable*
kernel logs to the console. This is very useful when debugging the
kernel at system bring-up. Since `loglevel=7` is the same as `debug`
this means you have to use `quiet` for a quiet boot, until sysklogd
takes over logging of kernel events.
* `panic=SEC`: By default the kernel does not reboot after a kernel
panic. This setting will cause a kernel reboot after SEC seconds.
* `quiet`: Suppress kernel logging to console, except for warnings and
errors.
errors. Also, see `loglevel` and `quiet` above.
* `rescue`: Start Finit rescue mode; no network, no `fsck` of file
systems in `/etc/fstab`, no `/etc/rc.local`, no `runparts`. The
configuration is read from `/lib/finit/rescue.conf`, and can be
modified by the operator.
* `rescue`: Start rescue/maintenance mode. If your system comes with
the bundled `sulogin` program (Finit, or from util-linux/Busybox),
you will be given a root login to a maintenance shell. However, if
`sulogin` is missing, the file `/lib/finit/rescue.conf` is read and
the system booted in a limited fallback mode. See [config.md][]
for more information.
* `single`, or `S`: Single user mode, runlevel 1, in Finit. Useful to
debug problems with the regular runlevel. All services and TTYs in
`[1]` will be started, so a `tty [1] @console nologin` configuration
presents you with a root console without login.
This option can be disabled with `configure --without-rescue`
For more on kernel boot paramaters, see the man page [bootparam(7)][].
**Note:** in this mode `initctl` will not work. Correct the problem
and use `reboot -f` to force reboot.
* `single`, or `S`: Overrides the configured runlevel (default: 2) to go
to after bootstrap by forcing it to runlevel 1, this is also known
as single user mode. Useful to debug startup problems. All services
and TTYs in `[1]` will be started, so a `tty [1] @console nologin`
configuration presents you with a root console without login.
* `1-9`, except `6`: override the configured `runlevel`. Like the `S`
and `rescue`, giving a single number on the kernel command line tells
Finit to ignore any `runlevel` in `/etc/finit.conf` as well as the
configure fallback `--with-runlevel=N` setting. Remember, `6` is the
reboot runlevel and is not permitted. Any other values are ignored.
For more on kernel boot parameters, see the man page [bootparam(7)][].
[config.md]: config.md#rescue-mode
[bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html
+78 -17
View File
@@ -13,9 +13,9 @@ Finit Conditions
Introduction
------------
Conditions are a new addition to Finit, introduced in v3, with the
intention of providing a mechanism for common synchronization problems.
For example:
Conditions are a relatively new addition to Finit, introduced in v3,
with the intention of providing a mechanism for common synchronization
problems. For example:
- *"wait for service A to start before starting service B"*, or
- *"wait for basic network access to be available"*
@@ -27,6 +27,16 @@ specified separated by comma. Multiple conditions are logically AND'ed
during evaluation, i.e. all conditions must be satisfied in order for a
service to run.
A special syntax, using a leading `!` in run/task/service conditions,
denote if a:
- service does not support `SIGHUP`
- run/task should not block runlevel changes (i.e., bootstrap)
Finit guarantees by default that all run/tasks run (at least) once
per runlevel. For most tasks this is a good default, for example
checking SSH host keys or loading keymap. However, for conditions
that are unlikely to happen it is not. (See example below.)
### Example
@@ -35,22 +45,40 @@ service to run.
In this example the Network monitor daemon `netd` is not started until
both the `pid/setupd` *and* `pid/zebra` conditions are satisfied. A
`pid/` condition is satisfied by the corresponding service's PID file
being created.
being created, i.e., the service's default readiness notification.
**NOTE:** Conditions also stop services when a condition is no longer
asserted. I.e., if the Zebra process above stops or restarts, netd
will also stop or restart.
Another example is `dropbear`, it does not support `SIGHUP`, but we can
also see optional sourcing of arguments from an environment file:
service [2345789] <!> env:-/etc/default/dropbear dropbear -F -R $DROPBEAR_ARGS -- Dropbear SSH daemon
Finally, the weird "block runlevel changes" example. Here we see what
happens when Finit receives `SIGPWR`, sent from a power daemon like
[powstatd(8)][]. A condition is asserted and a user can set up their
own task to act on it. We do not want this task to block Finit from
moving to the next runlevel after bootstrap, so we set `<!>`:
task [S0123456789] <!sys/pwr/fail> name:pwrfail initctl poweroff -- Power failure, shutting down
Triggering
----------
Conditions are mainly triggered (asserted) by built-in plugins, e.g.,
`netlink.so` and `pidfile.so`, see below for built-in conditions. Finit
also supports user-defined conditions, sometimes referred to as static
or one-shot conditions. They live in the `<usr/...` namespace and are
constrained to a flat hierarchy without any sub-directories, unlike the
pidfile plugin, for instance.
- `netlink.so`: provides `<net/...>`
- `pidfile.so`: provides `<pid/...>`
- Cmdline `finit.cond=arg`: provides `<boot/arg>`
See below for built-in conditions. Finit also supports user-defined
conditions, sometimes referred to as static or one-shot conditions.
They live in the `<usr/...>` namespace and are constrained to a flat
hierarchy without any sub-directories, unlike the pidfile plugin, for
instance.
User-defined conditions are controlled using the `initctl cond set` and
`initctl cond clear` commands:
@@ -87,12 +115,35 @@ Static (one-shot) conditions, like `usr/`, never enter the `flux` state.
Built-in Conditions
-------------------
Finit comes with a `pidfile` and `netlink` plugin. When enabled, the
`pidfile` plugin watches `/var/run/` (recursively) for PID files created
by the monitored services, and sets a corresponding condition in the
`pid/` namespace. Similarily, the `netlink` plugin provides basic
conditions for when an interface is brought up/down and when a default
route (gateway) is set, in the `net/` namespace.
Finit comes with a set of plugins for conditions:
- `devmon` (built-in)
- `netlink`
- `pidfile`
- `sys`
- `usr`
The `devmon` (built-in) plugin monitors `/dev` and `/dev/dir` for device
nodes being created and removed. It is active only when a run, task, or
service has declared a `<dev/foo>` or `<dev/dir/bar>` condition.
The `pidfile` plugin (recursively) watches `/run/` (recursively) for PID
files created by the monitored services, and sets a corresponding
condition in the `pid/` namespace.
Similarly, the `netlink` plugin provides basic conditions for when an
interface is brought up/down and when a default route (gateway) is set,
in the `net/` namespace.
The `sys` and `usr` plugins monitor are passive condition monitors where
the action is provided by `keventd`, signal handlers, and in the case of
`usr`, the end-user via the `initctl` tool.
Additionally, the various states of a run/task/sysv/service can also be
used as conditions, the image above shows the state names. The syntax
for a `service` type process: `<service/foo/STATE>`. The other types,
in particular run/task/sysv, there are the additional states `success`
and `failure`.
With the example listed above, finit does not start the `/sbin/netd`
daemon until `setupd` and `zebra` has started *and* created their PID
@@ -111,6 +162,14 @@ Built-in conditions:
- `net/<IFNAME>/exist`
- `net/<IFNAME>/up`
- `net/<IFNAME>/running`
- `service/<NAME[:ID]>/<STATE>`
- `{run, task, sysv}/<NAME[:ID]>/{<STATE>, success, failure}`
- `sys/pwr/ac`
- `sys/pwr/fail`
- `sys/key/ctrlaltdel`
- `usr/foo`
- `boot/arg`
- `dev/node` and `dev/dir/node`
**Note:** `up` means administratively up, the interface flag `IFF_UP`.
`running` is the `IFF_RUNNING` flag, meaning operatively up. The
@@ -156,7 +215,7 @@ Debugging
If a service is not being started as it should, the problem might be
that one of its conditions is not in the expected state. Use the
command `initctl status` to inspect service status. Services in the
`ready` state are pending a condition.
`waiting` state are pending a condition.
In that situation, running `initctl cond show` reveals which of the
conditions that are not satisfied. Listed as `off` below.
@@ -173,7 +232,7 @@ PID IDENT STATUS CONDITION (+ ON, ~ FLUX, - OFF)
Here we can see that `netd` is allowed to run since both its conditions
are in the `on` state, as indicated by the `+`-prefix. `udhcpc` however
is not allowed to run since `net/vlan1/exist` condition is not satsifed.
is not allowed to run since `net/vlan1/exist` condition is not satisfied.
As indicated by the `-`-prefix.
To fake interface `vlan1` suddenly appearing, and test what happens to
@@ -224,3 +283,5 @@ Therefore, any plugin that supplies Finit with conditions must ensure
that their state is updated after each reconfiguration. This can be
done by binding to the `HOOK_SVC_RECONF` hook. For an example of how
to do this, see `plugins/pidfile.c`.
[powstatd(8)]: https://manpages.ubuntu.com/manpages/trusty/en/man8/powstatd.8.html
+917 -100
View File
File diff suppressed because it is too large Load Diff
+154 -29
View File
@@ -8,7 +8,8 @@ Hooks & Plugins
* [Shutdown Hooks](#shutdown-hooks)
Finit can be extended to add general functionality in the form of I/O
monitors, or hook plugins.
monitors, or hook plugins. It is even possible to run scripts at these
hook points, see below.
The following sections detail existing plugins and hook points. For
more information, see the plugins listed below.
@@ -27,33 +28,92 @@ For your convenience a set of *optional* plugins are available:
system and runs at `HOOK_BASEFS_UP`. The `/var`, `/run`, and `/dev`
file systems must be writable for this plugin to work.
Note: On an embedded system both `/var` and `/run` can be `tmpfs` RAM
disks and `/dev` is usually a `devtmpfs`. This must be defined in the
`/etc/fstab` file and in the Linux kernel config.
This plugin is a wrapper for the [tmpfiles.d(5)][] implementation that
Finit has. Capable but limited: no aging, attributes, or subvolumes.
By default, `/lib/finit/tmpfiles.d` carries all the default .conf
files distributed with Finit. It is read first but can be overridden
by any of the standard tmpfiles.d directories, e.g. `/etc/tmpfiles.d`.
> **Note:** On an embedded system both `/var` and `/run` can be `tmpfs`
> RAM disks and `/dev` is usually a `devtmpfs`. This must be defined
> in the `/etc/fstab` file and in the Linux kernel config.
* *dbus.so*: Setup and start system message bus, D-Bus, at boot.
_Optional plugin._
* *hotplug.so*: Setup and start either udev or mdev hotplug daemon, if
available.
* *hook-scripts.so*: Trigger the execution of scripts from plugin hook
points (see [Hooks](#hooks)). _Optional plugin._
This plugin is particularly useful for early boot debugging that needs
to take place before regular services are available.
For example, say that you want to enable some kernel tracing before
modules are loaded. With hook scripts, you can just drop in a shell
script in `/libexec/finit/hook/mount/all/` that will poke the right
control files in tracefs.
Scripts are located in `/libexec/finit/hook` by default, this can be
customized at build-time using the `--with-hook-scripts-path=PATH`
argument to `configure`.
* *hotplug.so*: Replaced with `/lib/finit/system/10-hotplug.conf`, which
checks for `udevd` and `mdev` at boot. This file can be overridden by a
file in `/etc/finit.d/10-hotplug.conf`.
Enabled by default.
> See the [Services](config.md#services) section in the configuration
> guide for an example how to run `mdevd`, alternative to plain mdev.
* *rtc.so*: Restore and save system clock from/to RTC on boot/halt.
Enabled by default.
* *modules-load.so*: Scans /etc/modules-load.d for modules to modprobe.
* *modules-load.so*: Scans `/etc/modules-load.d/*.conf` for modules to
load using `modprobe`. Each file can contain multiple lines with the
name of the module to load. Any line starting with the standard UNIX
comment character, `#`, or `;`, is skipped.
Modules are by default loaded in runlevel `S` using the `task` stanza.
Each module gets a unique `name:modprobe.foo`, and optional`:ID`. The
runlevel can be changed per file using:
set runlevel 2345
The `:ID` is a globally incremented index, which can be disabled per
file (anywhere) using the following config line:
set noindex
To change the index used by the plugin:
set index 1234
**Note:** unlike the traditional .conf `module` directive, which load
any listed module immediately, this plugin creates a background `task`
which load the module(s) in the background. The program is modprobe,
`/sbin/modprobe`, which you can override per .conf file:
set modprobe /path/to/maybe-a-modprobe-wrapper
Since these tasks run in the background, they usually return `[ OK ]`
at boot, unless the modprobe tool does not exist. Check syslog for
warnings and the actual status of the operation using `initctl`.
* *netlink.so*: Listens to Linux kernel Netlink events for gateway and
interfaces. These events are then sent to the Finit service monitor
for services that may want to be SIGHUP'ed on new default route or
interfaces going up/down.
interfaces going up/down. Enabled by default.
* *resolvconf.so*: Setup necessary files for `resolvconf` at startup.
_Optional plugin._
* *tty.so*: Watches `/dev`, using inotify, for new device nodes (TTY's)
to start/stop getty consoles on them on demand. Useful when plugging
in a usb2serial converter to login to your embedded device.
in a usb2serial converter to login to your embedded device. Enabled
by default.
* *urandom.so*: Setup random seed at startup.
* *urandom.so*: Setup random seed at startup. Enabled by default.
* *x11-common.so*: Setup necessary files for X-Window. _Optional plugin._
@@ -67,40 +127,105 @@ state, etc. Available hook points are:
Hooks
-----
In the below listings, the first label is the hook point for a C plugin,
the second is the condition name and hook script path. A hook script is
a plain shell script, or program, that does a very small dedicated job
at the below hook points.
See [Run-parts Scripts](config.md#run-parts-scripts) for details on the
requirements, possibilities, and *limitations* of hook scripts.
All hook scripts are called with at least one environment variable set,
the hook name, useful when reusing the same hook script for multiple
hook points:
- `FINIT_HOOK_NAME`: set to the second label, e.g., `hook/net/up`
- `FINIT_SHUTDOWN`: set for `hook/sys/shutdown` and later to one
of `halt`, `poweroff`, or `reboot`.
**Example:**
$ mkdir -p /libexec/finit/hook/sys/down
$ cat <<EOF >/libexec/finit/hook/sys/down/foo.sh
#!/bin/sh
echo 'I run just before the reboot() syscall at shutdown/reboot'
echo 'I have access to /dev since devtmpfs is exempt from umount'
echo "FINIT_HOOK_NAME: $FINIT_HOOK_NAME"
if [ -n "$FINIT_SHUTDOWN" ]; then
echo "FINIT_SHUTDOWN: $FINIT_SHUTDOWN"
fi
exit 0
EOF
$ chmod +x /libexec/finit/hook/sys/down/foo.sh
> **Note:** to use hook scripts, even for pre-bootstrap and pre-shutdown
> tasks, you must build with `configure --enable-hook-scripts-plugin`.
### Bootstrap Hooks
* `HOOK_ROOTFS_UP`: When `finit.conf` has been read and `/` has is
mounted — very early
* `HOOK_BANNER`, `hook/sys/banner`: The very first point at which a
plugin can run. Intended to be used as a banner replacement.
Essentially this runs just before entering runlevel S. Assume nothing
is available, so be prepared to use absolute paths, etc.
* `HOOK_BASEFS_UP`: All of `/etc/fstab` is mounted, swap is available
and default init signals are setup
* `HOOK_ROOTFS_UP`, `hook/mount/root`: When `finit.conf` has been read
and `/` has is mounted — very early
* `HOOK_NETWORK_UP`: System bootstrap, runlevel S, has completed and
networking is up (`lo` is up and the `network` script has run)
* `HOOK_MOUNT_ERROR`, `hook/mount/error`: executed if `mount -a` fails
* `HOOK_SVC_UP`: All services in the active runlevel has been launched
* `HOOK_MOUNT_POST`, `hook/mount/post`: always executed after `mount -a`
* `HOOK_SYSTEM_UP`: All services *and* everything in `/etc/finit.d`
has been launched
* `HOOK_BASEFS_UP`, `hook/mount/all`: All of `/etc/fstab` is mounted,
swap is available and default init signals are setup
* `HOOK_SVC_PLUGIN`, `hook/svc/plugin`: Called in `conf_init()` right
before loading `/etc/finit.conf`. For plugins to register any early
run/task/services, please do NOT use any earlier hook point. That
will cause uninitialized rlimits that lead to unpredictable results
when Finit later tries to start the run/task/service.
* `HOOK_NETWORK_UP`, `hook/net/up`: System bootstrap, runlevel S, has
completed and networking is up (`lo` is up and the `network` script
has run)
* `HOOK_SVC_UP`, `hook/svc/up`: All services in the active runlevel have
been launched
* `HOOK_SYSTEM_UP`, `hook/sys/up`: All services *and* everything in
`/etc/finit.d` has been launched
### Runtime Hooks
* `HOOK_SVC_RECONF`: Called when the user has changed something in the
`/etc/finit.d` directory and issued `SIGHUP`. The hook is called when
all modified/removed services have been stopped. When the hook has
completed, Finit continues to start all modified and new services.
* `HOOK_SVC_RECONF`, N/A: Called when the user has changed something in
the `/etc/finit.d` directory and issued `SIGHUP`. The hook is called
when all modified/removed services have been stopped. When the hook
has completed, Finit continues to start all modified and new services.
* `HOOK_RUNLEVEL_CHANGE`: Called when the user has issued a runlevel
change. The hook is called when services not matching the new
runlevel have been been stopped. When the hook has completed, Finit
continues to start all services in the new runlevel.
* `HOOK_RUNLEVEL_CHANGE`, N/A: Called when the user has issued a
runlevel change. The hook is called when services not matching the
new runlevel have been been stopped. When the hook has completed,
Finit continues to start all services in the new runlevel.
### Shutdown Hooks
* `HOOK_SHUTDOWN`: Called at shutdown/reboot, right before all
services are sent `SIGTERM`
* `HOOK_NETWORK_DN`, `hook/net/down`: Called right after having changed
to runlevel 6, or 0, when all services have received their 'stop' signal.
* `HOOK_SHUTDOWN`, `hook/sys/shutdown`: Called at shutdown/reboot, right
before all services are sent `SIGTERM`
* `HOOK_SVC_DN`, `hook/svc/down`: In shutdown/reboot, all services and
non-reserved processes have been killed. **Note:** only hook scripts
can run here!
* `HOOK_SYSTEM_DN`, `hook/sys/down`: In shutdown/reboot, called after
all non-reserved file systems have been unmounted, just before Finit
tells the kernel to reboot or shut down. **Note:** only hook scripts
can run here!
Plugins like `tty.so` extend finit by acting on events, they are called
I/O plugins and are called from the finit main loop when `poll()`
detects an event. See the source code for `plugins/*.c` for more help
and ideas.
[tmpfiles.d(5)]: https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html
+55 -1
View File
@@ -1,7 +1,59 @@
Finit Services
==============
![The service state machine](svc-machine.png "The service state machine")
Starting & Monitoring
---------------------
Finit can start and monitor the following types of daemons:
* Forks to background, creates a PID file
* Runs in foreground:
- creates a PID file
- does not create a PID file -- Finit can create it for you (optional)
Finit can *not* start and monitor a daemon that:
* Forks to background and does *not* create a PID file
| | Forking | Creates PID File | Finit creates PID File |
|---|---------|------------------|------------------------|
| ✔ | Yes | Yes | No |
| ✔ | No | Yes | No |
| ✔ | No | No | Yes, optionally |
| ✘ | Yes | No | No |
> **Note:** PID files is one mechanism used to assert conditions to
> synchronize the start and stop of other, dependent, services.
### Forks to Background w/ PID File
There are two syntax variants, type 1 and type 2. The former is the
traditional one used also for `sysv` start/stop scripts, and the latter
is inspired by systemd, with a twist -- it lets Finit guess the pifdile
to look for based on the standard path and the basename of the command.
service pid:!/run/serv.pid serv -- Forking service, type 1
service type:forking serv -- Forking service, type 2
In this example the resulting files to watch for are `/run/serv.pid` and
`/var/run/serv.pid`, respectively. On most modern Linux systems this is
the same directory (`/var/run` is a symlink to `../run`).
### Runs in Foreground w/ PID File
service serv -n -p -- Foreground service w/ PID file
### Runs in Foreground w/o PID File
Same as previous, but we tell Finit to create the PID file, because we
need it to synchronize start/stop of a dependent service.
service pid:/run/serv.pid serv -n -- Foreground service w/o PID file
### Runs in Foreground w/ Custom PID File
service pid:/run/servy.pid serv -n -p -P /run/servy.pid -- Foreground service w/ custom PID file
State Machine
-------------
@@ -11,6 +63,8 @@ For `run`s and `task`s there is an additional end state called `DONE`,
not shown in the diagram for brevity. Services start in the `HALTED`
state.
![The service state machine](svc-machine.png "The service state machine")
The current state depends on the two following conditions:
* `E`: Service enabled. In order for `E` to be satisfied, the service
+17 -9
View File
@@ -12,28 +12,36 @@ have been adopted:
Same effect as `finit q`, `init q`, or `initctl reload`, reloads all
*.conf files in `/etc/finit.d/`
This also restarts the API (initctl) socket, like SysV init and systemd
does on USR1 with their FIFO/D-Bus.
`SIGUSR1`
---------
Calls shutdown hooks, including `HOOK_SHUTDOWN`, stopping all running
processes, and unmounts all file systems. Then tells kernel to halt.
Most people these days want `SIGUSR2` though.
Since Finit 4.1 this signal causes Finit to restart its API (initctl)
socket, like SysV init and systemd does on USR1 with their FIFO/D-Bus.
Finit <= 4.0 performed a system halt (like USR2 without power-off), but
this caused compatibility problems with systemd and sysvinit on desktop
systems. Hence, since Finit 4.1 it is no longer possible to halt a
system with a signal.
SysV init and systemd use this to re-open their FIFO/D-Bus.
`SIGUSR2`
---------
Like SIGUSR1, but tell kernel to power-off the system, if ACPI or
similar exists to actually do this. If the kernel fails power-off,
Finit falls back to halt.
Calls shutdown hooks, including `HOOK_SHUTDOWN`, stopping all running
processes, and unmounts all file systems. Then tells kernel to power
off the system, if ACPI or similar exists to actually do this. If the
kernel fails power-off, Finit falls back to halt.
SysV init N/A, systemd dumps its internal state to log.
`SIGTERM`
---------
Like `SIGUSR1`, but tell kernel to reboot the system when done.
Like `SIGUSR2`, but tell kernel to reboot the system when done.
SysV init N/A, systemd rexecutes itself.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 230 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+141
View File
@@ -0,0 +1,141 @@
_cond()
{
initctl -pt cond dump | awk '{print $4}' | sed 's/<\(.*\)>/\1/'
}
_ident()
{
if [ -n "$1" ]; then
initctl ident | grep -q $1
else
initctl ident
fi
}
_svc()
{
initctl ls -pt | grep $1 | sed "s/.*\/\(.*\)/\1/g" | sort -u
}
_enabled()
{
echo "$(_svc enabled)"
}
_available()
{
all=$(mktemp)
ena=$(mktemp)
echo "$(_svc available)" >$all
echo "$(_svc enabled)" >$ena
grep -v -f $ena $all
rm $all $ena
}
# Determine first non-option word. Usually the command
_firstword() {
local firstword i
firstword=
for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
if [[ ${COMP_WORDS[i]} != -* ]]; then
firstword=${COMP_WORDS[i]}
break
fi
done
echo $firstword
}
# Determine last non-option word. Uusally a sub-command
_lastword() {
local lastword i
lastword=
for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
if [[ ${COMP_WORDS[i]} != -* ]] && [[ -n ${COMP_WORDS[i]} ]] && [[ ${COMP_WORDS[i]} != $cur ]]; then
lastword=${COMP_WORDS[i]}
fi
done
echo $lastword
}
_initctl()
{
local cur command
cur=${COMP_WORDS[COMP_CWORD]}
prev="${COMP_WORDS[COMP_CWORD-1]}"
firstword=$(_firstword)
lastword=$(_lastword)
commands="status cond debug help kill ls log version list enable \
disable touch show cat edit create delete reload start \
stop restart signal cgroup ps top plugins runlevel reboot \
halt poweroff suspend utmp"
cond_cmds="set get clear status dump"
cond_types="hook net pid service task usr"
signals="int term hup stop tstp cont usr1 usr2 pwr"
options="-b --batch \
-c --create \
-d --debug \
-f --force \
-h --help \
-j --json \
-n --noerr \
-1 --once \
-p --plain \
-q --quiet \
-t --no-heading \
-v --verbose \
-V --version"
case "${firstword}" in
enable)
COMPREPLY=($(compgen -W "$(_available)" -- $cur))
;;
disable|touch)
COMPREPLY=($(compgen -W "$(_enabled)" -- $cur))
;;
show|cat|edit|delete)
COMPREPLY=($(compgen -W "$(_svc .)" -- $cur))
;;
start|stop|restart|log|status)
COMPREPLY=($(compgen -W "$(_ident)" -- $cur))
;;
signal|kill)
if $(_ident "${prev}"); then
COMPREPLY=($(compgen -W "$signals" -- $cur))
else
COMPREPLY=($(compgen -W "$(_ident)" -- $cur))
fi
;;
cond)
case "${lastword}" in
set|clear)
compopt -o nospace
COMPREPLY=($(compgen -W "usr/" -- $cur))
;;
get)
COMPREPLY=($(compgen -W "$(_cond)" -- $cur))
;;
dump)
COMPREPLY=($(compgen -W "$cond_types" -- $cur))
;;
*)
COMPREPLY=($(compgen -W "$cond_cmds" -- $cur))
;;
esac
;;
*)
COMPREPLY=($(compgen -W "$commands" -- $cur))
;;
esac
if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W "$options" -- $cur))
fi
}
complete -F _initctl initctl
+19 -23
View File
@@ -1,8 +1,6 @@
# From https://github.com/collectd/collectd/blob/master/configure.ac
# Dependency handling currently unused
define([toupper], [translit([$1], [a-z], [A-Z])])
define([sanitize], [translit([$1], [-], [_])])
define([enadis], [ifelse([$1], [yes], [disable], [enable])])
# AC_PLUGIN(name, default, info)
@@ -10,27 +8,25 @@ define([enadis], [ifelse([$1], [yes], [disable], [enable])])
AC_DEFUN([AC_PLUGIN],[
m4_divert_once([HELP_ENABLE], [
Optional Plugins:])
define(PLUGGY, m4_translit([$1],[a-z-][A-Z-]))dnl
AC_ARG_ENABLE([$1-plugin], AS_HELP_STRING([--enadis($2)-$1-plugin], [$3]), [
if test "x$enableval" = "xyes"; then
enable_plugin="yes"
else
enable_plugin="no"
define(pluggy, sanitize($1))
define(PLUGGY, toupper(pluggy))
AC_ARG_ENABLE([$1-plugin], AS_HELP_STRING([--enadis($2)-$1-plugin], [$3]), [
if test "x$enableval" = "xyes"; then
enable_plugin="yes"
fi], [
if test "x$enable_all_plugins" = "xauto"; then
if test "x$2" = "xyes"; then
enable_plugin="yes"
else
enable_plugin="no"
fi], [
if test "x$enable_all_plugins" = "xauto"; then
if test "x$2" = "xyes"; then
enable_plugin="yes"
else
enable_plugin="no"
fi
else
enable_plugin="$enable_all_plugins"
fi])
if test "x$enable_plugin" = "xyes"; then
AC_DEFINE([HAVE_]PLUGGY[_PLUGIN], 1, [Define to 1 if the $1 plugin is enabled.])
plugins="$1 $plugins"
enable_plugin="no"
fi
AM_CONDITIONAL([BUILD_]PLUGGY[_PLUGIN], test "x$enable_plugin" = "xyes")
enable_pluggy="$enable_plugin"])
else
enable_plugin="$enable_all_plugins"
fi])
if test "x$enable_plugin" = "xyes"; then
AC_DEFINE(HAVE_[]m4_translit($1,[-a-z],[_A-Z])_PLUGIN, 1, [Define to 1 if the $1 plugin is enabled.])
plugins="$1 $plugins"
fi
AM_CONDITIONAL(BUILD_[]m4_translit($1,[-a-z],[_A-Z])_PLUGIN, test "x$enable_plugin" = "xyes")])
+2
View File
@@ -0,0 +1,2 @@
Makefile
Makefile.in
+2
View File
@@ -0,0 +1,2 @@
dist_man8_MANS = finit.8 initctl.8
dist_man5_MANS = finit.conf.5
+348
View File
@@ -0,0 +1,348 @@
.\" Hey, EMACS: -*- nroff -*-
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.Dd Apr 22, 2023
.\" Please adjust this date whenever revising the manpage.
.Dt FINIT 8 SMM
.Os Linux
.Sh NAME
.Nm finit
.Nd Fast init for Linux systems
.Sh SYNOPSIS
.Nm /sbin/finit
.Op --
.Op debug
.Op finit.cond=foo[,bar[,baz]]
.Op finit.config=/path/to/alt/finit.conf
.Op finit.debug
.Op finit.fstab=/etc/fstab.alt
.Op finit.status=<on,off>
.Op finit.status_style=<classic,modern>
.Op loglevel=<0-7>
.Op panic=SEC
.Op quiet
.Op rescue | recover
.Op single | S
.Nm /sbin/telinit
.Op Fl hv
.Op q | Q | 0-9
.Sh DESCRIPTION
Fast init for Linux systems. Reverse engineered from the EeePC
fastinit, 10+ years ago by Claudio Matsuoka, "gaps filled with frog
DNA ...". Focus is on small and embedded systems, although Finit is
fully usable on server and desktop systems as well.
.Pp
Features include:
.Bl -bullet -width 1n -compact
.It
Runlevels, defined per service
.It
One-shot tasks, services (daemons), or SysV init start/stop scripts
.It
Runparts and
.Pa /etc/rc.local
support
.It
Process supervision similar to
.Xr systemd 8
.It
Sourcing environment files
.It
Conditions for network/process/custom dependencies
.It
Process readiness notification for synchronizing system startup as well
as reconfiguration at runtime. Natively PID files are used, but systemd
.Cm sd_notify()
and s6 notification is also supported.
.It
Limited support for
.Xr tmpfiles.d 5 ,
no aging, attributes, or subvolumes
.It
Pre/Post script actions
.It
Tooling to enable/disable services
.It
Built-in getty
.It
Built-in watchdog, with support for hand-over to
.Lk https://troglobit.com/watchdogd.html watchdogd
.It
Built-in support for Debian/BusyBox
.Pa /etc/network/interfaces
.It
Cgroups v2, both configuration and monitoring in `initctl top`
.It
Plugin support for customization
.It
Proper rescue mode with bundled `sulogin` for protected maintenance shell
.El
.Sh BOOTPARAM
.Nm
support the following command line parameters to alter the behavior
at boot. Notice the
.Cm --
separator needed to tell the kernel which paramters should be given to
PID 1. For more information on this, and available kernel command line
options, see
.Xr bootparam 7 .
.Bl -tag -width pid -offset indent
.It Cm debug
Enable kernel debug. Debug messages are printed to the console until
Finit starts up, unless
.Cm loglevel=7
(below) is used.
.It Cm finit.cond=foo[,bar[,baz]]
set
.Cm <boot/foo>
condition, optionally multiple conditions can be set using the same
option, separated with a comma. Alternatively, multiple
.Cm foo.cond=arg
can be given. Each will result in a
.Cm <boot/arg>
condition being set to control the rest of the system bootstrap.
.Pp
Very useful for selecting different boot modes, e.g. manufacturing test,
firmware upgrade, or rescue mode.
.Pp
.Sy Note:
.Cm <boot/...>
conditions cannot be cleared with
.Nm initctl !
.It Cm finit.config=/path/to/alternative/finit.conf
override the compile-time bootstrap config file, default:
.Bd -unfilled -offset indent
./configure --with-config=/etc/finit.conf
.Ed
Useful when starting up in various rescue mode, factory, or
production test setups. Use the top-level configuration file
directive
.Cm rcsd Ar /path/to/finit.d
to override the default rcS.d directory.
.It Cm finit.debug
Enable Finit debug messages on system console and log. Sometimes useful
when doing board bringup. Before the system log daemon has started,
Finit use the kernel ring buffer,
.Pa /dev/kmsg .
.It Cm finit.fstab=/path/to/fstab.alt
Tell
.Nm
to use an alternate
.Cm fstab
to mount the file system from. Remember, this file must be on the
.Cm root=...
file system provided to Finit from the kernel. If this file is missing,
.Nm
falls back to its built-in default, which can be changed at build time
using the
.Cm --with-fstab=/path/to/footab
configure option. It is even possible to completely disable the
built-in using
.Cm --without-fstab ,
meaning
.Nm
.Sy must
be started with the
.Cm finit.fstab
option.
.Pp
Should
.Nm
discover that there is no fstab file available, including the fallback,
it triggers the same failure mode as when
.Cm fsck
fails, starting
.Xr sulogin 8 ,
if that is availble. When
.Cm sulogin
is missing, or when the user exits from
.Cm sulogin ,
the system is rebooted.
.Pp
Default fstab, unless changed at build-time:
.Pa /etc/fstab
.It Cm finit.status=<on,off>
Control finit boot progress, including banner. This used to be called
.Cm finit.show_status ,
which still works but is deprecated.
.It Cm finit.status_style=<classic,modern>
Set Finit boot progress style, when enabled.
.It Cm loglevel=<0-7>
set the kernel's log level, which is more granular than
.Cm debug .
Also, when
.Cm loglevel=7 ,
Finit will
.Em not disable
kernel logs to the console. This is very useful when debugging the
kernel at system bring-up. Since
.Cm loglevel=7
is the same as
.Cm debug
this means you have to use
.Cm quiet
for a quiet boot, until sysklogd takes over logging of kernel events.
.It Cm panic=SEC
By default the kernel does not reboot after a kernel panic. This
setting will cause a kernel reboot after
.Ar SEC
seconds.
.It Cm quiet
Suppress kernel logging to console, except for warnings and errors.
Also, see
.Cm loglevel
and
.Cm quiet
above.
.It Cm rescue | recover
Start rescue/maintenance mode. If your system comes with the bundled
.Cm sulogin
program (Finit, or from util-linux/Busybox), you will be given a root
login to a maintenance shell. However, if
.Cm sulogin
is missing, the file
.Pa /lib/finit/rescue.conf
is read and the system booted in a limited fallback mode. See
.Xr finit.conf 5
for more information.
.It Cm single | S
Single user mode, runlevel 1, in Finit. Useful to debug problems with
the regular runlevel. All services and TTYs in
.Cm [1]
will be started, e.g., a
.Cm tty [1] @console nologin
configuration presents you with a root console without login.
.Pp
.Sy Note:
by definition, single user mode does not have networking enabled. This
is also true for runlevel 1.
.El
.Sh BOOTING
.Pp
Before laucnhing services, the system needs to be bootstrapped. This
involves mounting all filesystems (not already mounted by an initramfs)
in
.Pa /etc/fstab ,
or any alternate
.Pa fstab
file provided on the Finit command line using
.Cm finit.fstab ,
ensuring that necessary filesystems like:
.Pa /dev ,
.Pa /proc ,
.Pa /sys ,
and
.Pa /run
are available and can provide the system with the services required.
.Pp
With that out of the way, a set of plugins take over:
.Pp
.Bl -tag -width bootmisc.so -offset indent
.It Cm bootmisc.so
Cleans up stale files from previous boots and default directories are
created in tmpfs filesystems
.It Cm modprobe.so
Probes kernel modules required by the system
.It Cm procps.so
Set kernel variables from
.Pa /etc/sysctl.conf
et al
.El
.Pp
When the plugins are done, finit reads
.Pa /etc/finit.conf
and all other enabled services in
.Pa /etc/finit.d/* .
First all services, run/tasks in runlevel S (bootStrap) are started,
When all run/tasks have completed, Finit changes to the configured
runlevel (default 2), Processes are started in parallel, in dependency
order according to their conditions.
.Pp
When all services and run/tasks have been started, the console progress
is disabled and all configured getty services are started.
.Sh CONDITIONS
The condition subysystem in Finit was initially created to track PID
files of daemons. If service/task B requires service A to have started,
Finit waits for the PID file of service A to be created/updated before
it starts service B. Conversely, if service A is stopped and its PID
file removed, service B is also stopped.
.Pp
The following condition families are available today:
.Pp
.Bl -tag -width service -offset indent
.It Cm net
Linux netlink events, e.g. net/route/default, net/eth0/up, and
net/et0/running
.It Cm pid
PID files based on the service declaration
.Cm name:id ,
gives the condition pid/name:id
.It Cm service
Tracks run/task/service state stansitions, including readiness. E.g.,
.Cm service/foo/ready
can be used as a condition for service
.Cm bar ,
provided
.Cm foo
properly signals its readiness to Finit.
.It Cm sys
System conditions, e.g. sys/key/ctrlaltdel and sys/pwr/fail
.It Cm usr
User conditions, assert and deassert using
.Cm initctl cond [set|clr] foo
.El
.Sh SIGNALS
PID 1 is the only process that by default blocks all signals. Finit
allows for the following signals to control operation, but recommends
instead using the
.Xr initctl 8
tool.
.Pp
.Bl -tag -width TERM
.It HUP
Tell
.Nm
to reload its configuration file(s), same as
.Cm initctl reload
.It USR1
Restart API
.Cm ( initctl )
socket.
.It USR2
Tell
.Nm
to perform a system shutdown, same as
.Cm initctl poweroff
.It TERM
Like SIGUSR2 but performs a reboot, same as
.Cm initctl reboot
.It INT
Sent from kernel when Ctrl-Alt-Del is pressed (on the console), this
asserts the sys/key/ctrlaltdel condition, which can be used to start
tasks or services
.It PWR
Sent from a a power daemon on changes to UPS status, Finit asserts
the sys/pwr/fail condition
.El
.Sh FILES
.Bl -tag -width /etc/finit.d/available/*.conf -compact
.It Pa /etc/finit.conf
Main configuration file
.It Pa /etc/finit.d/*.conf
Static service definitions
.It Pa /etc/finit.d/available/*.conf
Available services
.It Pa /etc/finit.d/enabled/*.conf
Symlinks from available
.It Pa /run/finit/
Runtime files, including the condition subsystem
.El
.Sh SEE ALSO
.Xr finit.conf 5
.Xr initctl 8
.Xr tmpfiles.d 5
.Sh AUTHORS
.Nm
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
maintained by Joachim Wiberg, with contributions by many others.
+989
View File
@@ -0,0 +1,989 @@
.\" Hey, EMACS: -*- nroff -*-
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.Dd July 11, 2023
.Dt FINIT.CONF 5 SMM
.Os Linux
.Sh NAME
.Nm finit.conf
.Nd Finit configuration file format
.Sh SYNOPSIS
.Nm /etc/finit.conf
.Nm /etc/finit.d/*.conf
.Nm /etc/finit.d/available/*.conf
.Nm /etc/finit.d/enabled/*.conf
.Sh DESCRIPTION
.Nm Finit
based systems can be set up with a single file:
.Pa /etc/finit.conf .
This is the traditional way of doing it which can be ideal for some
setups since it gives a great overview of the system configuration.
.Pp
More comprehensive setups, however, require more careful planning.
The recommendation is per-package
.Cm *.conf
files in
.Pa /etc/finit.d/available/ .
This allows end users to enable and disable parts of the system
configuration at runtime. Finit tracks which tasks and services belong
to a given file, so that when the user calls
.Cm initctl reload
to activate the changes they have made, only the affected tasks and
services are stopped, started, or restarted. Hence, this approach is
useful for modern package-based Linux distributions.
.Pp
The following sections describe the more of this in detail, starting
with files, the file format, and available directives. Remember to
also visit the other manual pages (references at the bottom).
.Sh FILES
.Bl -tag -width /etc/finit.d/available/*.conf -compact
.It Pa /etc/finit.conf
Main configuration file, optional
.It Pa /etc/finit.d/*.conf
Static (system) service definitions
.It Pa /etc/finit.d/available/*.conf
Available (installed) services
.It Pa /etc/finit.d/enabled/*.conf
Enabled services (symlink back)
.El
.Pp
Static services,
.Cm .conf
files in
.Pa /etc/finit.d/ ,
cannot be enabled or disabled using
.Cm initctl [enable | disable] service[.conf] .
An enabled service is a symlink back to the corresponding
.Cm ../available/
service
.Cm .conf
file. Please use the
.Cm initctl
tool to manage these symlinks to ensure proper operation.
.Pp
.Sy NOTE:
Previous versions of
.Nm Finit
created symlinks in
.Pa /etc/finit.d/
if
.Pa /etc/finit.d/enabled/
was missing, this is as of v4.4 not supported.
.Sh FILE FORMAT
The file format is line based, empty lines and comments, lines starting
with `#', are ignored. A configuration directive starts with a keyword
followed by a space and the rest of the line is treated as the value.
.Pp
As of Finit v4.4, configuration directives can be broken up in multiple
lines using the continuation character `\\', and trailing comments are
also allowed. Example:
.Bd -unfilled -offset indent
# Escape \\# chars if you want them literal in, e.g., descriptions
service name:sysklogd [S123456789] \\
env:-/etc/default/sysklogd \\
syslogd -F $SYSLOGD_ARGS \\
-- System log daemon \\# 1 # Comments allowed now
.Ed
.Sh DIRECTIVES
This section lists all supported configuration directives. There also exist
deprecated directives, see the Markdown documentation for details on these.
.Pp
.Bl -tag -width 1n
.It Cm rlimit Oo hard|soft Oc Ar RESOURCE Aq LIMIT | unlimited
.Pp
Set the hard or soft limit for a resource, or both if that argument is
omitted.
.Ar RESOURCE
is the lower-case
.Cm RLIMIT_
string constants from
.Xr setrlimit 2 ,
without prefix. E.g. to set
.Cm RLIMIT_CPU ,
use
.Cm cpu .
.Pp
.Ar LIMIT
is an integer that depends on the resource being modified, see
the man page, or the kernel
.Pa /proc/PID/limits
file, for details.
Finit versions before v3.1 used
.Cm infinity
for
.Cm unlimited ,
which is still supported, albeit deprecated.
.Bd -unfilled -offset indent
# No process is allowed more than 8MB of address space
rlimit hard as 8388608
# Core dumps may be arbitrarily large
rlimit soft core infinity
# CPU limit for all services, soft & hard = 10 sec
rlimit cpu 10
.Ed
.Pp
.Cm rlimit
can be set globally, in
.Pa /etc/finit.conf ,
or locally per each
.Pa /etc/finit.d/*.conf
read. I.e., a set of task/run/service stanzas can share the same
rlimits if they are in the same .conf.
.It Cm runlevel Aq N
The system runlevel to go to after bootstrap (S) has completed.
.Cm N
is the runlevel number 0-9, where 6 is reserved for reboot and 0 for
halt. All other can be used by operating system administrators.
Default: 2
.Pp
It s recommended to keep runlevel 1 as single-user mode, because
.Nm
disables networking in this mode.
.Pp
.Sy Note:
only read and executed in runlevel S (bootstrap).
.It Cm run Oo LVLS Oc Ao COND Ac Ar /path/to/cmd ARGS Op -- Optional description
One-shot command to run in sequence when entering a runlevel, with
optional arguments and description.
.Pp
.Cm run
commands are guaranteed to be completed before running the next
command. Highly useful if true serialization is needed. Usually
only used in the bootstrap (S) runlevel.
.Pp
.Cm Aq COND
conditions are described in
.Xr finit 8 ,
see also the
.Sx Examples
section below.
.It Cm task Oo LVLS Oc Ao COND Ac Ar /path/to/cmd ARGS Op -- Optional description
One-shot like
.Cm run ,
but starts in parallel with the next command.
.Pp
Both
.Cm run
and
.Cm task
commands are run in a shell, so pipes and redirects can be freely used:
.Bd -unfilled -offset indent
task [s] echo "foo" | cat >/tmp/bar
.Ed
.It Cm sysv Oo LVLS Oc Ao COND Ac Ar /path/to/script ARGS Op -- Optional description
Similar to
.Cm task
is the
.Cm sysv
stanza, which can be used to call SysV style start/stop scripts. The
primary intention for this command is to be able to re-use much of
existing setup and init scripts in Linux distributions.
.Pp
When entering an allowed runlevel, Finit calls
.Cm init-script start ,
when entering a disallowed runlevel, Finit calls
.Cm init-script stop ,
and if the Finit .conf, where the
.Cm sysv
stanza is declared, is modified, Finit calls
.Cm init-script restart
on
.Cm initctl reload .
Similar to how
.Cm service
stanzas work.
.Pp
Forking services started with
.Cm sysv
scripts can be monitored by Finit by declaring the PID file to look for:
.Bd -unfilled -offset indent
sysv pid:!/path/to/pidfile.pid /path/to/script ...
.Ed
.Pp
The leading '!' is to prevent Finit from managing the PID file, which is
the default behavior for the
.Cm pid:
command modifier.
.It Cm service Oo LVLS Oc Ao COND Ac Ar /path/to/daemon ARGS Op -- Optional description
Service, or daemon, to be monitored and automatically restarted if it
exits prematurely. Finit tries to restart services that die, by
default 10 times, before giving up and marking them as
.Em crashed .
After which they have to be restarted manually using
.Cm initctl restart NAME .
The number of restarts, the delay between each restart, and more is
configurable, see the options below.
.Pp
.Bd -filled -offset indent
.Sy Tip:
to allow endless restarts, see below option
.Cm respawn
.Ed
.Pp
For daemons that support it, we recommend appending
.Cm --foreground , --no-background , -n , -F ,
or similar command line argument to prevent them from forking off a
sub-process in the background. This is the most reliable way to monitor
a service.
.Pp
However, not all daemons support running in the foreground, or they may
start logging to the foreground as well, these are called forking
services and are supported using the same syntax as forking
.Cm sysv
services, using the
.Cm pid:!/path/to/pidfile.pid
command modifier syntax. There is an alternative syntax that may be
more intuitive, where Finit can also guess the PID file based on the
daemon's command name:
.Bd -unfilled -offset indent
service type:forking ntpd -- NTP daemon
.Ed
.Pp
Here we let BusyBox
.Nm ntpd
daemonize itself. Finit uses the basename of the binary to guess the
PID file to watch for the PID:
.Pa /var/run/ntpd.pid .
If Finit guesses wrong, you have to submit the full
.Cm pid:!/path/to/file.pid
option to your service stanza.
.Pp
.Sy Example: in the case of
.Cm ospfd
(below), we omit the
.Cm -d
flag (daemonize) to prevent it from forking to the background:
.Bd -unfilled -offset indent
service [2345] <pid/zebra> /sbin/ospfd -- OSPF daemon
.Ed
.Pp
.Cm [2345]
denote the runlevels
.Cm ospfd
is allowed to run in, they are optional and default to runlevel 2-5 if
omitted.
.Pp
.Cm <pid/zebra>
is the condition for starting
.Cm ospfd .
In this example Finit waits for another service,
.Cm zebra ,
to have created its PID file in
.Pa /var/run/quagga/zebra.pid
before starting
.Cm ospfd .
Finit watches *all* files in
.Pa /var/run ,
for each file named
.Cm *.pid ,
.Cm */pid ,
Finit opens it and find the matching
.Cm NAME:ID
using the PID.
.Pp
Some services do not maintain a PID file and rather than patching each
application Finit provides a workaround. A
.Cm pid
modifier keyword can be set to have Finit automatically create (when
starting) and later remove (when stopping) the PID file. The file is
created in the
.Pa /var/run
directory using the
.Xr basename 3
of the service. The full syntax of the
.Cm pid
modifier is:
.Bd -unfilled -offset indent
pid[:[!][/path/to/]filename[.pid]]
.Ed
.Pp
For example, by adding
.Cm pid:/run/foo.pid
to the service
.Cm /sbin/bar ,
that PID file will, not only be created and removed automatically, but
also be used by the Finit condition subsystem. So a service/run/task
can depend on the
.Cm <pid/bar>
condition.
.Pp
As an alternative "readiness" notification, Finit supports both systemd
and s6 style notification. This can be enabled by using the `notify`
option:
.Bl -tag -width 1n
.It Cm notify:systemd
tells Finit the service uses the
.Cm sd_notify()
API to signal PID 1 when it has completed its startup and is ready
to service events. This API expects
the environment variable
.Cm NOTIFY_SOCKET
to be set to the socket where the application can send
.Cm "READY=1\n"
when it is starting up or has processed a
.Cm SIGHUP .
For details, see:
.Pp
.Lk https://www.freedesktop.org/software/systemd/man/sd_notify.html
.It Cm notify:s6
puts Finit in s6 compatibility mode. Compared to the systemd
notification, s6 expect compliant daemons to send
.Cm "\\n"
and then close their socket. For details, see:
.Pp
.Lk https://skarnet.org/software/s6/notifywhenup.html
.Pp
Finit takes care of "hard-wiring" the READY state as long as the
application is running, events across any `SIGHUP`. Since s6 can give
its applications the descriptor number (must be >3) on then command
line, Finit provides the following syntax (
.Cm %n
is replaced by Finit with then descriptor number):
.Bd -unfilled -offset indent
service notify:s6 mdevd -C -O 4 -D %n
.Ed
.Pp
When a service is ready, either by Finit detecting its PID file, or
their respective readiness mechanism has been triggered, Finit creates
then service's ready condition which other services can depend on:
.Bd -unfilled -offset indent
$ initctl -v cond get service/mdevd/ready
on
.Ed
.El
.Pp
If a service should not be automatically started, it can be configured
as manual with the
.Cm manual:yes
command modifier. The service can then be started at any time by
running
.Cm initctl start NAME
.Pp
The name of a service, shown by the
.Cm initctl
tool, defaults to the basename of the service executable. It can be
changed with the
.Cm name:foo
command modifier.
.Pp
As mentioned previously, services are automatically restarted should
they crash, this is configurable with the following options:
.Bl -tag -width 1n
.It Cm restart:NUM
number of times Finit tries to restart a crashing
service, default: 10. When this limit is reached the service is
marked
.Em crashed
and must be restarted manually with
.Xr initctl 8 .
.It Cm restart_sec:SEC
number of seconds before Finit tries to restart
a crashing service, default: 2 seconds for the first five retries,
then back-off to 5 seconds. The maximum of this configured value
and the above (2 and 5) will be used
.It Cm restart:always
no upper limit on the number of times Finit tries to restart a crashing
service. Same as
.Cm restart:-1
.It Cm norestart
dont restart on failures, same as
.Cm restart:0
.It Cm respawn
bypasses the
.Cm restart
mechanism completely, allows endless restarts. Useful in many
use-cases, but not what
.Cm service
was originally designed for so not the default behavior.
.It Cm oncrash:reboot
when all retries have failed, and the service
has
.Em crashed ,
if this option is set the system is rebooted.
.It Cm oncrash:script
Similar to
.Cm oncrash:reboot ,
but instead of rebooting this action calls the
.Cm post:script
(see below) to let the operator decide the best course of action. If
the post:script option is not set, this is a no-op.
.Pp
The post:script is called with the same environment variables
.Sy except
for the
.Cm EXIT_CODE
variable which is set to
.Cm "crashed" .
.El
.Pp
When stopping a service (run/task/sysv/service), either manually or when
moving to another runlevel, Finit starts by sending SIGTERM, to allow
the process to shut down gracefully. If the process has not been
collected within 3 seconds, Finit sends SIGKILL. To halt the process
using a different signal, use the command modifier
.Cm halt:SIGNAL ,
e.g.,
.Cm halt:SIGPWR .
To change the delay between your halt signal and KILL, use the command
modifier
.Cm kill:SEC ,
e.g.,
.Cm kill:10
to wait 10 seconds before sending SIGKILL.
.Pp
Services support the
.Cm pre:script
and
.Cm post:script
command actions as well. These run as the same
.Cm @USER:GROUP
as the service itself, with any
.Cm env:file
sourced. The scripts must use an absolute path, but are executed from
the
.Cm $HOME
of the given user. The scripts are not called with any argument
(currently), but both get the
.Cm SERVICE_IDENT=foo
environment variable set. Here
.Cm foo
denotes the identity of the service, which if there are multiple
services named
.Cm foo ,
may be
.Cm foo:1 ,
or any unique identifier specified in the .conf file. The
.Cm post:script
is called with an additional set of environment variables:
.Bl -tag -offset indent -width 1n
.It Cm EXIT_CODE=[exited,signal,crashed]
set to one of
.Cm exited ,
.Cm signal ,
or
.Cm crashed
(see above).
.It Cm EXIT_STATUS=[num,SIGNAME]
set to one of exit status code from the program, if it exited normally,
or the signal name (HUP, TERM, etc.) if it exited due to signal
.El
.Pp
The scripts have a default execution time of 3 seconds before they are
SIGKILLed, this can be adjusted using the
.Cm kill:SEC
modifier syntax.
.It Cm runparts Aq DIR
Call
.Xr run-parts 8
on
.Cm DIR
to run start scripts. All executable files, or scripts, in the
directory are called, in alphabetic order. The scripts in this
directory are executed at the very end of bootstrap, runlevel S.
.Pp
It can be beneficial to use
.Cm S01name ,
.Cm S02othername ,
etc. if there is a dependency order between the scripts. Symlinks to
existing daemons can talso be used, but make sure they daemonize by
default.
.Pp
Similar to the
.Pa /etc/rc.local
shell script, make sure that all your services and programs either
terminate or start in the background or you will block Finit.
.Sy Note:
only read and executed in runlevel S (bootstrap).
.It Cm include Aq CONF
Include another configuration file. Absolute path required.
.It Cm log size:BYTES count:NUM
Log rotation for run/task/services using the
.Cm log
command modifier with redirection to a log file. Global setting,
applies to all services.
.Pp
The size can be given as bytes, without a specifier, or in `k`, `M`,
or `G`, e.g.
.Cm size:10M ,
or
.Cm size:3G .
A value of
.Cm size:0
disables log rotation. The default is
.Cm size:200k .
.Pp
The count value is recommended to be between 1-5, with a default 5.
Setting count to 0 means the logfile will be truncated when the MAX
size limit is reached.
.It Cm tty Oo LVLS Oc Ao COND Ac Ar DEV Oo BAUD Oc Oo noclear Oc Oo nowait Oc Oo nologin Oc Oo TERM Oc
This form of the
.Cm tty
stanza uses the built-in getty on the given TTY device
.Ar DEV ,
in the given runlevels.
.Ar DEV may be the special keyword
.Cm @console ,
or `console`, which is expanded from `/sys/class/tty/console/active`,
useful on embedded systems.
.Pp
The default baud rate is 0, i.e., keep kernel default.
.Pp
The `tty` stanza inherits runlevel, condition (and other feature)
parsing from the `service` stanza. So TTYs can run in one or many
runlevels and depend on any condition supported by Finit. This is
useful e.g. to depend on `<pid/elogind>` before starting a TTY.
.Bd -unfilled -offset indent
tty [12345] /dev/ttyAMA0 115200 noclear vt220
.Ed
.It Cm tty Oo LVLS Oc Ao COND Ac Ar CMD DEV Oo noclear Oc Oo nowait Oc
This form of the
.Cm tty
stanza is for using an external getty, like agetty or the BusyBox getty.
.Pp
By default, these first two syntax variants
.Em clear
the TTY and
.Em wait
for the user to press enter before starting getty.
.Bd -unfilled -offset indent
tty [12345] /sbin/getty -L 115200 /dev/ttyAMA0 vt100
tty [12345] /sbin/agetty -L ttyAMA0 115200 vt100 nowait
.Ed
.Pp
The
.Cm noclear
option disables clearing the TTY after each session. Clearing the TTY
when a user logs out is usually preferable.
.Pp
The
.Cm nowait
option disables the
.Cm Please press Enter to activate console
message before actually starting the getty program. On small and
embedded systems running multiple unused getty wastes both memory and
CPU cycles, so `wait` is the preferred default.
.Pp
The
.Cm nologin
option disables getty and
.Pa /bin/login ,
and gives the user a root (login) shell on the given TTY
.Cm DEV
immediately. Needless to say, this is a rather insecure option, but can
be very useful for developer builds, during board bringup, or similar.
.Pp
Notice the ordering, the
.Cm TERM
option to the built-in getty must be the last argument.
.Pp
Embedded systems may want to enable automatic `DEV` by supplying the
special
.Cm @console
device. This works regardless weather the system uses
.Cm ttyS0 , ttyAMA0 , ttyMXC0 ,
or anything else. Finit figures it out by querying sysfs:
.Pa /sys/class/tty/console/active .
The speed can be omitted to keep the kernel default.
.Pp
Most systems get by fine by just using `console`, which will evaluate
to
.Pa /dev/console .
If you have to use
.Cm @console
to get any output, you may have some issue with your kernel config.
.Bd -unfilled -offset indent
tty [12345] @console noclear vt220
.Ed
.Pp
On really bare bones systems, or for board bringup, Finit can give you a
shell prompt as soon as bootstrap is done, without opening any device
node:
.Bd -unfilled -offset indent
tty [12345789] notty
.Ed
.Pp
This should of course not be enabled on production systems. Because it
may give a user root access without having to log in. However, for
board bringup and system debugging it can come in handy.
.Pp
One can also use the
.Cm service
stanza to start a stand-alone shell:
.Bd -unfilled -offset indent
service [12345] /bin/sh -l
.Ed
.Pp
.It Cm tty Oo LVLS Oc Ao COND Ac Oo notty Oc Oo rescue Oc
The third
.Cm tty
form is for board bringup and the
.Cm rescue
boot mode. No device node is required in this variant, the same output
that the kernel uses is reused for stdio. If the
.Cm rescue
option is omitted, a shell is started. The flags
.Cm nologin , noclear ,
and
.Cm nowait
are implied. If the
.Cm rescue
option is set the bundled
.Pa /libexec/finit/sulogin
is started to present a bare-bones root login prompt. If the root
(uid:0, gid:0) user does not have a password set, no rescue is possible.
.El
.Sh COMMAND MODIFIERS
The run/task/tty/service/sysv stanzas take modifiers, or options, to
control their behavior. This section lists them with their limitations.
All modifiers must be placed between the stanza and its command.
.Bl -tag -width 1n
.It Cm @user:group
Every
.Cm run , task ,
or
.Cm service
can also list the privileges the
.Cm /path/to/cmd
should be executed with. Prefix the command with
.Cm @USR[:GRP] ,
group is optional, like this:
.Bd -unfilled -offset indent
run [2345] @joe:users logger "Hello world"
.Ed
.Pp
For multiple instances of the same command, e.g. a DHCP client or
multiple web servers, add
.Cm :ID
somewhere between the
.Cm run , task , service
keyword and the command, like this:
.Bd -unfilled -offset indent
service :80 [2345] httpd -f -h /http -p 80 -- Web server
service :8080[2345] httpd -f -h /http -p 8080 -- Old web server
.Ed
.Pp
Without the
.Cm :ID
to the service the latter will overwrite the former and only the old web
server would be started and supervised.
.It Cm log:/path/to/file
Redirect stdout/stderr of a command to the given log file. See the
global log directive, above, for details on log rotation.
.It Cm log:console
Redirect stdout/stderr of a command to
.Pa /dev/console ,
only use this for debugging or bringup.
.It Cm log:null
Redirect stdout/stderr of a command to
.Pa /dev/null .
.It Cm log:prio:facility.level,tag:ident
Redirect stdout/stderr of a command to syslog using the given priority
and tag identity.
.Bd -unfilled -offset indent
service log:prio:user.warn,tag:ntpd /sbin/ntpd pool.ntp.org -- NTP daemon
.Ed
.It Cm log
Default
.Cm prio
is
.Cm daemon.info
and the default
.Cm tag
identity is the basename of the service or run/task command.
.El
.Sh RESCUE MODE
Finit supports a rescue mode which is activated by the
.Cm rescue
option on the kernel command line. The rescue mode comes in two
flavors:
.Em traditional
and
.Em fallback .
.Ss Traditional
This is what most users expect. A very early maintenance login prompt,
served by the bundled
.Pa /libexec/finit/sulogin
program, or the standard
.Cm sulogin
from util-linux or BusyBox is searched for in the UNIX default
.Cm $PATH .
If a successful login is made, or the user exits (Ctrl-D), the rescue
mode is ended and the system boots up normally.
.Pp
.Sy Note:
if the user (UID 0 and GID 0) does not have a password, or
.Em the account is locked ,
the user is presented with a password-less prompt:
.Cm "Press enter to enter maintenance mode." ,
which opens up a root shell.
.Ss Fallback
If no
.Cm sulogin
program is found, Finit tries to bring up as much of its own
functionality as possible, yet limiting many aspects, meaning; no
network, no`fsck` of file systems in
.Pa /etc/fstab ,
no
.Pa /etc/rc.local ,
no
.Cm runparts ,
and most plugins are skipped (except those that provide functionality
for the condition subsystem).
.Pp
Instead of reading
.Pa /etc/finit.conf
et al, system configuration is read from
.Pa /lib/finit/rescue.conf ,
which can be freely modified by the system administrator.
.Pp
The bundled default `rescue.conf` contains nothing more than:
.Bd -unfilled -offset indent
runlevel 1
tty [12345] rescue
.Ed
.Pp
The
.Cm tty
has the
.Cm rescue
option set, which works similar to the board bring-up tty option
.Cm notty .
The major difference being that `sulogin` is started to query for
root/admin password. If
.Cm sulogin
is not found,
.Cm rescue
behaves like
.Cm notty
and gives a plain root shell prompt.
.Pp
If Finit cannot find
.Pa /lib/finit/rescue.conf
it defaults to:
.Bd -unfilled -offset indent
tty [12345] rescue
.Ed
.Pp
There is no way to exit the
.Em fallback
rescue mode.
.Sh SERVICE ENVIRONMENT
Finit supports sourcing environment variables from
.Pa /etc/default/* ,
or similar. This is a common pattern from SysV init scripts, where the
start/stop script is a generic script for the given service,
.Cm foo ,
and the options for the service are sourced from the file
.Pa /etc/default/foo .
Like this:
.Bd -unfilled -offset indent
/etc/default/foo:
FOO_OPTIONS=--extra-arg="bar" -s -x
/etc/finit.conf:
service [2345] env:-/etc/default/foo foo -n $FOO_OPTIONS -- Example foo daemon
.Ed
.Pp
Here the service
.Cm foo
is started with
.Op Fl -n ,
to make sure it runs in the foreground, and the with the options found
in the environment file. With the
.Cm ps
command we can see that the process is started with:
.Bd -unfilled -offset indent
foo -n --extra-arg=bar -s -x
.Ed
.Pp
.Sy Note:
the leading `-` determines if Finit should treat a missing environment
file as blocking the start of the service or not. When `-` is used, a
missing environment file does
.Em not
block the start.
.Sh SERVICE WRAPPER SCRIPTS
If your service requires to run additional commands, executed before the
service is actually started, like the systemd `ExecStartPre`, you can
use a wrapper shell script to start your service.
.Pp
The Finit service
.Cm .conf
file can be put into
.Pa /etc/finit.d/available ,
so you can control the service using
.Cm initctl .
Then use the path to the wrapper script in the Finit
.Cm .conf
service stanza. The following example employs a wrapper script in
.Pa /etc/start.d .
.Bd -unfilled
/etc/finit.d/available/program.conf:
service [235] <!> /etc/start.d/program -- Example Program
/etc/start.d/program:
#!/bin/sh
# Prepare the command line options
OPTIONS="-u $(cat /etc/username)"
# Execute the program
exec /usr/bin/program $OPTIONS
.Ed
.Pp
.Sy Note:
the example sets
.Cm <!>
to denote that it doesn't support SIGHUP. That way Finit will
stop/start the service instead of sending SIGHUP at restart/reload
events.
.Sh TEMPLATING
Finit comes with rudimentary support for templating, similar to that of
systemd. Best illustrated with an example:
.Bd -unfilled -offset indent
$ initctl show avahi-autoipd@
service :%i avahi-autoipd --syslog %i -- ZeroConf for %i
.Ed
.Pp
To enable ZeroConf for, e.g.,
.Cm eth0 ,
use
.Bd -unfilled -offset indent
$ initctl enable avahi-autoipd@eth0.conf
.Ed
.Pp
The enabled symlink will be set up to
.Cm avahi-autoipd@.conf
and every instance of
.Cm %i
will in the instantiated directive be replaced with
.Cm eth0 .
Inspect the result with:
.Bd -unfilled -offset indent
$ initctl status avahi-autoipd:eth0
.Ed
.Sh CGROUPS
There are three major cgroup configuration directives:
.Pp
.Bl -enum -offset indent -compact
.It
Global top-level group: init, system, user, or a custom group
.It
Selecting a top-level group for a set of run/task/services
.It
Per run/task/service limits
.El
.Pp
Top-level group configuration.
.Bd -unfilled -offset indent
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
cgroup init cpu.weight:100
cgroup user cpu.weight:100
cgroup system cpu.weight:9800
.Ed
.Pp
Adding an extra cgroup
.Cm maint/
will require you to adjust the weight of the above three. We leave
.Cm init/
and
.Cm user/
as-is reducing weight of
.Cm system/
to 9700.
.Bd -unfilled -offset indent
cgroup system cpu.weight:9700
# Example extra cgroup 'maint'
cgroup maint cpu.weight:100
.Ed
.Pp
By default, the
.Cm system/
cgroup is selected for almost everything. The
.Cm init/
cgroup is reserved for PID 1 itself and its closest relatives. The
.Cm user/
cgroup is for local TTY logins spawned by getty.
.Pp
To select a different top-level cgroup, e.g.
.Cm maint/ ,
one can either define it for a group of run/task/service directives in a
.Cm .conf
or per each stanza:
.Bd -unfilled -offset indent
cgroup.maint
service [...] <...> /path/to/foo args -- description
service [...] <...> /path/to/bar args -- description
.Ed
.Pp
or
.Bd -unfilled -offset indent
service [...] <...> cgroup.maint /path/to/foo args -- description
.Ed
.Pp
The latter form also allows per-stanza limits on the form:
.Bd -unfilled -offset indent
service [...] <...> cgroup.maint:cpu.max:10000,mem.max:655360 /path/to/foo args -- description
.Ed
.Pp
Notice the comma separation and the
.Cm mem.
exception to the rule: every cgroup setting maps directly to cgroup v2
syntax. I.e.,
.Cm cpu.max
maps to the file
.Pm /sys/fs/cgroup/maint/foo/cpu.max .
There is no filtering, except for expanding the shorthand
.Cm mem.
to
.Cm memory. ,
if the file is not available, either the cgroup controller is not
available in your Linux kernel, or the name is misspelled.
.Pp
Linux cgroups and details surrounding values are not explained in the
Finit documentation. The Linux admin-guide cover this well:
.Lk https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
.Sh LIMITATIONS
As of Finit v4 there are no limitations to where
.Cm .conf
settings can be placed. Except for the system/global
.Cm rlimit
and
.Cm cgroup
top-level group declarations, which can only be set from
.Pa /etc/finit.conf ,
since it is the first
.Cm .conf
file Finit reads.
.Pp
Originally,
.Pp /etc/finit.conf
was the only way to set up a Finit system. Today it is mainly used for
bootstrap settings like system hostname, early module loading for
watchdogd, network bringup and system shutdown. These can now also be
set in any
.Cm .conf
file in
.Pa /etc/finit.d .
.Pp
There is, however, nothing preventing you from having all configuration
settings in
.Pa /etc/finit.conf .
.Sh SEE ALSO
.Xr finit 8 ,
.Xr initctl 8
.Sh AUTHORS
.Nm Finit
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
maintained by Joachim Wiberg, with contributions by many others.
+277
View File
@@ -0,0 +1,277 @@
.\" Hey, EMACS: -*- nroff -*-
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.Dd June 6, 2021
.\" Please adjust this date whenever revising the manpage.
.Dt INITCTL 8 SMM
.Os Linux
.Sh NAME
.Nm initctl
.Nd Control tool for Finit
.Sh SYNOPSIS
.Nm /sbin/initctl
.Op Fl bcfhjlpqtvV
.Op COMMAND
.Sh DESCRIPTION
.Nm
is the official tool for interacting with
.Xr finit 8 .
It comes with functions for showing status, querying health of services,
as well as editing, enabling and disabling services.
.Sh OPTIONS
This program follows the usual UNIX command line syntax, with long
options starting with two dashes (`-'). The options are as follows:
.Bl -tag -width Ds
.It Fl b, -batch
Batch mode, no screen size probing. Useful for scripting.
.It Fl c, -create
Create missing paths (and files) as needed. Useful with the
.Cm edit
command.
.It Fl f, -force
Ignore missing files and arguments, never prompt.
.It Fl h, -help
Show built-in help text.
.It Fl j, -json
JSON output in
.Ar status
and
.Ar cond
commands.
.It Fl n, -noerr
When scripting
.Nm
to stop, start, restart, or signal a task or service, this option can be
used to ignore error 69 (no such task or service) and instead return 0
(OK).
.It Fl 1, -once
Only one lap in commands like top.
.It Fl p, -plain
Use plain table headings, no ANSI control characters.
.It Fl q, -quiet
Silent, only return status of command.
.It Fl t, -no-heading
Skip table headings.
.It Fl v, -verbose
Verbose output, where applicable.
.It Fl V, -version
Show program version.
.El
.Sh COMMANDS
.Bl -tag -width Ds
.It Nm Ar debug
Toggle
.Nm finit
(daemon) debug to
.Pa /dev/console
.It Nm Ar help
Show built-in help text.
.It Nm Ar version
Show program version.
.It Nm Ar ls | list
List all
.Cm *.conf
files in
.Pa /etc/finit.d
.It Nm Ar create Ar CONF
Create
.Cm .conf
in
.Pa /etc/finit.d/available .
.Pp
Piping the contents into
.Nm
works as one would expect:
.Bd -literal -offset indent
echo "task name:foo /tmp/foo.sh -- Foo logger" | initctl create foo
initctl enable foo
initctl reload
.Ed
.It Nm Ar delete Ar CONF
Delete
.Cm .conf
in
.Pa /etc/finit.d/available
.It Nm Ar show Ar CONF
Show
.Cm .conf
in
.Pa /etc/finit.d/available
.It Nm Ar edit Ar CONF
Edit
.Cm .conf
in
.Pa /etc/finit.d/available
.It Nm Ar touch Ar CONF
Change (mark as modified)
.Cm .conf
in
.Pa /etc/finit.d/available ,
like
.Ar edit
this tells
.Nm finit
that a configuration has been changed and is a candidate to be restarted
(or SIGHUP'ed) on
.Cm initctl reload
.It Nm Ar enable Ar CONF
Enable
.Cm .conf
in
.Pa /etc/finit.d/available ,
i.e., add symlink in
.Pa /etc/finit.d/enabled
.It Nm Ar disable Ar CONF
Disable
.Cm .conf
in
.Pa /etc/finit.d/enabled ,
i.e., removes symlink.
.It Nm Ar reload
Reload
.Cm *.conf in
.Pa /etc/finit.d ,
i.e., activates changes.
.It Nm Ar cond set Ar COND Op COND ...
Set (assert) user-defined condition,
.Cm +usr/COND
.It Nm Ar cond get Ar COND
Get (quietly) the status of any condition. Defaults to user-defined
condions, but if a slash is detected, e.g.,
.Cm pid/foo
or
.Cm net/eth0/exist ,
then any condition can be read.
.Pp
The command is geared for scripting, check the exit code to get the
status of the condition: 0 - on, 1 - off, 255 - flux. For a more
verbose output, use the
.Fl v
option.
.It Nm Ar cond clr | clear Ar COND Op COND ...
Clear (deassert) user-defined condition,
.Cm -usr/COND
.It Nm Ar cond status
Show condition status, default
.Cm cond
command. Also supports the
.Fl j
option for detailed JSON output.
.It Nm Ar cond dump Op Cm TYPE
Dump all, or a given type of, conditions and their status. Also
supports the
.Fl j
option for detailed JSON output.
.It Nm Ar ident Op Cm NAME
Display indentities of all run/task/services, or only instances
matching
.Cm NAME .
A partial string, e.g.,
.Cm NAM ,
will not match anything.
.It Nm Ar log Op Cm NAME
Show ten last Finit, or
.Cm NAME ,
messages from syslog.
.It Nm Ar start Cm NAME[:ID]
Start service by name, with optional ID, e.g.,
.Cm initctl start tty:1
.It Nm Ar stop Cm NAME[:ID]
Stop/Pause a running service by name.
.It Nm Ar reload Cm NAME[:ID]
Reload service as if its configuration had changed. Internally,
.Nm finit
marks the named service as "dirty" and turns the state machine,
resulting in a SIGHUP or restart of (at least) the named service.
Any dependant services are also restarted.
.Pp
.Sy Note:
no .conf file is reloaded with this variant of the command. Essentially
it is the same as calling
.Cm restart .
Except for two things:
.Bl -enum -offset indent -compact
.It
if the service supports HUP, it's signaled instead of stop-started, and
.It
it allows restarting run/task in the same runlevel -- which is otherwise
restricted.
.El
.It Nm Ar signal Cm NAME:[ID] S
Send signal S to service, by name.
.Cm S
may be a complete signal name such as SIGHUP, or short name such as HUP, or the signal number such as 1 (SIGHUP).
.It Nm Ar restart Cm NAME[:ID]
Restart (stop/start) service by name.
.It Nm Ar status Cm NAME[:ID]
Show service status, by name. If only
.Cm NAME
is given and multiple instances exits, a summary of all matching
instances are shown. Only an exact match displays detailed status
for a given instance.
.Pp
With the
.Fl q
option this command is silent, provided the
.Ar NAME[:ID]
selection matches a single run/task/service. The exit code of
.Nm
is non-zero if there is a problem. Zero is returned if a run/task has
run (at least) once in the current runlevel, and when a service is running
(as expected). See the
.Fl j
option for detailed JSON output suitable for machine parsing.
.Pp
.Sy Tip:
.Xr jq 1
is a useful scripting tool in combination with JSON output.
.It Nm Ar status
Show status of all services, default command. Also supports the
.Fl j
option for detailed JSON output.
.It Nm Ar cgroup
List cgroup config overview.
.It Nm Ar ps
List processes based on cgroups.
.It Nm Ar top
Show top-like listing based on cgroups.
.It Nm Ar plugins
List installed plugins.
.It Nm Ar runlevel Op Ar 0-9
Show or set runlevel: 0 halt, 6 reboot.
.Pp
If called at boot (runlevel S) to set the runlevel, Finit only schedules
the change, effectively overriding the configured runlevel from
.Pa /etc/finit.conf .
Useful to trigger a fail-safe mode, or similar.
.It Nm Ar reboot
Reboot system, default if
.Cm reboot
is symlinked to
.Nm .
.It Nm Ar halt
Halt system, default if
.Cm halt
is symlinked to
.Nm .
.It Nm Ar poweroff
Power-off system, default if
.Cm poweroff
is symlinked to
.Nm .
.It Nm Ar suspend
Suspend system, default if
.Cm suspend
is symlinked to
.Nm .
.It Nm Ar utmp show
Raw dump of UTMP/WTMP db.
.El
.Sh SEE ALSO
.Xr finit.conf 5
.Xr finit 8
.Sh AUTHORS
.Nm finit
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
maintained by Joachim Wiberg, with contributions by many others.
+42 -10
View File
@@ -1,13 +1,13 @@
pkglibdir = $(plugin_path)
AM_LDFLAGS = -module -avoid-version -shared
AM_CFLAGS = -W -Wall -Wextra -Wno-unused-parameter -std=gnu99
AM_CPPFLAGS = -I$(top_srcdir)/src -U_FORTIFY_SOURCE
AM_CPPFLAGS = -I$(top_srcdir)/src
AM_CPPFLAGS += -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE -D_DEFAULT_SOURCE
AM_CPPFLAGS += $(lite_CFLAGS)
AM_CPPFLAGS += -D__FINIT__ $(lite_CFLAGS) $(uev_CFLAGS)
if STATIC
noinst_LTLIBRARIES = libplug.la
libplug_la_SOURCES = bootmisc.c modprobe.c rtc.c pidfile.c procps.c tty.c urandom.c usr.c
libplug_la_SOURCES = bootmisc.c pidfile.c procps.c sys.c usr.c
if BUILD_ALSA_UTILS_PLUGIN
libplug_la_SOURCES += alsa-utils.c
@@ -17,14 +17,14 @@ if BUILD_DBUS_PLUGIN
libplug_la_SOURCES += dbus.c
endif
if BUILD_HOTPLUG_PLUGIN
libplug_la_SOURCES += hotplug.c
endif
if BUILD_MODULES_LOAD_PLUGIN
libplug_la_SOURCES += modules-load.c
endif
if BUILD_MODPROBE_PLUGIN
libplug_la_SOURCES += modprobe.c
endif
if BUILD_NETLINK_PLUGIN
libplug_la_SOURCES += netlink.c
endif
@@ -33,8 +33,24 @@ if BUILD_RESOLVCONF_PLUGIN
libplug_la_SOURCES += resolvconf.c
endif
if BUILD_RTC_PLUGIN
libplug_la_SOURCES += rtc.c
endif
if BUILD_TTY_PLUGIN
libplug_la_SOURCES += tty.c
endif
if BUILD_URANDOM_PLUGIN
libplug_la_SOURCES += urandom.c
endif
if BUILD_X11_COMMON_PLUGIN
libplug_la_SOURCES += x11-common.c
endif
else
pkglib_LTLIBRARIES = bootmisc.la modprobe.la rtc.la pidfile.la procps.la tty.la urandom.la usr.la
pkglib_LTLIBRARIES = bootmisc.la pidfile.la procps.la sys.la usr.la
if BUILD_ALSA_UTILS_PLUGIN
pkglib_LTLIBRARIES += alsa-utils.la
@@ -44,14 +60,18 @@ if BUILD_DBUS_PLUGIN
pkglib_LTLIBRARIES += dbus.la
endif
if BUILD_HOTPLUG_PLUGIN
pkglib_LTLIBRARIES += hotplug.la
if BUILD_HOOK_SCRIPTS_PLUGIN
pkglib_LTLIBRARIES += hook-scripts.la
endif
if BUILD_MODULES_LOAD_PLUGIN
pkglib_LTLIBRARIES += modules-load.la
endif
if BUILD_MODPROBE_PLUGIN
pkglib_LTLIBRARIES += modprobe.la
endif
if BUILD_NETLINK_PLUGIN
pkglib_LTLIBRARIES += netlink.la
endif
@@ -60,6 +80,18 @@ if BUILD_RESOLVCONF_PLUGIN
pkglib_LTLIBRARIES += resolvconf.la
endif
if BUILD_RTC_PLUGIN
pkglib_LTLIBRARIES += rtc.la
endif
if BUILD_TTY_PLUGIN
pkglib_LTLIBRARIES += tty.la
endif
if BUILD_URANDOM_PLUGIN
pkglib_LTLIBRARIES += urandom.la
endif
if BUILD_X11_COMMON_PLUGIN
pkglib_LTLIBRARIES += x11-common.la
endif
+19 -4
View File
@@ -1,6 +1,6 @@
/* Save and restore ALSA sound settings using alsactl
*
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2012-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,7 +21,12 @@
* THE SOFTWARE.
*/
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
@@ -30,16 +35,26 @@
static void save(void *arg)
{
if (rescue) {
dbg("Skipping %s plugin in rescue mode.", __FILE__);
return;
}
if (whichp(ALSACTL)) {
_d("Saving sound settings ...");
dbg("Saving sound settings ...");
run_interactive(ALSACTL " -g store", "Saving sound settings");
}
}
static void restore(void *arg)
{
if (rescue) {
dbg("Skipping %s plugin in rescue mode.", __FILE__);
return;
}
if (whichp(ALSACTL)) {
_d("Restoring sound settings ...");
dbg("Restoring sound settings ...");
run_interactive(ALSACTL " -g restore", "Restoring sound settings");
}
}
+59 -74
View File
@@ -1,6 +1,6 @@
/* Setup necessary system files for, e.g. UTMP (tracking logins)
*
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2012-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,24 +21,35 @@
* THE SOFTWARE.
*/
#include "config.h" /* Generated by configure script */
#include <ftw.h>
#ifdef HAVE_MNTENT_H
#include <mntent.h>
#endif
#include <string.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "config.h"
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
#include "tmpfiles.h"
#include "util.h"
#include "utmp-api.h"
static int is_tmpfs(char *path)
{
struct mntent mount;
struct mntent *mnt;
char buf[256];
int tmpfs = 0;
FILE *fp;
char *dir;
struct mntent *mnt;
/* If path is a symlink, check what it resolves to */
dir = realpath(path, NULL);
@@ -51,7 +62,7 @@ static int is_tmpfs(char *path)
return 0; /* Dunno, maybe not */
}
while ((mnt = getmntent(fp))) {
while ((mnt = getmntent_r(fp, &mount, buf, sizeof(buf)))) {
if (!strcmp(dir, mnt->mnt_dir))
break;
}
@@ -70,7 +81,7 @@ static int bootclean(const char *fpath, const struct stat *sb, int tflag, struct
if (ftw->level == 0)
return 1;
_d("Removing %s ...", fpath);
dbg("Removing %s ...", fpath);
(void)remove(fpath);
return 0;
@@ -100,6 +111,45 @@ static void clean(void *arg)
}
}
/* Kernel defines the following compulsory and recommended links
* https://github.com/torvalds/linux/blob/v5.18/Documentation/admin-guide/devices.rst#compulsory-links
*/
static void kernel_links(void)
{
struct {
char *tgt, *lnk;
int optional;
} k[] = {
{ "/proc/self/fd", "/dev/fd", 0 },
{ "fd/0", "/dev/stdin", 0 },
{ "fd/1", "/dev/stdout", 0 },
{ "fd/2", "/dev/stderr", 0 },
{ "socksys", "/dev/nfsd", 0 },
{ "null", "/dev/X0R", 0 },
{ "/proc/kcore", "/dev/core", 1 },
{ "ram0", "/dev/ramdisk", 1 },
{ "qft0", "/dev/ftape", 1 },
{ "video0", "/dev/bttv0", 1 },
{ "radio0", "/dev/radio", 1 },
};
char *fn, buf[80];
size_t i;
for (i = 0; i < NELEMS(k); i++) {
fn = k[i].tgt;
if (k[i].optional) {
if (fn[0] != '/') {
snprintf(buf, sizeof(buf), "/dev/%s", k[i].tgt);
fn = buf;
}
if (!fexist(fn))
continue;
}
ln(k[i].tgt, k[i].lnk);
}
}
/*
* Setup standard FHS 2.3 structure in /var, and write runlevel to UTMP
*/
@@ -109,80 +159,15 @@ static void setup(void *arg)
prev = umask(0);
_d("Setting up FHS structure in /var ...");
makedir("/var/cache", 0755);
makedir("/var/db", 0755); /* _PATH_VARDB on some systems */
makedir("/var/games", 0755);
makedir("/var/lib", 0755);
makedir("/var/lib/misc", 0755); /* _PATH_VARDB on some systems */
makedir("/var/lib/alarm", 0755);
makedir("/var/lib/urandom",0755);
if (fisdir("/run")) {
_d("System with new /run tmpfs ...");
makedir("/run/lock", 1777);
symlink("/run/lock", "/var/lock");
symlink("/dev/shm", "/run/shm");
/* Kernel symlinks, e.g. /proc/self/fd -> /dev/fd */
kernel_links();
/* compat only, should really be set up by OS/dist */
symlink("/run", "/var/run");
} else {
makedir("/var/lock", 1777);
makedir("/var/run", 0755);
}
makedir("/var/log", 0755);
makedir("/var/mail", 0755);
makedir("/var/opt", 0755);
makedir("/var/spool", 0755);
makedir("/var/spool/cron", 0755);
makedir("/var/tmp", 0755);
makedir("/var/empty", 0755);
/*
* UTMP actually needs multiple db files
*/
if (has_utmp()) {
int gid;
/*
* If /etc/group or "utmp" group is missing, default to
* "root", or "wheel", group.
*/
_d("Setting up necessary UTMP files ...");
gid = getgroup("utmp");
if (gid < 0)
gid = 0;
create("/var/run/utmp", 0644, 0, gid); /* Currently logged in */
create("/var/log/wtmp", 0644, 0, gid); /* Login history */
create("/var/log/btmp", 0600, 0, gid); /* Failed logins */
create("/var/log/lastlog", 0644, 0, gid);
}
/* Create all system tmpfiles.d(5) */
tmpfilesd();
/* Set BOOT_TIME UTMP entry */
utmp_set_boot();
#ifdef TOUCH_ETC_NETWORK_RUN_IFSTATE
touch("/etc/network/run/ifstate");
#else
erase("/etc/network/run/ifstate");
#endif
_d("Setting up misc files ...");
makedir("/var/run/network",0755); /* Needed by Debian/Ubuntu ifupdown */
makedir("/var/run/lldpd", 0755); /* Needed by lldpd */
makedir("/var/run/pluto", 0755); /* Needed by Openswan */
mksubsys("/var/run/quagga", 0755, "quagga", "quagga");
mksubsys("/var/log/quagga", 0755, "quagga", "quagga");
mksubsys("/var/run/frr", 0755, "frr", "frr");
mksubsys("/var/log/frr", 0755, "frr", "frr");
makedir("/var/run/sshd", 01755); /* OpenSSH */
if (!fexist("/etc/mtab"))
symlink("../proc/self/mounts", "/etc/mtab");
/* Void Linux has a uuidd that runs as uuid:uuid and needs /run/uuid */
mksubsys("/var/run/uuidd", 0755, "uuidd", "uuidd");
umask(prev);
}
+116 -26
View File
@@ -1,6 +1,6 @@
/* Setup and start system message bus, D-Bus
*
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2012-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,7 +22,11 @@
*/
#include <sys/types.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "config.h"
@@ -31,49 +35,135 @@
#include "service.h"
#include "conf.h"
#define DAEMON "dbus-daemon"
#define ARGS "--nofork --system --syslog-only"
#define DESC "D-Bus message bus daemon"
#define DBUS_DAEMON "dbus-daemon"
#define DBUS_ARGS "--nofork --system --syslog-only"
#define DBUS_DESC "D-Bus message bus daemon"
#define DAEMONUSER "messagebus"
#ifndef DBUS_DAEMONUSER
#define DBUS_DAEMONUSER "messagebus"
#endif
#ifndef DBUS_DAEMONGROUP
#define DBUS_DAEMONGROUP "messagebus"
#endif
/*
* Dumnpster diving for the D-Bus main configuration file
* where <pidfile> is defined.
*/
static char *dbus_pidfn(void)
{
char *alt[] = {
"/usr/share/dbus-1/system.conf",
"/etc/dbus-1/system.conf",
NULL
};
int i;
for (i = 0; alt[i]; i++) {
char *fn = alt[i];
char buf[256];
FILE *fp;
fp = fopen(fn, "r");
if (!fp)
continue;
fn = NULL;
while (fgets(buf, sizeof(buf), fp)) {
char *pos;
pos = strstr(buf, "<pidfile>");
if (!pos)
continue;
fn = pos + strlen("<pidfile>");
pos = strstr(fn, "</pidfile>");
if (!pos) {
fn = NULL;
break;
}
*pos = 0;
break;
}
fclose(fp);
if (fn)
return strdup(fn);
}
return NULL;
}
static void setup(void *arg)
{
char *group = DBUS_DAEMONGROUP;
char *user = DBUS_DAEMONUSER;
char line[256];
char *pidfn;
mode_t prev;
char *cmd;
cmd = which(DAEMON);
if (!cmd) {
_d("Skipping plugin, %s is not installed.", DAEMON);
if (rescue) {
dbg("Skipping %s plugin in rescue mode.", __FILE__);
return;
}
prev =umask(0);
cmd = which(DBUS_DAEMON);
if (!cmd) {
dbg("Skipping plugin, %s is not installed.", DBUS_DAEMON);
return;
}
mksubsys("/var/run/dbus", 0755, DAEMONUSER, DAEMONUSER);
if (whichp("dbus-uuidgen"))
run_interactive("dbus-uuidgen --ensure", "Creating machine UUID for D-Bus");
if (getuser(user, NULL) == -1) {
if (getuser("dbus", NULL) == -1)
user = "root"; /* fallback */
else
user = "dbus"; /* e.g., Buildroot */
}
if (getgroup(group) == -1) {
if (getgroup("dbus") == -1)
group = "root"; /* fallback */
else
group = "dbus"; /* e.g., Buildroot */
}
/* Clean up from any previous pre-bootstrap run */
remove("/var/run/dbus/pid");
/* Register service with Finit */
snprintf(line, sizeof(line), "[S12345789] @%s:%s %s %s -- %s",
DAEMONUSER, DAEMONUSER, cmd, ARGS, DESC);
if (service_register(SVC_TYPE_SERVICE, line, global_rlimit, NULL))
_pe("Failed registering %s", DAEMON);
free(cmd);
pidfn = dbus_pidfn();
if (pidfn)
remove(pidfn);
dbg("Creating D-Bus Required Directories ...");
prev = umask(0);
mksubsys("/var/run/dbus", 0755, user, group);
mksubsys("/var/run/lock/subsys", 0755, user, group);
mksubsys("/var/lib/dbus", 0755, user, group);
mksubsys("/tmp/dbus", 0755, user, group);
umask(prev);
/* Generate machine id for dbus */
if (whichp("dbus-uuidgen"))
run_interactive("dbus-uuidgen --ensure", "Verifying D-Bus machine UUID");
/*
* Register service with Finit
* Note: dbus drops privs after starting up.
*/
if (pidfn) {
snprintf(line, sizeof(line), "[S123456789] cgroup.system notify:none name:dbus pid:!%s %s %s -- %s",
pidfn, cmd, DBUS_ARGS, DBUS_DESC);
free(pidfn);
} else
snprintf(line, sizeof(line), "[S123456789] cgroup.system notify:none name:dbus %s %s -- %s",
cmd, DBUS_ARGS, DBUS_DESC);
conf_save_service(SVC_TYPE_SERVICE, line, "dbus.conf");
free(cmd);
}
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_BASEFS_UP] = {
.cb = setup
},
.depends = { "bootmisc", },
.name = __FILE__,
.hook[HOOK_SVC_PLUGIN] = { .cb = setup },
};
PLUGIN_INIT(plugin_init)
+117
View File
@@ -0,0 +1,117 @@
/* Trigger scripts to run from finit's hooks
*
* Copyright (c) 2022 Tobias Waldekranz <tobias@waldekranz.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
#include "config.h"
extern void plugin_script_run(hook_point_t no);
static void hscript_run_parts(hook_point_t no)
{
plugin_script_run(no);
}
static void hscript_banner(void *arg)
{
hscript_run_parts(HOOK_BANNER);
}
static void hscript_rootfs_up(void *arg)
{
hscript_run_parts(HOOK_ROOTFS_UP);
}
static void hscript_mount_error(void *arg)
{
hscript_run_parts(HOOK_MOUNT_ERROR);
}
static void hscript_mount_post(void *arg)
{
hscript_run_parts(HOOK_MOUNT_POST);
}
static void hscript_basefs_up(void *arg)
{
hscript_run_parts(HOOK_BASEFS_UP);
}
static void hscript_network_up(void *arg)
{
hscript_run_parts(HOOK_NETWORK_UP);
}
static void hscript_svc_up(void *arg)
{
hscript_run_parts(HOOK_SVC_UP);
}
static void hscript_system_up(void *arg)
{
hscript_run_parts(HOOK_SYSTEM_UP);
}
static void hscript_shutdown(void *arg)
{
hscript_run_parts(HOOK_SHUTDOWN);
}
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_BANNER] = { .cb = hscript_banner },
.hook[HOOK_ROOTFS_UP] = { .cb = hscript_rootfs_up },
.hook[HOOK_MOUNT_ERROR] = { .cb = hscript_mount_error },
.hook[HOOK_MOUNT_POST] = { .cb = hscript_mount_post },
.hook[HOOK_BASEFS_UP] = { .cb = hscript_basefs_up },
.hook[HOOK_NETWORK_UP] = { .cb = hscript_network_up },
.hook[HOOK_SVC_UP] = { .cb = hscript_svc_up },
.hook[HOOK_SYSTEM_UP] = { .cb = hscript_system_up },
.hook[HOOK_SHUTDOWN] = { .cb = hscript_shutdown },
/*
* We have exited here, so these are handled a bit differently by Finit,
* when hook scripts are enabled, just to provide the user with the same
* interface:
*
* .hook[HOOK_SVC_DN] = { .cb = hscript_svc_down },
* .hook[HOOK_SYS_DN] = { .cb = hscript_system_down },
*/
};
PLUGIN_INIT(plugin_init)
{
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
/**
* Local Variables:
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
-111
View File
@@ -1,111 +0,0 @@
/* Heuristically find and initialize a suitable hotplug daemon
*
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include "config.h"
#include "conf.h"
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
#include "service.h"
static void setup(void *arg)
{
char cmd[256];
char *path;
/*
* Populate /dev and prepare for runtime events from kernel.
* Prefer udev if mdev is also available on the system.
*/
path = which("udevd");
if (!path)
path = which("/lib/systemd/systemd-udevd");
if (path) {
/* Register udevd as a monitored service */
snprintf(cmd, sizeof(cmd), "[S12345789] pid:udevd name:udevd log %s "
"-- Device event managing daemon", path);
if (service_register(SVC_TYPE_SERVICE, cmd, global_rlimit, NULL)) {
_pe("Failed registering %s", path);
} else {
snprintf(cmd, sizeof(cmd), ":1 [S] <pid/udevd> log "
"udevadm trigger -c add -t devices "
"-- Requesting device events");
service_register(SVC_TYPE_RUN, cmd, global_rlimit, NULL);
snprintf(cmd, sizeof(cmd), ":2 [S] <pid/udevd> log "
"udevadm trigger -c add -t subsystems "
"-- Requesting subsystem events");
service_register(SVC_TYPE_RUN, cmd, global_rlimit, NULL);
}
free(path);
/* Debian has this little script to copy generated
* rules while the system was read-only. TODO: When
* this functionality was hardcoded in finit.c, this
* call was made in crank_worker(). Now that
* filesystems are mounted earlier we should be able
* to make this call directly after the triggers have
* run, but this has not been tested AT ALL. */
if (fexist("/lib/udev/udev-finish"))
run_interactive("/lib/udev/udev-finish", "Finalizing udev");
} else {
path = which("mdev");
if (path) {
/* Embedded Linux systems usually have BusyBox mdev */
if (debug)
touch("/dev/mdev.log");
snprintf(cmd, sizeof(cmd), "%s -s", path);
free(path);
run_interactive(cmd, "Populating device tree");
}
}
}
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_BASEFS_UP] = {
.cb = setup
},
.depends = { "bootmisc" },
};
PLUGIN_INIT(plugin_init)
{
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
/**
* Local Variables:
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+78 -15
View File
@@ -1,6 +1,6 @@
/* Coldplug modules using modalias magic
*
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2021-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -40,11 +40,15 @@
#include <sys/stat.h>
#include <sys/time.h> /* gettimeofday() */
#include <sys/types.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "config.h"
#include "finit.h"
#include "helpers.h"
#include "util.h"
#include "plugin.h"
struct module {
@@ -67,14 +71,14 @@ static int modprobe(char *alias)
pid = fork();
switch (pid) {
case -1:
_pe("Failed forking modprobe child");
err(1, "Failed forking modprobe child");
return 1;
case 0:
execvp(args[0], args);
break;
default:
if (!complete(args[0], pid))
_d("Successful modprobe of %s", alias);
dbg("Successful modprobe of %s", alias);
break;
}
@@ -102,7 +106,7 @@ static void alias_remove(struct module *m)
TAILQ_REMOVE(&modules, m, link);
free(m->alias);
free(m);
}
}
static int alias_exist(char *alias)
{
@@ -116,27 +120,86 @@ static int alias_exist(char *alias)
return 0;
}
static int scan_alias(const char *path, const struct stat *st, int flag, struct FTW *unused)
static void alias_add_uniq(char *alias)
{
if (alias_exist(alias))
return;
alias_add(alias);
}
static FILE *maybe_fopen_alias(const char *file, const char *path)
{
const char *basename;
basename = basenm(path);
if (!strcmp(basename, path))
return NULL;
if (strcmp(file, basename))
return NULL;
return fopen(path, "r");
}
static int scan_modalias(const char *path)
{
FILE *fp;
char buf[256];
FILE *fp;
if (fnmatch("*/modalias", path, 0))
return 0;
fp = fopen(path, "r");
fp = maybe_fopen_alias("modalias", path);
if (!fp)
return 0;
return 1;
if (fgets(buf, sizeof(buf), fp)) {
chomp(buf);
if (!alias_exist(buf))
alias_add(buf);
alias_add_uniq(buf);
}
fclose(fp);
return 0;
}
static int scan_uevent(const char *path)
{
char buf[256];
FILE *fp;
fp = maybe_fopen_alias("uevent", path);
if (!fp)
return 1;
while (fgets(buf, sizeof(buf), fp)) {
if (strstr(buf, "MODALIAS=") != buf)
continue;
chomp(buf);
alias_add_uniq(buf + strlen("MODALIAS="));
break;
}
fclose(fp);
return 0;
}
static int scan_alias(const char *path, const struct stat *st,
int flag, struct FTW *unused)
{
/* Sanity check: is this a regular file we can read? */
if (!(S_ISREG(st->st_mode) && (st->st_mode & S_IRUSR)))
return 0;
if (!scan_uevent(path))
return 0;
scan_modalias(path);
return 0;
}
static void coldplug(void *arg)
{
struct module *m, *tmp;
+169 -44
View File
@@ -21,10 +21,37 @@
* THE SOFTWARE.
*/
#include <lite/lite.h>
/*
* This plugin scans files in /etc/modules-load.d/, for each line in the
* file it assumes the name of a kernel module, with optional arguments.
* Each module is loaded when entering runlevel 2, 3, 4, or 5, using the
* modprobe tool.
*
* Loading is done by inserting a `task` stanza in Finit, ensuring all
* modules are loaded in parallel, with other modules and programs.
* Each `task` stanza is by default given the name:modprobe.module and
* indexed with `:ID`, starting with 1.
*
* Indexing can be disabled per file in /etc/modules-load.d/, anywwhere
* in a file, by putting the keyword `noindex` on a line of its own. A
* noindex command can appear anywhere in the file, and up to the point
* it is read, tasks will be indexed with an incrementing `:ID`. When
* `noindex` is read indexing is disabled and all subseequent tasks will
* not have any `:ID` at all.
*
* Please note, the :ID is there for your benefit, it ensures that tasks
* in Finit are unique. If you have two tasks with the same name and ID
* (or no ID), the last one read replaces any preceeding one!
*/
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "helpers.h"
@@ -35,60 +62,158 @@
#ifndef MODULES_LOAD_PATH
#define MODULES_LOAD_PATH "/etc/modules-load.d"
#endif
#define MODPROBE_PATH "/sbin/modprobe"
#define SERVICE_LINE \
":%d name:modprobe.%s [2345] /sbin/modprobe %s %s -- Kernel module: %s"
"cgroup.init name:modprobe.%s :%d [%s] %s %s %s --"
#define SERVICE_LINE_NOINDEX \
"cgroup.init name:modprobe.%s [%s] %s %s %s --"
static int modules_load(const char *file, int index)
{
char module_path[PATH_MAX];
char *modprobe_path;
int num = 0;
char *line;
char *lvl;
FILE *fp;
strlcpy(module_path, MODULES_LOAD_PATH "/", sizeof(module_path));
strlcat(module_path, file, sizeof(module_path));
fp = fopen(module_path, "r");
if (!fp) {
warnx("failed opening %s for reading, skipping ...", module_path);
return 0;
}
modprobe_path = strdup(MODPROBE_PATH);
if (!modprobe_path) {
fail:
warnx("failed allocating memory in modules-load plugin.");
fclose(fp);
return -1;
}
lvl = strdup("S");
if (!lvl) {
free(modprobe_path);
goto fail;
}
while ((line = fparseln(fp, NULL, NULL, NULL, 0))) {
char cmd[CMD_SIZE], *mod, *args, *set;
/*
* fparseln() skips regular UNIX comments only.
* This is for modules-load.d(5) compat.
*/
if (line[0] == ';')
goto next;
/* trim whitespace */
mod = strip_line(line);
if (!mod[0])
goto next;
/* Finit extension 'set foo bar' */
if ((set = fgetval(mod, "set", "= \t"))) {
char *val = mod;
if (!strcmp(set, "noindex")) {
index = 0;
free(set);
goto next;
}
if ((val = fgetval(set, "index", "= \t"))) {
index = atoi(val);
free(set);
free(val);
goto next;
}
if ((val = fgetval(set, "runlevel", "= \t"))) {
free(lvl);
lvl = val;
free(set);
goto next;
}
if ((val = fgetval(set, "modprobe", "= \t"))) {
if (access(val, X_OK)) {
warn("%s: cannot use %s", module_path, val);
free(set);
free(val);
free(line);
goto skip;
} else {
free(modprobe_path);
modprobe_path = val;
}
free(set);
goto next;
}
/* unknown 'set' command, ignore. */
goto next;
}
mod = strtok_r(mod, " ", &args);
if (!mod)
goto next;
if (!index)
snprintf(cmd, sizeof(cmd), SERVICE_LINE_NOINDEX, mod, lvl, modprobe_path, mod, args);
else
snprintf(cmd, sizeof(cmd), SERVICE_LINE, mod, index++, lvl, modprobe_path, mod, args);
dbg("task %s", cmd);
service_register(SVC_TYPE_TASK, cmd, global_rlimit, NULL);
num++;
next:
free(line);
}
skip:
free(modprobe_path);
free(lvl);
fclose(fp);
return num;
}
/* XXX: check here for .conf only? */
static int module_filter(const struct dirent *d)
{
if (d->d_type == DT_DIR)
return 0;
if (d->d_name[0] == '.')
return 0; /* skip dot files */
if (d->d_name[strlen(d->d_name) - 1] == '~')
return 0; /* skip backup files */
return 1;
}
static void load(void *arg)
{
FILE *fp;
DIR *dirp;
struct dirent *direntp;
char line[256];
struct dirent **dentry;
int index = 1;
int i, num;
_d("Scanning " MODULES_LOAD_PATH " for config files ...");
dirp = opendir(MODULES_LOAD_PATH);
if (!dirp) return;
while ((direntp = readdir(dirp)))
{
char module_path[PATH_MAX];
strlcpy(module_path, MODULES_LOAD_PATH "/", sizeof(module_path));
strlcat(module_path, direntp->d_name, sizeof(module_path));
fp = fopen(module_path, "r");
if (!fp) continue;
while (fgets(line, sizeof(line), fp)) {
char cmd[CMD_SIZE], *mod, *args;
mod = strip_line(line);
if (!*mod) continue;
mod = chomp(mod);
if (!mod || !*mod) continue;
mod = strtok_r(mod, " ", &args);
snprintf(cmd, sizeof(cmd), SERVICE_LINE,
index, mod, mod, args, mod);
service_register(SVC_TYPE_TASK, cmd, global_rlimit, NULL);
index++;
dbg("Scanning " MODULES_LOAD_PATH " for config files ...");
num = scandir(MODULES_LOAD_PATH, &dentry, module_filter, alphasort);
if (num > 0) {
for (i = 0; i < num; i++) {
index += modules_load(dentry[i]->d_name, index);
free(dentry[i]);
}
fclose(fp);
free(dentry);
}
closedir(dirp);
}
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_BASEFS_UP] = {
.cb = load
},
.name = __FILE__,
.hook[HOOK_SVC_PLUGIN] = { .cb = load },
};
PLUGIN_INIT(plugin_init)
+245 -57
View File
@@ -1,7 +1,8 @@
/* Netlink plugin for IFUP/IFDN and GW events
*
* Copyright (C) 2009-2011 Mårten Wikström <marten.wikstrom@keystream.se>
* Copyright (C) 2009-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (C) 2009-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -30,34 +31,38 @@
#include "cond.h"
#include "helpers.h"
#include "plugin.h"
#include "service.h"
static int nlmsg_validate(struct nlmsghdr *nh, size_t len)
{
if (!NLMSG_OK(nh, len))
return 1;
#define NL_BUFSZ 4096
if (nh->nlmsg_type == NLMSG_DONE) {
_d("Done with netlink messages.");
return 1;
}
struct nl_request {
struct nlmsghdr nh;
union {
struct rtmsg rtm;
struct ifinfomsg ifi;
};
};
if (nh->nlmsg_type == NLMSG_ERROR) {
_d("Netlink reports error.");
return 1;
}
static int nl_defidx;
static int nl_ifdown;
static char *nl_buf;
return 0;
}
static void nl_route(struct nlmsghdr *nlmsg, ssize_t len)
{
char daddr[INET_ADDRSTRLEN];
char gaddr[INET_ADDRSTRLEN];
struct in_addr ind, ing;
struct rtmsg *r;
struct rtattr *a;
int plen = 0;
int dst = 0;
int idx = 0;
int gw = 0;
int la;
int gw = 0, dst = 0, mask = 0, idx = 0;
if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg))) {
_e("Packet too small or truncated!");
errx(1, "Packet too small or truncated!");
return;
}
@@ -65,7 +70,7 @@ static void nl_route(struct nlmsghdr *nlmsg, ssize_t len)
a = RTM_RTA(r);
la = RTM_PAYLOAD(nlmsg);
if (la >= len) {
_e("Packet too large!");
errx(1, "Packet too large!");
return;
}
@@ -75,29 +80,38 @@ static void nl_route(struct nlmsghdr *nlmsg, ssize_t len)
switch (a->rta_type) {
case RTA_GATEWAY:
gw = *((int *)data);
//_d("GW: 0x%04x", gw);
//dbg("GW: 0x%04x", gw);
break;
case RTA_DST:
dst = *((int *)data);
mask = r->rtm_dst_len;
//_d("MASK: 0x%04x", mask);
plen = r->rtm_dst_len;
//dbg("Prefix LEN: 0x%04x", plen);
break;
case RTA_OIF:
idx = *((int *)data);
//_d("IDX: 0x%04x", idx);
//dbg("IDX: 0x%04x", idx);
break;
}
a = RTA_NEXT(a, la);
}
if ((!dst && !mask) && (gw || idx)) {
if (nlmsg->nlmsg_type == RTM_DELROUTE)
ind.s_addr = dst;
ing.s_addr = gw;
inet_ntop(AF_INET, &ind, daddr, sizeof(daddr));
inet_ntop(AF_INET, &ing, gaddr, sizeof(gaddr));
dbg("Got gw %s dst/len %s/%d ifindex %d", gaddr, daddr, plen, idx);
if ((!dst && !plen) && (gw || idx)) {
if (nlmsg->nlmsg_type == RTM_DELROUTE) {
cond_clear("net/route/default");
else
nl_defidx = 0;
} else {
cond_set("net/route/default");
nl_defidx = idx;
}
}
}
@@ -117,14 +131,14 @@ static int validate_ifname(const char *ifname)
if (!ifname || !ifname[0])
return 1;
if (strlen(ifname) >= IFNAMSIZ)
if (strnlen(ifname, IFNAMSIZ) == IFNAMSIZ)
return 1;
if (strstr(ifname, ".."))
if (!strcmp(ifname, ".") || !strcmp(ifname, ".."))
return 1;
while (*ifname) {
if (*ifname == '/' || isspace(*ifname))
if (*ifname == '/' || *ifname == ':' || isspace(*ifname))
return 1;
ifname++;
}
@@ -132,15 +146,28 @@ static int validate_ifname(const char *ifname)
return 0;
}
/*
* Check if this interface was associated with the default route
* previously, or if it's been removed. If so, trigger a recheck
* of the system default route.
*/
static void nl_check_default(char *ifname)
{
int idx = (int)if_nametoindex(ifname);
if ((nl_defidx > 0 && nl_defidx == idx) || (idx == 0 && errno == ENODEV))
nl_ifdown = 1;
}
static void nl_link(struct nlmsghdr *nlmsg, ssize_t len)
{
int la;
char ifname[IFNAMSIZ + 1];
struct rtattr *a;
struct ifinfomsg *i;
struct rtattr *a;
int la;
if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) {
_e("Packet too small or truncated!");
errx(1, "Packet too small or truncated!");
return;
}
@@ -148,7 +175,7 @@ static void nl_link(struct nlmsghdr *nlmsg, ssize_t len)
a = (struct rtattr *)((char *)i + NLMSG_ALIGN(sizeof(struct ifinfomsg)));
la = NLMSG_PAYLOAD(nlmsg, sizeof(struct ifinfomsg));
if (la >= len) {
_e("Packet too large!");
errx(1, "Packet too large!");
return;
}
@@ -158,7 +185,7 @@ static void nl_link(struct nlmsghdr *nlmsg, ssize_t len)
strlcpy(ifname, RTA_DATA(a), sizeof(ifname));
if (validate_ifname(ifname)) {
_d("Invalid interface name '%s', skipping ...", ifname);
dbg("Invalid interface name '%s', skipping ...", ifname);
continue;
}
@@ -168,55 +195,208 @@ static void nl_link(struct nlmsghdr *nlmsg, ssize_t len)
* New interface has appeared, or interface flags has changed.
* Check ifi_flags here to see if the interface is UP/DOWN
*/
_d("%s: New link, flags 0x%x, change 0x%x", ifname, i->ifi_flags, i->ifi_change);
dbg("%s: New link, flags 0x%x, change 0x%x", ifname, i->ifi_flags, i->ifi_change);
net_cond_set(ifname, "exist", 1);
net_cond_set(ifname, "up", i->ifi_flags & IFF_UP);
net_cond_set(ifname, "running", i->ifi_flags & IFF_RUNNING);
if (!(i->ifi_flags & IFF_UP) || !(i->ifi_flags & IFF_RUNNING))
nl_check_default(ifname);
break;
case RTM_DELLINK:
/* NOTE: Interface has disappeared, not link down ... */
_d("%s: Delete link", ifname);
dbg("%s: Delete link", ifname);
net_cond_set(ifname, "exist", 0);
net_cond_set(ifname, "up", 0);
net_cond_set(ifname, "running", 0);
nl_check_default(ifname);
break;
case RTM_NEWADDR:
_d("%s: New Address", ifname);
dbg("%s: New Address", ifname);
break;
case RTM_DELADDR:
_d("%s: Deconfig Address", ifname);
dbg("%s: Deconfig Address", ifname);
break;
default:
_d("%s: Msg 0x%x", ifname, nlmsg->nlmsg_type);
dbg("%s: Msg 0x%x", ifname, nlmsg->nlmsg_type);
break;
}
}
}
static void nl_callback(void *arg, int sd, int events)
static int nl_parse(int sd)
{
static char buf[4096];
struct nlmsghdr *nh;
ssize_t len;
while (1) {
struct nlmsghdr *nh;
ssize_t len;
size_t l;
memset(buf, 0, sizeof(buf));
len = recv(sd, buf, sizeof(buf), 0);
if (len < 0) {
if (errno != EINTR) /* Signal */
_pe("recv()");
while ((len = recv(sd, nl_buf, NL_BUFSZ, 0)) < 0) {
switch (errno) {
case EAGAIN: /* Nothing more right now. */
return 0;
case EINTR: /* Signal */
continue;
case ENOBUFS: /* netlink(7) */
break;
default:
err(1, "recv()");
break;
}
return -1;
}
// dbg("recv %zd bytes", len);
l = (size_t)len;
for (nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, l); nh = NLMSG_NEXT(nh, l)) {
struct nlmsgerr *nle;
switch (nh->nlmsg_type) {
case NLMSG_DONE:
// dbg("Done with netlink messages.");
return 0;
case NLMSG_ERROR:
// dbg("Kernel netlink comm. error.");
nle = NLMSG_DATA(nh);
if (nle) {
errno = -nle->error;
err(1, "Kernel netlink error %d", errno);
}
return -1;
case RTM_NEWROUTE:
case RTM_DELROUTE:
// dbg("Netlink route ...");
nl_route(nh, len);
break;
case RTM_NEWLINK:
case RTM_DELLINK:
// dbg("Netlink link ...");
nl_link(nh, len);
break;
default:
warnx("unhandled netlink message, type %d", nh->nlmsg_type);
break;
}
}
}
}
static int nl_request(int sd, unsigned int seq, int type)
{
struct nl_request *nlr = (struct nl_request *)nl_buf;
memset(nlr, 0, sizeof(struct nl_request));
nlr->nh.nlmsg_type = type;
nlr->nh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
nlr->nh.nlmsg_seq = seq;
nlr->nh.nlmsg_pid = 1;
switch (type) {
case RTM_GETROUTE:
// dbg("RTM_GETROUTE");
nlr->rtm.rtm_family = AF_INET;
nlr->rtm.rtm_table = RT_TABLE_MAIN;
nlr->nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
break;
case RTM_GETLINK:
// dbg("RTM_GETLINK");
nlr->ifi.ifi_family = AF_UNSPEC;
nlr->ifi.ifi_change = 0xFFFFFFFF;
nlr->nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
break;
default:
warnx("Cannot resync, unhandled message type %d", type);
return -1;
}
if (send(sd, nlr, nlr->nh.nlmsg_len, 0) < 0)
return 1;
return nl_parse(sd);
}
static void nl_resync_routes(int sd, unsigned int seq)
{
if (nl_request(sd, seq, RTM_GETROUTE))
err(1, "Failed netlink route request");
}
static void nl_resync_ifaces(int sd, unsigned int seq)
{
if (nl_request(sd, seq, RTM_GETLINK))
err(1, "Failed netlink link request");
}
/*
* We've potentially lost netlink events, let's resync with kernel.
*/
static void nl_resync(int all)
{
unsigned int seq = 0;
int sd;
sd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
if (sd < 0) {
err(1, "netlink socket");
return;
}
for (nh = (struct nlmsghdr *)buf; !nlmsg_validate(nh, len); nh = NLMSG_NEXT(nh, len)) {
//_d("Well formed netlink message received. type %d ...", nh->nlmsg_type);
if (nh->nlmsg_type == RTM_NEWROUTE || nh->nlmsg_type == RTM_DELROUTE)
nl_route(nh, len);
else
nl_link(nh, len);
if (all) {
dbg("============================ RESYNC =================================");
/* this doesn't update conditions, and thus does not stop services */
cond_deassert("net/");
nl_resync_ifaces(sd, seq++);
nl_resync_routes(sd, seq++);
/* delayed update after we've corrected things */
service_step_all(SVC_TYPE_ANY);
dbg("=========================== RESYNCED ================================");
} else
nl_resync_routes(sd, seq++);
close(sd);
}
static void nl_callback(void *arg, int sd, int events)
{
if (nl_parse(sd) < 0) {
if (errno == ENOBUFS) { /* netlink(7) */
warnx("busy system, resynchronizing with kernel.");
nl_resync(1);
return;
}
}
/*
* Linux doesn't send route changes when interfaces go down, so
* we need to check ourselves, e.g. for loss of default route.
*/
if (nl_ifdown) {
dbg("interface down, checking default route.");
if (nl_defidx > 0) {
nl_defidx = 0;
nl_resync(0);
if (nl_defidx <= 0) {
cond_clear("net/route/default");
nl_defidx = 0;
}
}
nl_ifdown = 0;
}
}
@@ -236,22 +416,29 @@ static plugin_t plugin = {
PLUGIN_INIT(plugin_init)
{
int sd;
struct sockaddr_nl sa;
int sd;
sd = socket(AF_NETLINK, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, NETLINK_ROUTE);
if (sd < 0) {
_pe("socket()");
err(1, "socket()");
return;
}
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
sa.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_LINK; // | RTMGRP_NOTIFY | RTMGRP_IPV4_IFADDR;
sa.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_LINK;
sa.nl_pid = getpid();
if (bind(sd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
_pe("bind()");
err(1, "bind()");
close(sd);
return;
}
nl_buf = malloc(NL_BUFSZ);
if (!nl_buf) {
err(1, "malloc()");
close(sd);
return;
}
@@ -263,6 +450,7 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
close(plugin.io.fd);
}
/**
+63 -28
View File
@@ -1,7 +1,7 @@
/* Simple pidfile event monitor for the Finit condition engine
*
* Copyright (c) 2015-2016 Tobias Waldekranz <tobias@waldekranz.com>
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2016-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -52,7 +52,7 @@ static int pidfile_add_path(struct iwatch *iw, char *path)
ptr = slash++;
slash = strchr(ptr, '/');
if (slash) {
_d("Path too deep, skipping.");
dbg("Path too deep, skipping %s", path);
return -1;
}
}
@@ -66,46 +66,78 @@ static void pidfile_update_conds(char *dir, char *name, uint32_t mask)
char cond[MAX_COND_LEN];
char fn[PATH_MAX];
svc_t *svc;
char *nm;
paste(fn, sizeof(fn), dir, name);
if (fnmatch("*\\.pid", fn, 0) && fnmatch("*/pid", fn, 0))
return;
_d("path: %s, mask: %08x", fn, mask);
dbg("path: %s, mask: %08x", fn, mask);
svc = svc_find_by_pidfile(fn);
if (!svc) {
_d("No matching svc for %s", fn);
dbg("No matching svc for %s", fn);
return;
}
_d("Found svc %s for %s with pid %d", svc->name, fn, svc->pid);
/* Service condistion to set/clear */
mkcond(svc, cond, sizeof(cond));
nm = svc_ident(svc, NULL, 0);
dbg("Found svc %s for %s with pid %d", nm, fn, svc->pid);
if (svc_is_stopping(svc)) {
dbg("Ignoring pidfile death rattles while service %s is %s", nm, svc_status(svc));
goto sneaky_zebra;
}
if (mask & (IN_CLOSE_WRITE | IN_ATTRIB | IN_MODIFY | IN_MOVED_TO)) {
svc_started(svc);
if (!svc_has_pidfile(svc))
/*
* only mark native services as started, the s6 and
* systemd style services rely on their respective
* readiness notification. Issue #343
*/
if (svc->notify == SVC_NOTIFY_PID)
svc_started(svc);
if (!svc_has_pidfile(svc)) {
dbg("Setting %s PID file to %s", svc->name, fn);
pid_file_set(svc, fn, 1);
}
if (svc_is_forking(svc)) {
pid_t pid;
pid = pid_file_read(pid_file(svc));
pid = pid_file_read(fn);
if (pid == -1) {
cond_clear(cond);
/* handle case when service dies immediately */
if (!fexist(fn))
cond_clear(cond);
return;
}
/* Service is not crashing, let's tell state machine! */
service_forked(svc);
if (pid != svc->pid) {
_d("Forking service %s changed PID from %d to %d",
svc->cmd, svc->pid, pid);
dbg("Forking service %s (cmd %s) changed PID from %d to %d",
svc_ident(svc, NULL, 0), svc->cmd, svc->pid, pid);
svc->pid = pid;
/* Complement log in service.c for non-forking services */
logit(LOG_CONSOLE | LOG_NOTICE, "Started %s[%d]", svc_ident(svc, NULL, 0), pid);
}
}
cond_set(cond);
} else if (mask & IN_DELETE)
if (svc->notify == SVC_NOTIFY_PID)
cond_set(cond);
if (svc->notify == SVC_NOTIFY_PID || svc->notify == SVC_NOTIFY_NONE)
service_ready(svc, 1);
} else if (mask & IN_DELETE) {
sneaky_zebra:
cond_clear(cond);
if (svc->notify == SVC_NOTIFY_PID)
service_ready(svc, 0);
}
}
/* synthesize events in case of new run dirs */
@@ -127,7 +159,7 @@ static void pidfile_scandir(struct iwatch *iw, char *dir, int len)
return;
for (i = 0; i < gl.gl_pathc; i++) {
_d("scan found %s", gl.gl_pathv[i]);
dbg("scan found %s", gl.gl_pathv[i]);
pidfile_update_conds(dir, gl.gl_pathv[i], IN_CREATE);
}
globfree(&gl);
@@ -142,7 +174,7 @@ static void pidfile_handle_dir(struct iwatch *iw, char *dir, char *name, int mas
struct iwatch_path *iwp;
paste(path, sizeof(path), dir, name);
_d("path: %s", path);
dbg("path: %s", path);
iwp = iwatch_find_by_path(iw, path);
@@ -166,7 +198,7 @@ static void pidfile_callback(void *arg, int fd, int events)
sz = read(fd, ev_buf, sizeof(ev_buf) - 1);
if (sz <= 0) {
_pe("invalid inotify event");
err(1, "invalid inotify event");
return;
}
ev_buf[sz] = 0;
@@ -218,6 +250,9 @@ static void pidfile_reconf(void *arg)
if (svc_is_changed(svc) || svc_is_starting(svc))
continue;
if (svc->notify == SVC_NOTIFY_PID)
service_ready(svc, 1);
mkcond(svc, cond, sizeof(cond));
if (cond_get(cond) == COND_ON)
continue;
@@ -226,9 +261,9 @@ static void pidfile_reconf(void *arg)
}
/*
* This will call service_step(), which in turn will schedule itself
* as long as stepped services change state. Services going from
* WAITING to RUNNING will reassert their conditions in that loop,
* This calls service_step(), which in turn schedules itself as
* long as stepped services change state. Services going from
* PAUSED to RUNNING reassert their conditions in that loop,
* which in turn may unlock other services, and so on.
*/
service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_RUNTASK);
@@ -240,7 +275,7 @@ static void pidfile_init(void *arg)
char *path;
if (mkpath(pid_runpath(_PATH_CONDPID, piddir, sizeof(piddir)), 0755) && errno != EEXIST) {
_pe("Failed creating %s condition directory, %s", COND_PID, _PATH_CONDPID);
err(1, "Failed creating %s condition directory, %s", COND_PID, _PATH_CONDPID);
return;
}
@@ -251,10 +286,10 @@ static void pidfile_init(void *arg)
*/
path = realpath(_PATH_VARRUN, NULL);
if (!path) {
_d("Failed querying realpath(%s): %s", _PATH_VARRUN, strerror(errno));
dbg("Failed querying realpath(%s): %s", _PATH_VARRUN, strerror(errno));
path = realpath("/run", NULL);
if (!path) {
_e("System does not have %s or /run, aborting.", _PATH_VARRUN);
errx(1, "System does not have %s or /run, aborting.", _PATH_VARRUN);
return;
}
}
@@ -275,15 +310,15 @@ static void pidfile_init(void *arg)
*
* service <net/iface/lo> /sbin/dropbear ...
*
* Which provides the <pid/dropbear> condition, will not be set by
* pidfile.so during `initctl reload` because dropbear is still
* SIGSTP:ed waiting for <net/iface/lo>.
* This service provides the <pid/dropbear> condition, which will not be
* set by pidfile.so during `initctl reload` because dropbear is still
* SIGSTP:ed (in state PAUSED) waiting for <net/iface/lo>.
*/
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_BASEFS_UP] = { .cb = pidfile_init },
.hook[HOOK_SVC_RECONF] = { .cb = pidfile_reconf },
.depends = { "netlink" },
.depends = { "netlink" }, /* bootmisc depends on us */
};
PLUGIN_INIT(plugin_init)
@@ -303,8 +338,8 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit)
{
iwatch_exit(&iw_pidfile);
plugin_unregister(&plugin);
iwatch_exit(&iw_pidfile);
}
/**
+20 -6
View File
@@ -1,6 +1,6 @@
/* Set kernel variables from /etc/sysctl.conf et al
*
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2016-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,14 +22,24 @@
*/
#include <glob.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
static void setup(void *arg)
{
size_t i;
glob_t gl;
char buf[160];
if (rescue) {
dbg("Skipping %s plugin in rescue mode.", __FILE__);
return;
}
glob("/run/sysctl.d/*.conf", 0, NULL, &gl);
glob("/etc/sysctl.d/*.conf", GLOB_APPEND, NULL, &gl);
@@ -39,9 +49,13 @@ static void setup(void *arg)
glob("/mnt/sysctl.d/*.conf", GLOB_APPEND, NULL, &gl);
glob("/etc/sysctl.conf", GLOB_APPEND, NULL, &gl);
if (gl.gl_pathc > 0) {
size_t i;
for (i = 0; i < gl.gl_pathc; i++) {
snprintf(buf, sizeof(buf), "/sbin/sysctl -e -p %s >/dev/null", gl.gl_pathv[i]);
run(buf);
char cmd[160];
snprintf(cmd, sizeof(cmd), "/sbin/sysctl -e -p %s >/dev/null", gl.gl_pathv[i]);
run(cmd, "sysctl");
}
globfree(&gl);
}
+8 -4
View File
@@ -1,6 +1,6 @@
/* Setup necessary files for resolvconf
*
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2012-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,7 +21,11 @@
* THE SOFTWARE.
*/
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "helpers.h"
@@ -33,7 +37,7 @@
*/
static void setup(void *arg)
{
_d("Setting up the resolver ...");
dbg("Setting up the resolver ...");
mkpath("/etc/resolvconf", 0755);
mkpath("/etc/resolvconf/run", 0755);
mkpath("/var/run/resolvconf", 0755);
@@ -41,7 +45,7 @@ static void setup(void *arg)
touch("/etc/resolvconf/run/enable-updates");
chdir("/etc/resolvconf/run/interface");
run_parts("/etc/resolvconf/update.d", "-i");
run_parts("/etc/resolvconf/update.d", "-i", NULL, 0, 0);
chdir("/");
}
+208 -50
View File
@@ -1,6 +1,6 @@
/* Save and restore RTC using hwclock
*
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2012-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,17 +21,40 @@
* THE SOFTWARE.
*/
#include "config.h"
#include <time.h>
#include <sys/ioctl.h>
#include <linux/rtc.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
/* Kernel RTC driver validates against this date for sanity check */
#define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */
/*
* Kernel RTC driver validates against this date for sanity check. The
* on NTP sync the driver can also update the RTC every 11 mins. We use
* the same update interval to handle manual time set and file save.
*/
#define RTC_TIMESTAMP_BEGIN_2000 "2000-01-01 00:00:00"
#define RTC_FMT "%Y-%m-%d %H:%M:%S"
#define RTC_PERIOD (11 * 60 * 1000)
#ifdef RTC_TIMESTAMP_CUSTOM
static char *rtc_timestamp = RTC_TIMESTAMP_CUSTOM;
#else
static char *rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000;
#endif
static time_t rtc_date_fallback = 946684800LL;
static char *rtc_file = RTC_FILE;
static uev_t rtc_timer;
static void tz_set(char *tz, size_t len)
{
@@ -56,6 +79,125 @@ static void tz_restore(char *tz)
tzset();
}
static int time_set(struct tm *tm)
{
struct tm fallback = { 0 };
struct timeval tv = { 0 };
char tz[128];
int rc = 0;
tz_set(tz, sizeof(tz));
if (!tm) {
logit(LOG_NOTICE, "Resetting system clock to kernel default, %s.", rtc_timestamp);
tm = &fallback;
/* Attempt to set RTC to a sane value ... */
tv.tv_sec = rtc_date_fallback;
if (!gmtime_r(&tv.tv_sec, tm)) {
rc = 1;
goto out;
}
}
tm->tm_isdst = -1; /* Use tzdata to figure it out, please. */
tv.tv_sec = mktime(tm);
if (tv.tv_sec == (time_t)-1 || tv.tv_sec < rtc_date_fallback) {
errno = EINVAL;
rc = 2;
} else {
if (settimeofday(&tv, NULL) == -1)
rc = 1;
}
out:
tz_restore(tz);
return rc;
}
static int time_get(struct tm *tm)
{
struct timeval tv = { 0 };
char tz[128];
int rc = 0;
tz_set(tz, sizeof(tz));
rc = gettimeofday(&tv, NULL);
if (rc < 0 || tv.tv_sec < rtc_date_fallback)
rc = 2;
else
gmtime_r(&tv.tv_sec, tm);
tz_restore(tz);
return rc;
}
static void file_save(void *arg)
{
struct tm tm = { 0 };
int rc = 0;
FILE *fp;
if (!rtc_file)
return;
fp = fopen(rtc_file, "w");
if (!fp) {
logit(LOG_WARNING, "Failed saving system clock to %s, code %d: %s",
rtc_file, errno, strerror(errno));
return;
}
if ((rc = time_get(&tm))) {
logit(LOG_WARNING, "System clock invalid, before %s, not saving", rtc_timestamp);
print_desc(NULL, "System clock invalid, skipping");
} else {
char buf[32] = { 0 };
print_desc(NULL, "Saving system clock to file");
strftime(buf, sizeof(buf), RTC_FMT, &tm);
fprintf(fp, "%s\n", buf);
}
print(rc, NULL);
fclose(fp);
}
static void file_restore(void *arg)
{
struct tm tm = { 0 };
int rc = 1;
FILE *fp;
if (!rtc_file) {
logit(LOG_NOTICE, "System has no RTC (missing driver?), skipping restore.");
return;
}
print_desc(NULL, "Restoring system clock from backup");
fp = fopen(rtc_file, "r");
if (fp) {
char buf[32];
if (fgets(buf, sizeof(buf), fp)) {
chomp(buf);
strptime(buf, RTC_FMT, &tm);
rc = time_set(&tm);
}
fclose(fp);
} else
logit(LOG_WARNING, "Missing %s", rtc_file);
if (rc) {
time_set(NULL);
rc = 2;
}
print(rc, NULL);
}
static int rtc_open(void)
{
char *alt[] = {
@@ -79,102 +221,118 @@ static int rtc_open(void)
static void rtc_save(void *arg)
{
struct timeval tv = { 0 };
struct tm tm = { 0 };
int fd, rc = 0;
char tz[128];
if (rescue) {
dbg("Skipping %s plugin in rescue mode.", __FILE__);
return;
}
fd = rtc_open();
if (fd < 0)
return;
tz_set(tz, sizeof(tz));
rc = gettimeofday(&tv, NULL);
if (rc < 0 || tv.tv_sec < RTC_TIMESTAMP_BEGIN_2000) {
if ((rc = time_get(&tm))) {
print_desc(NULL, "System clock invalid, not saving to RTC");
invalid:
logit(LOG_ERR, "System clock invalid, before 2000-01-01 00:00, not saving to RTC");
} else {
print_desc(NULL, "Saving system clock (UTC) to RTC");
rc = ioctl(fd, RTC_SET_TIME, &tm);
}
if (rc && errno == EINVAL) {
logit(LOG_WARNING, "System clock invalid, before %s, not saving to RTC", rtc_timestamp);
rc = 2;
goto out;
}
print_desc(NULL, "Saving system time (UTC) to RTC");
gmtime_r(&tv.tv_sec, &tm);
if (ioctl(fd, RTC_SET_TIME, &tm) < 0) {
if (EINVAL == errno)
goto invalid;
rc = 1;
goto out;
}
out:
tz_restore(tz);
print(rc, NULL);
close(fd);
}
static void rtc_restore(void *arg)
{
struct timeval tv = { 0 };
struct tm tm = { 0 };
int fd, rc = 0;
char tz[128];
if (rescue) {
dbg("Skipping %s plugin in rescue mode.", __FILE__);
return;
}
fd = rtc_open();
if (fd < 0)
if (fd < 0) {
file_restore(arg);
return;
}
tz_set(tz, sizeof(tz));
if (ioctl(fd, RTC_RD_TIME, &tm) < 0) {
if ((rc = ioctl(fd, RTC_RD_TIME, &tm)) < 0) {
char msg[120];
snprintf(msg, sizeof(msg), "Failed restoring system clock, %s",
EINVAL == errno ? "RTC time is too old" :
ENOENT == errno ? "RTC has no saved time" : "see log for details");
print_desc(NULL, msg);
} else {
print_desc(NULL, "Restoring system clock (UTC) from RTC");
rc = time_set(&tm);
}
invalid:
logit(LOG_ERR, "Failed restoring system clock from RTC.");
if (rc) {
logit(LOG_WARNING, "Failed restoring system clock from RTC.");
if (EINVAL == errno)
logit(LOG_ERR, "RTC time is too old (before 2000-01-01 00:00)");
logit(LOG_WARNING, "RTC time is too old (before %s)", rtc_timestamp);
else if (ENOENT == errno)
logit(LOG_ERR, "RTC has no previously saved (valid) time.");
logit(LOG_WARNING, "RTC has no previously saved (valid) time.");
else
logit(LOG_ERR, "RTC error code %d: %s", errno, strerror(errno));
rc = 2;
goto out;
}
logit(LOG_WARNING, "RTC error code %d: %s", errno, strerror(errno));
print_desc(NULL, "Restoring system clock (UTC) from RTC");
tm.tm_isdst = -1; /* Use tzdata to figure it out, please. */
tv.tv_sec = mktime(&tm);
if (tv.tv_sec < RTC_TIMESTAMP_BEGIN_2000) {
errno = EINVAL;
goto invalid;
}
print(2, NULL);
if (settimeofday(&tv, NULL) == -1)
rc = 1;
/* Try restoring from last save game */
if (rtc_file)
file_restore(arg);
} else
print(0, NULL);
out:
tz_restore(tz);
print(rc, NULL);
close(fd);
}
static void save(void *arg)
{
rtc_save(arg);
file_save(arg);
}
static void update(uev_t *w, void *arg, int events)
{
save(arg);
}
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_BASEFS_UP] = {
.cb = rtc_restore
},
.hook[HOOK_SHUTDOWN] = {
.cb = rtc_save
.cb = save
}
};
PLUGIN_INIT(plugin_init)
{
struct tm tm = { 0 };
if (!strptime(rtc_timestamp, RTC_FMT, &tm)) {
logit(LOG_WARNING, "Invalid restore date '%s', reverting to '%s'",
rtc_timestamp, RTC_TIMESTAMP_BEGIN_2000);
rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000;
} else
rtc_date_fallback = mktime(&tm);
uev_timer_init(ctx, &rtc_timer, update, NULL, RTC_PERIOD, RTC_PERIOD);
plugin_register(&plugin);
}
+213
View File
@@ -0,0 +1,213 @@
/* System condition event monitor for the Finit condition engine
*
* Copyright (c) 2021-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <dirent.h>
#include <fnmatch.h>
#include <glob.h>
#include <limits.h>
#include <paths.h>
#include "finit.h"
#include "cond.h"
#include "pid.h"
#include "plugin.h"
#include "iwatch.h"
static struct iwatch iw_sys;
static int sys_add_path(struct iwatch *iw, char *path)
{
return iwatch_add(iw, path, IN_ONLYDIR | IN_CLOSE_WRITE);
}
/*
* unlink conditions with no active task/service, otherwise they may
* trigger inadvertently when calling `initctl reload` to activate
* a new configuration.
*/
static void sys_update_conds(char *dir, char *name, uint32_t mask)
{
char path[256];
char *cond;
char *ptr;
ptr = strrchr(name, '/');
if (ptr)
snprintf(path, sizeof(path), "%s/%s", dir, ++ptr);
else
snprintf(path, sizeof(path), "%s/%s", dir, name);
cond = strstr(path, COND_BASE);
if (!cond)
return;
cond += strlen(COND_BASE) + 1;
dbg("cond: %s set: %d", cond, (mask & IN_CREATE) ? 1 : 0);
if (!cond_update(cond))
unlink(path);
}
/* synthesize events in case of new run dirs */
static void sys_scandir(struct iwatch *iw, char *dir, int len)
{
glob_t gl;
size_t i;
char path[len + 6];
int rc;
snprintf(path, sizeof(path), "%s/*", dir);
rc = glob(path, GLOB_NOSORT, NULL, &gl);
if (rc && rc != GLOB_NOMATCH)
return;
for (i = 0; i < gl.gl_pathc; i++) {
dbg("scan found %s", gl.gl_pathv[i]);
sys_update_conds(dir, gl.gl_pathv[i], IN_CREATE);
}
globfree(&gl);
}
/*
* create/remove sub-directory in monitored directory
*/
static void sys_handle_dir(struct iwatch *iw, char *dir, char *name, int mask)
{
char path[strlen(dir) + strlen(name) + 2];
struct iwatch_path *iwp;
paste(path, sizeof(path), dir, name);
dbg("path: %s", path);
iwp = iwatch_find_by_path(iw, path);
if (mask & IN_CREATE) {
if (!iwp) {
if (!sys_add_path(iw, path))
sys_scandir(iw, path, sizeof(path));
}
} else if (mask & IN_DELETE) {
if (iwp)
iwatch_del(&iw_sys, iwp);
}
}
static void sys_callback(void *arg, int fd, int events)
{
static char ev_buf[8 *(sizeof(struct inotify_event) + NAME_MAX + 1) + 1];
struct inotify_event *ev;
ssize_t sz;
size_t off;
sz = read(fd, ev_buf, sizeof(ev_buf) - 1);
if (sz <= 0) {
err(1, "invalid inotify event");
return;
}
ev_buf[sz] = 0;
for (off = 0; off < (size_t)sz; off += sizeof(*ev) + ev->len) {
struct iwatch_path *iwp;
if (off + sizeof(*ev) > (size_t)sz)
break;
ev = (struct inotify_event *)&ev_buf[off];
if (off + sizeof(*ev) + ev->len > (size_t)sz)
break;
dbg("name %s, event: 0x%08x", ev->name, ev->mask);
if (!ev->mask)
continue;
/* Find base path for this event */
iwp = iwatch_find_by_wd(&iw_sys, ev->wd);
if (!iwp)
continue;
if (ev->mask & IN_ISDIR) {
sys_handle_dir(&iw_sys, iwp->path, ev->name, ev->mask);
continue;
}
if (ev->mask & (IN_CREATE | IN_DELETE))
sys_update_conds(iwp->path, ev->name, ev->mask);
}
}
static void sys_init(void *arg)
{
char sysdir[MAX_ARG_LEN];
char *path;
mkpath(_PATH_COND, 0755);
if (mkpath(pid_runpath(_PATH_CONDSYS, sysdir, sizeof(sysdir)), 0755) && errno != EEXIST) {
err(1, "Failed creating %s condition directory, %s", COND_SYS, _PATH_CONDSYS);
return;
}
path = realpath(_PATH_CONDSYS, NULL);
if (!path) {
err(1, "Cannot figure out real path to %s, aborting", _PATH_CONDSYS);
return;
}
if (iwatch_add(&iw_sys, path, IN_ONLYDIR))
iwatch_exit(&iw_sys);
free(path);
}
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_BASEFS_UP] = { .cb = sys_init },
.depends = { "bootmisc", },
};
PLUGIN_INIT(plugin_init)
{
int fd;
fd = iwatch_init(&iw_sys);
if (fd < 0)
return;
plugin.io.fd = fd;
plugin.io.cb = sys_callback;
plugin.io.flags = PLUGIN_IO_READ;
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
iwatch_exit(&iw_sys);
}
/**
* Local Variables:
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+12 -9
View File
@@ -1,7 +1,7 @@
/* Optional TTY Watcher, used to catch new TTYs that are discovered, e.g., USB
*
* Copyright (c) 2013 Mattias Walström <lazzer@gmail.com>
* Copyright (c) 2013-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2013-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -27,7 +27,11 @@
#include <unistd.h> /* read() */
#include <sys/inotify.h>
#include <sys/stat.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "helpers.h"
@@ -51,7 +55,7 @@ static void setup(void)
plugin.io.fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (-1 == plugin.io.fd || inotify_add_watch(plugin.io.fd, "/dev", IN_CREATE | IN_DELETE) < 0)
_pe("Failed starting TTY watcher");
err(1, "Failed starting TTY watcher");
}
static void do_tty(char *tty, size_t len, int creat)
@@ -63,10 +67,10 @@ static void do_tty(char *tty, size_t len, int creat)
svc = svc_find_by_tty(name);
if (svc) {
if (svc_is_blocked(svc) && creat) {
_d("%s: blocked, re-enabling", svc_ident(svc, NULL, 0));
dbg("%s: blocked, re-enabling", svc_ident(svc, NULL, 0));
svc_start(svc);
} else if (svc->pid) {
_d("%s: missing ...", svc_ident(svc, NULL, 0));
dbg("%s: missing ...", svc_ident(svc, NULL, 0));
svc_missing(svc);
}
@@ -83,7 +87,7 @@ static void tty_watcher(void *arg, int fd, int events)
sz = read(fd, ev_buf, sizeof(ev_buf) - 1);
if (sz <= 0) {
_pe("invalid inotify event");
err(1, "invalid inotify event");
return;
}
ev_buf[sz] = 0;
@@ -99,7 +103,7 @@ static void tty_watcher(void *arg, int fd, int events)
if (!ev->mask)
continue;
_d("tty %s, event: 0x%08x", ev->name, ev->mask);
dbg("tty %s, event: 0x%08x", ev->name, ev->mask);
do_tty(ev->name, ev->len, ev->mask & IN_CREATE);
}
}
@@ -112,10 +116,9 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
if (plugin.io.fd)
close(plugin.io.fd);
plugin_unregister(&plugin);
}
/**
+116 -15
View File
@@ -1,6 +1,6 @@
/* Setup random seed
/* Setup and save random seed at boot/shutdown
*
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2012-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,20 +22,58 @@
*/
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h> /* gettimeofday() */
#include <sys/types.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include <linux/random.h>
#include "config.h"
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
#ifndef RANDOM_BYTES
#define RANDOM_BYTES (32*1024)
#endif
#ifdef RANDOMSEED
static void fallback(FILE *fp)
{
struct timeval tv;
int iter = 128;
gettimeofday(&tv, NULL);
srandom(tv.tv_sec % 3600);
while (iter--) {
uint32_t i, prng = random();
for (i = 0; i < sizeof(prng); i++)
fputc((prng >> (i * CHAR_BIT)) & UCHAR_MAX, fp);
}
}
#endif
static void setup(void *arg)
{
#ifdef RANDOMSEED
if (!fexist(RANDOMSEED)) {
struct rand_pool_info *rpi;
ssize_t len = 0;
struct stat st;
int rc = -1;
int fd, err;
if (rescue) {
dbg("Skipping %s plugin in rescue mode.", __FILE__);
return;
}
if (stat(RANDOMSEED, &st) || st.st_size < 512) {
int ret = 1;
mode_t prev;
FILE *fp;
@@ -44,16 +82,22 @@ static void setup(void *arg)
prev = umask(077);
fp = fopen(RANDOMSEED, "w");
if (fp) {
int iter = 128;
struct timeval tv;
const char *hwrng = "/dev/hwrng";
FILE *hw;
gettimeofday(&tv, NULL);
srandom(tv.tv_sec % 3600);
while (iter--) {
uint32_t i, prng = random();
hw = fopen(hwrng, "r");
if (hw) {
char buf[512];
size_t len;
for (i = 0; i < sizeof(prng); i++)
fputc((prng >> (i * CHAR_BIT)) & UCHAR_MAX, fp);
len = fread(buf, sizeof(buf[0]), sizeof(buf), hw);
if (len == 0)
fallback(fp);
else
len = fwrite(buf, sizeof(buf[0]), len, fp);
fclose(hw);
} else {
fallback(fp);
}
ret = fclose(fp);
}
@@ -61,8 +105,60 @@ static void setup(void *arg)
umask(prev);
}
print_desc("Initializing random number generator", NULL);
print_result(512 != copyfile(RANDOMSEED, "/dev/urandom", 0, 0));
print_desc("Seeding random number generator", NULL);
/*
* Simply copying our saved entropy to /dev/urandom doesn't
* increment the kernel "entropy count", instead we must use
* the ioctl below.
*/
fd = open(RANDOMSEED, O_RDONLY);
if (fd < 0)
goto fallback;
rpi = malloc(sizeof(*rpi) + RANDOM_BYTES);
if (!rpi) {
close(fd);
goto fallback;
}
do {
ssize_t num;
num = read(fd, &rpi->buf[len], RANDOM_BYTES - len);
if (num <= 0) {
if (num == -1 && errno == EINTR)
continue;
if (len > 0)
break;
close(fd);
free(rpi);
goto fallback;
}
len += num;
} while (len < RANDOM_BYTES);
close(fd);
fd = open("/dev/urandom", O_WRONLY);
if (fd < 0) {
free(rpi);
goto fallback;
}
rpi->buf_size = len;
rpi->entropy_count = len * 8;
rc = ioctl(fd, RNDADDENTROPY, rpi);
err = errno;
close(fd);
free(rpi);
if (rc < 0)
logit(LOG_WARNING, "Failed adding entropy to kernel random pool: %s", strerror(err));
print_result(rc < 0);
return;
fallback:
print_result(512 > copyfile(RANDOMSEED, "/dev/urandom", 0, 0));
#endif
}
@@ -71,10 +167,15 @@ static void save(void *arg)
#ifdef RANDOMSEED
mode_t prev;
if (rescue) {
dbg("Skipping %s plugin in rescue mode.", __FILE__);
return;
}
prev = umask(077);
print_desc("Saving random seed", NULL);
print_result(512 != copyfile("/dev/urandom", RANDOMSEED, 512, 0));
print_result(RANDOM_BYTES != copyfile("/dev/urandom", RANDOMSEED, RANDOM_BYTES, 0));
umask(prev);
#endif
+11 -7
View File
@@ -1,6 +1,6 @@
/* User-defined condtion event monitor for the Finit condition engine
/* User-defined condition event monitor for the Finit condition engine
*
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2021-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -52,7 +52,7 @@ static void usr_callback(void *arg, int fd, int events)
sz = read(fd, ev_buf, sizeof(ev_buf) - 1);
if (sz <= 0) {
_pe("invalid inotify event");
err(1, "invalid inotify event");
return;
}
ev_buf[sz] = 0;
@@ -65,7 +65,7 @@ static void usr_callback(void *arg, int fd, int events)
if (off + sizeof(*ev) + ev->len > (size_t)sz)
break;
_d("name %s, event: 0x%08x", ev->name, ev->mask);
dbg("name %s, event: 0x%08x", ev->name, ev->mask);
if (!ev->mask)
continue;
@@ -84,24 +84,28 @@ static void usr_init(void *arg)
char usrdir[MAX_ARG_LEN];
char *path;
mkpath(_PATH_COND, 0755);
if (mkpath(pid_runpath(_PATH_CONDUSR, usrdir, sizeof(usrdir)), 0755) && errno != EEXIST) {
_pe("Failed creating %s condition directory, %s", COND_USR, _PATH_CONDUSR);
err(1, "Failed creating %s condition directory, %s", COND_USR, _PATH_CONDUSR);
return;
}
path = realpath(_PATH_CONDUSR, NULL);
if (!path) {
_pe("Cannot figure out real path to %s, aborting", _PATH_CONDUSR);
err(1, "Cannot figure out real path to %s, aborting", _PATH_CONDUSR);
return;
}
if (iwatch_add(&iw_usr, path, IN_ONLYDIR))
iwatch_exit(&iw_usr);
free(path);
}
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_BASEFS_UP] = { .cb = usr_init },
.depends = { "bootmisc", },
};
PLUGIN_INIT(plugin_init)
@@ -121,8 +125,8 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit)
{
iwatch_exit(&iw_usr);
plugin_unregister(&plugin);
iwatch_exit(&iw_usr);
}
/**
+12 -32
View File
@@ -1,6 +1,6 @@
/* Console setup (for X)
*
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2012-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,7 +24,11 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "helpers.h"
@@ -32,42 +36,18 @@
static void setup(void *arg)
{
const char *username = "nobody";
char line[LINE_SIZE];
mode_t prev;
#ifdef PAM_CONSOLE
int fd;
#endif
prev = umask(0);
makedir("/var/run/console", 01777);
snprintf(line, sizeof(line), "/var/run/console/%s", username);
touch(line);
#ifdef PAM_CONSOLE
if ((fd = open("/var/run/console/console.lock", O_CREAT|O_WRONLY|O_TRUNC, 0644)) >= 0) {
write(fd, username, strlen(username));
close(fd);
run("pam_console_apply");
if (rescue) {
dbg("Skipping %s plugin in rescue mode.", __FILE__);
return;
}
#endif
makedir("/tmp/.X11-unix", 01777);
makedir("/tmp/.ICE-unix", 01777);
if (whichp("restorecon"))
run("restorecon /tmp/.ICE-unix /tmp/.X11-unix");
umask(prev);
if (fexist("/var/run/console/console.lock") && which("pam_console_apply"))
run("pam_console_apply", "pam-console");
}
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_NETWORK_UP] = {
.cb = setup
},
.depends = { "bootmisc", }
.hook[HOOK_SVC_PLUGIN] = { .cb = setup },
};
PLUGIN_INIT(plugin_init)
+4
View File
@@ -1,8 +1,12 @@
.deps/*
finit
getty
initctl
keventd
logit
reboot
runparts
sulogin
watchdogd
Makefile
Makefile.in
+40 -11
View File
@@ -8,38 +8,65 @@ AM_LDFLAGS = -export-dynamic
endif
sbin_PROGRAMS = finit initctl
pkglibexec_PROGRAMS =
finit_pkglibdir = $(pkglibdir)
finit_pkglib_SCRIPTS = rescue.conf sample.conf
pkglibexec_PROGRAMS = getty logit runparts
if SULOGIN
pkglibexec_PROGRAMS += sulogin
endif
if KEVENTD
pkglibexec_PROGRAMS += keventd
endif
if WATCHDOGD
pkglibexec_PROGRAMS += watchdogd
endif
if LOGIT
pkglibexec_PROGRAMS += logit
dist_pkglibexec_SCRIPTS = coldplug
finit_pkglibdir = $(pkglibdir)
finit_pkglib_SCRIPTS = rescue.conf sample.conf
getty_SOURCES = finit.h getty.c helpers.h logrotate.c stty.c utmp-api.c utmp-api.h
getty_CFLAGS = -W -Wall -Wextra -std=gnu99
getty_CFLAGS += $(lite_CFLAGS)
getty_LDADD = $(lite_LIBS)
keventd_SOURCES = keventd.c iwatch.c iwatch.h util.c util.h
keventd_CFLAGS = -W -Wall -Wextra -std=gnu99
keventd_CFLAGS += $(lite_CFLAGS)
keventd_LDADD = $(lite_LIBS)
runparts_SOURCES = runparts.c
runparts_CFLAGS = -W -Wall -Wextra -std=gnu99
runparts_CFLAGS += $(lite_CFLAGS)
runparts_LDADD = $(lite_LIBS)
sulogin_SOURCES = sulogin.c
sulogin_CFLAGS = -W -Wall -Wextra -std=gnu99
sulogin_LDADD = -lcrypt
logit_SOURCES = logit.c logrotate.c
logit_CFLAGS = -W -Wall -Wextra -Wno-unused-parameter -std=gnu99
logit_CFLAGS += $(lite_CFLAGS)
logit_LDADD = $(lite_LIBS)
endif
finit_SOURCES = api.c cgroup.c cgroup.h \
client.c client.h \
cond.c cond-w.c cond.h \
conf.c conf.h \
devmon.c devmon.h \
exec.c finit.c finit.h \
getty.c stty.c \
stty.c \
helpers.c helpers.h \
iwatch.c iwatch.h \
log.c log.h \
mdadm.c mount.c \
pid.c pid.h \
plugin.c plugin.h private.h \
schedule.c schedule.h \
runparts.c schedule.c schedule.h \
service.c service.h \
sig.c sig.h \
sm.c sm.h \
svc.c svc.h \
tmpfiles.c tmpfiles.h \
tty.c tty.h \
util.c util.h \
utmp-api.c utmp-api.h
@@ -47,8 +74,10 @@ if LOGROTATE
finit_SOURCES += logrotate.c
endif
pkginclude_HEADERS = cond.h finit.h helpers.h log.h plugin.h svc.h
pkginclude_HEADERS = cgroup.h cond.h conf.h finit.h helpers.h log.h \
plugin.h svc.h service.h
finit_CPPFLAGS = $(AM_CPPFLAGS) -D__FINIT__
finit_CFLAGS = -W -Wall -Wextra -Wno-unused-parameter -std=gnu99
finit_CFLAGS += $(lite_CFLAGS) $(uev_CFLAGS)
finit_LDADD = $(lite_LIBS) $(uev_LIBS)
@@ -60,7 +89,7 @@ endif
initctl_SOURCES = initctl.c initctl.h cgutil.c cgutil.h \
client.c client.h cond.c cond.h reboot.c \
serv.c serv.h svc.h util.c util.h
serv.c serv.h svc.h util.c util.h log.h
initctl_CFLAGS = -W -Wall -Wextra -Wno-unused-parameter -std=gnu99
initctl_CFLAGS += $(lite_CFLAGS) $(uev_CFLAGS)
initctl_LDADD = $(lite_LIBS) $(uev_LIBS)
+200 -70
View File
@@ -1,6 +1,6 @@
/* External client API, using UNIX domain socket.
*
* Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2015-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,6 +21,8 @@
* THE SOFTWARE.
*/
#include "config.h" /* Generated by configure script */
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -29,10 +31,13 @@
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include <uev/uev.h>
#include "config.h"
#include "finit.h"
#include "cond.h"
#include "conf.h"
@@ -40,36 +45,40 @@
#include "log.h"
#include "plugin.h"
#include "private.h"
#include "sig.h"
#include "schedule.h"
#include "service.h"
#include "sig.h"
#include "util.h"
extern svc_t *wdog;
static uev_t api_watcher;
static int call(int (*action)(svc_t *), char *buf, size_t len)
static int call(int (*action)(svc_t *, void *), char *buf, size_t len)
{
return svc_parse_jobstr(buf, len, action, NULL);
return svc_parse_jobstr(buf, len, NULL, action, NULL);
}
static int stop(svc_t *svc)
static int stop(svc_t *svc, void *user_data)
{
if (!svc)
return 1;
service_timeout_cancel(svc);
svc_stop(svc);
service_step(svc);
service_step_all(SVC_TYPE_ANY);
return 0;
}
static int start(svc_t *svc)
static int start(svc_t *svc, void *user_data)
{
if (!svc)
return 1;
service_timeout_cancel(svc);
svc_start(svc);
service_step(svc);
service_step_all(SVC_TYPE_ANY);
return 0;
}
@@ -79,25 +88,30 @@ static int start(svc_t *svc)
* responsibility of initctl to do. Otherwise we'd block PID 1,
* or introduce some nasty race conditions.
*/
static int restart(svc_t *svc)
static int restart(svc_t *svc, void *user_data)
{
if (!svc)
return 1;
svc_mark_dirty(svc);
svc_start(svc);
if (!svc_is_running(svc))
return start(svc, user_data);
service_timeout_cancel(svc);
service_stop(svc);
service_step(svc);
return 0;
}
static int reload(svc_t *svc)
static int reload(svc_t *svc, void *user_data)
{
if (!svc)
return 1;
if (svc_is_blocked(svc))
svc_start(svc);
else
service_timeout_cancel(svc);
svc_mark_dirty(svc);
service_step(svc);
@@ -110,8 +124,28 @@ static int do_start (char *buf, size_t len) { return call(start, buf, len); }
static int do_restart(char *buf, size_t len) { return call(restart, buf, len); }
static int do_reload (char *buf, size_t len) { return call(reload, buf, len); }
static int do_signal_svc(svc_t *svc, void *user_data)
{
int signo;
if (!svc || !user_data || !svc_is_running(svc))
return 1;
signo = *(int *)user_data;
return !!kill(svc->pid, signo);
}
static int do_signal(char *buf, size_t len, int sig)
{
/* Sanity check: do we know this signal? */
if (!*sig2str(sig))
return 1;
return svc_parse_jobstr(buf, len, &sig, do_signal_svc, NULL);
}
static char query_buf[368];
static int missing(char *job, char *id)
static int missing(char *job, char *id, void *user_data)
{
char buf[20];
@@ -129,7 +163,7 @@ static int missing(char *job, char *id)
static int do_query(char *buf, size_t len)
{
query_buf[0] = 0;
if (svc_parse_jobstr(buf, len, NULL, missing)) {
if (svc_parse_jobstr(buf, len, NULL, NULL, missing)) {
memcpy(buf, query_buf, len);
return 1;
}
@@ -173,70 +207,93 @@ static svc_t *do_find(char *buf, size_t len)
if (!id)
return svc_named_iterator(&iter, 1, input);
return svc_find_by_nameid(input, id);
return svc_find(input, id);
}
static svc_t *do_find_byc(char *buf, size_t len)
{
svc_t *svc, *iter = NULL;
char *input;
input = sanitize(buf, len);
if (!input) {
_d("Invalid input");
dbg("Invalid input");
return NULL;
}
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
char cond[MAX_COND_LEN];
mkcond(svc, cond, sizeof(cond));
_d("Comparing input %s with cond %s", input, cond);
if (string_compare(cond, input))
return svc;
}
_d("None found");
return NULL;
return svc_find_by_cond(input);
}
static int do_reboot(int cmd, char *buf, size_t len)
static void bypass_shutdown(void *);
struct wq emergency = { .cb = bypass_shutdown };
static void bypass_shutdown(void *unused)
{
cprintf("TIMEOUT TIMEOUT SHUTTING DOWN NOW!!\n");
do_shutdown(halt);
}
static int do_reboot(int cmd, int timeout, char *buf, size_t len)
{
int rc = 1;
switch (cmd) {
case INIT_CMD_REBOOT:
_d("reboot");
halt = SHUT_REBOOT;
break;
case INIT_CMD_HALT:
halt = SHUT_HALT;
break;
case INIT_CMD_POWEROFF:
halt = SHUT_OFF;
break;
case INIT_CMD_SUSPEND:
break;
default:
return 255;
}
if (timeout > 0) {
emergency.delay = timeout * 1000;
schedule_work(&emergency);
}
switch (cmd) {
case INIT_CMD_REBOOT:
dbg("reboot");
halt = SHUT_REBOOT;
service_runlevel(6);
break;
case INIT_CMD_HALT:
_d("halt");
dbg("halt");
halt = SHUT_HALT;
service_runlevel(0);
break;
case INIT_CMD_POWEROFF:
_d("poweroff");
dbg("poweroff");
halt = SHUT_OFF;
service_runlevel(0);
break;
case INIT_CMD_SUSPEND:
_d("suspend");
dbg("suspend");
sync();
rc = reboot(RB_SW_SUSPEND);
rc = suspend();
if (rc) {
if (errno == EINVAL)
snprintf(buf, len, "Kernel does not support suspend.");
snprintf(buf, len, "Kernel does not support suspend to RAM.");
else
snprintf(buf, len, "Failed: %s", strerror(errno));
}
break;
default:
rc = 255;
/* Handled previously */
break;
}
@@ -265,7 +322,7 @@ static void send_svc(int sd, svc_t *svc)
len = write(sd, svc, sizeof(*svc));
if (len != sizeof(*svc))
_d("Failed sending svc_t to client");
dbg("Failed sending svc_t to client");
}
static void api_cb(uev_t *w, void *arg, int events)
@@ -277,7 +334,7 @@ static void api_cb(uev_t *w, void *arg, int events)
sd = accept(w->fd, NULL, NULL);
if (sd < 0) {
_pe("Failed serving API request");
err(1, "Failed serving API request");
goto error;
}
@@ -294,19 +351,51 @@ static void api_cb(uev_t *w, void *arg, int events)
if (EAGAIN == errno)
break;
_e("Failed reading initctl request, error %d: %s", errno, strerror(errno));
/* we get here when client restarts itself */
if (ECONNRESET == errno)
break;
errx(1, "Failed reading initctl request, error %d: %s", errno, strerror(errno));
}
break;
}
if (rq.magic != INIT_MAGIC || len != sizeof(rq)) {
_e("Invalid initctl request");
errx(1, "Invalid initctl request");
break;
}
switch (rq.cmd) {
case INIT_CMD_RELOAD:
case INIT_CMD_START_SVC:
case INIT_CMD_RESTART_SVC:
case INIT_CMD_STOP_SVC:
case INIT_CMD_RELOAD_SVC:
case INIT_CMD_REBOOT:
case INIT_CMD_HALT:
case INIT_CMD_POWEROFF:
case INIT_CMD_SUSPEND:
if (IS_RESERVED_RUNLEVEL(runlevel)) {
strterm(rq.data, sizeof(rq.data));
warnx("Unsupported command (cmd: %d, data: %s) in runlevel S and 6/0.",
rq.cmd, rq.data);
goto leave;
}
default:
break;
}
switch (rq.cmd) {
case INIT_CMD_RUNLVL:
/* Allow changing cfglevel in runlevel S */
if (IS_RESERVED_RUNLEVEL(runlevel)) {
if (runlevel != INIT_LEVEL) {
warnx("Cannot abort runlevel 6/0.");
break;
}
}
switch (rq.runlevel) {
case 's':
case 'S':
@@ -314,57 +403,70 @@ static void api_cb(uev_t *w, void *arg, int events)
/* fallthrough */
case '0'...'9':
_d("Setting new runlevel %c", rq.runlevel);
dbg("Setting new runlevel %c", rq.runlevel);
lvl = rq.runlevel - '0';
if (lvl == 0)
halt = SHUT_OFF;
if (lvl == 6)
halt = SHUT_REBOOT;
service_runlevel(lvl);
/* User requested change in next runlevel */
if (runlevel == INIT_LEVEL)
cfglevel = lvl;
else
service_runlevel(lvl);
break;
default:
_d("Unsupported runlevel: %d", rq.runlevel);
dbg("Unsupported runlevel: %d", rq.runlevel);
break;
}
break;
case INIT_CMD_DEBUG:
_d("debug");
dbg("debug");
log_debug();
break;
case INIT_CMD_RELOAD: /* 'init q' and 'initctl reload' */
_d("reload");
dbg("reload");
service_reload_dynamic();
break;
case INIT_CMD_START_SVC:
_d("start %s", rq.data);
dbg("start %s", rq.data);
strterm(rq.data, sizeof(rq.data));
result = do_start(rq.data, sizeof(rq.data));
break;
case INIT_CMD_RESTART_SVC:
_d("restart %s", rq.data);
dbg("restart %s", rq.data);
strterm(rq.data, sizeof(rq.data));
result = do_restart(rq.data, sizeof(rq.data));
break;
case INIT_CMD_STOP_SVC:
_d("stop %s", rq.data);
dbg("stop %s", rq.data);
strterm(rq.data, sizeof(rq.data));
result = do_stop(rq.data, sizeof(rq.data));
break;
case INIT_CMD_RELOAD_SVC:
_d("reload %s", rq.data);
dbg("reload %s", rq.data);
strterm(rq.data, sizeof(rq.data));
result = do_reload(rq.data, sizeof(rq.data));
break;
case INIT_CMD_GET_PLUGINS:
result = plugin_list(rq.data, sizeof(rq.data));
break;
case INIT_CMD_PLUGIN_DEPS:
result = plugin_deps(rq.data, sizeof(rq.data));
break;
case INIT_CMD_GET_RUNLEVEL:
_d("get runlevel");
dbg("get runlevel");
rq.runlevel = runlevel;
rq.sleeptime = prevlevel;
break;
@@ -373,21 +475,21 @@ static void api_cb(uev_t *w, void *arg, int events)
case INIT_CMD_HALT:
case INIT_CMD_POWEROFF:
case INIT_CMD_SUSPEND:
result = do_reboot(rq.cmd, rq.data, sizeof(rq.data));
result = do_reboot(rq.cmd, rq.sleeptime, rq.data, sizeof(rq.data));
break;
case INIT_CMD_ACK:
_d("Client failed reading ACK");
dbg("Client failed reading ACK");
goto leave;
case INIT_CMD_WDOG_HELLO:
_d("wdog hello");
dbg("wdog hello");
if (rq.runlevel <= 0) {
result = 1;
break;
}
_e("Request to hand-over wdog ... to PID %d", rq.runlevel);
dbg("Request to hand-over wdog ... to PID %d", rq.runlevel);
svc = svc_find_by_pid(rq.runlevel);
if (!svc) {
logit(LOG_ERR, "Cannot find PID %d, not registered.", rq.runlevel);
@@ -403,7 +505,7 @@ static void api_cb(uev_t *w, void *arg, int events)
if (wdog->protect) {
logit(LOG_NOTICE, "Stopping and deleting built-in watchdog.");
stop(wdog);
stop(wdog, NULL);
svc_del(wdog);
}
}
@@ -411,9 +513,9 @@ static void api_cb(uev_t *w, void *arg, int events)
break;
case INIT_CMD_SVC_ITER:
// _d("svc iter, first: %d", rq.runlevel);
// dbg("svc iter, first: %d", rq.runlevel);
/*
* XXX: This severly limits the number of
* XXX: This severely limits the number of
* simultaneous client connections, but will
* have to do for now.
*/
@@ -422,25 +524,46 @@ static void api_cb(uev_t *w, void *arg, int events)
goto leave;
case INIT_CMD_SVC_QUERY:
_d("svc query: %s", rq.data);
dbg("svc query: %s", rq.data);
strterm(rq.data, sizeof(rq.data));
result = do_query(rq.data, sizeof(rq.data));
break;
case INIT_CMD_SVC_FIND:
_d("svc find: %s", rq.data);
dbg("svc find: %s", rq.data);
strterm(rq.data, sizeof(rq.data));
send_svc(sd, do_find(rq.data, sizeof(rq.data)));
goto leave;
case INIT_CMD_SVC_FIND_BYC:
_d("svc find by cond: %s", rq.data);
dbg("svc find by cond: %s", rq.data);
strterm(rq.data, sizeof(rq.data));
send_svc(sd, do_find_byc(rq.data, sizeof(rq.data)));
goto leave;
case INIT_CMD_SIGNAL:
/* runlevel is reused for signal */
dbg("svc signal %d: %s", rq.runlevel, rq.data);
strterm(rq.data, sizeof(rq.data));
result = do_signal(rq.data, sizeof(rq.data), rq.runlevel);
break;
case INIT_CMD_NOTIFY_SOCKET:
svc = svc_find_by_pid(rq.runlevel);
if (!svc) {
errx(1, "Unknown PID, cannot register notify socket");
result = 1;
break;
}
if (uev_io_init(ctx, &svc->notify_watcher, service_notify_cb, svc, sd, UEV_READ)) {
err(1, "Falied initializing %s readiness notifier", svc_ident(svc, NULL, 0));
break;
}
return; /* Don't close sd, used for notify */
default:
_d("Unsupported cmd: %d", rq.cmd);
dbg("Unsupported cmd: %d", rq.cmd);
break;
}
@@ -450,7 +573,7 @@ static void api_cb(uev_t *w, void *arg, int events)
rq.cmd = INIT_CMD_ACK;
len = write(sd, &rq, sizeof(rq));
if (len != sizeof(rq))
_d("Failed sending ACK/NACK back to client");
dbg("Failed sending ACK/NACK back to client");
}
leave:
@@ -461,39 +584,46 @@ leave:
error:
api_exit();
if (api_init(w->ctx))
_e("Unrecoverable error on API socket");
errx(1, "Unrecoverable error on API socket");
}
int api_init(uev_ctx_t *ctx)
{
int sd;
mode_t oldmask;
struct sockaddr_un sun = {
.sun_family = AF_UNIX,
.sun_path = INIT_SOCKET,
};
mode_t oldmask;
int uid, gid;
int sd;
_d("Setting up external API socket ...");
dbg("Setting up external API socket ...");
sd = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
if (-1 == sd) {
_pe("Failed starting external API socket");
err(1, "Failed starting external API socket");
return 1;
}
uid = geteuid();
gid = getgroup(DEFGROUP);
erase(INIT_SOCKET);
oldmask = umask(0077);
oldmask = umask(0117);
if (-1 == bind(sd, (struct sockaddr*)&sun, sizeof(sun)))
goto error;
if (-1 == listen(sd, 10))
goto error;
if (chown(INIT_SOCKET, uid, gid))
err(1, "Failed setting group %s on %s", DEFGROUP, INIT_SOCKET);
umask(oldmask);
if (!uev_io_init(ctx, &api_watcher, api_cb, NULL, sd, UEV_READ))
return 0;
error:
_pe("Failed intializing API socket");
err(1, "Failed initializing API socket");
umask(oldmask);
close(sd);
return 1;
+104 -41
View File
@@ -1,6 +1,6 @@
/* Finit control group support functions
*
* Copyright (c) 2019-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2019-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,8 +24,13 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <lite/lite.h>
#include <lite/queue.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
# include <libite/queue.h> /* BSD sys/queue.h API */
#else
# include <lite/lite.h>
# include <lite/queue.h> /* BSD sys/queue.h API */
#endif
#include <sys/mount.h>
#include <sys/sysinfo.h> /* get_nprocs_conf() */
@@ -42,7 +47,7 @@ struct cg {
char *cfg; /* kernel settings */
int active; /* for mark & sweep */
int protected; /* for init/, user/, & system/ */
int is_protected; /* for init/, user/, & system/ */
};
static TAILQ_HEAD(, cg) cgroups = TAILQ_HEAD_INITIALIZER(cgroups);
@@ -51,22 +56,23 @@ static char controllers[256];
static struct iwatch iw_cgroup;
static uev_t cgw;
static int avail;
static void cgset(const char *path, char *ctrl, char *prop)
{
char *val;
_d("path %s, ctrl %s, prop %s", path ?: "NIL", ctrl ?: "NIL", prop ?: "NIL");
dbg("path %s, ctrl %s, prop %s", path ?: "NIL", ctrl ?: "NIL", prop ?: "NIL");
if (!path || !ctrl) {
_e("Missing path or controller, skipping!");
errx(1, "Missing path or controller, skipping!");
return;
}
if (!prop) {
prop = strchr(ctrl, '.');
if (!prop) {
_e("Invalid cgroup ctrl syntax: %s", ctrl);
errx(1, "Invalid cgroup ctrl syntax: %s", ctrl);
return;
}
@@ -75,20 +81,20 @@ static void cgset(const char *path, char *ctrl, char *prop)
val = strchr(prop, ':');
if (!val) {
_e("Missing cgroup ctrl value, prop %s", prop);
errx(1, "Missing cgroup ctrl value, prop %s", prop);
return;
}
*val++ = 0;
/* disallow sneaky relative paths */
if (strstr(ctrl, "..") || strstr(prop, "..")) {
_e("Possible security violation; '..' not allowed in cgroup config!");
errx(1, "Possible security violation; '..' not allowed in cgroup config!");
return;
}
_d("%s/%s.%s <= %s", path, ctrl, prop, val);
dbg("%s/%s.%s <= %s", path, ctrl, prop, val);
if (fnwrite(val, "%s/%s.%s", path, ctrl, prop))
_pe("Failed setting %s/%s.%s = %s", path, ctrl, prop, val);
err(1, "Failed setting %s/%s.%s = %s", path, ctrl, prop, val);
}
/*
@@ -100,16 +106,16 @@ static void group_init(char *path, int leaf, const char *cfg)
{
char *ptr, *s;
_d("path %s, leaf %d, cfg %s", path, leaf, cfg ?: "NIL");
dbg("path %s, leaf %d, cfg %s", path, leaf, cfg ?: "NIL");
if (!fisdir(path)) {
if (mkdir(path, 0755)) {
_pe("Failed creating cgroup %s", path);
err(1, "Failed creating cgroup %s", path);
return;
}
/* enable detected controllers on domain groups */
if (!leaf && fnwrite(controllers, "%s/cgroup.subtree_control", path))
_pe("Failed enabling %s for %s", controllers, path);
err(1, "Failed enabling %s for %s", controllers, path);
}
if (!cfg || !cfg[0])
@@ -117,14 +123,14 @@ static void group_init(char *path, int leaf, const char *cfg)
s = strdupa(cfg);
if (!s) {
_pe("Failed activating cgroup cfg for %s", path);
err(1, "Failed activating cgroup cfg for %s", path);
return;
}
_d("%s <=> %s", path, s);
dbg("%s <=> %s", path, s);
ptr = strtok(s, ",");
while (ptr) {
_d("ptr: %s", ptr);
dbg("ptr: %s", ptr);
if (!strncmp("mem.", ptr, 4))
cgset(path, "memory", &ptr[4]);
else
@@ -138,7 +144,7 @@ static int cgroup_leaf_init(char *group, char *name, int pid, const char *cfg)
{
char path[256];
_d("group %s, name %s, pid %d, cfg %s", group, name, pid, cfg ?: "NIL");
dbg("group %s, name %s, pid %d, cfg %s", group, name, pid, cfg ?: "NIL");
if (pid < 0 || pid == 1) {
errno = EINVAL;
return 1;
@@ -150,7 +156,7 @@ static int cgroup_leaf_init(char *group, char *name, int pid, const char *cfg)
/* move process to new group */
if (fnwrite(str("%d", pid), "%s/cgroup.procs", path))
_pe("Failed moving pid %d to group %s", pid, path);
err(1, "Failed moving pid %d to group %s", pid, path);
strlcat(path, "/cgroup.events", sizeof(path));
@@ -159,6 +165,9 @@ static int cgroup_leaf_init(char *group, char *name, int pid, const char *cfg)
int cgroup_user(char *name, int pid)
{
if (!avail)
return 0;
return cgroup_leaf_init("user", name, pid, NULL);
}
@@ -166,12 +175,18 @@ int cgroup_service(char *name, int pid, struct cgroup *cg)
{
char *group = "system";
if (!avail)
return 0;
if (cg && cg->name[0]) {
char path[256];
if (!strcmp(cg->name, "root"))
return fnwrite(str("%d", pid), FINIT_CGPATH "/cgroup.procs");
if (!strcmp(cg->name, "init"))
return fnwrite(str("%d", pid), FINIT_CGPATH "/init/cgroup.procs");
snprintf(path, sizeof(path), "/sys/fs/cgroup/%s", cg->name);
if (fisdir(path))
group = cg->name;
@@ -196,13 +211,13 @@ static void cgroup_handle_event(char *event, uint32_t mask)
char *ptr;
FILE *fp;
_d("event: '%s', mask: %08x", event, mask);
dbg("event: '%s', mask: %08x", event, mask);
if (!(mask & IN_MODIFY))
return;
fp = fopen(event, "r");
if (!fp) {
_d("Failed opening %s, skipping ...", event);
dbg("Failed opening %s, skipping ...", event);
return;
}
@@ -246,7 +261,7 @@ static void cgroup_events_cb(uev_t *w, void *arg, int events)
sz = read(w->fd, ev_buf, sizeof(ev_buf) - 1);
if (sz <= 0) {
_pe("invalid inotify event");
err(1, "invalid inotify event");
return;
}
ev_buf[sz] = 0;
@@ -272,7 +287,7 @@ static void cgroup_events_cb(uev_t *w, void *arg, int events)
cgroup_handle_event(iwp->path, ev->mask);
}
#ifdef ENABLE_AUTO_RELOAD
#ifdef AUTO_RELOAD
if (conf_any_change())
service_reload_dynamic();
#endif
@@ -299,8 +314,11 @@ void cgroup_mark_all(void)
{
struct cg *cg;
if (!avail)
return;
TAILQ_FOREACH(cg, &cgroups, link) {
if (cg->protected)
if (cg->is_protected)
continue;
cg->active = 0;
@@ -315,6 +333,9 @@ void cgroup_cleanup(void)
struct cg *cg, *tmp;
char path[256];
if (!avail)
return;
TAILQ_FOREACH_SAFE(cg, &cgroups, link, tmp) {
if (cg->active)
continue;
@@ -327,10 +348,13 @@ void cgroup_cleanup(void)
/*
* Add, or update, settings for top-level cgroup
*/
int cgroup_add(char *name, char *cfg, int protected)
int cgroup_add(char *name, char *cfg, int is_protected)
{
struct cg *cg;
if (!avail)
return 0;
if (!name)
return -1;
if (!cfg)
@@ -340,12 +364,12 @@ int cgroup_add(char *name, char *cfg, int protected)
if (!cg) {
cg = malloc(sizeof(struct cg));
if (!cg) {
_pe("Failed allocating 'struct cg' for %s", name);
err(1, "Failed allocating 'struct cg' for %s", name);
return -1;
}
cg->name = strdup(name);
if (!cg->name) {
_pe("Failed setting cgroup name %s", name);
err(1, "Failed setting cgroup name %s", name);
free(cg);
return -1;
}
@@ -355,13 +379,13 @@ int cgroup_add(char *name, char *cfg, int protected)
cg->cfg = strdup(cfg);
if (!cg->cfg) {
_pe("Failed add/update of cgroup %s", name);
err(1, "Failed add/update of cgroup %s", name);
TAILQ_REMOVE(&cgroups, cg, link);
free(cg->name);
free(cg);
return -1;
}
cg->protected = protected;
cg->is_protected = is_protected;
cg->active = 1;
return 0;
@@ -375,6 +399,9 @@ int cgroup_del(char *dir)
struct cg *cg;
char path[256];
if (!avail)
return 0;
TAILQ_FOREACH(cg, &cgroups, link) {
snprintf(path, sizeof(path), FINIT_CGPATH "/%s", cg->name);
if (strcmp(path, dir))
@@ -387,7 +414,7 @@ int cgroup_del(char *dir)
}
if (rmdir(dir) && errno != ENOENT) {
_d("Failed removing %s: %s", dir, strerror(errno));
dbg("Failed removing %s: %s", dir, strerror(errno));
return -1;
}
@@ -406,6 +433,9 @@ void cgroup_config(void)
{
struct cg *cg;
if (!avail)
return;
TAILQ_FOREACH(cg, &cgroups, link) {
char path[256];
int leaf = 0;
@@ -433,15 +463,30 @@ void cgroup_init(uev_ctx_t *ctx)
FILE *fp;
int fd;
#ifndef CGROUP2_ENABLED
avail = 0;
return;
#endif
if (mount("none", FINIT_CGPATH, "cgroup2", opts, NULL)) {
_pe("Failed mounting cgroup v2");
if (errno == ENOENT)
logit(LOG_INFO, "Kernel does not support cgroups v2, disabling.");
else if (errno == EPERM) /* Probably inside an unpriviliged container */
logit(LOG_INFO, "Not allowed to mount cgroups v2, disabling.");
else
err(1, "Failed mounting cgroup v2");
avail = 0;
return;
}
avail = 1;
/* Find available controllers */
fp = fopen(FINIT_CGPATH "/cgroup.controllers", "r");
if (!fp) {
_pe("Failed opening %s", FINIT_CGPATH "/cgroup.controllers");
err(1, "Failed opening %s", FINIT_CGPATH "/cgroup.controllers");
abort:
umount(FINIT_CGPATH);
avail = 0;
return;
}
@@ -457,9 +502,29 @@ void cgroup_init(uev_ctx_t *ctx)
fclose(fp);
/* Check for cpu controller, abort if missing */
if (!strstr(controllers, "+cpu")) {
logit(LOG_NOTICE, "Missing CPU controller, disabling cgroup support.");
goto abort;
}
/* Enable all controllers */
if (fnwrite(controllers, FINIT_CGPATH "/cgroup.subtree_control"))
_pe("Failed enabling %s for %s", controllers, FINIT_CGPATH "/cgroup.subtree_control");
if (fnwrite(controllers, FINIT_CGPATH "/cgroup.subtree_control")) {
err(1, "Failed enabling %s for %s", controllers, FINIT_CGPATH "/cgroup.subtree_control");
goto abort;
}
/* prepare cgroup.events watcher */
fd = iwatch_init(&iw_cgroup);
if (fd == -1)
goto abort;
if (uev_io_init(ctx, &cgw, cgroup_events_cb, NULL, fd, UEV_READ)) {
err(1, "Failed setting up cgroup.events watcher");
iwatch_exit(&iw_cgroup);
close(fd);
goto abort;
}
/* Default (protected) groups, PID 1, services, and user/login processes */
cgroup_add("init", "cpu.weight:100", 1);
@@ -468,14 +533,12 @@ void cgroup_init(uev_ctx_t *ctx)
cgroup_config();
/* Move ourselves to init (best effort, otherwise run in 'root' group */
if (fnwrite("1", FINIT_CGPATH "/init/cgroup.procs"))
_pe("Failed moving PID 1 to cgroup ", FINIT_CGPATH "/init");
/* prepare cgroup.events watcher */
fd = iwatch_init(&iw_cgroup);
if (uev_io_init(ctx, &cgw, cgroup_events_cb, NULL, fd, UEV_READ)) {
_pe("Failed setting up cgroup.events watcher");
if (fnwrite("1", FINIT_CGPATH "/init/cgroup.procs")) {
err(1, "Failed moving PID 1 to cgroup %s", FINIT_CGPATH "/init");
uev_io_stop(&cgw);
iwatch_exit(&iw_cgroup);
close(fd);
goto abort;
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
/* Finit control group support functions
*
* Copyright (c) 2019-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2019-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -34,7 +34,7 @@ struct cgroup {
void cgroup_mark_all(void);
void cgroup_cleanup (void);
int cgroup_add (char *name, char *cfg, int protected);
int cgroup_add (char *name, char *cfg, int is_protected);
int cgroup_del (char *dir);
void cgroup_config (void);
+21 -11
View File
@@ -1,6 +1,6 @@
/* New client tool, replaces old /dev/initctl API and telinit tool
*
* Copyright (c) 2019-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2019-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,18 +23,22 @@
#include "config.h"
#include <err.h>
#include <dirent.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <search.h>
#include <inttypes.h>
#include <lite/lite.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include <sys/sysinfo.h> /* sysinfo() */
#include "cgutil.h"
#include "initctl.h"
#include "log.h"
#define CDIM plain ? "" : "\e[2m"
#define CRST plain ? "" : "\e[0m"
@@ -49,6 +53,10 @@ uint64_t total_ram; /* From sysinfo() */
struct cg dummy; /* empty result "NULL" */
struct cg *list;
int cgroup_avail(void)
{
return fismnt(FINIT_CGPATH);
}
char *pid_cmdline(int pid, char *buf, size_t len)
{
@@ -236,7 +244,7 @@ static float cgroup_cpuload(struct cg *cg)
snprintf(fn, sizeof(fn), "%s/cpu.stat", cg->cg_path);
fp = fopen(fn, "r");
if (!fp)
err(1, "Cannot open %s", fn);
ERR(72, "Cannot open %s", fn);
while (fgets(buf, sizeof(buf), fp)) {
uint64_t curr;
@@ -272,13 +280,13 @@ static struct cg *append(char *path)
if (access(fn, F_OK)) {
/* older kernels, 4.19, don't have summary cpu.stat in root */
if (strcmp(path, FINIT_CGPATH))
warn("not a cgroup path with cpu controller, %s", path);
WARN("not a cgroup path with cpu controller, %s", path);
return NULL;
}
cg = calloc(1, sizeof(struct cg));
if (!cg)
err(1, "failed allocating struct cg");
ERR(71, "failed allocating struct cg");
cg->cg_path = strdup(path);
if (list)
@@ -288,7 +296,7 @@ static struct cg *append(char *path)
item.key = cg->cg_path;
item.data = cg;
if (!hsearch(item, ENTER))
err(1, "failed adding to hash table");
ERR(70, "failed adding to hash table");
return cg;
}
@@ -426,7 +434,6 @@ int cgroup_tree(char *path, char *pfx, int mode, int pos)
pid_comm(pid, comm, sizeof(comm));
if (pid_cmdline(pid, buf, sizeof(buf))) {
char proc[ttcols];
int len;
switch (mode) {
case 1:
@@ -448,6 +455,8 @@ int cgroup_tree(char *path, char *pfx, int mode, int pos)
if (plain) {
strlcat(row, proc, rplen);
} else {
int len;
strlcat(row, CDIM, rlen);
strlcat(row, proc, rlen);
@@ -580,7 +589,7 @@ static void key(uev_t *w, void *arg, int events)
break;
default:
warnx("Got char 0x%02x", ch);
dbg("Got char 0x%02x", ch);
break;
}
}
@@ -592,7 +601,6 @@ int show_cgtop(char *arg)
uev_t timer, input, sigint, sigterm, sigquit;
char path[512];
uev_ctx_t ctx;
int flags;
if (!arg)
arg = FINIT_CGPATH;
@@ -602,7 +610,7 @@ int show_cgtop(char *arg)
}
if (!hcreate(ttrows + 25))
err(1, "failed creating hash table");
ERR(70, "failed creating hash table");
sysinfo(&si);
total_ram = si.totalram * si.mem_unit;
@@ -611,6 +619,8 @@ int show_cgtop(char *arg)
uev_timer_init(&ctx, &timer, cgtop, arg, 1, ionce ? 0 : 1000);
if (!ionce && !plain) {
int flags;
atexit(cleanup);
ttraw();
hidecursor();
+3 -1
View File
@@ -1,6 +1,6 @@
/* Cgroup utility functions for initctl
*
* Copyright (c) 2019-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2019-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -52,6 +52,8 @@ struct cg {
} cg_cpu;
};
int cgroup_avail(void);
char *pid_cmdline (int pid, char *buf, size_t len);
char *pid_comm (int pid, char *buf, size_t len);
char *pid_cgroup (int pid, char *buf, size_t len);
+77 -35
View File
@@ -1,6 +1,6 @@
/* External client API, using UNIX domain socket.
*
* Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2015-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,13 +21,15 @@
* THE SOFTWARE.
*/
#include <err.h>
#include <errno.h>
#include <poll.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "client.h"
#include "log.h"
#define REQUEST_TIMEOUT 15000
static int sd = -1;
@@ -39,11 +41,17 @@ int client_connect(void)
};
sd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (-1 == sd)
err(1, "Failed creating UNIX domain socket");
if (-1 == sd) {
warn("Failed creating UNIX domain socket");
return -1;
}
if (connect(sd, (struct sockaddr*)&sun, sizeof(sun)) == -1)
err(1, "Failed connecting to finit");
if (connect(sd, (struct sockaddr*)&sun, sizeof(sun)) == -1) {
if (errno != ENOENT)
warnx("Failed connecting to finit");
close(sd);
sd = -1;
}
return sd;
}
@@ -63,60 +71,97 @@ int client_disconnect(void)
return rc;
}
int client_send(struct init_request *rq, ssize_t len)
/* Only valid after client_connect() */
int client_socket(void)
{
return sd;
}
int client_request(struct init_request *rq, ssize_t len)
{
struct pollfd pfd = { 0 };
int sd, result = 255;
int rc;
sd = client_connect();
if (-1 == sd)
if (client_connect() == -1)
return -1;
pfd.fd = sd;
pfd.events = POLLOUT;
if (poll(&pfd, 1, 2000) <= 0) {
if (poll(&pfd, 1, REQUEST_TIMEOUT) <= 0) {
warn("Timed out waiting for Finit, errno %d", errno);
goto exit;
return -1;
}
if (write(sd, rq, len) != len) {
warn("Failed communicating with Finit, errno %d", errno);
goto exit;
return -1;
}
/*
* Exception, only command that don't need to wait for a
* response from Finit. Registers the client socket as a
* readiness notification socket with Finit
*/
if (rq->cmd == INIT_CMD_NOTIFY_SOCKET) {
rq->cmd = INIT_CMD_ACK;
return 0;
}
pfd.fd = sd;
pfd.events = POLLIN;
if (poll(&pfd, 1, 2000) <= 0) {
warn("Timed out waiting for reply from Finit, errno %d", errno);
goto exit;
pfd.events = POLLIN | POLLERR | POLLHUP;
if ((rc = poll(&pfd, 1, REQUEST_TIMEOUT)) <= 0) {
if (rc) {
if (errno == EINTR) /* shutdown/reboot */
return -1;
warn("poll(), errno %d", errno);
} else
warnx("Timed out waiting for reply from Finit.");
return -1;
}
if (read(sd, rq, len) != len) {
warn("Failed reading reply from Finit, errno %d", errno);
goto exit;
return -1;
}
if (rq->cmd == INIT_CMD_NACK)
result = 1;
else
result = 0;
exit:
return -1;
return 0;
}
int client_send(struct init_request *rq, ssize_t len)
{
int rc = 0;
if (client_request(rq, len))
rc = 255;
client_disconnect();
return result;
return rc;
}
int client_command(int cmd)
{
struct init_request rq = {
.magic = INIT_MAGIC,
.runlevel = getpid(),
.cmd = cmd,
};
return client_request(&rq, sizeof(rq));
}
svc_t *client_svc_iterator(int first)
{
int sd = -1;
struct init_request rq = {
.magic = INIT_MAGIC,
.cmd = INIT_CMD_SVC_ITER,
};
static svc_t svc;
sd = client_connect();
if (sd == -1)
if (client_connect() == -1)
return NULL;
if (first)
@@ -135,24 +180,22 @@ svc_t *client_svc_iterator(int first)
return &svc;
error:
perror("Failed communicating with finit");
warn("Failed communicating with finit, error %d", errno);
client_disconnect();
sd = -1;
return NULL;
}
svc_t *do_cmd(int cmd, const char *arg)
static svc_t *do_find(int cmd, const char *arg)
{
struct init_request rq = {
.magic = INIT_MAGIC,
.cmd = cmd,
};
static svc_t svc;
int sd = -1;
sd = client_connect();
if (sd == -1)
if (client_connect() == -1)
return NULL;
strlcpy(rq.data, arg, sizeof(rq.data));
@@ -168,20 +211,19 @@ svc_t *do_cmd(int cmd, const char *arg)
return &svc;
error:
client_disconnect();
perror("Failed communicating with finit");
warn("Failed communicating with finit, error %d", errno);
return NULL;
}
svc_t *client_svc_find(const char *arg)
{
return do_cmd(INIT_CMD_SVC_FIND, arg);
return do_find(INIT_CMD_SVC_FIND, arg);
}
svc_t *client_svc_find_by_cond(const char *arg)
{
return do_cmd(INIT_CMD_SVC_FIND_BYC, arg);
return do_find(INIT_CMD_SVC_FIND_BYC, arg);
}
/**
+5 -1
View File
@@ -1,6 +1,6 @@
/* External client API, using UNIX domain socket.
*
* Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2015-2024 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -29,8 +29,12 @@
int client_connect (void);
int client_disconnect (void);
int client_socket (void);
int client_request (struct init_request *rq, ssize_t len);
int client_send (struct init_request *rq, ssize_t len);
int client_command (int cmd);
svc_t *client_svc_iterator (int first);
svc_t *client_svc_find (const char *arg);
svc_t *client_svc_find_by_cond (const char *arg);
Executable
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
# With the daemon mode ('mdev -df') we no longer need the hotplug helper
echo "" > /proc/sys/kernel/hotplug
# Wait for 'mdev -df' to set up its event queue.
sleep 1
# Trigger 'add' event for all devices and subsystems to load all modules
# and any firmware needed by the hardware.
find /sys/devices -name uevent -print | while IFS='' read X; do echo add > $X; done
+239 -43
View File
@@ -21,15 +21,85 @@
* THE SOFTWARE.
*/
#include <dirent.h>
#include <ftw.h>
#include <libgen.h>
#include <lite/lite.h>
#include <stdio.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "cond.h"
#include "pid.h"
#include "service.h"
#include "sm.h"
struct cond_boot {
TAILQ_ENTRY(cond_boot) link;
char *name;
};
static TAILQ_HEAD(, cond_boot) cond_boot_list = TAILQ_HEAD_INITIALIZER(cond_boot_list);
/*
* Parse finit.cond=cond[,cond[,...]] from command line. It creates a
* temporary linked list of conds which are freed when finit reaches
* cond_init(), which calls cond_boot_strap() to realize the conditions
* in the file system as regular static conditions. Policy, however,
* dictates that these are read-only and should not be possible to
* manage from initctl.
*/
void cond_boot_parse(char *arg)
{
struct cond_boot *node;
if (!arg)
return;
node = malloc(sizeof(*node));
if (!node) {
err(1, "Out of memory cannot track boot conditions");
return;
}
node->name = strdup(arg);
TAILQ_INSERT_HEAD(&cond_boot_list, node, link);
}
/*
* Convert all conditions read from the kernel command line (above) into
* proper finit conditions.
*/
static void cond_boot_strap(void)
{
struct cond_boot *node, *tmp;
TAILQ_FOREACH_SAFE(node, &cond_boot_list, link, tmp) {
TAILQ_REMOVE(&cond_boot_list, node, link);
if (node->name) {
char *ptr;
ptr = strtok(node->name, ",");
while (ptr) {
char cond[strlen(ptr) + 6];
if (strncmp(ptr, "boot/", 5))
snprintf(cond, sizeof(cond), "boot/%s", ptr);
else
snprintf(cond, sizeof(cond), "%s", ptr);
cond_set_oneshot_noupdate(cond);
ptr = strtok(NULL, ",");
}
free(node->name);
}
free(node);
}
}
/*
* The service condition name is constructed from the 'pid/' prefix and
@@ -106,7 +176,7 @@ static void cond_bump_reconf(void)
rgen++;
if (cond_set_gen(_PATH_RECONF, rgen))
_pe("Failed setting %s to gen %d", _PATH_RECONF, rgen);
err(1, "Failed setting %s to gen %d", _PATH_RECONF, rgen);
}
static int cond_checkpath(const char *path)
@@ -116,105 +186,194 @@ static int cond_checkpath(const char *path)
strlcpy(buf, path, sizeof(buf));
dir = dirname(buf);
if (!dir) {
_e("Invalid path '%s' for condition", path);
errx(1, "Invalid path '%s' for condition", path);
return 1;
}
if (mkpath(dir, 0755) && errno != EEXIST) {
_pe("Failed creating dir '%s' for condition '%s'", dir, path);
err(1, "Failed creating dir '%s' for condition '%s'", dir, path);
return 1;
}
return 0;
}
static int do_delete(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftw)
{
const char *cond, *ptr;
if (ftw->level == 0)
return 1;
ptr = strstr(fpath, COND_BASE);
if (!ptr) {
warnx("%s does not seem to be a Finit condition, skipping", fpath);
return 0;
}
if (remove(fpath))
err(1, "Failed removing condition %s", fpath);
cond = ptr + strlen(COND_BASE) + 1;
if (sm_is_in_teardown(&sm))
cond_clear_noupdate(cond);
else
cond_update(cond);
return 0;
}
static void cond_delpath(const char *path)
{
nftw(path, do_delete, 20, FTW_DEPTH);
if (remove(path)) {
switch (errno) {
case ENOENT: /* Ignore */
case ENOTEMPTY: /* Only at shutdown and for directories */
break;
default:
err(1, "Failed removing condition path %s", path);
break;
}
}
}
int cond_set_path(const char *path, enum cond_state next)
{
enum cond_state prev;
unsigned int rgen;
_d("%s <= %d", path, next);
rgen = cond_get_gen(_PATH_RECONF);
if (!rgen) {
_e("Unable to read configuration generation (%s)", path);
return -1;
}
dbg("%s <= %d", path, next);
prev = cond_get_path(path);
switch (next) {
case COND_ON:
if (cond_checkpath(path))
return 0;
rgen = cond_get_gen(_PATH_RECONF);
if (!rgen) {
errx(1, "Unable to read configuration generation (%s)", path);
return -1;
}
cond_set_gen(path, rgen);
break;
case COND_OFF:
if (unlink(path) && errno != ENOENT)
_pe("Failed removing condition '%s'", path);
if (unlink(path)) {
switch (errno) {
case ENOENT:
break;
case EISDIR:
cond_delpath(path);
break;
default:
err(1, "Failed removing condition '%s'", path);
break;
}
}
break;
default:
_e("Invalid condition state");
errx(1, "Invalid condition state");
return 0;
}
return next != prev;
}
/* Should only be used by cond_set*(), cond_clear(), and usr plugin! */
void cond_update(const char *name)
/* Should only be used by cond_set*(), cond_clear(), and usr/sys plugins! */
int cond_update(const char *name)
{
svc_t *svc, *iter = NULL;
int affects = 0;
_d("%s", name);
// dbg("%s", name);
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
if (!svc_has_cond(svc) || !cond_affects(name, svc->cond))
continue;
_d("%s: match <%s> %s(%s)", name ?: "nil", svc->cond, svc->desc, svc->cmd);
affects++;
dbg("%s: match <%s> %s(%s)", name ?: "nil", svc->cond, svc->desc, svc->cmd);
/* Fix bug #314: race condition between crashing services and conditions */
if (svc_is_restart(svc) && cond_get_agg(svc->cond) == COND_OFF) {
dbg("%s: cancel timer & unblock => WAITING state.", name ?: "nil");
service_timeout_cancel(svc);
svc_unblock(svc);
}
service_step(svc);
}
return affects;
}
int cond_set_noupdate(const char *name)
{
dbg("%s", name);
if (string_compare(name, "nop"))
return 1;
if (!cond_set_path(cond_path(name), COND_ON))
return 1;
return 0;
}
void cond_set(const char *name)
{
_d("%s", name);
if (string_compare(name, "nop"))
return;
if (!cond_set_path(cond_path(name), COND_ON))
// dbg("%s", name);
if (cond_set_noupdate(name))
return;
cond_update(name);
}
void cond_set_oneshot(const char *name)
int cond_set_oneshot_noupdate(const char *name)
{
const char *path;
if (string_compare(name, "nop"))
return;
return 1;
path = cond_path(name);
_d("%s => %s", name, path);
dbg("%s => %s", name, path);
if (cond_checkpath(path))
return 1;
if (symlink(_PATH_RECONF, path) && errno != EEXIST) {
err(1, "Failed creating onshot cond %s", name);
return 1;
}
return 0;
}
void cond_set_oneshot(const char *name)
{
dbg("%s", name);
if (cond_set_oneshot_noupdate(name))
return;
if (symlink(_PATH_RECONF, path) && errno != EEXIST)
_pe("Failed creating onshot cond %s", name);
cond_update(name);
}
int cond_clear_noupdate(const char *name)
{
dbg("%s", name);
if (string_compare(name, "nop"))
return 1;
if (!cond_set_path(cond_path(name), COND_OFF))
return 1;
return 0;
}
void cond_clear(const char *name)
{
_d("%s", name);
if (string_compare(name, "nop"))
return;
if (!cond_set_path(cond_path(name), COND_OFF))
// dbg("%s", name);
if (cond_clear_noupdate(name))
return;
cond_update(name);
@@ -222,12 +381,12 @@ void cond_clear(const char *name)
void cond_reload(void)
{
_d("");
dbg("");
cond_bump_reconf();
}
static int reassert(const char *fpath, const struct stat *sb, int tflg, struct FTW *ftw)
static int do_assert(const char *fpath, const struct stat *sb, int tflg, struct FTW *ftw, int set)
{
char *nm;
@@ -239,25 +398,56 @@ static int reassert(const char *fpath, const struct stat *sb, int tflg, struct F
nm = strstr((char *)fpath, COND_BASE);
if (!nm) {
_e("Incorrect condtion path %s, cannot reassert", fpath);
errx(1, "Incorrect condition path %s, cannot %sassert", fpath, set ? "re" : "de");
return 1;
}
nm += strlen(COND_BASE);
_d("Reasserting %s => %s", fpath, nm);
cond_set(nm);
dbg("%sasserting %s => %s", set ? "Re" : "De", fpath, nm);
if (set)
cond_set(nm);
else
cond_clear_noupdate(nm); /* important, see netlink plugin! */
return 0;
}
static int reassert(const char *fpath, const struct stat *sb, int tflg, struct FTW *ftw)
{
return do_assert(fpath, sb, tflg, ftw, 1);
}
static int deassert(const char *fpath, const struct stat *sb, int tflg, struct FTW *ftw)
{
return do_assert(fpath, sb, tflg, ftw, 0);
}
/*
* Used only by netlink plugin atm.
* type: is a one of pid/, net/, etc.
*/
void cond_reassert(const char *type)
void cond_reassert(const char *pat)
{
_d("%s", type);
nftw(cond_path(type), reassert, 20, FTW_DEPTH);
dbg("%s", pat);
nftw(cond_path(pat), reassert, 20, FTW_DEPTH);
}
/*
* Used only by netlink plugin atm.
*/
void cond_deassert(const char *pat)
{
dbg("%s", pat);
nftw(cond_path(pat), deassert, 20, FTW_DEPTH);
}
/*
* Check if we have bootstrapped enough of the system to use conditions.
* Will answer 'No' before bootstrap done *and* at shutdown/reboot.
*/
int cond_is_available(void)
{
return fisdir(_PATH_COND);
}
void cond_init(void)
@@ -265,11 +455,17 @@ void cond_init(void)
char path[MAX_ARG_LEN];
if (mkpath(pid_runpath(_PATH_COND, path, sizeof(path)), 0755) && errno != EEXIST) {
_pe("Failed creating condition base directory '%s'", _PATH_COND);
err(1, "Failed creating condition base directory '%s'", _PATH_COND);
return;
}
cond_bump_reconf();
cond_boot_strap();
}
void cond_exit(void)
{
cond_delpath(_PATH_COND);
}
/**
+6 -2
View File
@@ -21,8 +21,12 @@
* THE SOFTWARE.
*/
#include <lite/lite.h>
#include <stdio.h>
#ifdef _LIBITE_LITE
# include <libite/lite.h>
#else
# include <lite/lite.h>
#endif
#include "finit.h"
#include "cond.h"
@@ -108,7 +112,7 @@ enum cond_state cond_get_agg(const char *names)
int cond_affects(const char *name, const char *names)
{
static char conds[MAX_COND_LEN];
char conds[MAX_COND_LEN];
char *cond;
if (!name || !names)
+20 -4
View File
@@ -2,15 +2,20 @@
#define FINIT_COND_H_
#include <paths.h>
#include <svc.h>
#include "svc.h"
#define COND_BASE "finit/cond"
#define COND_USR "usr/"
#define COND_DEV "dev/"
#define COND_PID "pid/"
#define COND_SYS "sys/"
#define COND_USR "usr/"
#define _PATH_COND _PATH_VARRUN COND_BASE "/"
#define _PATH_CONDUSR _PATH_COND COND_USR
#define _PATH_CONDDEV _PATH_COND COND_DEV
#define _PATH_CONDPID _PATH_COND COND_PID
#define _PATH_CONDSYS _PATH_COND COND_SYS
#define _PATH_CONDUSR _PATH_COND COND_USR
#define _PATH_RECONF _PATH_COND "reconf"
typedef enum cond_state {
@@ -28,14 +33,25 @@ enum cond_state cond_get (const char *name);
enum cond_state cond_get_agg (const char *names);
int cond_affects (const char *name, const char *names);
void cond_update (const char *name);
void cond_boot_parse (char *arg);
int cond_update (const char *name);
int cond_set_path (const char *path, enum cond_state new);
void cond_set (const char *name);
void cond_set_oneshot (const char *name);
void cond_clear (const char *name);
void cond_reload (void);
int cond_set_noupdate(const char *name);
int cond_set_oneshot_noupdate(const char *name);
int cond_clear_noupdate(const char *name);
void cond_reassert (const char *pat);
void cond_deassert (const char *pat);
int cond_is_available(void);
void cond_init (void);
void cond_exit (void);
#endif /* FINIT_COND_H_ */

Some files were not shown because too many files have changed in this diff Show More