mirror of
https://github.com/troglobit/finit.git
synced 2026-10-13 10:14:47 +00:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58e31dbd22 | ||
|
|
85058b54a8 | ||
|
|
f16df142d7 | ||
|
|
f9f52a46a6 | ||
|
|
ef1bfb869f | ||
|
|
5002c74876 | ||
|
|
a0bc23c48f | ||
|
|
350cf6e578 | ||
|
|
b96a8d8766 | ||
|
|
a419828dea | ||
|
|
702b22d4a3 |
@@ -29,11 +29,11 @@ jobs:
|
|||||||
sudo apt-get -y update
|
sudo apt-get -y update
|
||||||
sudo apt-get -y install pkg-config
|
sudo apt-get -y install pkg-config
|
||||||
wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
|
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.5.2/libite-2.5.2.tar.gz
|
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 libuev-2.3.2.tar.xz
|
||||||
tar xf libite-2.5.2.tar.gz
|
tar xf libite-2.3.1.tar.gz
|
||||||
(cd libuev-2.3.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
(cd libuev-2.3.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
||||||
(cd libite-2.5.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
(cd libite-2.3.1 && ./configure --prefix=/usr && make && sudo make install-strip)
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Static Finit
|
- name: Static Finit
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: Release General
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- '[0-9]+.[0-9]+*'
|
- '[0-9]+.[0-9]+'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
|
|||||||
+5
-80
@@ -10,73 +10,14 @@ All relevant changes are documented in this file.
|
|||||||
Critical bug fix release. If you run a 32-bit target with GLIBC 2.34
|
Critical bug fix release. If you run a 32-bit target with GLIBC 2.34
|
||||||
you *need* to upgrade!
|
you *need* to upgrade!
|
||||||
|
|
||||||
> **Note:** system verbosity on console at start and shutdown has been
|
|
||||||
> increased. Now the output of all commands is logged to the
|
|
||||||
> system logger, for early services `/dev/kmsg` is used.
|
|
||||||
>
|
|
||||||
> **Also:** please notice the updated support for enabling and disabling
|
|
||||||
> kernel and Finit debug messages on the system console. Very
|
|
||||||
> useful when debugging either of them, e.g., a kernel module.
|
|
||||||
> For details, see [cmdline.md](doc/cmdline.md).
|
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
* Support for overriding default runlevel from kernel command line. Any
|
|
||||||
runlevel `[1-9]` may be selected, except 6 (reboot). Issue #261
|
|
||||||
* New command line option: `finit.fstab=/etc/fstab.custom`, with full
|
|
||||||
support for mounting, mount helpers, fsck, and swapon/off, issue #224
|
|
||||||
* Support for special device `/dev/root`, which may not exist in `/dev`.
|
|
||||||
Finit now looks up the matching block device for `/` in `/sys/block/`
|
|
||||||
* Loading `module`s no longer shows arguments in progress output
|
* Loading `module`s no longer shows arguments in progress output
|
||||||
* Warning messages in progress output now in yellow, not red, issue #214
|
* Warning messages in progress output now in yellow, not red, issue 214
|
||||||
* `initctl`, new command line option `-V,--version` for ease of use
|
* `initctl`, new command line option `-v,--version` for ease of use
|
||||||
|
* Extended environment variables for pre/post scripts, issue #189
|
||||||
* New condition `done` for run task, issue #207 by Ming Liu, Atlas Copco
|
* New condition `done` for run task, issue #207 by Ming Liu, Atlas Copco
|
||||||
* Refactor parts of shutdown and reboot sequence for PREEMPT-RT kernels,
|
* Refactor parts of shutdown and reboot sequence for PREEMPT-RT kernels,
|
||||||
by Robert Andersson, Mathias Thore, and Ming Liu, Atlas Copco
|
by Robert Andersson, Mathias Thore, and Ming Liu, Atlas Copco
|
||||||
* Conditions for run/task/sysv status, e.g. `run/foo/success` and
|
|
||||||
`task/bar/failure`. Issue #232, by Ming Liu, Atlas Copco
|
|
||||||
* Conditions for services, 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`
|
|
||||||
* `initctl signal` support, by Jörgen Sigvardsson, issue #225
|
|
||||||
* `initctl cond get` support to match `cond [set | clear]`, issue #255
|
|
||||||
* `[WARN]` messages on console now printed in yellow, issue #214
|
|
||||||
* Network services now also stopped when going to runlevel 6 (reboot),
|
|
||||||
not just runlevel 0 (shutdown) or 1 (single-user)
|
|
||||||
* When `ifup` is missing on the system, bring at least `lo` up at boot
|
|
||||||
* Log output from `ifup -a` (and `ifdown -a`), to syslog
|
|
||||||
* Avoid blocking PID 1 when starting SysV init scripts
|
|
||||||
* Allow custom `pid:` for SysV init scripts
|
|
||||||
* Document supported types of forking/non-forking services
|
|
||||||
* Auto-detect running in some common forms of containers
|
|
||||||
* Simplify shutdown/reboot when running in a container
|
|
||||||
* Log to `stderr` when running in a container w/o syslog daemon
|
|
||||||
* Add support for `type:forking` to services, already supported but
|
|
||||||
with a very difficult `pid:` syntax, issue #223. Docs updated
|
|
||||||
* Support for setting global environment variables in `finit.conf`,
|
|
||||||
please note: this also affects Finit itself, be careful!
|
|
||||||
* Extended environment variables for pre/post scripts, issue #189
|
|
||||||
* Document secret service option `respawn`, which bypasses the crash
|
|
||||||
semantics, allowing endless restarts
|
|
||||||
* Document secret `HOOK_BANNER`, the first hook point before the banner
|
|
||||||
* New plugin: `hook-scripts`, allows [run-parts(8)][] style scripts to
|
|
||||||
run on any hook point. Contributed by Tobias Waldekranz
|
|
||||||
* `initctl` (`reboot`) falls back to `-f` when it detects it is in
|
|
||||||
`sulogin` recovery mode, issue #247
|
|
||||||
* The bundled `sulogin` is no longer enabled by default, in favor of
|
|
||||||
distribution versions. Enable with `./configure --with-sulogin`
|
|
||||||
* Support args to sysv-like scripts, e.g. `bridge-stp br0 start`
|
|
||||||
* The `modules-load` plugin now skips all lines starting with `#` and
|
|
||||||
`;`. Furthermore, files in `/etc/modules-load.d/*.conf` are now read
|
|
||||||
in lexicographic order and UNIX backup files (`foo.conf~`) are skipped
|
|
||||||
* The `name:id` tuple is now more consistently used in all log and debug
|
|
||||||
messages instead of the basename of the command
|
|
||||||
|
|
||||||
[run-parts(8)]: https://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
* Fix nasty 32/64-bit alignment issue between finit and its plugins,
|
* Fix nasty 32/64-bit alignment issue between finit and its plugins,
|
||||||
@@ -86,22 +27,6 @@ you *need* to upgrade!
|
|||||||
or does not have the required controllers (cpu)
|
or does not have the required controllers (cpu)
|
||||||
* Fix #217: iwatcher initialization issue, by Ming Liu, Atlas Copco
|
* Fix #217: iwatcher initialization issue, by Ming Liu, Atlas Copco
|
||||||
* Fix #218: initctl matches too many services, by Ming Liu, Atlas Copco
|
* Fix #218: initctl matches too many services, by Ming Liu, Atlas Copco
|
||||||
* Fix #219: not all filesystems unmounted at shutdown, by Ming Liu,
|
|
||||||
Mathias Thore, and Robert Andersson, Atlas Copco
|
|
||||||
* Fix #226: initctl shows wrong PID for crashing services
|
|
||||||
* Fix #227: reboot stalls if process stopped with `[WARN]`
|
|
||||||
* Fix #233: initctl shows wrong status for run/task, by Sergio Morlans
|
|
||||||
and Ming Liu, Atlas Copco
|
|
||||||
* Fix #248: source `env:file` also in `pre:` and `post` scripts
|
|
||||||
* Fix #260: drop limit on device name in `Checking filesystem`...` output
|
|
||||||
* Fix start/stop and monitoring (restart) of SysV init scripts and
|
|
||||||
forking services, see the updated documentation for details
|
|
||||||
* Fix call to `swapoff` at shutdown, does not support `-e` flag
|
|
||||||
* Fix suspend to RAM issue. Previously `reboot(RB_SW_SUSPEND)` was
|
|
||||||
used, now the modern `/sys/power/state` API is used instead.
|
|
||||||
* Fix nasty run/task/service matcher bug, triggered by stanzas using the
|
|
||||||
same basename of a command but different `:ID`. Caused Finit to match
|
|
||||||
with already registered but different run/task/service
|
|
||||||
|
|
||||||
|
|
||||||
[4.2][] - 2022-01-16
|
[4.2][] - 2022-01-16
|
||||||
@@ -856,7 +781,7 @@ The inetd release.
|
|||||||
### Changes
|
### Changes
|
||||||
* Add support for built-in inetd super server -- launch services on
|
* Add support for built-in inetd super server -- launch services on
|
||||||
demand. Supports filtering per interface and custom Inet ports.
|
demand. Supports filtering per interface and custom Inet ports.
|
||||||
* Upgrade to [libuEv][] v1.1.0 to better handle error conditions.
|
* Upgrade to [libuEv] v1.1.0 to better handle error conditions.
|
||||||
* Allow mixed case config directives in `finit.conf`
|
* Allow mixed case config directives in `finit.conf`
|
||||||
* Add support for RFC 868 (rdate) time plugin, start as inetd service.
|
* Add support for RFC 868 (rdate) time plugin, start as inetd service.
|
||||||
* Load plugins before parsing `finit.conf`, this makes it possible to
|
* Load plugins before parsing `finit.conf`, this makes it possible to
|
||||||
@@ -887,7 +812,7 @@ The inetd release.
|
|||||||
[1.11][] - 2015-01-24 [YANKED]
|
[1.11][] - 2015-01-24 [YANKED]
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
The [libuEv][] release.
|
The [libuEv] release.
|
||||||
|
|
||||||
**Note:** This release has been *yanked* from distribution due to a
|
**Note:** This release has been *yanked* from distribution due to a
|
||||||
regression in launching background processes and TTY's. Fixed in
|
regression in launching background processes and TTY's. Fixed in
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -29,5 +29,3 @@ release: distcheck
|
|||||||
printf "$$file.md5\t"; cat ../$$file.md5 | cut -f1 -d' '; \
|
printf "$$file.md5\t"; cat ../$$file.md5 | cut -f1 -d' '; \
|
||||||
printf "$$file.sha256\t"; cat ../$$file.sha256 | cut -f1 -d' '; \
|
printf "$$file.sha256\t"; cat ../$$file.sha256 | cut -f1 -d' '; \
|
||||||
done
|
done
|
||||||
|
|
||||||
DISTCHECK_CONFIGURE_FLAGS = --with-fstab=/etc/fstab
|
|
||||||
|
|||||||
@@ -54,11 +54,6 @@ on server and desktop systems as well. For working examples, see the
|
|||||||
* [Alpine Linux](contrib/alpine/), and
|
* [Alpine Linux](contrib/alpine/), and
|
||||||
* [Debian GNU/Linux](contrib/debian/)
|
* [Debian GNU/Linux](contrib/debian/)
|
||||||
|
|
||||||
> **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 x86_64 systems. Custom
|
|
||||||
> setups, targeted at embedded systems, can be found in [myLinux][].
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
@@ -603,7 +598,6 @@ and proposed extensions.
|
|||||||
[Joachim Wiberg]: https://troglobit.com
|
[Joachim Wiberg]: https://troglobit.com
|
||||||
[License]: https://en.wikipedia.org/wiki/MIT_License
|
[License]: https://en.wikipedia.org/wiki/MIT_License
|
||||||
[License Badge]: https://img.shields.io/badge/License-MIT-teal.svg
|
[License Badge]: https://img.shields.io/badge/License-MIT-teal.svg
|
||||||
[GitHub]: https://github.com/troglobit/myLinux/
|
|
||||||
[GitHub]: https://github.com/troglobit/finit/actions/workflows/build.yml/
|
[GitHub]: https://github.com/troglobit/finit/actions/workflows/build.yml/
|
||||||
[GitHub Status]: https://github.com/troglobit/finit/actions/workflows/build.yml/badge.svg
|
[GitHub Status]: https://github.com/troglobit/finit/actions/workflows/build.yml/badge.svg
|
||||||
[Coverity Scan]: https://scan.coverity.com/projects/3545
|
[Coverity Scan]: https://scan.coverity.com/projects/3545
|
||||||
|
|||||||
+4
-33
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT(Finit, 4.3-rc2, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/projects/finit/)
|
AC_INIT(Finit, 4.3-dev, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
|
||||||
AC_CONFIG_AUX_DIR(aux)
|
AC_CONFIG_AUX_DIR(aux)
|
||||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
|
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
@@ -33,8 +33,8 @@ AC_PROG_MKDIR_P
|
|||||||
|
|
||||||
# Configuration.
|
# Configuration.
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_CHECK_HEADERS([termios.h sys/ioctl.h mntent.h sys/sysmacros.h])
|
AC_CHECK_HEADERS([fstaby.h termios.h sys/ioctl.h])
|
||||||
AC_CHECK_FUNCS([strstr getopt getmntent getmntent_r])
|
AC_CHECK_FUNCS([strstr getopt getfsenty])
|
||||||
|
|
||||||
# Check for uint[8,16,32]_t
|
# Check for uint[8,16,32]_t
|
||||||
AC_TYPE_UINT8_T
|
AC_TYPE_UINT8_T
|
||||||
@@ -90,17 +90,12 @@ AC_PLUGIN([modprobe], [yes], [Coldplug modules using modalias magic])
|
|||||||
AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
|
AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
|
||||||
AC_PLUGIN([x11-common], [no], [Console setup (for X)])
|
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([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([hook-scripts], [no], [Trigger script execution from hook points])
|
|
||||||
AC_PLUGIN([hotplug], [yes], [Setup and start udev or mdev hotplug daemon])
|
AC_PLUGIN([hotplug], [yes], [Setup and start udev or mdev hotplug daemon])
|
||||||
AC_PLUGIN([rtc], [yes], [Save and restore RTC using hwclock])
|
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([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([urandom], [yes], [Setup and save random seed at boot/shutdown])
|
||||||
|
|
||||||
# Check for extra arguments or packages
|
# Check for extra arguments or packages
|
||||||
AC_ARG_WITH(fstab,
|
|
||||||
AS_HELP_STRING([--with-fstab=FILE], [System default fstab, default $sysconfdir/fstab]),
|
|
||||||
[fstab=$withval], [fstab=yes])
|
|
||||||
|
|
||||||
AC_ARG_WITH(heading,
|
AC_ARG_WITH(heading,
|
||||||
AS_HELP_STRING([--with-heading=GREET], [Heading for boot progress. Default: PRETTY_NAME from /etc/os-release, fallback to "Finit vX.YY"]),
|
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])
|
[heading=$withval], [heading=yes])
|
||||||
@@ -130,7 +125,7 @@ AC_ARG_WITH(hostname,
|
|||||||
[hostname=$withval], [hostname=yes])
|
[hostname=$withval], [hostname=yes])
|
||||||
|
|
||||||
AC_ARG_WITH(runlevel,
|
AC_ARG_WITH(runlevel,
|
||||||
AS_HELP_STRING([--with-runlevel=N], [Runlevel to switch to after bootstrap [1-9], default: 2]),
|
AS_HELP_STRING([--with-runlevel=N], [Runlevel to switch to after bootstrap, default: 2]),
|
||||||
[runlevel=$withval], [runlevel=yes])
|
[runlevel=$withval], [runlevel=yes])
|
||||||
|
|
||||||
AC_ARG_WITH(random-seed,
|
AC_ARG_WITH(random-seed,
|
||||||
@@ -140,18 +135,10 @@ AC_ARG_WITH(random-seed,
|
|||||||
AC_ARG_WITH(keventd,
|
AC_ARG_WITH(keventd,
|
||||||
AS_HELP_STRING([--with-keventd], [Enable built-in keventd, default: no]),, [with_keventd=no])
|
AS_HELP_STRING([--with-keventd], [Enable built-in keventd, default: no]),, [with_keventd=no])
|
||||||
|
|
||||||
AC_ARG_WITH(sulogin,
|
|
||||||
AS_HELP_STRING([--with-sulogin], [Enable built-in sulogin, default: no.]),, [with_sulogin=no])
|
|
||||||
|
|
||||||
AC_ARG_WITH(watchdog,
|
AC_ARG_WITH(watchdog,
|
||||||
AS_HELP_STRING([--with-watchdog=[DEV]], [Enable built-in watchdog, default: /dev/watchdog]),
|
AS_HELP_STRING([--with-watchdog=[DEV]], [Enable built-in watchdog, default: /dev/watchdog]),
|
||||||
[watchdog=$withval], [with_watchdog=no 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])
|
|
||||||
|
|
||||||
|
|
||||||
### Enable features ###########################################################################
|
### Enable features ###########################################################################
|
||||||
|
|
||||||
# Create config.h from selected features and fallback defaults
|
# Create config.h from selected features and fallback defaults
|
||||||
@@ -177,12 +164,6 @@ AS_IF([test "x$enable_logrotate" != "xno"], [
|
|||||||
AM_CONDITIONAL(LOGROTATE, [test "x$enable_logrotate" = "xyes"])
|
AM_CONDITIONAL(LOGROTATE, [test "x$enable_logrotate" = "xyes"])
|
||||||
|
|
||||||
### With features ##############################################################################
|
### With features ##############################################################################
|
||||||
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$with_config" != "xno"], [
|
||||||
AS_IF([test "x$conf" = "xyes"], [
|
AS_IF([test "x$conf" = "xyes"], [
|
||||||
conf=$sysconfdir/finit.conf])])
|
conf=$sysconfdir/finit.conf])])
|
||||||
@@ -237,8 +218,6 @@ AS_IF([test "x$with_random_seed" != "xno"], [
|
|||||||
|
|
||||||
AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes])
|
AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes])
|
||||||
|
|
||||||
AS_IF([test "x$with_sulogin" != "xno"], [with_sulogin=yes])
|
|
||||||
|
|
||||||
AS_IF([test "x$with_watchdog" != "xno"], [
|
AS_IF([test "x$with_watchdog" != "xno"], [
|
||||||
AS_IF([test "x$watchdog" = "xyes"], [
|
AS_IF([test "x$watchdog" = "xyes"], [
|
||||||
watchdog=/dev/watchdog])
|
watchdog=/dev/watchdog])
|
||||||
@@ -246,15 +225,9 @@ AS_IF([test "x$with_watchdog" != "xno"], [
|
|||||||
AC_DEFINE_UNQUOTED(WDT_DEVNODE, "$watchdog", [Built-in watchdog device node])], [
|
AC_DEFINE_UNQUOTED(WDT_DEVNODE, "$watchdog", [Built-in watchdog device node])], [
|
||||||
watchdog=])
|
watchdog=])
|
||||||
|
|
||||||
AS_IF([test "x$enable_hook_scripts_plugin" = "xyes" -a "x$with_hook_scripts_path" != "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])])
|
|
||||||
|
|
||||||
# Control build with automake flags
|
# Control build with automake flags
|
||||||
AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"])
|
AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"])
|
||||||
AM_CONDITIONAL(KEVENTD, [test "x$with_keventd" != "xno"])
|
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(WATCHDOGD, [test "x$with_watchdog" != "xno"])
|
||||||
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(CONTRIB, [test "x$enable_contrib" = "xyes"])
|
||||||
@@ -288,7 +261,6 @@ cat <<EOF
|
|||||||
Exec prefix...........: $eprefix
|
Exec prefix...........: $eprefix
|
||||||
Sysconfdir............: `eval echo $sysconfdir`
|
Sysconfdir............: `eval echo $sysconfdir`
|
||||||
Localstatedir.........: `eval echo $localstatedir`
|
Localstatedir.........: `eval echo $localstatedir`
|
||||||
Default fstab.........: `eval echo $fstab`
|
|
||||||
Finit config file.....: $conf_path
|
Finit config file.....: $conf_path
|
||||||
Finit config.d path...: $rcsd_path
|
Finit config.d path...: $rcsd_path
|
||||||
Finit plugin path.....: $plugin_path
|
Finit plugin path.....: $plugin_path
|
||||||
@@ -306,7 +278,6 @@ Optional features:
|
|||||||
Install doc/..........: $enable_doc
|
Install doc/..........: $enable_doc
|
||||||
Install contrib/......: $enable_contrib
|
Install contrib/......: $enable_contrib
|
||||||
Built-in keventd......: $with_keventd
|
Built-in keventd......: $with_keventd
|
||||||
Built-in sulogin......: $with_sulogin
|
|
||||||
Built-in watchdogd....: $with_watchdog $watchdog
|
Built-in watchdogd....: $with_watchdog $watchdog
|
||||||
Built-in logrotate....: $enable_logrotate
|
Built-in logrotate....: $enable_logrotate
|
||||||
Skip fsck check.......: $enable_fastboot
|
Skip fsck check.......: $enable_fastboot
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
Bootstrap
|
Bootstrap
|
||||||
=========
|
=========
|
||||||
|
|
||||||
0. Get bearings, disable kernel logs, initialize TTY and print banner,
|
|
||||||
unless `HOOK_BANNER` is defined, then call that instead
|
|
||||||
1. Prepare emergency shell, if enabled
|
1. Prepare emergency shell, if enabled
|
||||||
2. Set up initial signal handlers
|
2. Set up initial signal handlers
|
||||||
3. Set up default $PATH early
|
3. Set up default $PATH early
|
||||||
|
|||||||
+9
-25
@@ -29,8 +29,8 @@ optional plugins to enable. It depends on two external libraries:
|
|||||||
The configure script checks for all dependencies, including the correct
|
The configure script checks for all dependencies, including the correct
|
||||||
version of the above mentioned libraries. Currently required versions:
|
version of the above mentioned libraries. Currently required versions:
|
||||||
|
|
||||||
- libite v2.2.0, or later
|
- libite v2.2.0
|
||||||
- libuEv v2.2.0, or later
|
- libuEv v2.2.0
|
||||||
|
|
||||||
|
|
||||||
Configure
|
Configure
|
||||||
@@ -54,7 +54,7 @@ Below are a few of the main switches to configure:
|
|||||||
will be linked statically.
|
will be linked statically.
|
||||||
|
|
||||||
* `--enable-kernel-cmdline`: Enable Finit pre-4.1 parsing of init args from
|
* `--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
|
`/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
|
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-alsa-utils-plugin`: Enable the optional `alsa-utils.so` sound plugin.
|
||||||
@@ -65,19 +65,8 @@ Below are a few of the main switches to configure:
|
|||||||
|
|
||||||
* `--enable-x11-common-plugin`: Enable the optional X Window `x11-common.so` plugin.
|
* `--enable-x11-common-plugin`: Enable the optional X Window `x11-common.so` plugin.
|
||||||
|
|
||||||
* `--with-sulgin`: 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>
|
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
|
Example
|
||||||
-------
|
-------
|
||||||
@@ -85,8 +74,8 @@ Example
|
|||||||
First, unpack the archive:
|
First, unpack the archive:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ tar xf finit-4.3.tar.gz
|
$ tar xf finit-4.1.tar.gz
|
||||||
$ cd finit-4.3/
|
$ cd finit-4.1/
|
||||||
```
|
```
|
||||||
|
|
||||||
Then configure, build and install:
|
Then configure, build and install:
|
||||||
@@ -102,7 +91,7 @@ $ make
|
|||||||
$ DESTDIR=/tmp/finit make install
|
$ DESTDIR=/tmp/finit make install
|
||||||
```
|
```
|
||||||
|
|
||||||
In this example the [finit-4.3.tar.gz][1] archive is unpacked to the
|
In this example the [finit-4.1.tar.gz][1] archive is unpacked to the
|
||||||
user's home directory, configured, built and installed to a temporary
|
user's home directory, configured, built and installed to a temporary
|
||||||
staging directory. The environment variable `DESTDIR` controls the
|
staging directory. The environment variable `DESTDIR` controls the
|
||||||
destination directory when installing, very useful for building binary
|
destination directory when installing, very useful for building binary
|
||||||
@@ -157,22 +146,17 @@ enabled. The default Finit rescue mode configuration is installed into
|
|||||||
|
|
||||||
By default the a root shell, without login, is started.
|
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
|
Debugging
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Edit, or append to, the kernel command line: remove `quiet` to enable
|
Edit, or append to, the kernel command line: remove `quiet` to enable
|
||||||
kernel messages and add `finit.debug` to enable Finit debug messages.
|
kernel messages and add `debug` to enable Finit debug messages.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
append="init=/sbin/finit -- finit.debug"
|
append="init=/sbin/finit debug"
|
||||||
```
|
```
|
||||||
|
|
||||||
Notice the `--` separator.
|
|
||||||
|
|
||||||
To debug startup issues, in particular issues with getty/login, add
|
To debug startup issues, in particular issues with getty/login, add
|
||||||
the following to your Finit .conf file:
|
the following to your Finit .conf file:
|
||||||
|
|
||||||
@@ -191,6 +175,6 @@ it only for debugging start up issues when Finit crashes.
|
|||||||
systems since they can potentially give a user root access.
|
systems since they can potentially give a user root access.
|
||||||
|
|
||||||
|
|
||||||
[1]: ftp://troglobit.com/finit/finit-4.3.tar.gz
|
[1]: ftp://troglobit.com/finit/finit-4.1.tar.gz
|
||||||
[libuEv]: https://github.com/troglobit/libuev
|
[libuEv]: https://github.com/troglobit/libuev
|
||||||
[libite]: https://github.com/troglobit/libite
|
[libite]: https://github.com/troglobit/libite
|
||||||
|
|||||||
+6
-41
@@ -10,32 +10,13 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
|
|||||||
> parameters to init. E.g., `init=/sbin/finit -- finit.debug rescue`
|
> parameters to init. E.g., `init=/sbin/finit -- finit.debug rescue`
|
||||||
|
|
||||||
* `debug`: Enable kernel debug. Debug messages are printed to the
|
* `debug`: Enable kernel debug. Debug messages are printed to the
|
||||||
console until Finit starts up, unless `loglevel=7` (below) is used.
|
console until Finit starts up.
|
||||||
|
|
||||||
* `finit.debug[=bool]`: Enable finit debug. This is operated
|
* `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.fstab=</path/to/etc/fstab.alternative>`: Tell Finit to use an
|
* `finit.show_status[=bool]`: Control finit boot progress, including
|
||||||
alternate `fstab` to mount the file system from. Remember, this file
|
banner.
|
||||||
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,
|
* `finit.status_style=<classic,modern>`: Set Finit boot progress style,
|
||||||
when enabled.
|
when enabled.
|
||||||
@@ -45,18 +26,11 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
|
|||||||
signals and has no job control. Recommend using, and modifying,
|
signals and has no job control. Recommend using, and modifying,
|
||||||
`rescue` mode instead.
|
`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=SEC`: By default the kernel does not reboot after a kernel
|
||||||
panic. This setting will cause a kernel reboot after SEC seconds.
|
panic. This setting will cause a kernel reboot after SEC seconds.
|
||||||
|
|
||||||
* `quiet`: Suppress kernel logging to console, except for warnings and
|
* `quiet`: Suppress kernel logging to console, except for warnings and
|
||||||
errors. Also, see `loglevel` and `quiet` above.
|
errors.
|
||||||
|
|
||||||
* `rescue`: Start rescue/maintenance mode. If your system comes with
|
* `rescue`: Start rescue/maintenance mode. If your system comes with
|
||||||
the bundled `sulogin` program (Finit, or from util-linux/Busybox),
|
the bundled `sulogin` program (Finit, or from util-linux/Busybox),
|
||||||
@@ -65,21 +39,12 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
|
|||||||
the system booted in a limited fallback mode. See [config.md][]
|
the system booted in a limited fallback mode. See [config.md][]
|
||||||
for more information.
|
for more information.
|
||||||
|
|
||||||
**Note:** in this mode `initctl` will not work. Correct the problem
|
|
||||||
and use `reboot -f` to force reboot.
|
|
||||||
|
|
||||||
* `single`, or `S`: Single user mode, runlevel 1, in Finit. Useful to
|
* `single`, or `S`: Single user mode, runlevel 1, in Finit. Useful to
|
||||||
debug problems with the regular runlevel. All services and TTYs in
|
debug problems with the regular runlevel. All services and TTYs in
|
||||||
`[1]` will be started, so a `tty [1] @console nologin` configuration
|
`[1]` will be started, so a `tty [1] @console nologin` configuration
|
||||||
presents you with a root console without login.
|
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)][].
|
For more on kernel boot parameters, see the man page [bootparam(7)][].
|
||||||
|
|
||||||
[config.md]: config.md#rescue-mode
|
[config.md][]: config.md#rescue-mode
|
||||||
[bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html
|
[bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html
|
||||||
|
|||||||
+5
-58
@@ -73,36 +73,6 @@ document [Finit Services](service.md).
|
|||||||
> examples in the `contrib/` directory, which can be used as a base.
|
> examples in the `contrib/` directory, which can be used as a base.
|
||||||
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
In Finit v4.3 support for setting environment variables in `finit.conf`,
|
|
||||||
and any `*.conf`, was added. It is worth noting that these are global
|
|
||||||
and *shared with all* services -- the only way to have service-local
|
|
||||||
environment is detailed in the next section.
|
|
||||||
|
|
||||||
The syntax for global environment variables is straight forward:
|
|
||||||
|
|
||||||
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 environment of already started processes can
|
|
||||||
not be changed.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
Service Environment
|
Service Environment
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
@@ -353,10 +323,6 @@ calls `init-script restart` on `initctl reload`. Similar to how
|
|||||||
|
|
||||||
Forking services started with `sysv` scripts can be monitored by Finit
|
Forking services started with `sysv` scripts can be monitored by Finit
|
||||||
by declaring the PID file to look for: `pid:!/path/to/pidfile.pid`.
|
by declaring the PID file to look for: `pid:!/path/to/pidfile.pid`.
|
||||||
Notice the leading `!`, it signifies Finit should not try to create the
|
|
||||||
file, but rather watch that file for the resulting forked-off PID. This
|
|
||||||
syntax also works for forking daemons that do not have a command line
|
|
||||||
option to run it in the foreground, more on this below in `service`.
|
|
||||||
|
|
||||||
> `<COND>` is described in the [Services](#services) section.
|
> `<COND>` is described in the [Services](#services) section.
|
||||||
|
|
||||||
@@ -372,27 +338,15 @@ After which they have to be manually restarted with `initctl restart
|
|||||||
NAME`. The limits controling this are configurable, see the options
|
NAME`. The limits controling this are configurable, see the options
|
||||||
below.
|
below.
|
||||||
|
|
||||||
> **Tip:** to allow endless restarts, see below option `respawn`
|
|
||||||
|
|
||||||
For daemons that support it, we recommend appending `--foreground`,
|
For daemons that support it, we recommend appending `--foreground`,
|
||||||
`--no-background`, `-n`, `-F`, or similar command line argument to
|
`--no-background`, `-n`, `-F`, or similar command line argument to
|
||||||
prevent them from forking off a sub-process in the background. This is
|
prevent them from forking off a sub-process in the background. This is
|
||||||
the most reliable way to monitor a service.
|
the most reliable way to monitor a service.
|
||||||
|
|
||||||
However, not all daemons support running in the foreground, or they may
|
However, not all daemons support running in the foreground, or they may
|
||||||
start logging to the foreground as well, these are forking daemons and
|
start logging to the foreground as well, these are called forking
|
||||||
are supported using the same syntax as forking `sysv` services, using
|
services and are supported using the same syntax as forking `sysv`
|
||||||
the `pid:!/path/to/pidfile.pid` syntax. There is an alternative syntax
|
services, using the `pid:!/path/to/pidfile.pid` syntax.
|
||||||
that may be more intuitive, where Finit can also guess the PID file
|
|
||||||
based on the daemon's command name:
|
|
||||||
|
|
||||||
service type:forking ntpd -- NTP daemon
|
|
||||||
|
|
||||||
This example lets BusyBox `ntpd` daemonize itself. Finit uses the
|
|
||||||
basename of the binary to guess the PID file to watch for the PID:
|
|
||||||
`/var/run/ntpd.pid`. If Finit guesses wrong, you have to submit the
|
|
||||||
full `pid:!/path/to/file.pid`.
|
|
||||||
|
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
@@ -443,17 +397,13 @@ As mentioned previously, services are automatically restarted, this is
|
|||||||
configurable with the following options:
|
configurable with the following options:
|
||||||
|
|
||||||
* `restart:NUM` -- number of times Finit tries to restart a crashing
|
* `restart:NUM` -- number of times Finit tries to restart a crashing
|
||||||
service, default: 10, max: 255. When this limit is reached the
|
service, default: 10. When this limit is reached the service is
|
||||||
service is marked *crashed* and must be restarted manually with
|
marked *crashed* and must be restarted manually with `initctl`
|
||||||
`initctl restart NAME`
|
|
||||||
* `restart_sec:SEC` -- number of seconds before Finit tries to restart
|
* `restart_sec:SEC` -- number of seconds before Finit tries to restart
|
||||||
a crashing service, default: 2 seconds for the first five retries,
|
a crashing service, default: 2 seconds for the first five retries,
|
||||||
then back-off to 5 seconds. The maximum of this configured value
|
then back-off to 5 seconds. The maximum of this configured value
|
||||||
and the above (2 and 5) will be used
|
and the above (2 and 5) will be used
|
||||||
* `norestart` -- dont restart on failures, same as `restart:0`
|
* `norestart` -- dont restart on failures, same as `restart:0`
|
||||||
* `respawn` -- bypasses the `restart` mechanism completely, allows
|
|
||||||
endless restarts. Useful in many use-cases, but not what `service`
|
|
||||||
was originally designed for so not the default behavior
|
|
||||||
* `oncrash:reboot` -- when all retries have failed, and the service
|
* `oncrash:reboot` -- when all retries have failed, and the service
|
||||||
has *crashed*, if this option is set the system is rebooted.
|
has *crashed*, if this option is set the system is rebooted.
|
||||||
Note, future releases may include other `oncrash:` actions
|
Note, future releases may include other `oncrash:` actions
|
||||||
@@ -675,9 +625,6 @@ activate it.
|
|||||||
|
|
||||||
The rescue mode comes in two flavors; *traditional* and *fallback*.
|
The rescue mode comes in two flavors; *traditional* and *fallback*.
|
||||||
|
|
||||||
> **Note:** in this mode `initctl` will not work. Use the `-f` flag to
|
|
||||||
> force `reboot`, `shutdown`, or `poweroff`.
|
|
||||||
|
|
||||||
|
|
||||||
### Traditional
|
### Traditional
|
||||||
|
|
||||||
|
|||||||
+5
-34
@@ -34,50 +34,26 @@ For your convenience a set of *optional* plugins are available:
|
|||||||
* *dbus.so*: Setup and start system message bus, D-Bus, at boot.
|
* *dbus.so*: Setup and start system message bus, D-Bus, at boot.
|
||||||
_Optional plugin._
|
_Optional plugin._
|
||||||
|
|
||||||
* *hook-scripts.so*: Trigger the execution of scripts from plugin hook
|
|
||||||
points (see [Hooks](#hooks)). Scripts are located in
|
|
||||||
`/libexec/finit/hook` by default, this can be build-time customized
|
|
||||||
by using the `--with-hook-scripts-path=PATH` argument to
|
|
||||||
`configure`. _Optional plugin._
|
|
||||||
|
|
||||||
* *hotplug.so*: Setup and start either udev or mdev hotplug daemon, if
|
* *hotplug.so*: Setup and start either udev or mdev hotplug daemon, if
|
||||||
available. Enabled by default.
|
available.
|
||||||
|
|
||||||
* *rtc.so*: Restore and save system clock from/to RTC on boot/halt.
|
* *rtc.so*: Restore and save system clock from/to RTC on boot/halt.
|
||||||
Enabled by default.
|
|
||||||
|
|
||||||
* *modules-load.so*: Scans `/etc/modules-load.d/*.conf` for modules to
|
* *modules-load.so*: Scans /etc/modules-load.d for modules to modprobe.
|
||||||
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, `#`, is skipped.
|
|
||||||
|
|
||||||
Modules are loaded when entering runlevel `[2345]` using the `task`
|
|
||||||
stanza. Each module gets a unique `name:modprobe.foo`, and
|
|
||||||
optional`:ID`. The `:ID` is a globally incremented index, which can
|
|
||||||
be disabled per file (anywhere) using the following config line:
|
|
||||||
|
|
||||||
set noindex
|
|
||||||
|
|
||||||
**Note:** unlike the traditional .conf `module` directive, which load
|
|
||||||
any listed module immediately, this plugin creates standard `taks`
|
|
||||||
directives which load the module(s) in the background. As long as
|
|
||||||
the `modprobe` program is found in the path, these tasks will always
|
|
||||||
return `[ OK ]` at boot. Check the actual status using `initctl`.
|
|
||||||
|
|
||||||
* *netlink.so*: Listens to Linux kernel Netlink events for gateway and
|
* *netlink.so*: Listens to Linux kernel Netlink events for gateway and
|
||||||
interfaces. These events are then sent to the Finit service monitor
|
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
|
for services that may want to be SIGHUP'ed on new default route or
|
||||||
interfaces going up/down. Enabled by default.
|
interfaces going up/down.
|
||||||
|
|
||||||
* *resolvconf.so*: Setup necessary files for `resolvconf` at startup.
|
* *resolvconf.so*: Setup necessary files for `resolvconf` at startup.
|
||||||
_Optional plugin._
|
_Optional plugin._
|
||||||
|
|
||||||
* *tty.so*: Watches `/dev`, using inotify, for new device nodes (TTY's)
|
* *tty.so*: Watches `/dev`, using inotify, for new device nodes (TTY's)
|
||||||
to start/stop getty consoles on them on demand. Useful when plugging
|
to start/stop getty consoles on them on demand. Useful when plugging
|
||||||
in a usb2serial converter to login to your embedded device. Enabled
|
in a usb2serial converter to login to your embedded device.
|
||||||
by default.
|
|
||||||
|
|
||||||
* *urandom.so*: Setup random seed at startup. Enabled by default.
|
* *urandom.so*: Setup random seed at startup.
|
||||||
|
|
||||||
* *x11-common.so*: Setup necessary files for X-Window. _Optional plugin._
|
* *x11-common.so*: Setup necessary files for X-Window. _Optional plugin._
|
||||||
|
|
||||||
@@ -93,11 +69,6 @@ Hooks
|
|||||||
|
|
||||||
### Bootstrap Hooks
|
### Bootstrap Hooks
|
||||||
|
|
||||||
* `HOOK_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_ROOTFS_UP`: When `finit.conf` has been read and `/` has is
|
* `HOOK_ROOTFS_UP`: When `finit.conf` has been read and `/` has is
|
||||||
mounted — very early
|
mounted — very early
|
||||||
|
|
||||||
|
|||||||
+1
-11
@@ -27,17 +27,7 @@ Finit can *not* start and monitor a daemon that:
|
|||||||
|
|
||||||
### Forks to Background w/ PID File
|
### Forks to Background w/ PID File
|
||||||
|
|
||||||
There are two syntax variants, type 1 and type 2. The former is the
|
service pid:!/run/serv.pid serv -- Forking service
|
||||||
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
|
### Runs in Foreground w/ PID File
|
||||||
|
|
||||||
|
|||||||
+2
-85
@@ -11,11 +11,9 @@
|
|||||||
.Nd Fast init for Linux systems
|
.Nd Fast init for Linux systems
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm /sbin/finit
|
.Nm /sbin/finit
|
||||||
.Op --
|
.Op finit.status_style=classic
|
||||||
|
.Op finit.show_status=[on,off]
|
||||||
.Op finit.debug
|
.Op finit.debug
|
||||||
.Op finit.fstab=/etc/fstab.alt
|
|
||||||
.Op finit.status=<on,off>
|
|
||||||
.Op finit.status_style=<classic,modern>
|
|
||||||
.Op rescue | recover
|
.Op rescue | recover
|
||||||
.Op single | S
|
.Op single | S
|
||||||
.Nm /sbin/telinit
|
.Nm /sbin/telinit
|
||||||
@@ -63,93 +61,12 @@ Plugin support for customization
|
|||||||
.It
|
.It
|
||||||
Proper rescue mode with bundled `sulogin` for protected maintenance shell
|
Proper rescue mode with bundled `sulogin` for protected maintenance shell
|
||||||
.El
|
.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 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 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.
|
|
||||||
.El
|
|
||||||
.Sh BOOTING
|
.Sh BOOTING
|
||||||
.Pp
|
.Pp
|
||||||
Before laucnhing services, the system needs to be bootstrapped. This
|
Before laucnhing services, the system needs to be bootstrapped. This
|
||||||
involves mounting all filesystems (not already mounted by an initramfs)
|
involves mounting all filesystems (not already mounted by an initramfs)
|
||||||
in
|
in
|
||||||
.Pa /etc/fstab ,
|
.Pa /etc/fstab ,
|
||||||
or any alternate
|
|
||||||
.Pa fstab
|
|
||||||
file provided on the Finit command line using
|
|
||||||
.Cm finit.fstab ,
|
|
||||||
ensuring that necessary filesystems like:
|
ensuring that necessary filesystems like:
|
||||||
.Pa /dev ,
|
.Pa /dev ,
|
||||||
.Pa /proc ,
|
.Pa /proc ,
|
||||||
|
|||||||
+1
-28
@@ -182,12 +182,6 @@ After which they have to be restarted manually using
|
|||||||
The number of restarts, the delay between each restart, and more is
|
The number of restarts, the delay between each restart, and more is
|
||||||
configurable, see the options below.
|
configurable, see the options below.
|
||||||
.Pp
|
.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
|
For daemons that support it, we recommend appending
|
||||||
.Cm --foreground , --no-background , -n , -F ,
|
.Cm --foreground , --no-background , -n , -F ,
|
||||||
or similar command line argument to prevent them from forking off a
|
or similar command line argument to prevent them from forking off a
|
||||||
@@ -200,21 +194,7 @@ services and are supported using the same syntax as forking
|
|||||||
.Cm sysv
|
.Cm sysv
|
||||||
services, using the
|
services, using the
|
||||||
.Cm pid:!/path/to/pidfile.pid
|
.Cm pid:!/path/to/pidfile.pid
|
||||||
command modifier syntax. There is an alternative syntax that may be
|
command modifier syntax.
|
||||||
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
|
.Pp
|
||||||
.Sy Example: in the case of
|
.Sy Example: in the case of
|
||||||
.Cm ospfd
|
.Cm ospfd
|
||||||
@@ -307,13 +287,6 @@ and the above (2 and 5) will be used
|
|||||||
.It Cm norestart
|
.It Cm norestart
|
||||||
dont restart on failures, same as
|
dont restart on failures, same as
|
||||||
.Cm restart:0
|
.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
|
.It Cm oncrash:reboot
|
||||||
when all retries have failed, and the service
|
when all retries have failed, and the service
|
||||||
has
|
has
|
||||||
|
|||||||
@@ -64,10 +64,6 @@ if BUILD_DBUS_PLUGIN
|
|||||||
pkglib_LTLIBRARIES += dbus.la
|
pkglib_LTLIBRARIES += dbus.la
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_HOOK_SCRIPTS_PLUGIN
|
|
||||||
pkglib_LTLIBRARIES += hook-scripts.la
|
|
||||||
endif
|
|
||||||
|
|
||||||
if BUILD_HOTPLUG_PLUGIN
|
if BUILD_HOTPLUG_PLUGIN
|
||||||
pkglib_LTLIBRARIES += hotplug.la
|
pkglib_LTLIBRARIES += hotplug.la
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Save and restore ALSA sound settings using alsactl
|
/* Save and restore ALSA sound settings using alsactl
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+4
-10
@@ -1,6 +1,6 @@
|
|||||||
/* Setup necessary system files for, e.g. UTMP (tracking logins)
|
/* Setup necessary system files for, e.g. UTMP (tracking logins)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,12 +21,8 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <ftw.h>
|
#include <ftw.h>
|
||||||
#ifdef HAVE_MNTENT_H
|
|
||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
#endif
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef _LIBITE_LITE
|
#ifdef _LIBITE_LITE
|
||||||
# include <libite/lite.h>
|
# include <libite/lite.h>
|
||||||
@@ -43,12 +39,10 @@
|
|||||||
|
|
||||||
static int is_tmpfs(char *path)
|
static int is_tmpfs(char *path)
|
||||||
{
|
{
|
||||||
struct mntent mount;
|
|
||||||
struct mntent *mnt;
|
|
||||||
char buf[256];
|
|
||||||
int tmpfs = 0;
|
int tmpfs = 0;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *dir;
|
char *dir;
|
||||||
|
struct mntent *mnt;
|
||||||
|
|
||||||
/* If path is a symlink, check what it resolves to */
|
/* If path is a symlink, check what it resolves to */
|
||||||
dir = realpath(path, NULL);
|
dir = realpath(path, NULL);
|
||||||
@@ -61,7 +55,7 @@ static int is_tmpfs(char *path)
|
|||||||
return 0; /* Dunno, maybe not */
|
return 0; /* Dunno, maybe not */
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((mnt = getmntent_r(fp, &mount, buf, sizeof(buf)))) {
|
while ((mnt = getmntent(fp))) {
|
||||||
if (!strcmp(dir, mnt->mnt_dir))
|
if (!strcmp(dir, mnt->mnt_dir))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -141,7 +135,7 @@ static void setup(void *arg)
|
|||||||
ln("/dev/shm", "/run/shm");
|
ln("/dev/shm", "/run/shm");
|
||||||
|
|
||||||
/* compat only, should really be set up by OS/dist */
|
/* compat only, should really be set up by OS/dist */
|
||||||
ln("/run", "/var/run");
|
ln("../run", "/var/run");
|
||||||
} else {
|
} else {
|
||||||
makedir("/var/lock", 1777);
|
makedir("/var/lock", 1777);
|
||||||
makedir("/var/run", 0755);
|
makedir("/var/run", 0755);
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Setup and start system message bus, D-Bus
|
/* Setup and start system message bus, D-Bus
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,116 +0,0 @@
|
|||||||
/* 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"
|
|
||||||
|
|
||||||
#define CHOOSE(x, y) y
|
|
||||||
static const char *hscript_paths[] = HOOK_TYPES;
|
|
||||||
#undef CHOOSE
|
|
||||||
|
|
||||||
static void hscript_run_parts(hook_point_t hook)
|
|
||||||
{
|
|
||||||
char path[CMD_SIZE] = "";
|
|
||||||
|
|
||||||
strlcat(path, PLUGIN_HOOK_SCRIPTS_PATH, sizeof(path));
|
|
||||||
strlcat(path, hscript_paths[hook] + 4, sizeof(path));
|
|
||||||
|
|
||||||
run_parts(path, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 },
|
|
||||||
};
|
|
||||||
|
|
||||||
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:
|
|
||||||
*/
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Heuristically find and initialize a suitable hotplug daemon
|
/* Heuristically find and initialize a suitable hotplug daemon
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Coldplug modules using modalias magic
|
/* Coldplug modules using modalias magic
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+24
-84
@@ -21,29 +21,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
@@ -63,94 +40,57 @@
|
|||||||
#define MODULES_LOAD_PATH "/etc/modules-load.d"
|
#define MODULES_LOAD_PATH "/etc/modules-load.d"
|
||||||
#endif
|
#endif
|
||||||
#define SERVICE_LINE \
|
#define SERVICE_LINE \
|
||||||
"cgroup.init name:modprobe.%s :%d [2345] /sbin/modprobe %s %s -- Kernel module: %s"
|
"cgroup.init :%d name:modprobe.%s [2345] /sbin/modprobe %s %s -- Kernel module: %s"
|
||||||
#define SERVICE_LINE_NOINDEX \
|
|
||||||
"cgroup.init name:modprobe.%s [2345] /sbin/modprobe %s %s -- Kernel module: %s"
|
|
||||||
|
|
||||||
static int load_file(const char *file, int index)
|
static void load(void *arg)
|
||||||
{
|
{
|
||||||
char module_path[PATH_MAX];
|
struct dirent *d;
|
||||||
char line[256];
|
char line[256];
|
||||||
int num = 0;
|
int index = 1;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
|
_d("Scanning " MODULES_LOAD_PATH " for config files ...");
|
||||||
|
|
||||||
|
dir = opendir(MODULES_LOAD_PATH);
|
||||||
|
if (!dir)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while ((d = readdir(dir))) {
|
||||||
|
char module_path[PATH_MAX];
|
||||||
|
|
||||||
strlcpy(module_path, MODULES_LOAD_PATH "/", sizeof(module_path));
|
strlcpy(module_path, MODULES_LOAD_PATH "/", sizeof(module_path));
|
||||||
strlcat(module_path, file, sizeof(module_path));
|
strlcat(module_path, d->d_name, sizeof(module_path));
|
||||||
|
|
||||||
fp = fopen(module_path, "r");
|
fp = fopen(module_path, "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return 0;
|
continue;
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), fp)) {
|
while (fgets(line, sizeof(line), fp)) {
|
||||||
char cmd[CMD_SIZE], *mod, *args;
|
char cmd[CMD_SIZE], *mod, *args;
|
||||||
|
|
||||||
chomp(line);
|
|
||||||
|
|
||||||
mod = strip_line(line);
|
mod = strip_line(line);
|
||||||
if (!mod[0])
|
if (!*mod)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mod[0] == '#' || mod[0] == ';')
|
mod = chomp(mod);
|
||||||
|
if (!mod || !*mod)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!strcmp(mod, "set noindex")) {
|
|
||||||
index = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strncmp(mod, "set index", 9)) {
|
|
||||||
mod += 9;
|
|
||||||
args = strchr(mod, '=');
|
|
||||||
if (args) /* optional */
|
|
||||||
mod = args + 1;
|
|
||||||
index = atoi(mod);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
mod = strtok_r(mod, " ", &args);
|
mod = strtok_r(mod, " ", &args);
|
||||||
if (!mod)
|
if (!mod)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!index)
|
snprintf(cmd, sizeof(cmd), SERVICE_LINE, index, mod, mod, args, mod);
|
||||||
snprintf(cmd, sizeof(cmd), SERVICE_LINE_NOINDEX, mod, mod, args, mod);
|
|
||||||
else
|
|
||||||
snprintf(cmd, sizeof(cmd), SERVICE_LINE, mod, index++, mod, args, mod);
|
|
||||||
|
|
||||||
service_register(SVC_TYPE_TASK, cmd, global_rlimit, NULL);
|
service_register(SVC_TYPE_TASK, cmd, global_rlimit, NULL);
|
||||||
num++;
|
|
||||||
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: check here for .conf only? */
|
closedir(dir);
|
||||||
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)
|
|
||||||
{
|
|
||||||
struct dirent **dentry;
|
|
||||||
int index = 1;
|
|
||||||
int i, num;
|
|
||||||
|
|
||||||
_d("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 += load_file(dentry[i]->d_name, index);
|
|
||||||
free(dentry[i]);
|
|
||||||
}
|
|
||||||
free(dentry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
|
|||||||
+8
-10
@@ -1,8 +1,7 @@
|
|||||||
|
|
||||||
/* Netlink plugin for IFUP/IFDN and GW events
|
/* Netlink plugin for IFUP/IFDN and GW events
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009-2011 Mårten Wikström <marten.wikstrom@keystream.se>
|
* Copyright (C) 2009-2011 Mårten Wikström <marten.wikstrom@keystream.se>
|
||||||
* Copyright (C) 2009-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (C) 2009-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -253,18 +252,18 @@ static int nl_parse(int sd)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _d("recv %zd bytes", len);
|
_d("recv %lld bytes", len);
|
||||||
l = (size_t)len;
|
l = (size_t)len;
|
||||||
for (nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, l); nh = NLMSG_NEXT(nh, l)) {
|
for (nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, l); nh = NLMSG_NEXT(nh, l)) {
|
||||||
struct nlmsgerr *nle;
|
struct nlmsgerr *nle;
|
||||||
|
|
||||||
switch (nh->nlmsg_type) {
|
switch (nh->nlmsg_type) {
|
||||||
case NLMSG_DONE:
|
case NLMSG_DONE:
|
||||||
// _d("Done with netlink messages.");
|
_d("Done with netlink messages.");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case NLMSG_ERROR:
|
case NLMSG_ERROR:
|
||||||
// _d("Kernel netlink comm. error.");
|
_d("Kernel netlink comm. error.");
|
||||||
nle = NLMSG_DATA(nh);
|
nle = NLMSG_DATA(nh);
|
||||||
if (nle) {
|
if (nle) {
|
||||||
errno = -nle->error;
|
errno = -nle->error;
|
||||||
@@ -274,13 +273,13 @@ static int nl_parse(int sd)
|
|||||||
|
|
||||||
case RTM_NEWROUTE:
|
case RTM_NEWROUTE:
|
||||||
case RTM_DELROUTE:
|
case RTM_DELROUTE:
|
||||||
// _d("Netlink route ...");
|
_d("Netlink route ...");
|
||||||
nl_route(nh, len);
|
nl_route(nh, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RTM_NEWLINK:
|
case RTM_NEWLINK:
|
||||||
case RTM_DELLINK:
|
case RTM_DELLINK:
|
||||||
// _d("Netlink link ...");
|
_d("Netlink link ...");
|
||||||
nl_link(nh, len);
|
nl_link(nh, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -304,14 +303,14 @@ static int nl_request(int sd, unsigned int seq, int type)
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case RTM_GETROUTE:
|
case RTM_GETROUTE:
|
||||||
// _d("RTM_GETROUTE");
|
_d("RTM_GETROUTE");
|
||||||
nlr->rtm.rtm_family = AF_INET;
|
nlr->rtm.rtm_family = AF_INET;
|
||||||
nlr->rtm.rtm_table = RT_TABLE_MAIN;
|
nlr->rtm.rtm_table = RT_TABLE_MAIN;
|
||||||
nlr->nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
nlr->nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RTM_GETLINK:
|
case RTM_GETLINK:
|
||||||
// _d("RTM_GETLINK");
|
_d("RTM_GETLINK");
|
||||||
nlr->ifi.ifi_family = AF_UNSPEC;
|
nlr->ifi.ifi_family = AF_UNSPEC;
|
||||||
nlr->ifi.ifi_change = 0xFFFFFFFF;
|
nlr->ifi.ifi_change = 0xFFFFFFFF;
|
||||||
nlr->nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
nlr->nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||||
@@ -450,7 +449,6 @@ PLUGIN_INIT(plugin_init)
|
|||||||
PLUGIN_EXIT(plugin_exit)
|
PLUGIN_EXIT(plugin_exit)
|
||||||
{
|
{
|
||||||
plugin_unregister(&plugin);
|
plugin_unregister(&plugin);
|
||||||
close(plugin.io.fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-8
@@ -1,7 +1,7 @@
|
|||||||
/* Simple pidfile event monitor for the Finit condition engine
|
/* Simple pidfile event monitor for the Finit condition engine
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2016 Tobias Waldekranz <tobias@waldekranz.com>
|
* Copyright (c) 2015-2016 Tobias Waldekranz <tobias@waldekranz.com>
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -98,16 +98,10 @@ static void pidfile_update_conds(char *dir, char *name, uint32_t mask)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Service is not crashing, let's tell state machine! */
|
|
||||||
service_forked(svc);
|
|
||||||
|
|
||||||
if (pid != svc->pid) {
|
if (pid != svc->pid) {
|
||||||
_d("Forking service %s changed PID from %d to %d",
|
_d("Forking service %s changed PID from %d to %d",
|
||||||
svc->cmd, svc->pid, pid);
|
svc->cmd, svc->pid, pid);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,8 +305,8 @@ PLUGIN_INIT(plugin_init)
|
|||||||
|
|
||||||
PLUGIN_EXIT(plugin_exit)
|
PLUGIN_EXIT(plugin_exit)
|
||||||
{
|
{
|
||||||
plugin_unregister(&plugin);
|
|
||||||
iwatch_exit(&iw_pidfile);
|
iwatch_exit(&iw_pidfile);
|
||||||
|
plugin_unregister(&plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Set kernel variables from /etc/sysctl.conf et al
|
/* Set kernel variables from /etc/sysctl.conf et al
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Setup necessary files for resolvconf
|
/* Setup necessary files for resolvconf
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Save and restore RTC using hwclock
|
/* Save and restore RTC using hwclock
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+6
-2
@@ -1,6 +1,6 @@
|
|||||||
/* System condition event monitor for the Finit condition engine
|
/* System condition event monitor for the Finit condition engine
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -160,19 +160,23 @@ static void sys_init(void *arg)
|
|||||||
char sysdir[MAX_ARG_LEN];
|
char sysdir[MAX_ARG_LEN];
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
|
_d("Calling mkpath() on sys conds");
|
||||||
if (mkpath(pid_runpath(_PATH_CONDSYS, sysdir, sizeof(sysdir)), 0755) && errno != EEXIST) {
|
if (mkpath(pid_runpath(_PATH_CONDSYS, sysdir, sizeof(sysdir)), 0755) && errno != EEXIST) {
|
||||||
_pe("Failed creating %s condition directory, %s", COND_SYS, _PATH_CONDSYS);
|
_pe("Failed creating %s condition directory, %s", COND_SYS, _PATH_CONDSYS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_d("Calling realpth() on condsys");
|
||||||
path = realpath(_PATH_CONDSYS, NULL);
|
path = realpath(_PATH_CONDSYS, NULL);
|
||||||
if (!path) {
|
if (!path) {
|
||||||
_pe("Cannot figure out real path to %s, aborting", _PATH_CONDSYS);
|
_pe("Cannot figure out real path to %s, aborting", _PATH_CONDSYS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_d("Calling iwatch_add()");
|
||||||
if (iwatch_add(&iw_sys, path, IN_ONLYDIR))
|
if (iwatch_add(&iw_sys, path, IN_ONLYDIR))
|
||||||
iwatch_exit(&iw_sys);
|
iwatch_exit(&iw_sys);
|
||||||
|
_d("Done.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
@@ -197,8 +201,8 @@ PLUGIN_INIT(plugin_init)
|
|||||||
|
|
||||||
PLUGIN_EXIT(plugin_exit)
|
PLUGIN_EXIT(plugin_exit)
|
||||||
{
|
{
|
||||||
plugin_unregister(&plugin);
|
|
||||||
iwatch_exit(&iw_sys);
|
iwatch_exit(&iw_sys);
|
||||||
|
plugin_unregister(&plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-2
@@ -1,7 +1,7 @@
|
|||||||
/* Optional TTY Watcher, used to catch new TTYs that are discovered, e.g., USB
|
/* 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 Mattias Walström <lazzer@gmail.com>
|
||||||
* Copyright (c) 2013-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2013-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -116,9 +116,10 @@ PLUGIN_INIT(plugin_init)
|
|||||||
|
|
||||||
PLUGIN_EXIT(plugin_exit)
|
PLUGIN_EXIT(plugin_exit)
|
||||||
{
|
{
|
||||||
plugin_unregister(&plugin);
|
|
||||||
if (plugin.io.fd)
|
if (plugin.io.fd)
|
||||||
close(plugin.io.fd);
|
close(plugin.io.fd);
|
||||||
|
|
||||||
|
plugin_unregister(&plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Setup and save random seed at boot/shutdown
|
/* Setup and save random seed at boot/shutdown
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/* User-defined condition event monitor for the Finit condition engine
|
/* User-defined condition event monitor for the Finit condition engine
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -123,8 +123,8 @@ PLUGIN_INIT(plugin_init)
|
|||||||
|
|
||||||
PLUGIN_EXIT(plugin_exit)
|
PLUGIN_EXIT(plugin_exit)
|
||||||
{
|
{
|
||||||
plugin_unregister(&plugin);
|
|
||||||
iwatch_exit(&iw_usr);
|
iwatch_exit(&iw_usr);
|
||||||
|
plugin_unregister(&plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Console setup (for X)
|
/* Console setup (for X)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-4
@@ -8,10 +8,7 @@ AM_LDFLAGS = -export-dynamic
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
sbin_PROGRAMS = finit initctl
|
sbin_PROGRAMS = finit initctl
|
||||||
pkglibexec_PROGRAMS = getty logit
|
pkglibexec_PROGRAMS = getty logit sulogin
|
||||||
if SULOGIN
|
|
||||||
pkglibexec_PROGRAMS += sulogin
|
|
||||||
endif
|
|
||||||
if KEVENTD
|
if KEVENTD
|
||||||
pkglibexec_PROGRAMS += keventd
|
pkglibexec_PROGRAMS += keventd
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* External client API, using UNIX domain socket.
|
/* External client API, using UNIX domain socket.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,8 +21,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -38,6 +36,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <uev/uev.h>
|
#include <uev/uev.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
@@ -198,7 +197,7 @@ static svc_t *do_find(char *buf, size_t len)
|
|||||||
if (!id)
|
if (!id)
|
||||||
return svc_named_iterator(&iter, 1, input);
|
return svc_named_iterator(&iter, 1, input);
|
||||||
|
|
||||||
return svc_find(input, id);
|
return svc_find_by_nameid(input, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static svc_t *do_find_byc(char *buf, size_t len)
|
static svc_t *do_find_byc(char *buf, size_t len)
|
||||||
@@ -251,10 +250,10 @@ static int do_reboot(int cmd, char *buf, size_t len)
|
|||||||
case INIT_CMD_SUSPEND:
|
case INIT_CMD_SUSPEND:
|
||||||
_d("suspend");
|
_d("suspend");
|
||||||
sync();
|
sync();
|
||||||
rc = suspend();
|
rc = reboot(RB_SW_SUSPEND);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (errno == EINVAL)
|
if (errno == EINVAL)
|
||||||
snprintf(buf, len, "Kernel does not support suspend to RAM.");
|
snprintf(buf, len, "Kernel does not support suspend.");
|
||||||
else
|
else
|
||||||
snprintf(buf, len, "Failed: %s", strerror(errno));
|
snprintf(buf, len, "Failed: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
/* Finit control group support functions
|
/* Finit control group support functions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2019-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -465,9 +465,9 @@ void cgroup_init(uev_ctx_t *ctx)
|
|||||||
|
|
||||||
if (mount("none", FINIT_CGPATH, "cgroup2", opts, NULL)) {
|
if (mount("none", FINIT_CGPATH, "cgroup2", opts, NULL)) {
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
logit(LOG_INFO, "Kernel does not support cgroups v2, disabling.");
|
logit(LOG_NOTICE, "Kernel does not support cgroups v2, disabling.");
|
||||||
else if (errno == EPERM) /* Probably inside an unpriviliged container */
|
else if (errno == EPERM) /* Probably inside an unpriviliged container */
|
||||||
logit(LOG_INFO, "Not allowed to mount cgroups v2, disabling.");
|
logit(LOG_NOTICE, "Not allowed to mount cgroups v2, disabling.");
|
||||||
else
|
else
|
||||||
_pe("Failed mounting cgroup v2");
|
_pe("Failed mounting cgroup v2");
|
||||||
avail = 0;
|
avail = 0;
|
||||||
@@ -526,7 +526,7 @@ void cgroup_init(uev_ctx_t *ctx)
|
|||||||
|
|
||||||
/* Move ourselves to init (best effort, otherwise run in 'root' group */
|
/* Move ourselves to init (best effort, otherwise run in 'root' group */
|
||||||
if (fnwrite("1", FINIT_CGPATH "/init/cgroup.procs")) {
|
if (fnwrite("1", FINIT_CGPATH "/init/cgroup.procs")) {
|
||||||
_pe("Failed moving PID 1 to cgroup %s", FINIT_CGPATH "/init");
|
_pe("Failed moving PID 1 to cgroup ", FINIT_CGPATH "/init");
|
||||||
uev_io_stop(&cgw);
|
uev_io_stop(&cgw);
|
||||||
iwatch_exit(&iw_cgroup);
|
iwatch_exit(&iw_cgroup);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Finit control group support functions
|
/* Finit control group support functions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2019-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* New client tool, replaces old /dev/initctl API and telinit tool
|
/* New client tool, replaces old /dev/initctl API and telinit tool
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2019-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Cgroup utility functions for initctl
|
/* Cgroup utility functions for initctl
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2019-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+5
-11
@@ -1,6 +1,6 @@
|
|||||||
/* External client API, using UNIX domain socket.
|
/* External client API, using UNIX domain socket.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -39,17 +39,11 @@ int client_connect(void)
|
|||||||
};
|
};
|
||||||
|
|
||||||
sd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
sd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
||||||
if (-1 == sd) {
|
if (-1 == sd)
|
||||||
warn("Failed creating UNIX domain socket");
|
err(1, "Failed creating UNIX domain socket");
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connect(sd, (struct sockaddr*)&sun, sizeof(sun)) == -1) {
|
if (connect(sd, (struct sockaddr*)&sun, sizeof(sun)) == -1)
|
||||||
if (errno != ENOENT)
|
err(1, "Failed connecting to finit");
|
||||||
warnx("Failed connecting to finit");
|
|
||||||
close(sd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* External client API, using UNIX domain socket.
|
/* External client API, using UNIX domain socket.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-31
@@ -21,7 +21,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <ftw.h>
|
#include <ftw.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -133,25 +132,6 @@ static int cond_checkpath(const char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Intended for 'service/foo/`, nothing else */
|
|
||||||
static void cond_delpath(const char *path)
|
|
||||||
{
|
|
||||||
char fn[PATH_MAX];
|
|
||||||
struct dirent *d;
|
|
||||||
DIR *dir;
|
|
||||||
|
|
||||||
dir = opendir(path);
|
|
||||||
if (!dir)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while ((d = readdir(dir))) {
|
|
||||||
paste(fn, sizeof(fn), path, d->d_name);
|
|
||||||
remove(fn);
|
|
||||||
}
|
|
||||||
closedir(dir);
|
|
||||||
unlink(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cond_set_path(const char *path, enum cond_state next)
|
int cond_set_path(const char *path, enum cond_state next)
|
||||||
{
|
{
|
||||||
enum cond_state prev;
|
enum cond_state prev;
|
||||||
@@ -175,19 +155,9 @@ int cond_set_path(const char *path, enum cond_state next)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case COND_OFF:
|
case COND_OFF:
|
||||||
if (unlink(path)) {
|
if (unlink(path) && errno != ENOENT)
|
||||||
switch (errno) {
|
|
||||||
case ENOENT:
|
|
||||||
break;
|
|
||||||
case EISDIR:
|
|
||||||
cond_delpath(path);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_pe("Failed removing condition '%s'", path);
|
_pe("Failed removing condition '%s'", path);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
_e("Invalid condition state");
|
_e("Invalid condition state");
|
||||||
|
|||||||
+41
-178
@@ -1,6 +1,6 @@
|
|||||||
/* Parser for /etc/finit.conf and /etc/finit.d/<SVC>.conf
|
/* Parser for /etc/finit.conf and /etc/finit.d/<SVC>.conf
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -54,12 +54,6 @@
|
|||||||
int logfile_size_max = 200000; /* 200 kB */
|
int logfile_size_max = 200000; /* 200 kB */
|
||||||
int logfile_count_max = 5;
|
int logfile_count_max = 5;
|
||||||
|
|
||||||
struct env_entry {
|
|
||||||
TAILQ_ENTRY(env_entry) link;
|
|
||||||
char *name;
|
|
||||||
};
|
|
||||||
static TAILQ_HEAD(, env_entry) env_list = TAILQ_HEAD_INITIALIZER(env_list);
|
|
||||||
|
|
||||||
struct rlimit initial_rlimit[RLIMIT_NLIMITS];
|
struct rlimit initial_rlimit[RLIMIT_NLIMITS];
|
||||||
struct rlimit global_rlimit[RLIMIT_NLIMITS];
|
struct rlimit global_rlimit[RLIMIT_NLIMITS];
|
||||||
|
|
||||||
@@ -73,7 +67,7 @@ struct conf_change {
|
|||||||
static struct iwatch iw_conf;
|
static struct iwatch iw_conf;
|
||||||
static uev_t etcw;
|
static uev_t etcw;
|
||||||
|
|
||||||
static TAILQ_HEAD(, conf_change) conf_change_list = TAILQ_HEAD_INITIALIZER(conf_change_list);
|
static TAILQ_HEAD(head, conf_change) conf_change_list = TAILQ_HEAD_INITIALIZER(conf_change_list);
|
||||||
|
|
||||||
static int parse_conf(char *file, int is_rcsd);
|
static int parse_conf(char *file, int is_rcsd);
|
||||||
static void drop_changes(void);
|
static void drop_changes(void);
|
||||||
@@ -93,8 +87,7 @@ fallback:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* finit.debug = [on,off]
|
* finit.debug = [on,off]
|
||||||
* finit.fstab = /path/to/etc/fstab.aternative
|
* finit.show_status = [on,off]
|
||||||
* finit.status = [on,off] (compat finit.show_status)
|
|
||||||
* finit.status_style = [old,classic,modern]
|
* finit.status_style = [old,classic,modern]
|
||||||
*/
|
*/
|
||||||
static void parse_finit_opts(char *opt)
|
static void parse_finit_opts(char *opt)
|
||||||
@@ -110,11 +103,6 @@ static void parse_finit_opts(char *opt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_compare(opt, "fstab")) {
|
|
||||||
fstab = arg;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string_compare(opt, "status_style")) {
|
if (string_compare(opt, "status_style")) {
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
_e("status_style option requires an argument, skipping.");
|
_e("status_style option requires an argument, skipping.");
|
||||||
@@ -128,39 +116,12 @@ static void parse_finit_opts(char *opt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_compare(opt, "status") || string_compare(opt, "show_status")) {
|
if (string_compare(opt, "show_status")) {
|
||||||
show_progress(get_bool(arg, 1) ? PROGRESS_DEFAULT : PROGRESS_SILENT);
|
show_progress(get_bool(arg, 1) ? PROGRESS_DEFAULT : PROGRESS_SILENT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* When runlevel (single integer) is given on the command line,
|
|
||||||
* it overrides the runlevel in finit.conf and the built-in
|
|
||||||
* default (from configure). It do however have to pass the
|
|
||||||
* same sanity checks.
|
|
||||||
*/
|
|
||||||
static int parse_runlevel(char *arg)
|
|
||||||
{
|
|
||||||
const char *err = NULL;
|
|
||||||
char *ptr = arg;
|
|
||||||
long long num;
|
|
||||||
|
|
||||||
/* Sanity check the token is just digit(s) */
|
|
||||||
while (*ptr) {
|
|
||||||
if (!isdigit(*ptr++))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
num = strtonum(arg, 1, 9, &err);
|
|
||||||
if (err || num == 6) {
|
|
||||||
_d("Not a valid runlevel (%s), valid levels are [1-9], excluding 6, skipping.", arg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int)num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_arg(char *arg)
|
static void parse_arg(char *arg)
|
||||||
{
|
{
|
||||||
if (!strncmp(arg, "finit.", 6)) {
|
if (!strncmp(arg, "finit.", 6)) {
|
||||||
@@ -168,19 +129,11 @@ static void parse_arg(char *arg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_compare(arg, "rescue") || string_compare(arg, "recover")) {
|
if (string_compare(arg, "rescue") || string_compare(arg, "recover"))
|
||||||
rescue = 1;
|
rescue = 1;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string_compare(arg, "single") || string_compare(arg, "S")) {
|
if (string_compare(arg, "single") || string_compare(arg, "S"))
|
||||||
single = 1;
|
single = 1;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put any new command line options before this line. */
|
|
||||||
|
|
||||||
cmdlevel = parse_runlevel(arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KERNEL_CMDLINE
|
#ifdef KERNEL_CMDLINE
|
||||||
@@ -252,98 +205,8 @@ void conf_parse_cmdline(int argc, char *argv[])
|
|||||||
|
|
||||||
parse_kernel_cmdline();
|
parse_kernel_cmdline();
|
||||||
parse_kernel_loglevel();
|
parse_kernel_loglevel();
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
log_init();
|
||||||
* Clear all environment variables read in parse_env(), they may be
|
|
||||||
* removed now so let the next call to parse_env() restore them.
|
|
||||||
*/
|
|
||||||
void conf_reset_env(void)
|
|
||||||
{
|
|
||||||
struct env_entry *node, *tmp;
|
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(node, &env_list, link, tmp) {
|
|
||||||
TAILQ_REMOVE(&env_list, node, link);
|
|
||||||
if (node->name) {
|
|
||||||
unsetenv(node->name);
|
|
||||||
free(node->name);
|
|
||||||
}
|
|
||||||
free(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
setenv("PATH", _PATH_STDPATH, 1);
|
|
||||||
setenv("SHELL", _PATH_BSHELL, 1);
|
|
||||||
setenv("LOGNAME", "root", 1);
|
|
||||||
setenv("USER", "root", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets, and makes a note of, all KEY=VALUE lines in a given .conf line
|
|
||||||
* from finit.conf, or other .conf file. Note, PATH is always reset in
|
|
||||||
* the conf_reset_env() function.
|
|
||||||
*/
|
|
||||||
static void parse_env(char *line)
|
|
||||||
{
|
|
||||||
struct env_entry *node;
|
|
||||||
char *key, *val, *end;
|
|
||||||
|
|
||||||
/* skip any leading whitespace */
|
|
||||||
key = line;
|
|
||||||
while (isspace(*key))
|
|
||||||
key++;
|
|
||||||
|
|
||||||
/* find end of line */
|
|
||||||
end = key;
|
|
||||||
while (*end)
|
|
||||||
end++;
|
|
||||||
|
|
||||||
/* strip trailing whitespace */
|
|
||||||
if (end > key) {
|
|
||||||
end--;
|
|
||||||
while (isspace(*end))
|
|
||||||
*end-- = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = strchr(key, '=');
|
|
||||||
if (!val)
|
|
||||||
return;
|
|
||||||
*val++ = 0;
|
|
||||||
|
|
||||||
/* strip leading whitespace from value */
|
|
||||||
while (isspace(*val))
|
|
||||||
val++;
|
|
||||||
|
|
||||||
/* unquote value, if quoted */
|
|
||||||
if (val[0] == '"' || val[0] == '\'') {
|
|
||||||
char q = val[0];
|
|
||||||
|
|
||||||
if (*end == q) {
|
|
||||||
val = &val[1];
|
|
||||||
*end = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find end of key */
|
|
||||||
end = key;
|
|
||||||
while (*end)
|
|
||||||
end++;
|
|
||||||
|
|
||||||
/* strip trailing whitespace */
|
|
||||||
if (end > key) {
|
|
||||||
end--;
|
|
||||||
while (isspace(*end))
|
|
||||||
*end-- = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
setenv(key, val, 1);
|
|
||||||
|
|
||||||
node = malloc(sizeof(*node));
|
|
||||||
if (!node) {
|
|
||||||
_pe("Out of memory cannot track env vars");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
node->name = strdup(key);
|
|
||||||
TAILQ_INSERT_HEAD(&env_list, node, link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kmod_exists(char *mod)
|
static int kmod_exists(char *mod)
|
||||||
@@ -617,7 +480,7 @@ static void conf_parse_cgroup(char *line)
|
|||||||
cgroup_add(name, config, 0);
|
cgroup_add(name, config, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_static(char *line, int is_rcsd)
|
static void parse_static(char *line, int is_rcsd)
|
||||||
{
|
{
|
||||||
char cmd[CMD_SIZE];
|
char cmd[CMD_SIZE];
|
||||||
char *x;
|
char *x;
|
||||||
@@ -625,7 +488,7 @@ static int parse_static(char *line, int is_rcsd)
|
|||||||
if (BOOTSTRAP && (MATCH_CMD(line, "host ", x) || MATCH_CMD(line, "hostname ", x))) {
|
if (BOOTSTRAP && (MATCH_CMD(line, "host ", x) || MATCH_CMD(line, "hostname ", x))) {
|
||||||
if (hostname) free(hostname);
|
if (hostname) free(hostname);
|
||||||
hostname = strdup(strip_line(x));
|
hostname = strdup(strip_line(x));
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BOOTSTRAP && MATCH_CMD(line, "mknod ", x)) {
|
if (BOOTSTRAP && MATCH_CMD(line, "mknod ", x)) {
|
||||||
@@ -634,25 +497,25 @@ static int parse_static(char *line, int is_rcsd)
|
|||||||
strcpy(cmd, "mknod ");
|
strcpy(cmd, "mknod ");
|
||||||
strlcat(cmd, dev, sizeof(cmd));
|
strlcat(cmd, dev, sizeof(cmd));
|
||||||
run_interactive(cmd, "Creating device node %s", dev);
|
run_interactive(cmd, "Creating device node %s", dev);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Kernel module to load */
|
/* Kernel module to load */
|
||||||
if (BOOTSTRAP && MATCH_CMD(line, "module ", x)) {
|
if (BOOTSTRAP && MATCH_CMD(line, "module ", x)) {
|
||||||
kmod_load(strip_line(x));
|
kmod_load(strip_line(x));
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BOOTSTRAP && MATCH_CMD(line, "network ", x)) {
|
if (BOOTSTRAP && MATCH_CMD(line, "network ", x)) {
|
||||||
if (network) free(network);
|
if (network) free(network);
|
||||||
network = strdup(strip_line(x));
|
network = strdup(strip_line(x));
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BOOTSTRAP && MATCH_CMD(line, "runparts ", x)) {
|
if (BOOTSTRAP && MATCH_CMD(line, "runparts ", x)) {
|
||||||
if (runparts) free(runparts);
|
if (runparts) free(runparts);
|
||||||
runparts = strdup(strip_line(x));
|
runparts = strdup(strip_line(x));
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MATCH_CMD(line, "include ", x)) {
|
if (MATCH_CMD(line, "include ", x)) {
|
||||||
@@ -661,10 +524,11 @@ static int parse_static(char *line, int is_rcsd)
|
|||||||
strlcpy(cmd, file, sizeof(cmd));
|
strlcpy(cmd, file, sizeof(cmd));
|
||||||
if (!fexist(cmd)) {
|
if (!fexist(cmd)) {
|
||||||
_e("Cannot find include file %s, absolute path required!", x);
|
_e("Cannot find include file %s, absolute path required!", x);
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parse_conf(cmd, is_rcsd);
|
parse_conf(cmd, is_rcsd);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MATCH_CMD(line, "log ", x)) {
|
if (MATCH_CMD(line, "log ", x)) {
|
||||||
@@ -685,14 +549,12 @@ static int parse_static(char *line, int is_rcsd)
|
|||||||
logfile_size_max = size;
|
logfile_size_max = size;
|
||||||
if (count >= 0)
|
if (count >= 0)
|
||||||
logfile_count_max = count;
|
logfile_count_max = count;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MATCH_CMD(line, "shutdown ", x)) {
|
if (MATCH_CMD(line, "shutdown ", x)) {
|
||||||
if (sdown) free(sdown);
|
if (sdown) free(sdown);
|
||||||
sdown = strdup(strip_line(x));
|
sdown = strdup(strip_line(x));
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -709,7 +571,7 @@ static int parse_static(char *line, int is_rcsd)
|
|||||||
cfglevel = RUNLEVEL;
|
cfglevel = RUNLEVEL;
|
||||||
if (cfglevel < 1 || cfglevel > 9 || cfglevel == 6)
|
if (cfglevel < 1 || cfglevel > 9 || cfglevel == 6)
|
||||||
cfglevel = 2; /* Fallback */
|
cfglevel = 2; /* Fallback */
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -729,65 +591,72 @@ static int parse_static(char *line, int is_rcsd)
|
|||||||
if (disabled)
|
if (disabled)
|
||||||
service_init();
|
service_init();
|
||||||
}
|
}
|
||||||
return 0;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
static void parse_dynamic(char *line, struct rlimit rlimit[], char *file)
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_dynamic(char *line, struct rlimit rlimit[], char *file)
|
|
||||||
{
|
{
|
||||||
char *x;
|
char *x;
|
||||||
|
|
||||||
/* Monitored daemon, will be respawned on exit */
|
/* Monitored daemon, will be respawned on exit */
|
||||||
if (MATCH_CMD(line, "service ", x)) {
|
if (MATCH_CMD(line, "service ", x)) {
|
||||||
service_register(SVC_TYPE_SERVICE, x, rlimit, file);
|
service_register(SVC_TYPE_SERVICE, x, rlimit, file);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* One-shot task, will not be respawned */
|
/* One-shot task, will not be respawned */
|
||||||
if (MATCH_CMD(line, "task ", x)) {
|
if (MATCH_CMD(line, "task ", x)) {
|
||||||
service_register(SVC_TYPE_TASK, x, rlimit, file);
|
service_register(SVC_TYPE_TASK, x, rlimit, file);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like task but waits for completion, useful w/ [S] */
|
/* Like task but waits for completion, useful w/ [S] */
|
||||||
if (MATCH_CMD(line, "run ", x)) {
|
if (MATCH_CMD(line, "run ", x)) {
|
||||||
service_register(SVC_TYPE_RUN, x, rlimit, file);
|
service_register(SVC_TYPE_RUN, x, rlimit, file);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Similar to task but is treated like a SysV init script */
|
/* Similar to task but is treated like a SysV init script */
|
||||||
if (MATCH_CMD(line, "sysv ", x)) {
|
if (MATCH_CMD(line, "sysv ", x)) {
|
||||||
service_register(SVC_TYPE_SYSV, x, rlimit, file);
|
service_register(SVC_TYPE_SYSV, x, rlimit, file);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read resource limits */
|
/* Read resource limits */
|
||||||
if (MATCH_CMD(line, "rlimit ", x)) {
|
if (MATCH_CMD(line, "rlimit ", x)) {
|
||||||
conf_parse_rlimit(x, rlimit);
|
conf_parse_rlimit(x, rlimit);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read control group limits */
|
/* Read control group limits */
|
||||||
if (MATCH_CMD(line, "cgroup ", x)) {
|
if (MATCH_CMD(line, "cgroup ", x)) {
|
||||||
conf_parse_cgroup(x);
|
conf_parse_cgroup(x);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set current cgroup for the following services/run/tasks */
|
/* Set current cgroup for the following services/run/tasks */
|
||||||
if (MATCH_CMD(line, "cgroup.", x)) {
|
if (MATCH_CMD(line, "cgroup.", x)) {
|
||||||
strlcpy(cgroup_current, x, sizeof(cgroup_current));
|
strlcpy(cgroup_current, x, sizeof(cgroup_current));
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Regular or serial TTYs to run getty */
|
/* Regular or serial TTYs to run getty */
|
||||||
if (MATCH_CMD(line, "tty ", x)) {
|
if (MATCH_CMD(line, "tty ", x)) {
|
||||||
service_register(SVC_TYPE_TTY, strip_line(x), rlimit, file);
|
service_register(SVC_TYPE_TTY, strip_line(x), rlimit, file);
|
||||||
return 0;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
static void tabstospaces(char *line)
|
||||||
|
{
|
||||||
|
if (!line)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; line[i]; i++) {
|
||||||
|
if (line[i] == '\t')
|
||||||
|
line[i] = ' ';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_conf(char *file, int is_rcsd)
|
static int parse_conf(char *file, int is_rcsd)
|
||||||
@@ -821,13 +690,8 @@ static int parse_conf(char *file, int is_rcsd)
|
|||||||
if (MATCH_CMD(line, "#", x))
|
if (MATCH_CMD(line, "#", x))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!parse_static(line, is_rcsd))
|
parse_static(line, is_rcsd);
|
||||||
continue;
|
parse_dynamic(line, is_rcsd ? rlimit : global_rlimit, file);
|
||||||
if (!parse_dynamic(line, is_rcsd ? rlimit : global_rlimit, file))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Not static or dynamic conf, check if it is a global env. */
|
|
||||||
parse_env(line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@@ -851,7 +715,6 @@ int conf_reload(void)
|
|||||||
/* Mark and sweep */
|
/* Mark and sweep */
|
||||||
cgroup_mark_all();
|
cgroup_mark_all();
|
||||||
svc_mark_dynamic();
|
svc_mark_dynamic();
|
||||||
conf_reset_env();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset global rlimit to bootstrap values from conf_init().
|
* Reset global rlimit to bootstrap values from conf_init().
|
||||||
|
|||||||
+1
-2
@@ -1,6 +1,6 @@
|
|||||||
/* Parser for /etc/finit.conf and /etc/finit.d/<SVC>.conf
|
/* Parser for /etc/finit.conf and /etc/finit.d/<SVC>.conf
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -42,7 +42,6 @@ int conf_any_change (void);
|
|||||||
int conf_changed (char *file);
|
int conf_changed (char *file);
|
||||||
int conf_monitor (void);
|
int conf_monitor (void);
|
||||||
|
|
||||||
void conf_reset_env (void);
|
|
||||||
void conf_parse_cmdline (int argc, char *argv[]);
|
void conf_parse_cmdline (int argc, char *argv[]);
|
||||||
int conf_parse_runlevels (char *runlevels);
|
int conf_parse_runlevels (char *runlevels);
|
||||||
void conf_parse_cond (svc_t *svc, char *cond);
|
void conf_parse_cond (svc_t *svc, char *cond);
|
||||||
|
|||||||
+3
-5
@@ -1,7 +1,7 @@
|
|||||||
/* Functions for exec'ing processes
|
/* Functions for exec'ing processes
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -97,14 +97,12 @@ static int do_redirect(void)
|
|||||||
*/
|
*/
|
||||||
int run(char *cmd, char *log)
|
int run(char *cmd, char *log)
|
||||||
{
|
{
|
||||||
char *args[NUM_ARGS + 1] = { 0 };
|
|
||||||
int status, result, i = 0;
|
int status, result, i = 0;
|
||||||
|
char *args[NUM_ARGS + 1], *arg;
|
||||||
char *backup = NULL;
|
char *backup = NULL;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
if (!log) {
|
if (!log) {
|
||||||
char *arg;
|
|
||||||
|
|
||||||
/* We must create a copy that is possible to modify. */
|
/* We must create a copy that is possible to modify. */
|
||||||
backup = arg = strdup(cmd);
|
backup = arg = strdup(cmd);
|
||||||
if (!arg)
|
if (!arg)
|
||||||
@@ -166,7 +164,7 @@ int run(char *cmd, char *log)
|
|||||||
|
|
||||||
_exit(rc);
|
_exit(rc);
|
||||||
} else if (-1 == pid) {
|
} else if (-1 == pid) {
|
||||||
_pe("%s", !log ? args[0] : cmd);
|
_pe("%s", args[0]);
|
||||||
if (backup)
|
if (backup)
|
||||||
free(backup);
|
free(backup);
|
||||||
|
|
||||||
|
|||||||
+91
-218
@@ -1,7 +1,7 @@
|
|||||||
/* Finit - Fast /sbin/init replacement w/ I/O, hook & service plugins
|
/* Finit - Fast /sbin/init replacement w/ I/O, hook & service plugins
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -26,18 +26,16 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <getopt.h>
|
#ifdef HAVE_FSTAB_H
|
||||||
#ifdef HAVE_MNTENT_H
|
#include <fstab.h>
|
||||||
#include <mntent.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <mntent.h>
|
||||||
#include <time.h> /* tzet() */
|
#include <time.h> /* tzet() */
|
||||||
#include <sys/klog.h>
|
#include <sys/klog.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/stat.h> /* umask(), mkdir() */
|
#include <sys/stat.h> /* umask(), mkdir() */
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#ifdef HAVE_SYS_SYSMACROS_H
|
|
||||||
#include <sys/sysmacros.h>
|
|
||||||
#endif
|
|
||||||
#ifdef _LIBITE_LITE
|
#ifdef _LIBITE_LITE
|
||||||
# include <libite/lite.h>
|
# include <libite/lite.h>
|
||||||
#else
|
#else
|
||||||
@@ -62,14 +60,12 @@
|
|||||||
|
|
||||||
int runlevel = 0; /* Bootstrap 'S' */
|
int runlevel = 0; /* Bootstrap 'S' */
|
||||||
int cfglevel = RUNLEVEL; /* Fallback if no configured runlevel */
|
int cfglevel = RUNLEVEL; /* Fallback if no configured runlevel */
|
||||||
int cmdlevel = 0; /* runlevel override from cmdline */
|
|
||||||
int prevlevel = -1;
|
int prevlevel = -1;
|
||||||
int debug = 0; /* debug mode from kernel cmdline */
|
int debug = 0; /* debug mode from kernel cmdline */
|
||||||
int rescue = 0; /* rescue mode from kernel cmdline */
|
int rescue = 0; /* rescue mode from kernel cmdline */
|
||||||
int single = 0; /* single user mode from kernel cmdline */
|
int single = 0; /* single user mode from kernel cmdline */
|
||||||
int bootstrap = 1; /* set while bootrapping (for TTYs) */
|
int bootstrap = 1; /* set while bootrapping (for TTYs) */
|
||||||
int kerndebug = 0; /* set if /proc/sys/kernel/printk > 7 */
|
int kerndebug = 0; /* set if /proc/sys/kernel/printk > 7 */
|
||||||
char *fstab = FINIT_FSTAB;
|
|
||||||
char *sdown = NULL;
|
char *sdown = NULL;
|
||||||
char *network = NULL;
|
char *network = NULL;
|
||||||
char *hostname = NULL;
|
char *hostname = NULL;
|
||||||
@@ -110,167 +106,70 @@ static void banner(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sulogin(int do_reboot)
|
|
||||||
{
|
|
||||||
int rc = EX_OSFILE;
|
|
||||||
char *cmd[] = {
|
|
||||||
_PATH_SULOGIN,
|
|
||||||
"sulogin",
|
|
||||||
};
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < NELEMS(cmd); i++) {
|
|
||||||
char *path = which(cmd[i]);
|
|
||||||
|
|
||||||
if (access(path, X_OK)) {
|
|
||||||
free(path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = systemf("%s", path);
|
|
||||||
free(path);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (do_reboot) {
|
|
||||||
do_shutdown(SHUT_REBOOT);
|
|
||||||
exit(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *fs_root_dev(char *real, size_t len)
|
|
||||||
{
|
|
||||||
struct dirent *d;
|
|
||||||
struct stat st;
|
|
||||||
int found = 0;
|
|
||||||
dev_t dev;
|
|
||||||
DIR *dir;
|
|
||||||
|
|
||||||
if (stat("/", &st))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (S_ISBLK(st.st_mode))
|
|
||||||
dev = st.st_rdev;
|
|
||||||
else
|
|
||||||
dev = st.st_dev;
|
|
||||||
|
|
||||||
dir = opendir("/sys/block");
|
|
||||||
if (!dir)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while ((d = readdir(dir))) {
|
|
||||||
char buf[10];
|
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
if (fnread(buf, sizeof(buf), "/sys/block/%s/dev", d->d_name) == -1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ptr = strchr(buf, ':');
|
|
||||||
if (!ptr)
|
|
||||||
continue;
|
|
||||||
*ptr++ = 0;
|
|
||||||
|
|
||||||
if (atoi(buf) == (int)major(dev) && atoi(ptr) == (int)minor(dev)) {
|
|
||||||
/* Guess name, assume no renaming */
|
|
||||||
snprintf(real, len, "/dev/%s", d->d_name);
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
if (!found)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return real;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check all filesystems in /etc/fstab with a fs_passno > 0
|
* Check all filesystems in /etc/fstab with a fs_passno > 0
|
||||||
*/
|
*/
|
||||||
static int fsck(int pass)
|
static int fsck(int pass)
|
||||||
{
|
{
|
||||||
struct mntent mount;
|
struct fstab *fs;
|
||||||
struct mntent *mnt;
|
|
||||||
char real[192];
|
|
||||||
char buf[256];
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
fp = setmntent(fstab, "r");
|
if (!setfsent()) {
|
||||||
if (!fp) {
|
_pe("Failed opening fstab");
|
||||||
_pe("Failed opening fstab: %s", fstab);
|
return 1;
|
||||||
sulogin(1);
|
|
||||||
}
|
}
|
||||||
_d("Opened %s, pass %d", fstab, pass);
|
|
||||||
while ((mnt = getmntent_r(fp, &mount, buf, sizeof(buf)))) {
|
while ((fs = getfsent())) {
|
||||||
int fsck_rc = 0;
|
char cmd[80];
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char cmd[256];
|
int fsck_rc = 0;
|
||||||
char *dev;
|
|
||||||
|
|
||||||
_d("got: fsname '%s' dir '%s' type '%s' opts '%s' freq '%d' passno '%d'",
|
if (fs->fs_passno != pass)
|
||||||
mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts,
|
|
||||||
mnt->mnt_freq, mnt->mnt_passno);
|
|
||||||
|
|
||||||
if (mnt->mnt_passno == 0 || mnt->mnt_passno != pass)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Device to maybe fsck, */
|
|
||||||
dev = mnt->mnt_fsname;
|
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (stat(dev, &st) || !S_ISBLK(st.st_mode)) {
|
if (stat(fs->fs_spec, &st) || !S_ISBLK(st.st_mode)) {
|
||||||
int skip = 1;
|
if (!string_match(fs->fs_spec, "UUID=") && !string_match(fs->fs_spec, "LABEL=")) {
|
||||||
|
_d("Cannot fsck %s, not a block device: %s", fs->fs_spec, strerror(errno));
|
||||||
if (string_match(dev, "UUID=") || string_match(dev, "LABEL="))
|
|
||||||
skip = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Kernel short form for root= device, figure out
|
|
||||||
* actual device since we cannot rely on symlinks
|
|
||||||
* https://bugs.busybox.net/show_bug.cgi?id=8891
|
|
||||||
*/
|
|
||||||
else if (string_compare(dev, "/dev/root")) {
|
|
||||||
if (fs_root_dev(real, sizeof(real))) {
|
|
||||||
dev = real;
|
|
||||||
skip = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skip) {
|
|
||||||
_d("Cannot fsck %s, not a block device: %s", dev, strerror(errno));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ismnt("/proc/mounts", mnt->mnt_dir, "rw")) {
|
if (ismnt("/proc/mounts", fs->fs_file, "rw")) {
|
||||||
_d("Skipping fsck of %s, already mounted rw on %s.", dev, mnt->mnt_dir);
|
_d("Skipping fsck of %s, already mounted rw on %s.", fs->fs_spec, fs->fs_file);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FSCK_FIX
|
#ifdef FSCK_FIX
|
||||||
snprintf(cmd, sizeof(cmd), "fsck -yf %s", dev);
|
snprintf(cmd, sizeof(cmd), "fsck -yf %s", fs->fs_spec);
|
||||||
#else
|
#else
|
||||||
snprintf(cmd, sizeof(cmd), "fsck -a %s", dev);
|
snprintf(cmd, sizeof(cmd), "fsck -a %s", fs->fs_spec);
|
||||||
#endif
|
#endif
|
||||||
_d("Running pass %d fsck command %s", pass, cmd);
|
fsck_rc = run_interactive(cmd, "Checking filesystem %.13s", fs->fs_spec);
|
||||||
fsck_rc = run_interactive(cmd, "Checking filesystem %s", dev);
|
|
||||||
/*
|
/*
|
||||||
* "failure" is defined as exiting with a return code of
|
* "failure" is defined as exiting with a return code of
|
||||||
* 2 or larger. A return code of 1 indicates that filesystem
|
* 2 or larger. A return code of 1 indicates that filesystem
|
||||||
* errors were corrected but that the boot may proceed.
|
* errors were corrected but that the boot may proceed.
|
||||||
*/
|
*/
|
||||||
if (fsck_rc > 1) {
|
if (fsck_rc > 1) {
|
||||||
logit(LOG_CONSOLE | LOG_ALERT, "Failed fsck %s, attempting sulogin ...", dev);
|
char *sulogin[] = {
|
||||||
sulogin(1);
|
_PATH_SULOGIN,
|
||||||
|
"sulogin",
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < NELEMS(sulogin); i++) {
|
||||||
|
if (systemf(sulogin[i]))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_shutdown(SHUT_REBOOT);
|
||||||
}
|
}
|
||||||
rc += fsck_rc;
|
rc += fsck_rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
endmntent(fp);
|
endfsent();
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -303,22 +202,38 @@ static void fs_mount(const char *src, const char *tgt, const char *fstype,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SYSROOT
|
#ifndef SYSROOT
|
||||||
|
/* If / is not listed in fstab, or listed as 'ro', leave it alone */
|
||||||
|
static int fs_readonly_root(struct fstab *fs)
|
||||||
|
{
|
||||||
|
char *tok, *str;
|
||||||
|
|
||||||
|
if (!fs)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
str = fs->fs_mntops;
|
||||||
|
while ((tok = strtok(str, ","))) {
|
||||||
|
if (!strcmp(tok, "ro"))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
str = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void fs_remount_root(int fsckerr)
|
static void fs_remount_root(int fsckerr)
|
||||||
{
|
{
|
||||||
struct mntent *mnt;
|
struct fstab *fs;
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
fp = setmntent(fstab, "r");
|
if (!setfsent())
|
||||||
if (!fp)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while ((mnt = getmntent(fp))) {
|
while ((fs = getfsent())) {
|
||||||
if (!strcmp(mnt->mnt_dir, "/"))
|
if (!strcmp(fs->fs_file, "/"))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If / is not listed in fstab, or listed as 'ro', leave it alone */
|
if (fs_readonly_root(fs))
|
||||||
if (!mnt || hasmntopt(mnt, "ro"))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (fsckerr)
|
if (fsckerr)
|
||||||
@@ -328,7 +243,7 @@ static void fs_remount_root(int fsckerr)
|
|||||||
"Remounting / as read-write");
|
"Remounting / as read-write");
|
||||||
|
|
||||||
out:
|
out:
|
||||||
endmntent(fp);
|
endfsent();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void fs_remount_root(int fsckerr)
|
static void fs_remount_root(int fsckerr)
|
||||||
@@ -404,69 +319,22 @@ static void fs_finalize(void)
|
|||||||
fs_mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV, "mode=1777");
|
fs_mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV, "mode=1777");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fs_swapon(char *cmd, size_t len)
|
|
||||||
{
|
|
||||||
struct mntent *mnt;
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
if (!whichp("swapon"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
fp = setmntent(fstab, "r");
|
|
||||||
if (!fp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while ((mnt = getmntent(fp))) {
|
|
||||||
if (strcmp(mnt->mnt_type, MNTTYPE_SWAP))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
snprintf(cmd, len, "swapon %s", mnt->mnt_fsname);
|
|
||||||
run_interactive(cmd, "Enabling swap %s", mnt->mnt_fsname);
|
|
||||||
}
|
|
||||||
|
|
||||||
endmntent(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fs_mount_all(void)
|
static void fs_mount_all(void)
|
||||||
{
|
{
|
||||||
char cmd[256] = "mount -na";
|
|
||||||
|
|
||||||
if (!fstab || !fexist(fstab)) {
|
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "%s system fstab %s, trying fallback ...",
|
|
||||||
!fstab ? "Missing" : "Cannot find", fstab ?: "\b");
|
|
||||||
fstab = FINIT_FSTAB;
|
|
||||||
}
|
|
||||||
if (!fstab || !fexist(fstab)) {
|
|
||||||
logit(LOG_CONSOLE | LOG_EMERG, "%s system fstab %s, attempting sulogin ...",
|
|
||||||
!fstab ? "Missing" : "Cannot find", fstab ?: "\b");
|
|
||||||
sulogin(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Needed by fsck, both BusyBox and util-linux support this.
|
|
||||||
* We leave it set in the env. for the benefit of any mount
|
|
||||||
* helpers and other system tools that the user expects to
|
|
||||||
* behave even if we've booted with a different fstab.
|
|
||||||
*/
|
|
||||||
setenv("FSTAB_FILE", fstab, 1);
|
|
||||||
|
|
||||||
if (!rescue)
|
if (!rescue)
|
||||||
fs_remount_root(fsck_all());
|
fs_remount_root(fsck_all());
|
||||||
|
|
||||||
_d("Root FS up, calling hooks ...");
|
_d("Root FS up, calling hooks ...");
|
||||||
plugin_run_hooks(HOOK_ROOTFS_UP);
|
plugin_run_hooks(HOOK_ROOTFS_UP);
|
||||||
|
|
||||||
if (fstab && strcmp(fstab, "/etc/fstab"))
|
if (run_interactive("mount -na", "Mounting filesystems"))
|
||||||
snprintf(cmd, sizeof(cmd), "mount -na -T %s", fstab);
|
|
||||||
|
|
||||||
if (run_interactive(cmd, "Mounting filesystems from %s", fstab))
|
|
||||||
plugin_run_hooks(HOOK_MOUNT_ERROR);
|
plugin_run_hooks(HOOK_MOUNT_ERROR);
|
||||||
|
|
||||||
_d("Calling extra mount hook, after mount -a ...");
|
_d("Calling extra mount hook, after mount -a ...");
|
||||||
plugin_run_hooks(HOOK_MOUNT_POST);
|
plugin_run_hooks(HOOK_MOUNT_POST);
|
||||||
|
|
||||||
_d("Enable any swap ...");
|
if (whichp("swapon"))
|
||||||
fs_swapon(cmd, sizeof(cmd));
|
run("swapon -ea", "swapon");
|
||||||
|
|
||||||
_d("Finalize, ensure common file systems are available ...");
|
_d("Finalize, ensure common file systems are available ...");
|
||||||
fs_finalize();
|
fs_finalize();
|
||||||
@@ -570,12 +438,11 @@ static void crank_worker(void *unused)
|
|||||||
*/
|
*/
|
||||||
static void bootstrap_worker(void *work)
|
static void bootstrap_worker(void *work)
|
||||||
{
|
{
|
||||||
|
static int cnt = 120;
|
||||||
static struct wq final = {
|
static struct wq final = {
|
||||||
.cb = finalize,
|
.cb = finalize,
|
||||||
.delay = 10
|
.delay = 10
|
||||||
};
|
};
|
||||||
static int cnt = 120;
|
|
||||||
int level = cfglevel;
|
|
||||||
|
|
||||||
_d("Step all services ...");
|
_d("Step all services ...");
|
||||||
service_step_all(SVC_TYPE_ANY);
|
service_step_all(SVC_TYPE_ANY);
|
||||||
@@ -600,18 +467,11 @@ static void bootstrap_worker(void *work)
|
|||||||
if (runparts && fisdir(runparts) && !rescue)
|
if (runparts && fisdir(runparts) && !rescue)
|
||||||
run_parts(runparts, NULL);
|
run_parts(runparts, NULL);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start all tasks/services in the configured runlevel, or jump
|
* Start all tasks/services in the configured runlevel
|
||||||
* into the runlevel selected from the command line.
|
|
||||||
*/
|
*/
|
||||||
if (cmdlevel) {
|
|
||||||
_d("Runlevel %d requested from command line, starting all services ...", cmdlevel);
|
|
||||||
level = cmdlevel;
|
|
||||||
} else
|
|
||||||
_d("Change to default runlevel(%d), starting all services ...", cfglevel);
|
_d("Change to default runlevel(%d), starting all services ...", cfglevel);
|
||||||
|
service_runlevel(cfglevel);
|
||||||
service_runlevel(level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int version(int rc)
|
static int version(int rc)
|
||||||
@@ -710,7 +570,7 @@ int main(int argc, char *argv[])
|
|||||||
};
|
};
|
||||||
uev_ctx_t loop;
|
uev_ctx_t loop;
|
||||||
|
|
||||||
/* user calling telinit or init */
|
/* telinit or stand-alone process monitor */
|
||||||
if (getpid() != 1)
|
if (getpid() != 1)
|
||||||
return telinit(argc, argv);
|
return telinit(argc, argv);
|
||||||
|
|
||||||
@@ -721,12 +581,12 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse /proc/cmdline (debug, rescue, console=, etc.)
|
* Parse /proc/cmdline (debug, rescue, console=, etc.)
|
||||||
|
* Also calls log_init() to set correct log level
|
||||||
*/
|
*/
|
||||||
conf_parse_cmdline(argc, argv);
|
conf_parse_cmdline(argc, argv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figure out system console(s) and call log_init() to set
|
* Figure out system console(s)
|
||||||
* correct log level, possibly finit.debug enabled.
|
|
||||||
*/
|
*/
|
||||||
console_init();
|
console_init();
|
||||||
|
|
||||||
@@ -739,7 +599,10 @@ int main(int argc, char *argv[])
|
|||||||
/*
|
/*
|
||||||
* Set PATH, SHELL, and PWD early to something sane
|
* Set PATH, SHELL, and PWD early to something sane
|
||||||
*/
|
*/
|
||||||
conf_reset_env();
|
setenv("PATH", _PATH_STDPATH, 1);
|
||||||
|
setenv("SHELL", _PATH_BSHELL, 1);
|
||||||
|
setenv("LOGNAME", "root", 1);
|
||||||
|
setenv("USER", "root", 1);
|
||||||
|
|
||||||
if (chdir("/"))
|
if (chdir("/"))
|
||||||
_pe("Failed cd /");
|
_pe("Failed cd /");
|
||||||
@@ -747,8 +610,21 @@ int main(int argc, char *argv[])
|
|||||||
/*
|
/*
|
||||||
* In case of emergency.
|
* In case of emergency.
|
||||||
*/
|
*/
|
||||||
if (rescue)
|
if (rescue) {
|
||||||
rescue = sulogin(0);
|
char *sulogin[] = {
|
||||||
|
_PATH_SULOGIN,
|
||||||
|
"sulogin",
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < NELEMS(sulogin); i++) {
|
||||||
|
if (systemf(sulogin[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rescue = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load plugins early, the first hook is in banner(), so we
|
* Load plugins early, the first hook is in banner(), so we
|
||||||
@@ -777,10 +653,7 @@ int main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
cgroup_init(&loop);
|
cgroup_init(&loop);
|
||||||
|
|
||||||
/*
|
/* Check and mount filesystems. */
|
||||||
* Check custom fstab from cmdline, including fallback, then run
|
|
||||||
* fsck before mounting all filesystems, on error call sulogin.
|
|
||||||
*/
|
|
||||||
fs_mount_all();
|
fs_mount_all();
|
||||||
|
|
||||||
/* Bootstrap conditions, needed for hooks */
|
/* Bootstrap conditions, needed for hooks */
|
||||||
@@ -803,7 +676,7 @@ int main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
if (whichp(FINIT_LIBPATH_ "/watchdogd") && fexist(WDT_DEVNODE)) {
|
if (whichp(FINIT_LIBPATH_ "/watchdogd") && fexist(WDT_DEVNODE)) {
|
||||||
service_register(SVC_TYPE_SERVICE, "[123456789] cgroup.init name:watchdog :finit " FINIT_LIBPATH_ "/watchdogd -- Finit watchdog daemon", global_rlimit, NULL);
|
service_register(SVC_TYPE_SERVICE, "[123456789] cgroup.init name:watchdog :finit " FINIT_LIBPATH_ "/watchdogd -- Finit watchdog daemon", global_rlimit, NULL);
|
||||||
wdog = svc_find("watchdog", "finit");
|
wdog = svc_find_by_nameid("watchdog", "finit");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+2
-4
@@ -1,7 +1,7 @@
|
|||||||
/* Finit - Fast /sbin/init replacement w/ I/O, hook & service plugins
|
/* Finit - Fast /sbin/init replacement w/ I/O, hook & service plugins
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -110,18 +110,16 @@ struct init_request {
|
|||||||
|
|
||||||
extern int runlevel;
|
extern int runlevel;
|
||||||
extern int cfglevel;
|
extern int cfglevel;
|
||||||
extern int cmdlevel;
|
|
||||||
extern int prevlevel;
|
extern int prevlevel;
|
||||||
extern int debug;
|
extern int debug;
|
||||||
extern int rescue;
|
extern int rescue;
|
||||||
extern int single;
|
extern int single;
|
||||||
extern int bootstrap;
|
extern int bootstrap;
|
||||||
extern int kerndebug;
|
extern int kerndebug;
|
||||||
extern char *fstab;
|
extern char *rcsd;
|
||||||
extern char *sdown;
|
extern char *sdown;
|
||||||
extern char *network;
|
extern char *network;
|
||||||
extern char *hostname;
|
extern char *hostname;
|
||||||
extern char *rcsd;
|
|
||||||
extern char *runparts;
|
extern char *runparts;
|
||||||
extern char *osheading;
|
extern char *osheading;
|
||||||
extern uev_ctx_t *ctx;
|
extern uev_ctx_t *ctx;
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/* Initialize and serve a login terminal
|
/* Initialize and serve a login terminal
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
#include "config.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|||||||
+51
-28
@@ -1,7 +1,7 @@
|
|||||||
/* Misc. utility functions for finit and its plugins
|
/* Misc. utility functions for finit and its plugins
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -22,8 +22,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <ctype.h> /* isblank() */
|
#include <ctype.h> /* isblank() */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
@@ -83,7 +81,7 @@ char *console(void)
|
|||||||
|
|
||||||
void console_init(void)
|
void console_init(void)
|
||||||
{
|
{
|
||||||
log_init();
|
ttinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t cprintf(const char *fmt, ...)
|
ssize_t cprintf(const char *fmt, ...)
|
||||||
@@ -102,17 +100,6 @@ ssize_t cprintf(const char *fmt, ...)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tabstospaces(char *line)
|
|
||||||
{
|
|
||||||
if (!line)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i = 0; line[i]; i++) {
|
|
||||||
if (line[i] == '\t')
|
|
||||||
line[i] = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *strip_line(char *line)
|
char *strip_line(char *line)
|
||||||
{
|
{
|
||||||
char *ptr;
|
char *ptr;
|
||||||
@@ -513,25 +500,20 @@ void networking(int updown)
|
|||||||
if (fexist("/etc/network/interfaces")) {
|
if (fexist("/etc/network/interfaces")) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
|
if (!updown) {
|
||||||
|
run_interactive("ifdown -a", "Stopping networking");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
int rc = EX_OSERR;
|
int rc = EX_OSERR;
|
||||||
const char *cmd;
|
|
||||||
FILE *pp;
|
FILE *pp;
|
||||||
|
|
||||||
setsid();
|
setsid();
|
||||||
sig_unblock();
|
sig_unblock();
|
||||||
|
|
||||||
if (updown)
|
pp = popen("ifup -a 2>&1", "r");
|
||||||
cmd = "ifup -a 2>&1";
|
|
||||||
else if (whichp("ifquery"))
|
|
||||||
/* Regular ifodwn supports --force but not -f */
|
|
||||||
cmd = "ifdown -a --force 2>&1";
|
|
||||||
else
|
|
||||||
/* Busybox ifdown support -f, but not --force */
|
|
||||||
cmd = "ifdown -a -f 2>&1";
|
|
||||||
|
|
||||||
pp = popen(cmd, "r");
|
|
||||||
if (pp) {
|
if (pp) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
@@ -544,8 +526,7 @@ void networking(int updown)
|
|||||||
_exit(rc);
|
_exit(rc);
|
||||||
}
|
}
|
||||||
cgroup_service("network", pid, NULL);
|
cgroup_service("network", pid, NULL);
|
||||||
print(pid > 0 ? 0 : 1, "%s network interfaces ...",
|
print(pid > 0 ? 0 : 1, "Bringing up network interfaces ...");
|
||||||
updown ? "Bringing up" : "Taking down");
|
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -600,6 +581,48 @@ int in_container(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_GETFSENT
|
||||||
|
static lfile_t *fstab = NULL;
|
||||||
|
|
||||||
|
int setfsent(void)
|
||||||
|
{
|
||||||
|
if (fstab)
|
||||||
|
lfclose(fstab);
|
||||||
|
|
||||||
|
fstab = lfopen("/etc/fstab", " \t\n");
|
||||||
|
if (!fstab)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fstab *getfsent(void)
|
||||||
|
{
|
||||||
|
static struct fstab fs;
|
||||||
|
|
||||||
|
fs.fs_spec = lftok(fstab);
|
||||||
|
if (fs.fs_spec == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fs.fs_file = lftok(fstab);
|
||||||
|
fs.fs_vfstype = lftok(fstab);
|
||||||
|
fs.fs_mntops = lftok(fstab);
|
||||||
|
fs.fs_type = "rw";
|
||||||
|
fs.fs_freq = atoi(lftok(fstab) ?: "0");
|
||||||
|
fs.fs_passno = atoi(lftok(fstab) ?: "0");
|
||||||
|
|
||||||
|
return &fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void endfsent(void)
|
||||||
|
{
|
||||||
|
if (fstab)
|
||||||
|
lfclose(fstab);
|
||||||
|
|
||||||
|
fstab = NULL;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_GETFSENT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
|
|||||||
+22
-5
@@ -1,7 +1,7 @@
|
|||||||
/* Misc. utility functions and C-library extensions for finit and its plugins
|
/* Misc. utility functions and C-library extensions for finit and its plugins
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -25,6 +25,8 @@
|
|||||||
#ifndef FINIT_HELPERS_H_
|
#ifndef FINIT_HELPERS_H_
|
||||||
#define FINIT_HELPERS_H_
|
#define FINIT_HELPERS_H_
|
||||||
|
|
||||||
|
#include <mntent.h>
|
||||||
|
#include <sched.h> /* sched_yield() */
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -45,11 +47,26 @@ typedef enum {
|
|||||||
PROGRESS_MODERN,
|
PROGRESS_MODERN,
|
||||||
} pstyle_t;
|
} pstyle_t;
|
||||||
|
|
||||||
|
#ifndef HAVE_GETFSENT
|
||||||
|
struct fstab {
|
||||||
|
char *fs_spec; /* block device name */
|
||||||
|
char *fs_file; /* mount point */
|
||||||
|
char *fs_vfstype; /* file-system type */
|
||||||
|
char *fs_mntops; /* mount options */
|
||||||
|
const char *fs_type; /* rw/rq/ro/sw/xx option */
|
||||||
|
int fs_freq; /* dump frequency, in days */
|
||||||
|
int fs_passno; /* pass number on parallel dump */
|
||||||
|
};
|
||||||
|
|
||||||
|
int setfsent (void);
|
||||||
|
void endfsent (void);
|
||||||
|
struct fstab *getfsent (void);
|
||||||
|
#endif /* HAVE_GETFSENT */
|
||||||
|
|
||||||
char *console (void);
|
char *console (void);
|
||||||
void console_init (void);
|
void console_init (void);
|
||||||
ssize_t cprintf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
ssize_t cprintf (const char *fmt, ...);
|
||||||
|
|
||||||
void tabstospaces (char *line);
|
|
||||||
char *strip_line (char *line);
|
char *strip_line (char *line);
|
||||||
|
|
||||||
void enable_progress (int onoff);
|
void enable_progress (int onoff);
|
||||||
@@ -62,7 +79,7 @@ void stty (int fd, speed_t speed);
|
|||||||
|
|
||||||
void print_banner (const char *heading);
|
void print_banner (const char *heading);
|
||||||
void printv (const char *fmt, va_list ap);
|
void printv (const char *fmt, va_list ap);
|
||||||
void print (int action, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
void print (int action, const char *fmt, ...);
|
||||||
void print_desc (char *action, char *desc);
|
void print_desc (char *action, char *desc);
|
||||||
int print_result (int fail);
|
int print_result (int fail);
|
||||||
|
|
||||||
@@ -80,7 +97,7 @@ int in_container (void);
|
|||||||
|
|
||||||
int complete (char *cmd, int pid);
|
int complete (char *cmd, int pid);
|
||||||
int run (char *cmd, char *log);
|
int run (char *cmd, char *log);
|
||||||
int run_interactive (char *cmd, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
int run_interactive (char *cmd, char *fmt, ...);
|
||||||
int exec_runtask (char *cmd, char *args[]);
|
int exec_runtask (char *cmd, char *args[]);
|
||||||
pid_t run_getty (char *tty, char *cmd, char *args[], int noclear, int nowait, struct rlimit rlimit[]);
|
pid_t run_getty (char *tty, char *cmd, char *args[], int noclear, int nowait, struct rlimit rlimit[]);
|
||||||
pid_t run_sh (char *tty, int noclear, int nowait, struct rlimit rlimit[]);
|
pid_t run_sh (char *tty, int noclear, int nowait, struct rlimit rlimit[]);
|
||||||
|
|||||||
+4
-25
@@ -1,6 +1,6 @@
|
|||||||
/* New client tool, replaces old /dev/initctl API and telinit tool
|
/* New client tool, replaces old /dev/initctl API and telinit tool
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -391,7 +391,7 @@ static int do_cond_dump(char *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_cond_act(char *arg, int op)
|
static int do_cond_act(char *arg, int creat)
|
||||||
{
|
{
|
||||||
char oneshot[256];
|
char oneshot[256];
|
||||||
size_t off;
|
size_t off;
|
||||||
@@ -409,29 +409,17 @@ static int do_cond_act(char *arg, int op)
|
|||||||
snprintf(oneshot, sizeof(oneshot), _PATH_CONDUSR "%s", arg);
|
snprintf(oneshot, sizeof(oneshot), _PATH_CONDUSR "%s", arg);
|
||||||
off = strlen(_PATH_COND);
|
off = strlen(_PATH_COND);
|
||||||
|
|
||||||
switch (op) {
|
if (creat) {
|
||||||
case 2:
|
|
||||||
off = !fexist(oneshot);
|
|
||||||
if (verbose)
|
|
||||||
puts(off ? "off" : "on");
|
|
||||||
return off;
|
|
||||||
case 1:
|
|
||||||
if (symlink(_PATH_RECONF, oneshot) && errno != EEXIST)
|
if (symlink(_PATH_RECONF, oneshot) && errno != EEXIST)
|
||||||
err(1, "Failed asserting condition <%s>", &oneshot[off]);
|
err(1, "Failed asserting condition <%s>", &oneshot[off]);
|
||||||
break;
|
} else {
|
||||||
case 0:
|
|
||||||
if (erase(oneshot) && errno != ENOENT)
|
if (erase(oneshot) && errno != ENOENT)
|
||||||
err(1, "Failed deasserting condition <%s>", &oneshot[off]);
|
err(1, "Failed deasserting condition <%s>", &oneshot[off]);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errx(1, "Unsupported operation (%d)", op);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_cond_get(char *arg) { return do_cond_act(arg, 2); }
|
|
||||||
static int do_cond_set(char *arg) { return do_cond_act(arg, 1); }
|
static int do_cond_set(char *arg) { return do_cond_act(arg, 1); }
|
||||||
static int do_cond_clr(char *arg) { return do_cond_act(arg, 0); }
|
static int do_cond_clr(char *arg) { return do_cond_act(arg, 0); }
|
||||||
|
|
||||||
@@ -676,13 +664,6 @@ static char *svc_command(svc_t *svc, char *buf, size_t len)
|
|||||||
strlcat(buf, svc->args[i], len);
|
strlcat(buf, svc->args[i], len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (svc_is_sysv(svc)) {
|
|
||||||
char *cmd = svc->state == SVC_HALTED_STATE ? "stop" : "start";
|
|
||||||
|
|
||||||
strlcat(buf, " ", len);
|
|
||||||
strlcat(buf, cmd, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
strlcat(buf, bold ? "\e[0m" : "", len);
|
strlcat(buf, bold ? "\e[0m" : "", len);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
@@ -1018,7 +999,6 @@ static int usage(int rc)
|
|||||||
// " reload <NAME>[:ID] Reload (SIGHUP) service by name\n"
|
// " reload <NAME>[:ID] Reload (SIGHUP) service by name\n"
|
||||||
"\n"
|
"\n"
|
||||||
" cond set <COND> Set (assert) user-defined condition +usr/COND\n"
|
" cond set <COND> Set (assert) user-defined condition +usr/COND\n"
|
||||||
" cond get <COND> Get status of user-defined condition, see $? and -v\n"
|
|
||||||
" cond clear <COND> Clear (deassert) user-defined condition -usr/COND\n"
|
" cond clear <COND> Clear (deassert) user-defined condition -usr/COND\n"
|
||||||
" cond status Show condition status, default cond command\n"
|
" cond status Show condition status, default cond command\n"
|
||||||
" cond dump Dump all conditions and their status\n"
|
" cond dump Dump all conditions and their status\n"
|
||||||
@@ -1133,7 +1113,6 @@ int main(int argc, char *argv[])
|
|||||||
{ "status", NULL, do_cond_show, NULL, NULL }, /* default cmd */
|
{ "status", NULL, do_cond_show, NULL, NULL }, /* default cmd */
|
||||||
{ "dump", NULL, do_cond_dump, NULL, NULL },
|
{ "dump", NULL, do_cond_dump, NULL, NULL },
|
||||||
{ "set", NULL, do_cond_set, NULL, NULL },
|
{ "set", NULL, do_cond_set, NULL, NULL },
|
||||||
{ "get", NULL, do_cond_get, NULL, NULL },
|
|
||||||
{ "clr", NULL, do_cond_clr, NULL, NULL },
|
{ "clr", NULL, do_cond_clr, NULL, NULL },
|
||||||
{ "clear", NULL, do_cond_clr, NULL, NULL },
|
{ "clear", NULL, do_cond_clr, NULL, NULL },
|
||||||
{ NULL, NULL, NULL, NULL, NULL }
|
{ NULL, NULL, NULL, NULL, NULL }
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/* New client tool, replaces old /dev/initctl API and telinit tool
|
/* New client tool, replaces old /dev/initctl API and telinit tool
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -34,7 +34,7 @@ extern int heading; /* initctl -t */
|
|||||||
extern int verbose; /* initctl -v */
|
extern int verbose; /* initctl -v */
|
||||||
extern int plain; /* initctl -p */
|
extern int plain; /* initctl -p */
|
||||||
|
|
||||||
extern void print_header(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
extern void print_header(const char *fmt, ...);
|
||||||
|
|
||||||
#endif /* FINIT_INITCTL_H_ */
|
#endif /* FINIT_INITCTL_H_ */
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -1,7 +1,7 @@
|
|||||||
/* inotify watcher for files or directories
|
/* inotify watcher for files or directories
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2016 Tobias Waldekranz <tobias@waldekranz.com>
|
* Copyright (c) 2015-2016 Tobias Waldekranz <tobias@waldekranz.com>
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -62,10 +62,8 @@ int iwatch_init(struct iwatch *iw)
|
|||||||
* reconf of systems with lots of services.
|
* reconf of systems with lots of services.
|
||||||
*/
|
*/
|
||||||
len = sizeof(sz);
|
len = sizeof(sz);
|
||||||
if (!getsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, &len)) {
|
if (!getsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, &len))
|
||||||
if (setsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)))
|
setsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz));
|
||||||
_pe("Failed increasing size of inotify socket");
|
|
||||||
}
|
|
||||||
|
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
/* inotify watcher for files or directories
|
/* inotify watcher for files or directories
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2016 Tobias Waldekranz <tobias@waldekranz.com>
|
* Copyright (c) 2015-2016 Tobias Waldekranz <tobias@waldekranz.com>
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+6
-42
@@ -1,6 +1,6 @@
|
|||||||
/* Listens to kernel events like AC power status and manages sys/ conditions
|
/* Listens to kernel events like AC power status and manages sys/ conditions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -53,10 +52,6 @@
|
|||||||
static int num_ac_online;
|
static int num_ac_online;
|
||||||
static int num_ac;
|
static int num_ac;
|
||||||
|
|
||||||
static int running = 1;
|
|
||||||
static int level;
|
|
||||||
static int logon;
|
|
||||||
|
|
||||||
int debug; /* debug in other modules as well */
|
int debug; /* debug in other modules as well */
|
||||||
|
|
||||||
void logit(int prio, const char *fmt, ...)
|
void logit(int prio, const char *fmt, ...)
|
||||||
@@ -64,9 +59,9 @@ void logit(int prio, const char *fmt, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
if (logon)
|
if (!debug)
|
||||||
vsyslog(prio, fmt, ap);
|
vsyslog(prio, fmt, ap);
|
||||||
else if (prio <= level) {
|
else {
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
@@ -184,26 +179,6 @@ static void init(void)
|
|||||||
sys_cond("pwr/ac", 1);
|
sys_cond("pwr/ac", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_logging(int prio)
|
|
||||||
{
|
|
||||||
setlogmask(LOG_UPTO(prio));
|
|
||||||
level = prio;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void toggle_debug(int signo)
|
|
||||||
{
|
|
||||||
(void)signo;
|
|
||||||
|
|
||||||
debug ^= 1;
|
|
||||||
set_logging(debug ? LOG_DEBUG : LOG_NOTICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void shut_down(int signo)
|
|
||||||
{
|
|
||||||
(void)signo;
|
|
||||||
running = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Started by Finit as soon as possible when base filesystem is up,
|
* Started by Finit as soon as possible when base filesystem is up,
|
||||||
* modules have been probed, or insmodded from /etc/finit.conf, so by
|
* modules have been probed, or insmodded from /etc/finit.conf, so by
|
||||||
@@ -223,13 +198,10 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!debug) {
|
if (!debug) {
|
||||||
openlog("keventd", LOG_PID, LOG_DAEMON);
|
openlog("keventd", LOG_CONS | LOG_PID, LOG_DAEMON);
|
||||||
set_logging(LOG_NOTICE);
|
setlogmask(LOG_UPTO(LOG_NOTICE));
|
||||||
logon = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGUSR1, toggle_debug);
|
|
||||||
signal(SIGTERM, shut_down);
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
pfd.events = POLLIN;
|
pfd.events = POLLIN;
|
||||||
@@ -244,18 +216,11 @@ int main(int argc, char *argv[])
|
|||||||
panic("bind failed");
|
panic("bind failed");
|
||||||
|
|
||||||
logit(LOG_DEBUG, "Waiting for events ...");
|
logit(LOG_DEBUG, "Waiting for events ...");
|
||||||
while (running) {
|
while (-1 != poll(&pfd, 1, -1)) {
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
int ac = 0;
|
int ac = 0;
|
||||||
int i, len;
|
int i, len;
|
||||||
|
|
||||||
if (-1 == poll(&pfd, 1, -1)) {
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT);
|
len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
@@ -270,7 +235,6 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf[len] = 0;
|
buf[len] = 0;
|
||||||
logit(LOG_DEBUG, "%s", buf);
|
|
||||||
|
|
||||||
/* skip libusb events, focus on kernel events/changes */
|
/* skip libusb events, focus on kernel events/changes */
|
||||||
if (strncmp(buf, "change@", 7))
|
if (strncmp(buf, "change@", 7))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Finit daemon log functions
|
/* Finit daemon log functions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,8 +21,7 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#ifdef _LIBITE_LITE
|
#ifdef _LIBITE_LITE
|
||||||
@@ -41,8 +40,6 @@ static int loglevel = LOG_INFO;
|
|||||||
|
|
||||||
void log_init(void)
|
void log_init(void)
|
||||||
{
|
{
|
||||||
ttinit();
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
loglevel = LOG_DEBUG;
|
loglevel = LOG_DEBUG;
|
||||||
else
|
else
|
||||||
@@ -75,25 +72,24 @@ static int log_open(void)
|
|||||||
if (debug)
|
if (debug)
|
||||||
opts |= LOG_PERROR;
|
opts |= LOG_PERROR;
|
||||||
|
|
||||||
|
closelog();
|
||||||
openlog("finit", opts, LOG_DAEMON);
|
openlog("finit", opts, LOG_DAEMON);
|
||||||
setlogmask(LOG_UPTO(loglevel));
|
setlogmask(LOG_UPTO(loglevel));
|
||||||
|
|
||||||
return up = 1;
|
return up = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_close(void)
|
|
||||||
{
|
|
||||||
closelog();
|
|
||||||
up = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Toggle debug mode */
|
/* Toggle debug mode */
|
||||||
void log_debug(void)
|
void log_debug(void)
|
||||||
{
|
{
|
||||||
debug = !debug;
|
debug = !debug;
|
||||||
|
|
||||||
log_close();
|
if (debug) {
|
||||||
log_init();
|
loglevel = LOG_DEBUG;
|
||||||
|
} else {
|
||||||
|
loglevel = LOG_NOTICE;
|
||||||
|
ttinit();
|
||||||
|
}
|
||||||
log_open();
|
log_open();
|
||||||
|
|
||||||
logit(LOG_NOTICE, "Debug mode %s", debug ? "enabled" : "disabled");
|
logit(LOG_NOTICE, "Debug mode %s", debug ? "enabled" : "disabled");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Finit daemon log functions
|
/* Finit daemon log functions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -43,14 +43,14 @@
|
|||||||
#define _d(fmt, args...) logit(LOG_DEBUG, "%s():" fmt, __func__, ##args)
|
#define _d(fmt, args...) logit(LOG_DEBUG, "%s():" fmt, __func__, ##args)
|
||||||
#define _w(fmt, args...) logit(LOG_WARNING, "%s():" fmt, __func__, ##args)
|
#define _w(fmt, args...) logit(LOG_WARNING, "%s():" fmt, __func__, ##args)
|
||||||
#define _e(fmt, args...) logit(LOG_ERR, "%s():" fmt, __func__, ##args)
|
#define _e(fmt, args...) logit(LOG_ERR, "%s():" fmt, __func__, ##args)
|
||||||
#define _pe(fmt, args...) logit(LOG_ERR, "%s():" fmt ": %s", __func__, ##args, strerror(errno))
|
#define _pe(fmt, args...) logit(LOG_ERR, "%s():" fmt ": %n", __func__, ##args, strerror(errno))
|
||||||
|
|
||||||
void log_init (void);
|
void log_init (void);
|
||||||
void log_exit (void);
|
void log_exit (void);
|
||||||
|
|
||||||
void log_debug (void);
|
void log_debug (void);
|
||||||
|
|
||||||
void logit (int prio, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
void logit (int prio, const char *fmt, ...);
|
||||||
void flog (char *file, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
void flog (char *file, const char *fmt, ...);
|
||||||
|
|
||||||
#endif /* FINIT_LOG_H_ */
|
#endif /* FINIT_LOG_H_ */
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2018-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2018-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-3
@@ -1,6 +1,6 @@
|
|||||||
/* Handle MD arrays
|
/* Handle MD arrays
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,8 +21,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
+6
-28
@@ -1,6 +1,6 @@
|
|||||||
/* Mount and unmount helpers
|
/* Mount and unmount helpers
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,17 +21,10 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef HAVE_MNTENT_H
|
|
||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
#endif
|
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
|
|
||||||
#include "helpers.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SysV init on Debian/Ubuntu skips these protected mount points
|
* SysV init on Debian/Ubuntu skips these protected mount points
|
||||||
*
|
*
|
||||||
@@ -72,12 +65,12 @@ static void iterator_end(FILE **fp)
|
|||||||
*fp = NULL;
|
*fp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mntent *iterator(char *filename, FILE **fp)
|
static struct mntent *iterator(char *fstab, FILE **fp)
|
||||||
{
|
{
|
||||||
static struct mntent *mnt;
|
static struct mntent *mnt;
|
||||||
|
|
||||||
if (!*fp && filename) {
|
if (!*fp && fstab) {
|
||||||
*fp = setmntent(filename, "r");
|
*fp = setmntent(fstab, "r");
|
||||||
if (!*fp)
|
if (!*fp)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -93,28 +86,13 @@ static struct mntent *iterator(char *filename, FILE **fp)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int unmount(const char *target)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = umount(target);
|
|
||||||
if (rc) {
|
|
||||||
if (errno != EBUSY)
|
|
||||||
print(2, "Failed unmounting %s, error %d: %s", target, errno, strerror(errno));
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
print(0, "Unmounting %s", target);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void unmount_tmpfs(void)
|
void unmount_tmpfs(void)
|
||||||
{
|
{
|
||||||
struct mntent *mnt;
|
struct mntent *mnt;
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
|
|
||||||
while ((mnt = iterator("/proc/mounts", &fp))) {
|
while ((mnt = iterator("/proc/mounts", &fp))) {
|
||||||
if (!strcmp("tmpfs", mnt->mnt_fsname) && !unmount(mnt->mnt_dir))
|
if (!strcmp("tmpfs", mnt->mnt_fsname) && !umount(mnt->mnt_dir))
|
||||||
iterator_end(&fp); /* Restart iteration */
|
iterator_end(&fp); /* Restart iteration */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +103,7 @@ void unmount_regular(void)
|
|||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
|
|
||||||
while ((mnt = iterator("/proc/mounts", &fp))) {
|
while ((mnt = iterator("/proc/mounts", &fp))) {
|
||||||
if (!unmount(mnt->mnt_dir))
|
if (!umount(mnt->mnt_dir))
|
||||||
iterator_end(&fp); /* Restart iteration */
|
iterator_end(&fp); /* Restart iteration */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* PID and PID file helpers
|
/* PID and PID file helpers
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -22,8 +22,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -71,11 +69,10 @@ int pid_alive(pid_t pid)
|
|||||||
*/
|
*/
|
||||||
char *pid_get_name(pid_t pid, char *name, size_t len)
|
char *pid_get_name(pid_t pid, char *name, size_t len)
|
||||||
{
|
{
|
||||||
static char line[64];
|
|
||||||
char *pname = NULL;
|
|
||||||
char path[32];
|
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
char *pname, path[32];
|
||||||
|
static char line[64];
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "/proc/%d/status", pid);
|
snprintf(path, sizeof(path), "/proc/%d/status", pid);
|
||||||
fp = fopen(path, "r");
|
fp = fopen(path, "r");
|
||||||
@@ -116,8 +113,8 @@ char *pid_file(svc_t *svc)
|
|||||||
pid_t pid_file_read(const char *fn)
|
pid_t pid_file_read(const char *fn)
|
||||||
{
|
{
|
||||||
pid_t pid = 0;
|
pid_t pid = 0;
|
||||||
char buf[42];
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
char buf[42];
|
||||||
|
|
||||||
fp = fopen(fn, "r");
|
fp = fopen(fn, "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
@@ -160,11 +157,6 @@ int pid_file_set(svc_t *svc, char *file, int not)
|
|||||||
file++;
|
file++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (svc_is_forking(svc) && !not) {
|
|
||||||
logit(LOG_WARNING, "Service %s is forking, adjusting to pid:!%s", svc->name, file);
|
|
||||||
not = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pid_runpath(file, &svc->pidfile[not], sizeof(svc->pidfile) - not);
|
pid_runpath(file, &svc->pidfile[not], sizeof(svc->pidfile) - not);
|
||||||
if (not)
|
if (not)
|
||||||
svc->pidfile[0] = '!';
|
svc->pidfile[0] = '!';
|
||||||
@@ -207,8 +199,8 @@ int pid_file_parse(svc_t *svc, char *arg)
|
|||||||
|
|
||||||
/* 'pid:' implies argument following*/
|
/* 'pid:' implies argument following*/
|
||||||
if (!strncmp(arg, "pid:", 4)) {
|
if (!strncmp(arg, "pid:", 4)) {
|
||||||
char path[MAX_ARG_LEN];
|
|
||||||
int len, not = 0;
|
int len, not = 0;
|
||||||
|
char path[MAX_ARG_LEN];
|
||||||
|
|
||||||
arg += 4;
|
arg += 4;
|
||||||
if ((arg[0] == '!' && arg[1] == '/') || arg[0] == '/')
|
if ((arg[0] == '!' && arg[1] == '/') || arg[0] == '/')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* PID and PID file helpers
|
/* PID and PID file helpers
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+2
-3
@@ -1,6 +1,6 @@
|
|||||||
/* Plugin based services architecture for finit
|
/* Plugin based services architecture for finit
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,8 +21,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dlfcn.h> /* dlopen() et al */
|
#include <dlfcn.h> /* dlopen() et al */
|
||||||
#include <dirent.h> /* readdir() et al */
|
#include <dirent.h> /* readdir() et al */
|
||||||
@@ -36,6 +34,7 @@
|
|||||||
# include <lite/queue.h> /* BSD sys/queue.h API */
|
# include <lite/queue.h> /* BSD sys/queue.h API */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Plugin based services architecture for finit
|
/* Plugin based services architecture for finit
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
/* Private header file for main finit daemon, not for plugins
|
/* Private header file for main finit daemon, not for plugins
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+3
-10
@@ -1,6 +1,6 @@
|
|||||||
/* reboot, halt, poweroff, shutdown, suspend for finit
|
/* reboot, halt, poweroff, shutdown, suspend for finit
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2009-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -26,7 +26,6 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -160,13 +159,7 @@ int reboot_main(int argc, char *argv[])
|
|||||||
/* Check for any overrides */
|
/* Check for any overrides */
|
||||||
transform(NULL);
|
transform(NULL);
|
||||||
|
|
||||||
/* Check if we're in sulogin shell */
|
|
||||||
if (getenv("SULOGIN"))
|
|
||||||
force = 1;
|
|
||||||
|
|
||||||
if (force) {
|
if (force) {
|
||||||
sync();
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case CMD_REBOOT:
|
case CMD_REBOOT:
|
||||||
c = reboot(RB_AUTOBOOT);
|
c = reboot(RB_AUTOBOOT);
|
||||||
@@ -181,9 +174,9 @@ int reboot_main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SUSPEND:
|
case CMD_SUSPEND:
|
||||||
c = suspend();
|
c = reboot(RB_SW_SUSPEND);
|
||||||
if (c && errno == EINVAL)
|
if (c && errno == EINVAL)
|
||||||
errx(1, "Kernel does not support suspend to RAM.");
|
errx(1, "Kernel does not support suspend.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_UNKNOWN:
|
case CMD_UNKNOWN:
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Work queue helper functions
|
/* Work queue helper functions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2018-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Work queue helper functions
|
/* Work queue helper functions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2018-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+2
-32
@@ -1,6 +1,6 @@
|
|||||||
/* List and enable/disable service configurations
|
/* List and enable/disable service configurations
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2017-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -34,24 +34,9 @@
|
|||||||
# include <lite/lite.h>
|
# include <lite/lite.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "client.h"
|
|
||||||
#include "initctl.h"
|
#include "initctl.h"
|
||||||
|
|
||||||
|
|
||||||
static int is_builtin(char *arg)
|
|
||||||
{
|
|
||||||
svc_t *svc;
|
|
||||||
|
|
||||||
svc = client_svc_find(arg);
|
|
||||||
if (!svc)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (svc->file[0])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int calc_width(char *arr[], size_t len)
|
static int calc_width(char *arr[], size_t len)
|
||||||
{
|
{
|
||||||
int width = 0;
|
int width = 0;
|
||||||
@@ -307,8 +292,6 @@ int serv_touch(char *arg)
|
|||||||
if (!fexist(fn)) {
|
if (!fexist(fn)) {
|
||||||
if (!strstr(arg, "finit.conf"))
|
if (!strstr(arg, "finit.conf"))
|
||||||
errx(1, "%s not available.", arg);
|
errx(1, "%s not available.", arg);
|
||||||
if (is_builtin(arg))
|
|
||||||
errx(1, "%s is a built-in service.", arg);
|
|
||||||
|
|
||||||
strlcpy(path, FINIT_CONF, sizeof(path));
|
strlcpy(path, FINIT_CONF, sizeof(path));
|
||||||
fn = path;
|
fn = path;
|
||||||
@@ -328,9 +311,6 @@ int serv_show(char *arg)
|
|||||||
|
|
||||||
fn = conf(path, sizeof(path), arg, 0);
|
fn = conf(path, sizeof(path), arg, 0);
|
||||||
if (!fexist(fn)) {
|
if (!fexist(fn)) {
|
||||||
if (is_builtin(arg))
|
|
||||||
errx(1, "%s is a built-in service.", arg);
|
|
||||||
|
|
||||||
warnx("Cannot find %s", arg);
|
warnx("Cannot find %s", arg);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -365,9 +345,6 @@ static int do_edit(char *arg, int creat)
|
|||||||
|
|
||||||
fn = conf(path, sizeof(path), arg, creat);
|
fn = conf(path, sizeof(path), arg, creat);
|
||||||
if (!fexist(fn)) {
|
if (!fexist(fn)) {
|
||||||
if (is_builtin(arg))
|
|
||||||
errx(1, "%s is a built-in service.", arg);
|
|
||||||
|
|
||||||
if (!creat) {
|
if (!creat) {
|
||||||
warnx("Cannot find %s, use -c flag, create command, or select one of:", arg);
|
warnx("Cannot find %s, use -c flag, create command, or select one of:", arg);
|
||||||
return serv_list(NULL);
|
return serv_list(NULL);
|
||||||
@@ -394,7 +371,6 @@ int serv_edit(char *arg)
|
|||||||
if (!arg || !arg[0]) {
|
if (!arg || !arg[0]) {
|
||||||
if (!yorn("Do you want to edit %s (y/N)? ", FINIT_CONF))
|
if (!yorn("Do you want to edit %s (y/N)? ", FINIT_CONF))
|
||||||
return 0;
|
return 0;
|
||||||
arg = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return do_edit(arg, icreate);
|
return do_edit(arg, icreate);
|
||||||
@@ -409,9 +385,6 @@ int serv_creat(char *arg)
|
|||||||
if (!arg || !arg[0])
|
if (!arg || !arg[0])
|
||||||
errx(1, "missing argument to create");
|
errx(1, "missing argument to create");
|
||||||
|
|
||||||
if (is_builtin(arg))
|
|
||||||
errx(1, "%s is a built-in service.", arg);
|
|
||||||
|
|
||||||
/* Input from a pipe or a proper TTY? */
|
/* Input from a pipe or a proper TTY? */
|
||||||
if (isatty(STDIN_FILENO))
|
if (isatty(STDIN_FILENO))
|
||||||
return do_edit(arg, 1);
|
return do_edit(arg, 1);
|
||||||
@@ -447,11 +420,8 @@ int serv_delete(char *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn = conf(buf, sizeof(buf), arg, 0);
|
fn = conf(buf, sizeof(buf), arg, 0);
|
||||||
if (!fn) {
|
if (!fn)
|
||||||
if (is_builtin(arg))
|
|
||||||
errx(1, "%s is a built-in service.", arg);
|
|
||||||
errx(1, FINIT_RCSD " missing on system.");
|
errx(1, FINIT_RCSD " missing on system.");
|
||||||
}
|
|
||||||
|
|
||||||
if (!fexist(fn))
|
if (!fexist(fn))
|
||||||
warnx("cannot find %s", fn);
|
warnx("cannot find %s", fn);
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* List and enable/disable service configurations
|
/* List and enable/disable service configurations
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2017-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+82
-196
@@ -1,7 +1,7 @@
|
|||||||
/* Finit service monitor, task starter and generic API for managing svc_t
|
/* Finit service monitor, task starter and generic API for managing svc_t
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
#include "config.h" /* Generated by configure script */
|
#include "config.h" /* Generated by configure script */
|
||||||
|
|
||||||
#include <ctype.h> /* isblank() */
|
#include <ctype.h> /* isblank() */
|
||||||
#include <sched.h> /* sched_yield() */
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
@@ -90,7 +89,7 @@ static void service_timeout_cb(uev_t *w, void *arg, int events)
|
|||||||
* Returns:
|
* Returns:
|
||||||
* POSIX OK(0) on success, non-zero on error.
|
* POSIX OK(0) on success, non-zero on error.
|
||||||
*/
|
*/
|
||||||
int service_timeout_after(svc_t *svc, int timeout, void (*cb)(svc_t *svc))
|
static int service_timeout_after(svc_t *svc, int timeout, void (*cb)(svc_t *svc))
|
||||||
{
|
{
|
||||||
if (svc->timer_cb)
|
if (svc->timer_cb)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
@@ -108,7 +107,7 @@ int service_timeout_after(svc_t *svc, int timeout, void (*cb)(svc_t *svc))
|
|||||||
* Returns:
|
* Returns:
|
||||||
* POSIX OK(0) on success, non-zero on error.
|
* POSIX OK(0) on success, non-zero on error.
|
||||||
*/
|
*/
|
||||||
int service_timeout_cancel(svc_t *svc)
|
static int service_timeout_cancel(svc_t *svc)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -382,20 +381,6 @@ static char *group_name(svc_t *svc, char *buf, size_t len)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compose_cmdline(svc_t *svc, char *buf, size_t len)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
strlcpy(buf, svc->cmd, len);
|
|
||||||
for (i = 1; i < MAX_NUM_SVC_ARGS; i++) {
|
|
||||||
if (!strlen(svc->args[i]))
|
|
||||||
break;
|
|
||||||
|
|
||||||
strlcat(buf, " ", len);
|
|
||||||
strlcat(buf, svc->args[i], len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static pid_t service_fork(svc_t *svc)
|
static pid_t service_fork(svc_t *svc)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@@ -460,7 +445,6 @@ static pid_t service_fork(svc_t *svc)
|
|||||||
static int service_start(svc_t *svc)
|
static int service_start(svc_t *svc)
|
||||||
{
|
{
|
||||||
int result = 0, do_progress = 1;
|
int result = 0, do_progress = 1;
|
||||||
char cmdline[CMD_SIZE] = "";
|
|
||||||
sigset_t nmask, omask;
|
sigset_t nmask, omask;
|
||||||
char grnam[80];
|
char grnam[80];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@@ -497,9 +481,8 @@ static int service_start(svc_t *svc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compose_cmdline(svc, cmdline, sizeof(cmdline));
|
|
||||||
if (svc_is_sysv(svc))
|
if (svc_is_sysv(svc))
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s start' ...", cmdline);
|
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s start' ...", svc->cmd);
|
||||||
|
|
||||||
if (!svc->desc[0])
|
if (!svc->desc[0])
|
||||||
do_progress = 0;
|
do_progress = 0;
|
||||||
@@ -575,7 +558,7 @@ static int service_start(svc_t *svc)
|
|||||||
|
|
||||||
for (i = 0; i < we.we_wordc; i++) {
|
for (i = 0; i < we.we_wordc; i++) {
|
||||||
if (strlen(we.we_wordv[i]) >= sizeof(svc->args[i])) {
|
if (strlen(we.we_wordv[i]) >= sizeof(svc->args[i])) {
|
||||||
logit(LOG_ERR, "%s: expanded arg. '%s' too long", svc->cmd, we.we_wordv[i]);
|
logit(LOG_ERR, "%s: expanded arg. '%s' too long", we.we_wordv[i]);
|
||||||
rc = WRDE_NOSPACE;
|
rc = WRDE_NOSPACE;
|
||||||
goto nomem;
|
goto nomem;
|
||||||
}
|
}
|
||||||
@@ -586,16 +569,9 @@ static int service_start(svc_t *svc)
|
|||||||
}
|
}
|
||||||
wordfree(&we);
|
wordfree(&we);
|
||||||
} else {
|
} else {
|
||||||
size_t j;
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
args[i++] = svc->cmd;
|
args[i++] = svc->cmd;
|
||||||
/* this handles, e.g., bridge-stop br0 start */
|
args[i++] = svc->cmd;
|
||||||
for (j = 0; j < MAX_NUM_SVC_ARGS; j++) {
|
|
||||||
if (!strlen(svc->args[j]))
|
|
||||||
break;
|
|
||||||
args[i++] = svc->args[j];
|
|
||||||
}
|
|
||||||
args[i++] = "start";
|
args[i++] = "start";
|
||||||
}
|
}
|
||||||
args[i] = NULL;
|
args[i] = NULL;
|
||||||
@@ -628,7 +604,16 @@ static int service_start(svc_t *svc)
|
|||||||
|
|
||||||
_exit(status);
|
_exit(status);
|
||||||
} else if (debug) {
|
} else if (debug) {
|
||||||
_d("Starting %s", cmdline);
|
char buf[CMD_SIZE] = "";
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_NUM_SVC_ARGS; i++) {
|
||||||
|
if (strlen(svc->args[i]) == 0)
|
||||||
|
break;
|
||||||
|
if (buf[0])
|
||||||
|
strlcat(buf, " ", sizeof(buf));
|
||||||
|
strlcat(buf, svc->args[i], sizeof(buf));
|
||||||
|
}
|
||||||
|
_d("Starting %s %s", svc->cmd, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (svc_is_tty(svc))
|
if (svc_is_tty(svc))
|
||||||
@@ -636,7 +621,6 @@ static int service_start(svc_t *svc)
|
|||||||
else
|
else
|
||||||
cgroup_service(group_name(svc, grnam, sizeof(grnam)), pid, &svc->cgroup);
|
cgroup_service(group_name(svc, grnam, sizeof(grnam)), pid, &svc->cgroup);
|
||||||
|
|
||||||
if (!svc_is_sysv(svc))
|
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Starting %s[%d]", svc_ident(svc, NULL, 0), pid);
|
logit(LOG_CONSOLE | LOG_NOTICE, "Starting %s[%d]", svc_ident(svc, NULL, 0), pid);
|
||||||
|
|
||||||
svc->pid = pid;
|
svc->pid = pid;
|
||||||
@@ -733,7 +717,6 @@ static void service_cleanup(svc_t *svc)
|
|||||||
*/
|
*/
|
||||||
static int service_stop(svc_t *svc)
|
static int service_stop(svc_t *svc)
|
||||||
{
|
{
|
||||||
char cmdline[CMD_SIZE] = "";
|
|
||||||
int do_progress = 1;
|
int do_progress = 1;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
@@ -745,7 +728,6 @@ static int service_stop(svc_t *svc)
|
|||||||
|
|
||||||
service_timeout_cancel(svc);
|
service_timeout_cancel(svc);
|
||||||
|
|
||||||
compose_cmdline(svc, cmdline, sizeof(cmdline));
|
|
||||||
if (!svc_is_sysv(svc)) {
|
if (!svc_is_sysv(svc)) {
|
||||||
if (svc->pid <= 1)
|
if (svc->pid <= 1)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -755,7 +737,7 @@ static int service_stop(svc_t *svc)
|
|||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Stopping %s[%d], sending %s ...",
|
logit(LOG_CONSOLE | LOG_NOTICE, "Stopping %s[%d], sending %s ...",
|
||||||
svc_ident(svc, NULL, 0), svc->pid, sig_name(svc->sighalt));
|
svc_ident(svc, NULL, 0), svc->pid, sig_name(svc->sighalt));
|
||||||
} else {
|
} else {
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s stop' ...", cmdline);
|
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s stop' ...", svc->cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -765,14 +747,6 @@ static int service_stop(svc_t *svc)
|
|||||||
*/
|
*/
|
||||||
svc_started(svc);
|
svc_started(svc);
|
||||||
|
|
||||||
/*
|
|
||||||
* Verify there's still something there before we send the reaper.
|
|
||||||
*/
|
|
||||||
if (svc->pid > 1 && !pid_alive(svc->pid)) {
|
|
||||||
svc->pid = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!svc->desc[0])
|
if (!svc->desc[0])
|
||||||
do_progress = 0;
|
do_progress = 0;
|
||||||
|
|
||||||
@@ -795,30 +769,19 @@ static int service_stop(svc_t *svc)
|
|||||||
svc_set_state(svc, SVC_HALTED_STATE);
|
svc_set_state(svc, SVC_HALTED_STATE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char *args[MAX_NUM_SVC_ARGS + 1];
|
char *args[] = { svc->cmd, "stop", NULL };
|
||||||
size_t i = 0, j;
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
args[i++] = svc->cmd;
|
|
||||||
/* this handles, e.g., bridge-stop br0 stop */
|
|
||||||
for (j = 0; j < MAX_NUM_SVC_ARGS; j++) {
|
|
||||||
if (!strlen(svc->args[j]))
|
|
||||||
break;
|
|
||||||
args[i++] = svc->args[j];
|
|
||||||
}
|
|
||||||
args[i++] = "stop";
|
|
||||||
args[i] = NULL;
|
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
switch (pid) {
|
switch (pid) {
|
||||||
case 0:
|
case 0:
|
||||||
setsid();
|
setsid();
|
||||||
redirect(svc);
|
redirect(svc);
|
||||||
exec_runtask(args[0], &args[1]);
|
exec_runtask(svc->cmd, args);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
break;
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
_pe("Failed fork() to call sysv script '%s stop'", cmdline);
|
_pe("Failed fork() to call sysv script '%s stop'", svc->cmd);
|
||||||
rc = 1;
|
rc = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -960,7 +923,7 @@ static void parse_env(svc_t *svc, char *env)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (strlen(env) >= sizeof(svc->env)) {
|
if (strlen(env) >= sizeof(svc->env)) {
|
||||||
_e("%s: env file is too long (>%zu chars)", svc->cmd, sizeof(svc->env));
|
_e("%s: env file is too long (>%d chars)", svc->cmd, sizeof(svc->env));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -984,7 +947,7 @@ static void parse_cgroup(svc_t *svc, char *cgroup)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(ptr) >= sizeof(svc->cgroup)) {
|
if (strlen(ptr) >= sizeof(svc->cgroup)) {
|
||||||
_e("%s: cgroup settings too long (>%zu chars)", svc->cmd, sizeof(svc->cgroup));
|
_e("%s: cgroup settings too long (>%d chars)", svc->cmd, sizeof(svc->cgroup));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1020,39 +983,26 @@ static void parse_killdelay(svc_t *svc, char *delay)
|
|||||||
static void parse_script(char *type, char *script, char *buf, size_t len)
|
static void parse_script(char *type, char *script, char *buf, size_t len)
|
||||||
{
|
{
|
||||||
if (access(script, X_OK))
|
if (access(script, X_OK))
|
||||||
logit(LOG_WARNING, "%s:%s is missing or not executable, skipping.", type, script);
|
logit(LOG_WARNING, "%s: %s:%s is missing or not executable, skipping.", type, script);
|
||||||
else
|
else
|
||||||
strlcpy(buf, script, len);
|
strlcpy(buf, script, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 'name:<name>' or derived from '/path/to/cmd args'
|
* name:<name>
|
||||||
*/
|
*/
|
||||||
static char *parse_name(char *cmd, char *arg)
|
static void parse_name(svc_t *svc, char *arg)
|
||||||
{
|
{
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
|
|
||||||
if (arg && !strncasecmp(arg, "name:", 5)) {
|
if (arg && !strncasecmp(arg, "name:", 5)) {
|
||||||
name = arg + 5;
|
name = arg + 5;
|
||||||
} else {
|
} else {
|
||||||
char *ptr;
|
name = strrchr(svc->cmd, '/');
|
||||||
|
name = name ? name + 1 : svc->cmd;
|
||||||
ptr = strchr(cmd, ' ');
|
|
||||||
if (!ptr)
|
|
||||||
ptr = cmd + strlen(cmd);
|
|
||||||
|
|
||||||
while (ptr > cmd) {
|
|
||||||
if (*ptr == '/') {
|
|
||||||
ptr++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ptr--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
name = ptr;
|
strlcpy(svc->name, name, sizeof(svc->name));
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1204,7 +1154,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
char *dev = NULL;
|
char *dev = NULL;
|
||||||
int respawn = 0;
|
int respawn = 0;
|
||||||
int levels = 0;
|
int levels = 0;
|
||||||
int forking = 0, manual = 0;
|
int manual = 0;
|
||||||
int restart_max = SVC_RESPAWN_MAX;
|
int restart_max = SVC_RESPAWN_MAX;
|
||||||
int restart_tmo = 0;
|
int restart_tmo = 0;
|
||||||
unsigned oncrash_action = SVC_ONCRASH_IGNORE;
|
unsigned oncrash_action = SVC_ONCRASH_IGNORE;
|
||||||
@@ -1263,8 +1213,6 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
pid = cmd;
|
pid = cmd;
|
||||||
else if (!strncasecmp(cmd, "name:", 5))
|
else if (!strncasecmp(cmd, "name:", 5))
|
||||||
name = cmd;
|
name = cmd;
|
||||||
else if (!strncasecmp(cmd, "type:forking", 10))
|
|
||||||
forking = 1;
|
|
||||||
else if (!strncasecmp(cmd, "manual:yes", 10))
|
else if (!strncasecmp(cmd, "manual:yes", 10))
|
||||||
manual = 1;
|
manual = 1;
|
||||||
else if (!strncasecmp(cmd, "restart:", 8))
|
else if (!strncasecmp(cmd, "restart:", 8))
|
||||||
@@ -1310,7 +1258,6 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = parse_name(cmd, name);
|
|
||||||
if (!id)
|
if (!id)
|
||||||
id = "";
|
id = "";
|
||||||
|
|
||||||
@@ -1352,11 +1299,11 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
next:
|
next:
|
||||||
svc = svc_find_by_tty(dev);
|
svc = svc_find_by_tty(dev);
|
||||||
} else
|
} else
|
||||||
svc = svc_find(name, id);
|
svc = svc_find(cmd, id);
|
||||||
|
|
||||||
if (!svc) {
|
if (!svc) {
|
||||||
_d("Creating new svc for %s name %s id %s type %d", cmd, name, id, type);
|
_d("Creating new svc for %s id #%s type %d", cmd, id, type);
|
||||||
svc = svc_new(cmd, name, id, type);
|
svc = svc_new(cmd, id, type);
|
||||||
if (!svc) {
|
if (!svc) {
|
||||||
_e("Out of memory, cannot register service %s", cmd);
|
_e("Out of memory, cannot register service %s", cmd);
|
||||||
return errno = ENOMEM;
|
return errno = ENOMEM;
|
||||||
@@ -1369,8 +1316,6 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
svc->restart_tmo = restart_tmo;
|
svc->restart_tmo = restart_tmo;
|
||||||
svc->oncrash_action = oncrash_action;
|
svc->oncrash_action = oncrash_action;
|
||||||
} else {
|
} else {
|
||||||
_d("Found existing svc for %s name %s id %s type %d", cmd, name, id, type);
|
|
||||||
|
|
||||||
/* update type, may have changed from service -> task */
|
/* update type, may have changed from service -> task */
|
||||||
svc->type = type;
|
svc->type = type;
|
||||||
|
|
||||||
@@ -1379,6 +1324,10 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
svc_unblock(svc);
|
svc_unblock(svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Decode any optional pid:/optional/path/to/file.pid */
|
||||||
|
if (pid && (svc_is_daemon(svc) || svc_is_sysv(svc)) && pid_file_parse(svc, pid))
|
||||||
|
_e("Invalid 'pid' argument to service: %s", pid);
|
||||||
|
|
||||||
if (username) {
|
if (username) {
|
||||||
char *ptr = strchr(username, ':');
|
char *ptr = strchr(username, ':');
|
||||||
|
|
||||||
@@ -1393,7 +1342,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
svc->runlevels = levels;
|
svc->runlevels = levels;
|
||||||
_d("Service %s runlevel 0x%02x", svc_ident(svc, NULL, 0), svc->runlevels);
|
_d("Service %s runlevel 0x%02x", svc->cmd, svc->runlevels);
|
||||||
|
|
||||||
conf_parse_cond(svc, cond);
|
conf_parse_cond(svc, cond);
|
||||||
|
|
||||||
@@ -1427,7 +1376,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
id = ptr;
|
id = ptr;
|
||||||
strlcpy(svc->name, "tty", sizeof(svc->name));
|
strlcpy(svc->name, "tty", sizeof(svc->name));
|
||||||
strlcpy(svc->id, id, sizeof(svc->id));
|
strlcpy(svc->id, id, sizeof(svc->id));
|
||||||
}
|
} else
|
||||||
|
parse_name(svc, name);
|
||||||
|
|
||||||
parse_cmdline_args(svc, cmd);
|
parse_cmdline_args(svc, cmd);
|
||||||
|
|
||||||
@@ -1455,26 +1405,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
parse_env(svc, env);
|
parse_env(svc, env);
|
||||||
if (file)
|
if (file)
|
||||||
strlcpy(svc->file, file, sizeof(svc->file));
|
strlcpy(svc->file, file, sizeof(svc->file));
|
||||||
svc->respawn = respawn;
|
if (respawn)
|
||||||
svc->forking = forking;
|
svc->respawn = 1;
|
||||||
|
|
||||||
/* Decode any (optional) pid:/optional/path/to/file.pid */
|
|
||||||
if (svc_is_daemon(svc) || svc_is_sysv(svc)) {
|
|
||||||
char tmp[sizeof(svc->name) + 6]; /* pid:! + svc->name */
|
|
||||||
|
|
||||||
/* no pid: set, figure out a default to track this svc */
|
|
||||||
if (!pid && forking) {
|
|
||||||
snprintf(tmp, sizeof(tmp), "pid:!%s", svc->name);
|
|
||||||
pid = tmp;
|
|
||||||
logit(LOG_INFO, "%s: forking but no pid:!file set, guessing -> %s", svc->name, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid && pid_file_parse(svc, pid))
|
|
||||||
logit(LOG_WARNING, "%s: service has invalid 'pid:' config: %s", svc->name, pid);
|
|
||||||
|
|
||||||
if (svc->pidfile[0] == '!')
|
|
||||||
svc->forking = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set configured limits */
|
/* Set configured limits */
|
||||||
memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit));
|
memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit));
|
||||||
@@ -1547,22 +1479,14 @@ void service_monitor(pid_t lost, int status)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
_d("collected %s(%d), normal exit: %d, signaled: %d, exit code: %d",
|
_d("collected %s(%d), normal exit: %d, signaled: %d, exit code: %d",
|
||||||
svc_ident(svc, NULL, 0), lost, WIFEXITED(status), WIFSIGNALED(status), WEXITSTATUS(status));
|
svc->cmd, lost, WIFEXITED(status), WIFSIGNALED(status), WEXITSTATUS(status));
|
||||||
svc->status = status;
|
svc->status = status;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forking sysv/services declare themselves with pid:!/path/to/pid.file */
|
/* Forking sysv/services declare themselves with pid:!/path/to/pid.file */
|
||||||
if (svc_is_forking(svc)) {
|
if (svc_is_starting(svc) && svc_is_forking(svc))
|
||||||
/* Likely start script exiting */
|
return;
|
||||||
if (svc_is_starting(svc)) {
|
|
||||||
svc->pid = 0; /* Expect no more activity from this one */
|
|
||||||
goto cont;
|
|
||||||
}
|
|
||||||
|
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Stopped %s[%d]", svc_ident(svc, NULL, 0), lost);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Terminate any children in the same proess group, e.g. logit */
|
/* Terminate any children in the same proess group, e.g. logit */
|
||||||
kill(-svc->pid, SIGKILL);
|
kill(-svc->pid, SIGKILL);
|
||||||
@@ -1581,11 +1505,11 @@ void service_monitor(pid_t lost, int status)
|
|||||||
done:
|
done:
|
||||||
/* No longer running, update books. */
|
/* No longer running, update books. */
|
||||||
svc->start_time = svc->pid = 0;
|
svc->start_time = svc->pid = 0;
|
||||||
cont:
|
|
||||||
if (!service_step(svc)) {
|
if (!service_step(svc)) {
|
||||||
/* Clean out any bootstrap tasks, they've had their time in the sun. */
|
/* Clean out any bootstrap tasks, they've had their time in the sun. */
|
||||||
if (svc_clean_bootstrap(svc))
|
if (svc_clean_bootstrap(svc))
|
||||||
_d("collected bootstrap task %s(%d), removing.", svc_ident(svc, NULL, 0), lost);
|
_d("collected bootstrap task %s(%d), removing.", svc->cmd, lost);
|
||||||
}
|
}
|
||||||
|
|
||||||
sm_step(&sm);
|
sm_step(&sm);
|
||||||
@@ -1637,11 +1561,21 @@ static void service_kill_script(svc_t *svc)
|
|||||||
static void set_pre_post_envs(svc_t *svc, const char *type)
|
static void set_pre_post_envs(svc_t *svc, const char *type)
|
||||||
{
|
{
|
||||||
char buf[25 + 256] = "/etc/default:/etc/conf.d";
|
char buf[25 + 256] = "/etc/default:/etc/conf.d";
|
||||||
|
const char *fn = svc_getenv(svc);
|
||||||
|
const char *exist = "0";
|
||||||
|
|
||||||
setenv("SERVICE_TYPE", svc_typestr(svc), 1);
|
setenv("SERVICE_TYPE", svc_typestr(svc), 1);
|
||||||
setenv("SERVICE_IDENT", svc_ident(svc, NULL, 0), 1);
|
setenv("SERVICE_IDENT", svc_ident(svc, NULL, 0), 1);
|
||||||
setenv("SERVICE_SCRIPT_TYPE", type, 1);
|
setenv("SERVICE_SCRIPT_TYPE", type, 1);
|
||||||
|
|
||||||
|
if (fn) {
|
||||||
|
setenv("SERVICE_ENV_FILE", fn, 1);
|
||||||
|
if (!access(fn, R_OK))
|
||||||
|
exist = "1";
|
||||||
|
}
|
||||||
|
setenv("SERVICE_ENV_FILE", fn, 1);
|
||||||
|
setenv("SERVICE_ENV_FILE_EXIST", exist, 1);
|
||||||
|
|
||||||
#ifdef FINIT_SYSCONFIG
|
#ifdef FINIT_SYSCONFIG
|
||||||
strlcat(buf, ":", sizeof(buf));
|
strlcat(buf, ":", sizeof(buf));
|
||||||
strlcat(buf, FINIT_SYSCONFIG, sizeof(buf));
|
strlcat(buf, FINIT_SYSCONFIG, sizeof(buf));
|
||||||
@@ -1658,20 +1592,12 @@ static void service_pre_script(svc_t *svc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (svc->pid == 0) {
|
if (svc->pid == 0) {
|
||||||
char buf[CMD_SIZE];
|
|
||||||
char *argv[4] = {
|
char *argv[4] = {
|
||||||
"sh",
|
"sh",
|
||||||
"-ac",
|
"-c",
|
||||||
buf,
|
svc->pre_script,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
char *env_file;
|
|
||||||
|
|
||||||
env_file = svc_getenv(svc);
|
|
||||||
if (env_file)
|
|
||||||
snprintf(buf, sizeof(buf), ". %s; exec %s", env_file, svc->pre_script);
|
|
||||||
else
|
|
||||||
strlcpy(buf, svc->pre_script, sizeof(buf));
|
|
||||||
|
|
||||||
set_pre_post_envs(svc, "pre");
|
set_pre_post_envs(svc, "pre");
|
||||||
execvp(_PATH_BSHELL, argv);
|
execvp(_PATH_BSHELL, argv);
|
||||||
@@ -1691,24 +1617,17 @@ static void service_post_script(svc_t *svc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (svc->pid == 0) {
|
if (svc->pid == 0) {
|
||||||
char buf[CMD_SIZE];
|
|
||||||
char *argv[4] = {
|
char *argv[4] = {
|
||||||
"sh",
|
"sh",
|
||||||
"-ac",
|
"-c",
|
||||||
buf,
|
svc->post_script,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
char *env_file;
|
|
||||||
int rc, sig;
|
int rc, sig;
|
||||||
|
|
||||||
rc = WEXITSTATUS(svc->status);
|
rc = WEXITSTATUS(svc->status);
|
||||||
sig = WTERMSIG(svc->status);
|
sig = WTERMSIG(svc->status);
|
||||||
|
|
||||||
env_file = svc_getenv(svc);
|
|
||||||
if (env_file)
|
|
||||||
snprintf(buf, sizeof(buf), ". %s; exec %s", env_file, svc->post_script);
|
|
||||||
else
|
|
||||||
strlcpy(buf, svc->post_script, sizeof(buf));
|
|
||||||
set_pre_post_envs(svc, "post");
|
set_pre_post_envs(svc, "post");
|
||||||
|
|
||||||
if (WIFEXITED(svc->status)) {
|
if (WIFEXITED(svc->status)) {
|
||||||
@@ -1737,7 +1656,7 @@ static void service_retry(svc_t *svc)
|
|||||||
|
|
||||||
service_timeout_cancel(svc);
|
service_timeout_cancel(svc);
|
||||||
if (svc->respawn) {
|
if (svc->respawn) {
|
||||||
_d("%s crashed/exited, respawning ...", svc_ident(svc, NULL, 0));
|
_d("%s crashed/exited, respawning ...", svc->cmd);
|
||||||
svc_unblock(svc);
|
svc_unblock(svc);
|
||||||
service_step(svc);
|
service_step(svc);
|
||||||
return;
|
return;
|
||||||
@@ -1745,7 +1664,6 @@ static void service_retry(svc_t *svc)
|
|||||||
|
|
||||||
if (svc->state != SVC_HALTED_STATE ||
|
if (svc->state != SVC_HALTED_STATE ||
|
||||||
svc->block != SVC_BLOCK_RESTARTING) {
|
svc->block != SVC_BLOCK_RESTARTING) {
|
||||||
svc_set_state(svc, SVC_RUNNING_STATE);
|
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Successfully restarted crashing service %s.",
|
logit(LOG_CONSOLE | LOG_NOTICE, "Successfully restarted crashing service %s.",
|
||||||
svc_ident(svc, NULL, 0));
|
svc_ident(svc, NULL, 0));
|
||||||
return;
|
return;
|
||||||
@@ -1758,7 +1676,7 @@ static void service_retry(svc_t *svc)
|
|||||||
svc_crashing(svc);
|
svc_crashing(svc);
|
||||||
*restart_cnt = 0;
|
*restart_cnt = 0;
|
||||||
if (svc->oncrash_action == SVC_ONCRASH_REBOOT) {
|
if (svc->oncrash_action == SVC_ONCRASH_REBOOT) {
|
||||||
logit(LOG_ERR, "%s issuing reboot", svc_ident(svc, NULL, 0));
|
logit(LOG_ERR, "%s issuing reboot", svc->cmd);
|
||||||
sync();
|
sync();
|
||||||
kill(1, SIGTERM);
|
kill(1, SIGTERM);
|
||||||
}
|
}
|
||||||
@@ -1768,7 +1686,7 @@ static void service_retry(svc_t *svc)
|
|||||||
|
|
||||||
(*restart_cnt)++;
|
(*restart_cnt)++;
|
||||||
|
|
||||||
_d("%s crashed, trying to start it again, attempt %d", svc_ident(svc, NULL, 0), *restart_cnt);
|
_d("%s crashed, trying to start it again, attempt %d", svc->cmd, *restart_cnt);
|
||||||
logit(LOG_CONSOLE | LOG_WARNING, "Service %s[%d] died, restarting (%d/%d)",
|
logit(LOG_CONSOLE | LOG_WARNING, "Service %s[%d] died, restarting (%d/%d)",
|
||||||
svc_ident(svc, NULL, 0), svc->oldpid, *restart_cnt, svc->restart_max);
|
svc_ident(svc, NULL, 0), svc->oldpid, *restart_cnt, svc->restart_max);
|
||||||
svc_unblock(svc);
|
svc_unblock(svc);
|
||||||
@@ -1790,7 +1708,7 @@ static void svc_set_state(svc_t *svc, svc_state_t new)
|
|||||||
/* if PID isn't collected within SVC_TERM_TIMEOUT msec, kill it! */
|
/* if PID isn't collected within SVC_TERM_TIMEOUT msec, kill it! */
|
||||||
if (*state == SVC_STOPPING_STATE) {
|
if (*state == SVC_STOPPING_STATE) {
|
||||||
_d("%s is stopping, wait %d sec before sending SIGKILL ...",
|
_d("%s is stopping, wait %d sec before sending SIGKILL ...",
|
||||||
svc_ident(svc, NULL, 0), svc->killdelay / 1000);
|
svc->cmd, svc->killdelay / 1000);
|
||||||
service_timeout_cancel(svc);
|
service_timeout_cancel(svc);
|
||||||
service_timeout_after(svc, svc->killdelay, service_kill);
|
service_timeout_after(svc, svc->killdelay, service_kill);
|
||||||
}
|
}
|
||||||
@@ -1798,8 +1716,8 @@ static void svc_set_state(svc_t *svc, svc_state_t new)
|
|||||||
if (svc_is_runtask(svc)) {
|
if (svc_is_runtask(svc)) {
|
||||||
char success[MAX_COND_LEN], failure[MAX_COND_LEN];
|
char success[MAX_COND_LEN], failure[MAX_COND_LEN];
|
||||||
|
|
||||||
snprintf(success, sizeof(success), "%s/%s/success", svc_typestr(svc), svc_ident(svc, NULL, 0));
|
snprintf(success, sizeof(success), "%s/%s/success", svc_typestr(svc), svc->name);
|
||||||
snprintf(failure, sizeof(failure), "%s/%s/failure", svc_typestr(svc), svc_ident(svc, NULL, 0));
|
snprintf(failure, sizeof(failure), "%s/%s/failure", svc_typestr(svc), svc->name);
|
||||||
|
|
||||||
/* create success/failure condition when entering SVC_DONE_STATE. */
|
/* create success/failure condition when entering SVC_DONE_STATE. */
|
||||||
if (*state == SVC_DONE_STATE) {
|
if (*state == SVC_DONE_STATE) {
|
||||||
@@ -1815,39 +1733,6 @@ static void svc_set_state(svc_t *svc, svc_state_t new)
|
|||||||
cond_clear(failure);
|
cond_clear(failure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (svc_is_daemon(svc)) {
|
|
||||||
char cond[MAX_COND_LEN];
|
|
||||||
|
|
||||||
snprintf(cond, sizeof(cond), "service/%s/", svc_ident(svc, NULL, 0));
|
|
||||||
cond_clear(cond);
|
|
||||||
|
|
||||||
switch (svc->state) {
|
|
||||||
case SVC_HALTED_STATE:
|
|
||||||
case SVC_RUNNING_STATE:
|
|
||||||
strlcat(cond, svc_status(svc), sizeof(cond));
|
|
||||||
cond_set_oneshot(cond);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called by pidfile plugin for forking services that have successfully started.
|
|
||||||
* We get here when the service_monitor() collects the PID, sets svc->pid to 0,
|
|
||||||
* and the state machine prepares for the worst bu setting state to HALTED.
|
|
||||||
*/
|
|
||||||
void service_forked(svc_t *svc)
|
|
||||||
{
|
|
||||||
/* Stop forking_retry() timer */
|
|
||||||
service_timeout_cancel(svc);
|
|
||||||
|
|
||||||
/* Not crashing, restore RUNNING state */
|
|
||||||
svc_unblock(svc);
|
|
||||||
svc_set_state(svc, SVC_RUNNING_STATE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1868,7 +1753,7 @@ restart:
|
|||||||
old_state = svc->state;
|
old_state = svc->state;
|
||||||
enabled = svc_enabled(svc);
|
enabled = svc_enabled(svc);
|
||||||
|
|
||||||
_d("%20s(%4d): %8s %3sabled/%-7s cond:%-4s", svc_ident(svc, NULL, 0), svc->pid,
|
_d("%20s(%4d): %8s %3sabled/%-7s cond:%-4s", svc->cmd, svc->pid,
|
||||||
svc_status(svc), enabled ? "en" : "dis", svc_dirtystr(svc),
|
svc_status(svc), enabled ? "en" : "dis", svc_dirtystr(svc),
|
||||||
condstr(cond_get_agg(svc->cond)));
|
condstr(cond_get_agg(svc->cond)));
|
||||||
|
|
||||||
@@ -1892,7 +1777,7 @@ restart:
|
|||||||
if (!svc->pid) {
|
if (!svc->pid) {
|
||||||
char condstr[MAX_COND_LEN];
|
char condstr[MAX_COND_LEN];
|
||||||
|
|
||||||
_d("%s: stopped, cleaning up timers and conditions ...", svc_ident(svc, NULL, 0));
|
_d("%s: stopped, cleaning up timers and conditions ...", svc->cmd);
|
||||||
service_timeout_cancel(svc);
|
service_timeout_cancel(svc);
|
||||||
cond_clear(mkcond(svc, condstr, sizeof(condstr)));
|
cond_clear(mkcond(svc, condstr, sizeof(condstr)));
|
||||||
|
|
||||||
@@ -1960,26 +1845,27 @@ restart:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!svc->pid) {
|
if (!svc->pid) {
|
||||||
if (svc_is_daemon(svc) || svc_is_sysv(svc) || svc_is_tty(svc)) {
|
if (svc_is_daemon(svc) || svc_is_tty(svc)) {
|
||||||
svc_restarting(svc);
|
svc_restarting(svc);
|
||||||
svc_set_state(svc, SVC_HALTED_STATE);
|
svc_set_state(svc, SVC_HALTED_STATE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Restart directly after the first crash, except for forking services
|
* Restart directly after the first crash,
|
||||||
* which we need to wait for the forked-off child to create its pid
|
* then retry after 2 sec
|
||||||
* file. In both cases, after that, retry after 2 sec
|
|
||||||
*/
|
*/
|
||||||
if (!svc->respawn)
|
if (!svc->respawn)
|
||||||
_d("delayed restart of %s", svc_ident(svc, NULL, 0));
|
_d("delayed restart of %s", svc->cmd);
|
||||||
if (svc_is_forking(svc))
|
|
||||||
service_timeout_after(svc, 2000, service_retry);
|
|
||||||
else
|
|
||||||
service_timeout_after(svc, 1, service_retry);
|
service_timeout_after(svc, 1, service_retry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (svc_is_runtask(svc)) { /* only run/task, not sysv here */
|
if (svc_is_runtask(svc)) {
|
||||||
|
if (svc_is_sysv(svc)) {
|
||||||
|
if (!svc->started)
|
||||||
svc_set_state(svc, SVC_STOPPING_STATE);
|
svc_set_state(svc, SVC_STOPPING_STATE);
|
||||||
|
} else {
|
||||||
|
svc_set_state(svc, SVC_STOPPING_STATE);
|
||||||
|
}
|
||||||
svc->once++;
|
svc->once++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2058,7 +1944,7 @@ restart:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (svc->state != old_state) {
|
if (svc->state != old_state) {
|
||||||
_d("%20s(%4d): -> %8s", svc_ident(svc, NULL, 0), svc->pid, svc_status(svc));
|
_d("%20s(%4d): -> %8s", svc->cmd, svc->pid, svc_status(svc));
|
||||||
changed++;
|
changed++;
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
@@ -2129,15 +2015,15 @@ int service_completed(void)
|
|||||||
|
|
||||||
if (strstr(svc->cond, plugin_hook_str(HOOK_SVC_UP)) ||
|
if (strstr(svc->cond, plugin_hook_str(HOOK_SVC_UP)) ||
|
||||||
strstr(svc->cond, plugin_hook_str(HOOK_SYSTEM_UP))) {
|
strstr(svc->cond, plugin_hook_str(HOOK_SYSTEM_UP))) {
|
||||||
_d("Skipping %s(%s), post-strap hook", svc->desc, svc_ident(svc, NULL, 0));
|
_d("Skipping %s(%s), post-strap hook", svc->desc, svc->cmd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!svc->once) {
|
if (!svc->once) {
|
||||||
_d("%s has not yet completed ...", svc_ident(svc, NULL, 0));
|
_d("%s has not yet completed ...", svc->cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_d("%s has completed ...", svc_ident(svc, NULL, 0));
|
_d("%s has completed ...", svc->cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
+1
-6
@@ -1,7 +1,7 @@
|
|||||||
/* Finit service monitor, task starter and generic API for managing svc_t
|
/* Finit service monitor, task starter and generic API for managing svc_t
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -35,11 +35,6 @@ void service_runtask_clean (void);
|
|||||||
void service_reload_dynamic (void);
|
void service_reload_dynamic (void);
|
||||||
void service_update_rdeps (void);
|
void service_update_rdeps (void);
|
||||||
|
|
||||||
int service_timeout_after (svc_t *svc, int timeout, void (*cb)(svc_t *svc));
|
|
||||||
int service_timeout_cancel (svc_t *svc);
|
|
||||||
|
|
||||||
void service_forked (svc_t *svc);
|
|
||||||
|
|
||||||
int service_step (svc_t *svc);
|
int service_step (svc_t *svc);
|
||||||
void service_step_all (int types);
|
void service_step_all (int types);
|
||||||
void service_worker (void *unused);
|
void service_worker (void *unused);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Signal management - Be conservative with what finit responds to!
|
/* Signal management - Be conservative with what finit responds to!
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -69,12 +69,7 @@
|
|||||||
* Finit defaults to nothing but sets sys/pwr/fail condition.
|
* Finit defaults to nothing but sets sys/pwr/fail condition.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#ifdef HAVE_MNTENT_H
|
|
||||||
#include <mntent.h>
|
|
||||||
#endif
|
|
||||||
#include <string.h> /* strerror() */
|
#include <string.h> /* strerror() */
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
@@ -171,30 +166,6 @@ void mdadm_wait(void);
|
|||||||
void unmount_tmpfs(void);
|
void unmount_tmpfs(void);
|
||||||
void unmount_regular(void);
|
void unmount_regular(void);
|
||||||
|
|
||||||
static void fs_swapoff(void)
|
|
||||||
{
|
|
||||||
struct mntent *mnt;
|
|
||||||
char cmd[256];
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
if (!whichp("swapoff"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
fp = setmntent(fstab, "r");
|
|
||||||
if (!fp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while ((mnt = getmntent(fp))) {
|
|
||||||
if (strcmp(mnt->mnt_type, MNTTYPE_SWAP))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd), "swapoff %s", mnt->mnt_fsname);
|
|
||||||
run_interactive(cmd, "Disabling swap %s", mnt->mnt_fsname);
|
|
||||||
}
|
|
||||||
|
|
||||||
endmntent(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kernel threads have no cmdline so fgets() returns NULL for them. We
|
* Kernel threads have no cmdline so fgets() returns NULL for them. We
|
||||||
* also skip "special" processes, e.g. mdadm/mdmon or watchdogd that must
|
* also skip "special" processes, e.g. mdadm/mdmon or watchdogd that must
|
||||||
@@ -236,8 +207,7 @@ void do_iterate_proc(int (*cb)(int, void *), void *data)
|
|||||||
_d("Skipping %s ...", &file[1]);
|
_d("Skipping %s ...", &file[1]);
|
||||||
else
|
else
|
||||||
if (cb(pid, data)) {
|
if (cb(pid, data)) {
|
||||||
_d("PID %d is still alive (%s)", pid, file);
|
print(0, "PID %d is still alive (%s)", pid, file);
|
||||||
fclose(fp);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,21 +322,14 @@ void do_shutdown(shutop_t op)
|
|||||||
|
|
||||||
/* Unmount any tmpfs before unmounting swap ... */
|
/* Unmount any tmpfs before unmounting swap ... */
|
||||||
unmount_tmpfs();
|
unmount_tmpfs();
|
||||||
fs_swapoff();
|
if (whichp("swapoff"))
|
||||||
|
run("swapoff -e -a", "swapoff");
|
||||||
|
|
||||||
/* ... unmount remaining regular file systems. */
|
/* ... unmount remaining regular file systems. */
|
||||||
unmount_regular();
|
unmount_regular();
|
||||||
|
|
||||||
/*
|
/* We sit on / so we must remount it read-only */
|
||||||
* We sit on / so we must remount it ro, try all the things!
|
run("mount -n -o remount,ro -t none rootfs /", "mount");
|
||||||
* See the following links for details:
|
|
||||||
* - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=339023
|
|
||||||
* - https://bugs.launchpad.net/ubuntu/+source/util-linux/+bug/29187
|
|
||||||
*/
|
|
||||||
sync();
|
|
||||||
run("mount -n -o remount,ro -t dummytype dummydev /", NULL);
|
|
||||||
run("mount -n -o remount,ro dummydev /", NULL);
|
|
||||||
run("mount -n -o remount,ro /", "mount");
|
|
||||||
|
|
||||||
/* Call mdadm to mark any RAID array(s) as clean before halting. */
|
/* Call mdadm to mark any RAID array(s) as clean before halting. */
|
||||||
mdadm_wait();
|
mdadm_wait();
|
||||||
@@ -496,8 +459,8 @@ static void sigterm_cb(uev_t *w, void *arg, int events)
|
|||||||
*/
|
*/
|
||||||
static void sigchld_cb(uev_t *w, void *arg, int events)
|
static void sigchld_cb(uev_t *w, void *arg, int events)
|
||||||
{
|
{
|
||||||
int status;
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
|
||||||
if (UEV_ERROR == events) {
|
if (UEV_ERROR == events) {
|
||||||
_e("Unrecoverable error in signal watcher");
|
_e("Unrecoverable error in signal watcher");
|
||||||
@@ -560,8 +523,8 @@ static void chld_handler(int sig, siginfo_t *info, void *ctx)
|
|||||||
|
|
||||||
void sig_init(void)
|
void sig_init(void)
|
||||||
{
|
{
|
||||||
struct sigaction sa;
|
|
||||||
int i;
|
int i;
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
for (i = 1; i < NSIG; i++)
|
for (i = 1; i < NSIG; i++)
|
||||||
IGNSIG(sa, i, SA_RESTART);
|
IGNSIG(sa, i, SA_RESTART);
|
||||||
@@ -574,9 +537,9 @@ void sig_init(void)
|
|||||||
*/
|
*/
|
||||||
void sig_unblock(void)
|
void sig_unblock(void)
|
||||||
{
|
{
|
||||||
struct sigaction sa;
|
|
||||||
sigset_t nmask;
|
|
||||||
int i;
|
int i;
|
||||||
|
sigset_t nmask;
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
sigemptyset(&nmask);
|
sigemptyset(&nmask);
|
||||||
sigaddset(&nmask, SIGHUP);
|
sigaddset(&nmask, SIGHUP);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Signal management - Be conservative with what finit responds to!
|
/* Signal management - Be conservative with what finit responds to!
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-3
@@ -1,6 +1,6 @@
|
|||||||
/* Reset terminal line settings (stty sane)
|
/* Reset terminal line settings (stty sane)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,8 +21,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h> /* _POSIX_VDISABLE */
|
#include <unistd.h> /* _POSIX_VDISABLE */
|
||||||
|
|||||||
+1
-4
@@ -1,6 +1,6 @@
|
|||||||
/* poor man's sulogin, may be statically linked
|
/* poor man's sulogin, may be statically linked
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -193,9 +193,6 @@ int main(void)
|
|||||||
nopass:
|
nopass:
|
||||||
freepw(&pw);
|
freepw(&pw);
|
||||||
|
|
||||||
/* tell initctl/reboot to trigger force mode */
|
|
||||||
setenv("SULOGIN", "finit", 1);
|
|
||||||
|
|
||||||
return sh();
|
return sh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Low-level service primitives and generic API for managing svc_t structures
|
/* Low-level service primitives and generic API for managing svc_t structures
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -22,8 +22,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <ctype.h> /* isdigit() */
|
#include <ctype.h> /* isdigit() */
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -107,17 +105,16 @@ static void svc_gc(void *arg)
|
|||||||
/**
|
/**
|
||||||
* svc_new - Create a new service
|
* svc_new - Create a new service
|
||||||
* @cmd: External program to call
|
* @cmd: External program to call
|
||||||
* @name: Default or custom svc name
|
|
||||||
* @id: Instance id
|
* @id: Instance id
|
||||||
* @type: Service type, one of service, task, run
|
* @type: Service type, one of service, task, run
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* A pointer to a new &svc_t object, or %NULL if out of empty slots.
|
* A pointer to a new &svc_t object, or %NULL if out of empty slots.
|
||||||
*/
|
*/
|
||||||
svc_t *svc_new(char *cmd, char *name, char *id, int type)
|
svc_t *svc_new(char *cmd, char *id, int type)
|
||||||
{
|
{
|
||||||
svc_t *svc, *iter = NULL;
|
|
||||||
int job = -1;
|
int job = -1;
|
||||||
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
/* Find first job n:o if registering multiple instances */
|
/* Find first job n:o if registering multiple instances */
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
@@ -135,8 +132,6 @@ svc_t *svc_new(char *cmd, char *name, char *id, int type)
|
|||||||
|
|
||||||
svc->type = type;
|
svc->type = type;
|
||||||
svc->job = job;
|
svc->job = job;
|
||||||
if (name)
|
|
||||||
strlcpy(svc->name, name, sizeof(svc->name));
|
|
||||||
if (id && id[0])
|
if (id && id[0])
|
||||||
strlcpy(svc->id, id, sizeof(svc->id));
|
strlcpy(svc->id, id, sizeof(svc->id));
|
||||||
if (cmd)
|
if (cmd)
|
||||||
@@ -351,13 +346,13 @@ svc_t *svc_stop_completed(void)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* svc_find - Find a service object by its full path name
|
* svc_find - Find a service object by its full path name
|
||||||
* @name: Full path name, e.g., /sbin/syslogd
|
* @cmd: Full path name, e.g., /sbin/syslogd
|
||||||
* @id: Optional instance id
|
* @id: Optional instance id
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* A pointer to an &svc_t object, or %NULL if not found.
|
* A pointer to an &svc_t object, or %NULL if not found.
|
||||||
*/
|
*/
|
||||||
svc_t *svc_find(char *name, char *id)
|
svc_t *svc_find(char *cmd, char *id)
|
||||||
{
|
{
|
||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
@@ -365,7 +360,7 @@ svc_t *svc_find(char *name, char *id)
|
|||||||
id = "";
|
id = "";
|
||||||
|
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
if (!strcmp(svc->name, name) && !strcmp(svc->id, id))
|
if (!strcmp(svc->cmd, cmd) && !strcmp(svc->id, id))
|
||||||
return svc;
|
return svc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,6 +409,30 @@ svc_t *svc_find_by_jobid(int job, char *id)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* svc_find_by_nameid - Find an service object by its basename:ID
|
||||||
|
* @name: Process name to match
|
||||||
|
* @id: Optional instance id
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* A pointer to an &svc_t object, or %NULL if not found.
|
||||||
|
*/
|
||||||
|
svc_t *svc_find_by_nameid(char *name, char *id)
|
||||||
|
{
|
||||||
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
|
if (!id)
|
||||||
|
id = "";
|
||||||
|
|
||||||
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
|
if (!strcmp(svc->id, id) && !strcmp(name, svc->name))
|
||||||
|
return svc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
svc_t *svc_find_by_tty(char *dev)
|
svc_t *svc_find_by_tty(char *dev)
|
||||||
{
|
{
|
||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
@@ -699,7 +718,7 @@ int svc_parse_jobstr(char *str, size_t len, void *user_data, int (*found)(svc_t
|
|||||||
*ptr++ = 0;
|
*ptr++ = 0;
|
||||||
id = ptr;
|
id = ptr;
|
||||||
|
|
||||||
svc = svc_find(token, id);
|
svc = svc_find_by_nameid(token, id);
|
||||||
if (!svc && not_found)
|
if (!svc && not_found)
|
||||||
result += not_found(token, id, user_data);
|
result += not_found(token, id, user_data);
|
||||||
else if (found)
|
else if (found)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Low-level service primitives and generic API for managing svc_t structures
|
/* Low-level service primitives and generic API for managing svc_t structures
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
* Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -127,7 +127,6 @@ typedef struct svc {
|
|||||||
int starting; /* ... waiting for pidfile to be re-asserted */
|
int starting; /* ... waiting for pidfile to be re-asserted */
|
||||||
int runlevels;
|
int runlevels;
|
||||||
int sighup; /* This service supports SIGHUP :) */
|
int sighup; /* This service supports SIGHUP :) */
|
||||||
int forking; /* This is a service/sysv daemon that forks, wait for it ... */
|
|
||||||
svc_block_t block; /* Reason that this service is currently stopped */
|
svc_block_t block; /* Reason that this service is currently stopped */
|
||||||
char cond[MAX_COND_LEN];
|
char cond[MAX_COND_LEN];
|
||||||
|
|
||||||
@@ -193,13 +192,14 @@ typedef struct svc {
|
|||||||
struct timespec gc;
|
struct timespec gc;
|
||||||
} svc_t;
|
} svc_t;
|
||||||
|
|
||||||
svc_t *svc_new (char *cmd, char *name, char *id, int type);
|
svc_t *svc_new (char *cmd, char *id, int type);
|
||||||
int svc_del (svc_t *svc);
|
int svc_del (svc_t *svc);
|
||||||
void svc_validate (svc_t *svc);
|
void svc_validate (svc_t *svc);
|
||||||
|
|
||||||
svc_t *svc_find (char *name, char *id);
|
svc_t *svc_find (char *cmd, char *id);
|
||||||
svc_t *svc_find_by_pid (pid_t pid);
|
svc_t *svc_find_by_pid (pid_t pid);
|
||||||
svc_t *svc_find_by_jobid (int job, char *id);
|
svc_t *svc_find_by_jobid (int job, char *id);
|
||||||
|
svc_t *svc_find_by_nameid (char *name, char *id);
|
||||||
svc_t *svc_find_by_tty (char *dev);
|
svc_t *svc_find_by_tty (char *dev);
|
||||||
svc_t *svc_find_by_pidfile (char *fn);
|
svc_t *svc_find_by_pidfile (char *fn);
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ static inline int svc_is_daemon (svc_t *svc) { return svc && SVC_TYPE_SERVICE
|
|||||||
static inline int svc_is_sysv (svc_t *svc) { return svc && SVC_TYPE_SYSV == svc->type; }
|
static inline int svc_is_sysv (svc_t *svc) { return svc && SVC_TYPE_SYSV == svc->type; }
|
||||||
static inline int svc_is_tty (svc_t *svc) { return svc && SVC_TYPE_TTY == svc->type; }
|
static inline int svc_is_tty (svc_t *svc) { return svc && SVC_TYPE_TTY == svc->type; }
|
||||||
static inline int svc_is_runtask (svc_t *svc) { return svc && (SVC_TYPE_RUNTASK & svc->type);}
|
static inline int svc_is_runtask (svc_t *svc) { return svc && (SVC_TYPE_RUNTASK & svc->type);}
|
||||||
static inline int svc_is_forking (svc_t *svc) { return svc && svc->forking; }
|
static inline int svc_is_forking (svc_t *svc) { return (svc_is_daemon(svc) || svc_is_sysv(svc)) && svc->pidfile[0] == '!'; }
|
||||||
|
|
||||||
static inline int svc_in_runlevel (svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); }
|
static inline int svc_in_runlevel (svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); }
|
||||||
static inline int svc_nohup (svc_t *svc) { return svc && (0 == svc->sighup || 0 != svc->args_dirty); }
|
static inline int svc_nohup (svc_t *svc) { return svc && (0 == svc->sighup || 0 != svc->args_dirty); }
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Finit TTY handling
|
/* Finit TTY handling
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013 Mattias Walström <lazzer@gmail.com>
|
* Copyright (c) 2013 Mattias Walström <lazzer@gmail.com>
|
||||||
* Copyright (c) 2013-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2013-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -22,8 +22,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
|
||||||
|
|
||||||
#include <ctype.h> /* isdigit() */
|
#include <ctype.h> /* isdigit() */
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
@@ -172,7 +170,7 @@ int tty_parse_args(char *cmd, struct tty *tty)
|
|||||||
else
|
else
|
||||||
tty->args[tty->num++] = cmd;
|
tty->args[tty->num++] = cmd;
|
||||||
|
|
||||||
cmd = strtok(NULL, " ");
|
cmd = strtok(NULL, " \t");
|
||||||
} while (cmd && tty->num < NELEMS(tty->args));
|
} while (cmd && tty->num < NELEMS(tty->args));
|
||||||
|
|
||||||
/* rescue shells are always notty */
|
/* rescue shells are always notty */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Finit TTY handling
|
/* Finit TTY handling
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013 Mattias Walström <lazzer@gmail.com>
|
* Copyright (c) 2013 Mattias Walström <lazzer@gmail.com>
|
||||||
* Copyright (c) 2013-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2013-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+4
-43
@@ -1,6 +1,6 @@
|
|||||||
/* Misc. shared utility functions for initctl, reboot and finit
|
/* Misc. shared utility functions for initctl, reboot and finit
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,13 +21,10 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
#include "config.h"
|
||||||
|
|
||||||
#include <ctype.h> /* isprint() */
|
#include <ctype.h> /* isprint() */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#ifdef HAVE_MNTENT_H
|
|
||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
#endif
|
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -227,7 +224,7 @@ int fngetint(char *path, int *val)
|
|||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
if (fnread(buf, sizeof(buf), "%s", path) <= 0)
|
if (fnread(buf, sizeof(buf), path) <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
@@ -238,40 +235,6 @@ int fngetint(char *path, int *val)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a replacement for the non-working reboot(RB_SW_SUSPEND). It
|
|
||||||
* checks for suspend to RAM support, assuming `mem_sleep` has a sane
|
|
||||||
* default, e.g. 'deep' or 's2idle'. The latter should be possible to
|
|
||||||
* select from finit.conf, but for now we go with the kernel default.
|
|
||||||
* For more information on kernel sleep states, see:
|
|
||||||
* https://www.kernel.org/doc/html/latest/admin-guide/pm/sleep-states.html
|
|
||||||
*/
|
|
||||||
int suspend(void)
|
|
||||||
{
|
|
||||||
char buf[80];
|
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
if (fnread(buf, sizeof(buf), "/sys/power/state") <= 0) {
|
|
||||||
opnotsup:
|
|
||||||
errno = EINVAL;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
chomp(buf);
|
|
||||||
|
|
||||||
ptr = strtok(buf, " ");
|
|
||||||
while (ptr) {
|
|
||||||
if (!strcmp(ptr, "mem"))
|
|
||||||
break;
|
|
||||||
|
|
||||||
ptr = strtok(NULL, " ");
|
|
||||||
}
|
|
||||||
if (!ptr)
|
|
||||||
goto opnotsup;
|
|
||||||
|
|
||||||
return fnwrite("mem", "/sys/power/state");
|
|
||||||
}
|
|
||||||
|
|
||||||
int strtobytes(char *arg)
|
int strtobytes(char *arg)
|
||||||
{
|
{
|
||||||
int mod = 0, bytes;
|
int mod = 0, bytes;
|
||||||
@@ -491,9 +454,7 @@ static int hasopt(char *opts, char *opt)
|
|||||||
|
|
||||||
int ismnt(char *file, char *dir, char *mode)
|
int ismnt(char *file, char *dir, char *mode)
|
||||||
{
|
{
|
||||||
struct mntent mount;
|
|
||||||
struct mntent *mnt;
|
struct mntent *mnt;
|
||||||
char buf[256];
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
@@ -501,7 +462,7 @@ int ismnt(char *file, char *dir, char *mode)
|
|||||||
if (!fp)
|
if (!fp)
|
||||||
return 0; /* Dunno, maybe not */
|
return 0; /* Dunno, maybe not */
|
||||||
|
|
||||||
while ((mnt = getmntent_r(fp, &mount, buf, sizeof(buf)))) {
|
while ((mnt = getmntent(fp))) {
|
||||||
if (!strcmp(mnt->mnt_dir, dir)) {
|
if (!strcmp(mnt->mnt_dir, dir)) {
|
||||||
if (mode) {
|
if (mode) {
|
||||||
if (hasopt(mnt->mnt_opts, mode))
|
if (hasopt(mnt->mnt_opts, mode))
|
||||||
|
|||||||
+5
-7
@@ -1,6 +1,6 @@
|
|||||||
/* Misc. shared utility functions for initctl, reboot and finit
|
/* Misc. shared utility functions for initctl, reboot and finit
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -54,13 +54,11 @@ extern char *prognm;
|
|||||||
|
|
||||||
char *progname (char *arg0);
|
char *progname (char *arg0);
|
||||||
|
|
||||||
char *str (char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
char *str (char *fmt, ...);
|
||||||
int fnread (char *buf, size_t len, char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
|
int fnread (char *buf, size_t len, char *fmt, ...);
|
||||||
int fnwrite (char *value, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
int fnwrite (char *value, char *fmt, ...);
|
||||||
int fngetint (char *path, int *val);
|
int fngetint (char *path, int *val);
|
||||||
|
|
||||||
int suspend (void);
|
|
||||||
|
|
||||||
int strtobytes (char *arg);
|
int strtobytes (char *arg);
|
||||||
char *sig2str (int sig);
|
char *sig2str (int sig);
|
||||||
int str2sig (char *sig);
|
int str2sig (char *sig);
|
||||||
@@ -87,7 +85,7 @@ int ttcooked (void);
|
|||||||
#define ttcooked() 0
|
#define ttcooked() 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static __attribute__ ((format (printf, 1, 2))) inline void dbg(char *fmt, ...)
|
static inline void dbg(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/* UTMP API
|
/* UTMP API
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
#include "config.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* UTMP API
|
/* UTMP API
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Built-in watchdog daemon
|
/* Built-in watchdog daemon
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/* Built-in watchdog daemon
|
/* Built-in watchdog daemon
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-28
@@ -1,30 +1,8 @@
|
|||||||
SUBDIRS = common tenv
|
SUBDIRS = common tenv
|
||||||
|
|
||||||
EXTRA_DIST = skel/bin/busybox-x86_64.md5 skel/sbin/service.sh skel/bin/slay \
|
EXTRA_DIST = setup-root.sh
|
||||||
skel/etc/env skel/bin/pre.sh skel/bin/post.sh skel/sbin/task.sh \
|
|
||||||
skel/cdrom/.empty skel/dev/shm/.empty skel/dev/pts/.empty \
|
|
||||||
skel/etc/inittab skel/etc/hostname skel/etc/fstab \
|
|
||||||
skel/etc/init.d/rcS skel/etc/init.d/rcK skel/tmp/.empty \
|
|
||||||
skel/etc/finit.d/.empty skel/etc/init.d/S01-service.sh \
|
|
||||||
skel/etc/init.d/S02-serv.sh \
|
|
||||||
skel/proc/.empty skel/root/.empty skel/run/.empty \
|
|
||||||
skel/sbin/chrootsetup.sh skel/srv/.empty skel/sys/.empty \
|
|
||||||
skel/usr/bin/.empty skel/usr/lib/.empty skel/usr/sbin/.empty \
|
|
||||||
skel/home/.empty skel/usr/games/.empty skel/usr/src/.empty \
|
|
||||||
skel/usr/share/.empty skel/usr/include/.empty \
|
|
||||||
skel/usr/local/games/.empty skel/usr/local/sbin/.empty \
|
|
||||||
skel/usr/local/share/.empty skel/usr/local/src/.empty \
|
|
||||||
skel/usr/local/lib/.empty skel/usr/local/bin/.empty \
|
|
||||||
skel/usr/local/etc/.empty skel/var/.empty
|
|
||||||
|
|
||||||
EXTRA_DIST += setup-root.sh
|
|
||||||
EXTRA_DIST += add-remove-dynamic-service.sh
|
EXTRA_DIST += add-remove-dynamic-service.sh
|
||||||
EXTRA_DIST += add-remove-dynamic-service-sub-config.sh
|
EXTRA_DIST += add-remove-dynamic-service-sub-config.sh
|
||||||
EXTRA_DIST += cond-start-task.sh
|
|
||||||
EXTRA_DIST += failing-sysv.sh
|
|
||||||
EXTRA_DIST += global-envs.sh
|
|
||||||
EXTRA_DIST += pre-post-serv.sh
|
|
||||||
EXTRA_DIST += runlevel.sh
|
|
||||||
EXTRA_DIST += start-stop-service.sh
|
EXTRA_DIST += start-stop-service.sh
|
||||||
EXTRA_DIST += start-stop-service-sub-config.sh
|
EXTRA_DIST += start-stop-service-sub-config.sh
|
||||||
EXTRA_DIST += start-kill-service.sh
|
EXTRA_DIST += start-kill-service.sh
|
||||||
@@ -48,11 +26,6 @@ TESTS = checkself.sh
|
|||||||
TESTS += setup-root.sh
|
TESTS += setup-root.sh
|
||||||
TESTS += add-remove-dynamic-service.sh
|
TESTS += add-remove-dynamic-service.sh
|
||||||
TESTS += add-remove-dynamic-service-sub-config.sh
|
TESTS += add-remove-dynamic-service-sub-config.sh
|
||||||
TESTS += cond-start-task.sh
|
|
||||||
TESTS += failing-sysv.sh
|
|
||||||
TESTS += global-envs.sh
|
|
||||||
TESTS += pre-post-serv.sh
|
|
||||||
TESTS += runlevel.sh
|
|
||||||
TESTS += start-stop-service.sh
|
TESTS += start-stop-service.sh
|
||||||
TESTS += start-stop-service-sub-config.sh
|
TESTS += start-stop-service-sub-config.sh
|
||||||
TESTS += start-kill-service.sh
|
TESTS += start-kill-service.sh
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ test_teardown()
|
|||||||
say "Running test teardown."
|
say "Running test teardown."
|
||||||
|
|
||||||
texec rm -f "$FINIT_RCSD/service.conf"
|
texec rm -f "$FINIT_RCSD/service.conf"
|
||||||
|
texec rm -f /test_assets/service.sh
|
||||||
}
|
}
|
||||||
|
|
||||||
say "Test start $(date)"
|
say "Test start $(date)"
|
||||||
|
|
||||||
|
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
|
||||||
|
|
||||||
say "Add a dynamic service in $FINIT_RCSD/service.conf"
|
say "Add a dynamic service in $FINIT_RCSD/service.conf"
|
||||||
texec sh -c "echo 'service [2345] kill:20 log service.sh -- Dyn serv' > $FINIT_RCSD/service.conf"
|
texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh -- Dyn serv' > $FINIT_RCSD/service.conf"
|
||||||
|
|
||||||
say 'Reload Finit'
|
say 'Reload Finit'
|
||||||
texec sh -c "initctl reload"
|
texec sh -c "initctl reload"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
TEST_DIR=$(dirname "$0")
|
TEST_DIR=$(dirname "$0")
|
||||||
|
export DEBUG=1
|
||||||
|
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
. "$TEST_DIR/tenv/lib.sh"
|
. "$TEST_DIR/tenv/lib.sh"
|
||||||
@@ -13,12 +14,20 @@ test_teardown()
|
|||||||
say "Running test teardown."
|
say "Running test teardown."
|
||||||
|
|
||||||
texec rm -f "$FINIT_CONF"
|
texec rm -f "$FINIT_CONF"
|
||||||
|
texec rm -f /test_assets/service.sh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
say "Hi, this is /run et al"
|
||||||
|
texec sh -c "echo 'ROOT:/bin'; ls -l /bin/; echo 'ROOT:/sbin'; ls -l /sbin/; echo 'ROOT:/run'; ls -l /run/; echo 'ROOT:/run/finit/'; ls -l /run/finit/; echo 'ROOT:/dev'; ls -l /dev/; ps; ls -l /proc/1/fd/"
|
||||||
|
say "HUPing PID 1 ..."
|
||||||
|
texec sh -c "kill -HUP 1"
|
||||||
|
|
||||||
say "Test start $(date)"
|
say "Test start $(date)"
|
||||||
|
|
||||||
|
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
|
||||||
|
|
||||||
say "Add a dynamic service in $FINIT_CONF"
|
say "Add a dynamic service in $FINIT_CONF"
|
||||||
texec sh -c "echo 'service [2345] kill:20 log service.sh -- Dyn service' > $FINIT_CONF"
|
texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh -- Dyn service' > $FINIT_CONF"
|
||||||
|
|
||||||
say 'Reload Finit'
|
say 'Reload Finit'
|
||||||
texec sh -c "initctl reload"
|
texec sh -c "initctl reload"
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
|
EXTRA_DIST = service.conf service.sh S01-service.sh slay.sh
|
||||||
|
|
||||||
noinst_PROGRAMS = serv
|
noinst_PROGRAMS = serv
|
||||||
serv_SOURCES = serv.c
|
serv_SOURCES = serv.c
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# SysV style start script for service.sh
|
# SysV style start script for service.sh
|
||||||
|
|
||||||
DAEMON="/sbin/service.sh"
|
DAEMON="/test_assets/service.sh"
|
||||||
PIDFILE="/var/run/service.pid"
|
PIDFILE="/var/run/service.pid"
|
||||||
|
|
||||||
start()
|
start()
|
||||||
+2
-42
@@ -15,38 +15,6 @@
|
|||||||
|
|
||||||
#define PROGNM "serv"
|
#define PROGNM "serv"
|
||||||
|
|
||||||
static void verify_env(char *arg)
|
|
||||||
{
|
|
||||||
char *key, *value;
|
|
||||||
char *replica;
|
|
||||||
char *env;
|
|
||||||
|
|
||||||
key = replica = strdup(arg);
|
|
||||||
if (!replica)
|
|
||||||
err(1, "Failed duplicating arg %s", arg);
|
|
||||||
|
|
||||||
value = strchr(replica, ':');
|
|
||||||
if (!value)
|
|
||||||
errx(1, "Invalid format of KEY:VALUE arg, missing ':' in %s", replica);
|
|
||||||
*(value++) = 0;
|
|
||||||
|
|
||||||
env = getenv(key);
|
|
||||||
if (!env)
|
|
||||||
errx(1, "No '%s' in environment", key);
|
|
||||||
|
|
||||||
if (strcmp(env, value))
|
|
||||||
errx(1, "Mismatch, environment '%s' vs expected value '%s'", env, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void verify_noenv(char *key)
|
|
||||||
{
|
|
||||||
char *val;
|
|
||||||
|
|
||||||
val = getenv(key);
|
|
||||||
if (val)
|
|
||||||
errx(1, "Error, key %s is set in environment to '%s'", key, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sig(int signo)
|
static void sig(int signo)
|
||||||
{
|
{
|
||||||
warnx("We got signal %d ...", signo);
|
warnx("We got signal %d ...", signo);
|
||||||
@@ -80,10 +48,8 @@ static int usage(int rc)
|
|||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"%s [-nhp] [-P FILE]\n"
|
"%s [-nhp] [-P FILE]\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -h Show help text (this)\n"
|
|
||||||
" -e K:V Verify K environment variable is V value\n"
|
|
||||||
" -E K Verify K is not set in the environment\n"
|
|
||||||
" -n Run in foreground\n"
|
" -n Run in foreground\n"
|
||||||
|
" -h Show help text (this)\n"
|
||||||
" -p Create PID file despite running in foreground\n"
|
" -p Create PID file despite running in foreground\n"
|
||||||
" -P FILE Create PID file using FILE\n"
|
" -P FILE Create PID file using FILE\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -103,16 +69,10 @@ int main(int argc, char *argv[])
|
|||||||
char *pidfn = NULL;
|
char *pidfn = NULL;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "e:E:hnpP:")) != EOF) {
|
while ((c = getopt(argc, argv, "hnpP:")) != EOF) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
return usage(0);
|
return usage(0);
|
||||||
case 'e':
|
|
||||||
verify_env(optarg);
|
|
||||||
break;
|
|
||||||
case 'E':
|
|
||||||
verify_noenv(optarg);
|
|
||||||
break;
|
|
||||||
case 'n':
|
case 'n':
|
||||||
do_background = 0;
|
do_background = 0;
|
||||||
do_pidfile--;
|
do_pidfile--;
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
service [2345] kill:20 log /test_assets/service.sh
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# A run/task runs once per runlevel, unless its .conf is touched
|
|
||||||
# then it will run again on initctl reload. This test verifies
|
|
||||||
# this behavior, with the added twist of starting the task by
|
|
||||||
# asserting a condition.
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
TEST_DIR=$(dirname "$0")
|
|
||||||
|
|
||||||
# shellcheck source=/dev/null
|
|
||||||
. "$TEST_DIR/tenv/lib.sh"
|
|
||||||
|
|
||||||
TEST_CONF=$FINIT_RCSD/cond.conf
|
|
||||||
|
|
||||||
|
|
||||||
test_setup()
|
|
||||||
{
|
|
||||||
say "Test start $(date)"
|
|
||||||
}
|
|
||||||
|
|
||||||
test_teardown()
|
|
||||||
{
|
|
||||||
say "Test done $(date)"
|
|
||||||
say "Running test teardown."
|
|
||||||
texec rm -f "$TEST_CONF"
|
|
||||||
}
|
|
||||||
|
|
||||||
test_one()
|
|
||||||
{
|
|
||||||
cond=$1
|
|
||||||
stanza=$2
|
|
||||||
|
|
||||||
sleep 5
|
|
||||||
say 'Enable finit debug, try to figure out what is going on ...'
|
|
||||||
texec sh -c "initctl debug"
|
|
||||||
|
|
||||||
say "Add stanza '$stanza' to $TEST_CONF ..."
|
|
||||||
texec sh -c "echo '$stanza' > $TEST_CONF"
|
|
||||||
|
|
||||||
texec sh -c "ls -l /run/ /run/finit/"
|
|
||||||
say 'Reload Finit'
|
|
||||||
texec sh -c "initctl ls"
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
texec sh -c "initctl status"
|
|
||||||
texec sh -c "ps"
|
|
||||||
|
|
||||||
date
|
|
||||||
sleep 2
|
|
||||||
date
|
|
||||||
texec sh -c "ls -l /run/ /run/finit/"
|
|
||||||
say 'Asserting condition'
|
|
||||||
texec sh -c "initctl cond set $cond"
|
|
||||||
|
|
||||||
date
|
|
||||||
sleep 2
|
|
||||||
date
|
|
||||||
texec sh -c "ls -l /run/ /run/finit/"
|
|
||||||
texec sh -c "initctl status"
|
|
||||||
texec sh -c "ps"
|
|
||||||
texec sh -c "initctl status task.sh"
|
|
||||||
|
|
||||||
sleep 1
|
|
||||||
texec sh -c "echo Hej; cat /run/task.state"
|
|
||||||
|
|
||||||
assert_file_contains /run/task.state 1
|
|
||||||
|
|
||||||
say 'Reload Finit'
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
sleep 1
|
|
||||||
say 'Ensure task has not run again ...'
|
|
||||||
assert_file_contains /run/task.state 1
|
|
||||||
|
|
||||||
say 'Switch to another runlevel ...'
|
|
||||||
texec sh -c "initctl runlevel 3"
|
|
||||||
sleep 1
|
|
||||||
say 'Ensure task has run again ...'
|
|
||||||
assert_file_contains /run/task.state 2
|
|
||||||
|
|
||||||
say 'Touch task.sh .conf file and reload Finit ...'
|
|
||||||
texec sh -c "touch $TEST_CONF"
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
sleep 1
|
|
||||||
# texec sh -c "initctl status task.sh"
|
|
||||||
assert_file_contains /run/task.state 3
|
|
||||||
|
|
||||||
say "Done, drop stanza from $TEST_CONF ..."
|
|
||||||
texec sh -c "rm $TEST_CONF"
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
}
|
|
||||||
|
|
||||||
test_one "hello" "task <usr/hello> task.sh -- Hello task"
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Verify what happesn when sysv scripts start services that keep
|
|
||||||
# crashing -- hint: crashing sysv services should be detected by
|
|
||||||
# Finit just like regular services.
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
TEST_DIR=$(dirname "$0")
|
|
||||||
|
|
||||||
test_setup()
|
|
||||||
{
|
|
||||||
say "Test start $(date)"
|
|
||||||
texec sh -c "mkdir -p /etc/default"
|
|
||||||
}
|
|
||||||
|
|
||||||
test_teardown()
|
|
||||||
{
|
|
||||||
say "Test done $(date)"
|
|
||||||
say "Running test teardown."
|
|
||||||
|
|
||||||
texec rm -f "$FINIT_CONF"
|
|
||||||
}
|
|
||||||
|
|
||||||
# shellcheck source=/dev/null
|
|
||||||
. "$TEST_DIR/tenv/lib.sh"
|
|
||||||
|
|
||||||
# This instructs serv to check the environment, and exit
|
|
||||||
# if it cannot find "xyzzy", thus triggering a premature
|
|
||||||
# exit which Finit should act on to retstart it.
|
|
||||||
say "Setting up bogus /etc/default/serv"
|
|
||||||
texec sh -c "echo 'SERV_ARGS=\"-e xyzzy:lives\"' > /etc/default/serv"
|
|
||||||
|
|
||||||
say "Add sysv stanza to $FINIT_CONF"
|
|
||||||
texec sh -c "echo 'sysv restart:5 [2345] pid:!/run/serv.pid name:serv /etc/init.d/S02-serv.sh -- Crashing SysV service' > $FINIT_CONF"
|
|
||||||
|
|
||||||
#texec sh -c "initctl debug"
|
|
||||||
|
|
||||||
say 'Reload Finit'
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
#texec sh -c "initctl status serv"
|
|
||||||
#texec sh -c "ps"
|
|
||||||
|
|
||||||
say 'Pending sysv restarts by Finit ...'
|
|
||||||
#texec sh -c "initctl status serv"
|
|
||||||
#texec sh -c "ps"
|
|
||||||
retry 'assert_restarts 5 serv' 20 1
|
|
||||||
|
|
||||||
return 0
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
TEST_DIR=$(dirname "$0")
|
|
||||||
|
|
||||||
test_setup()
|
|
||||||
{
|
|
||||||
say "Test start $(date)"
|
|
||||||
}
|
|
||||||
|
|
||||||
test_teardown()
|
|
||||||
{
|
|
||||||
say "Test done $(date)"
|
|
||||||
|
|
||||||
texec rm -f "$FINIT_CONF"
|
|
||||||
}
|
|
||||||
|
|
||||||
# shellcheck source=/dev/null
|
|
||||||
. "$TEST_DIR/tenv/lib.sh"
|
|
||||||
|
|
||||||
#texec sh -c "initctl debug"
|
|
||||||
say "Add custom envs to $FINIT_CONF ..."
|
|
||||||
texec sh -c "echo 'foo=bar' > $FINIT_CONF"
|
|
||||||
texec sh -c "echo 'baz=qux' >> $FINIT_CONF"
|
|
||||||
|
|
||||||
say "Add service stanza to $FINIT_CONF ..."
|
|
||||||
texec sh -c "echo 'service serv -np -e foo:bar -- Verify foo=bar' >> $FINIT_CONF"
|
|
||||||
|
|
||||||
say 'Reload Finit'
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
sleep 1
|
|
||||||
retry 'assert_num_children 1 serv'
|
|
||||||
|
|
||||||
say "Modify $FINIT_CONF slightly ..."
|
|
||||||
texec sh -c "sed -i 's/foo:bar/baz:qux/; s/foo=bar/baz=qux/' $FINIT_CONF"
|
|
||||||
|
|
||||||
say 'Reload Finit'
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
sleep 1
|
|
||||||
retry 'assert_num_children 1 serv'
|
|
||||||
|
|
||||||
say "Swap envs completely in $FINIT_CONF ..."
|
|
||||||
texec sh -c "echo 'bar=foo' > $FINIT_CONF"
|
|
||||||
texec sh -c "echo 'qux=baz' >> $FINIT_CONF"
|
|
||||||
|
|
||||||
say "Add swapped service stanza to $FINIT_CONF ..."
|
|
||||||
texec sh -c "echo 'service serv -np -e bar:foo -E baz -- Verify bar=foo and no baz' >> $FINIT_CONF"
|
|
||||||
|
|
||||||
say 'Reload Finit'
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
sleep 1
|
|
||||||
retry 'assert_num_children 1 serv'
|
|
||||||
|
|
||||||
say "Done, drop service from $FINIT_CONF ..."
|
|
||||||
texec sh -c "rm $FINIT_CONF"
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
TEST_DIR=$(dirname "$0")
|
|
||||||
|
|
||||||
test_setup()
|
|
||||||
{
|
|
||||||
say "Test start $(date)"
|
|
||||||
}
|
|
||||||
|
|
||||||
test_teardown()
|
|
||||||
{
|
|
||||||
say "Test done $(date)"
|
|
||||||
|
|
||||||
texec rm -f "$FINIT_CONF"
|
|
||||||
}
|
|
||||||
|
|
||||||
test_one()
|
|
||||||
{
|
|
||||||
pre=$1
|
|
||||||
precont=$2
|
|
||||||
service=$3
|
|
||||||
post=$4
|
|
||||||
postcont=$5
|
|
||||||
|
|
||||||
say "Add service stanza '$service' to $FINIT_CONF ..."
|
|
||||||
texec sh -c "echo '$service' > $FINIT_CONF"
|
|
||||||
|
|
||||||
say 'Reload Finit'
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
|
|
||||||
retry 'assert_num_children 1 serv'
|
|
||||||
if [ -n "$pre" ]; then
|
|
||||||
assert_file_contains "$pre" "$precont"
|
|
||||||
texec sh -c "rm -f $pre"
|
|
||||||
fi
|
|
||||||
|
|
||||||
say 'Stop the service'
|
|
||||||
texec sh -c "initctl stop serv"
|
|
||||||
|
|
||||||
retry 'assert_num_children 0 serv'
|
|
||||||
if [ -n "$post" ]; then
|
|
||||||
assert_file_contains "$post" "$postcont"
|
|
||||||
texec sh -c "rm -f $post"
|
|
||||||
fi
|
|
||||||
|
|
||||||
say "Done, drop service from $FINIT_CONF ..."
|
|
||||||
texec sh -c "rm $FINIT_CONF"
|
|
||||||
texec sh -c "initctl reload"
|
|
||||||
}
|
|
||||||
|
|
||||||
# shellcheck source=/dev/null
|
|
||||||
. "$TEST_DIR/tenv/lib.sh"
|
|
||||||
|
|
||||||
#texec sh -c "initctl debug"
|
|
||||||
|
|
||||||
test_one "" "" "service serv -np -- Regular fg service, no pre/post scripts" "" ""
|
|
||||||
test_one "" "" "service env:/etc/env serv -np -e foo:bar -- serv + env, no pre/post scripts" "" ""
|
|
||||||
test_one /tmp/pre PRE "service pre:/bin/pre.sh serv -np -- serv + pre script" "" ""
|
|
||||||
test_one /tmp/pre bar "service env:/etc/env pre:/bin/pre.sh serv -np -e baz:qux -- Env + pre script" "" ""
|
|
||||||
test_one "" "" "service post:/bin/post.sh serv -np -- Regular fg service, post script" /tmp/post POST
|
|
||||||
test_one "" "" "service env:/etc/env post:/bin/post.sh serv -np -- Regular fg service, post script" /tmp/post qux
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user