mirror of
https://github.com/troglobit/finit.git
synced 2026-10-12 10:12:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8d6ad6546 | ||
|
|
3dfae3074e | ||
|
|
97bebe52c9 | ||
|
|
8e1845f57b | ||
|
|
6cd6769997 | ||
|
|
03884d3566 | ||
|
|
899925e249 | ||
|
|
efefa398ce | ||
|
|
1ee24c69bc | ||
|
|
b16a36980c | ||
|
|
c1b52bbc04 | ||
|
|
9461ad4d4d | ||
|
|
e2ef6e9c34 | ||
|
|
cdc8873f5b | ||
|
|
b82b205d92 | ||
|
|
39d879f240 | ||
|
|
9c1db9cab3 | ||
|
|
2f5c00f2bd | ||
|
|
dc36b313ff | ||
|
|
093fa0107a | ||
|
|
e8f5ec2579 | ||
|
|
62241668df | ||
|
|
ee67c08b64 | ||
|
|
41a14391a2 | ||
|
|
6eccca31b9 | ||
|
|
d497942a9f |
+13
-2
@@ -4,8 +4,8 @@ Change Log
|
|||||||
All relevant changes are documented in this file.
|
All relevant changes are documented in this file.
|
||||||
|
|
||||||
|
|
||||||
[4.1][UNRELEASED]
|
[4.1][] - 2021-06-06
|
||||||
-----------------
|
--------------------
|
||||||
|
|
||||||
Bug fix release. Also disables handlers for `SIGINT` and `SIGPWR`, a
|
Bug fix release. Also disables handlers for `SIGINT` and `SIGPWR`, a
|
||||||
new set of `sys` conditions are instead generated which can be used to
|
new set of `sys` conditions are instead generated which can be used to
|
||||||
@@ -36,6 +36,9 @@ trigger external programs.
|
|||||||
falls back to an unauthenticated `/bin/sh`
|
falls back to an unauthenticated `/bin/sh`
|
||||||
* Dropped (broken) support for multiple consoles. Finit now follows
|
* Dropped (broken) support for multiple consoles. Finit now follows
|
||||||
the default console selected by the kernel, `/dev/console`
|
the default console selected by the kernel, `/dev/console`
|
||||||
|
* Dropped signal handlers for SIGSTOP/TSTP and SIGCONT
|
||||||
|
* Added support for `\n`, in addition to `\r`, in "Please press Enter"
|
||||||
|
prompt before starting getty
|
||||||
* Finit no longer parses `/proc/cmdline` for its options. Instead all
|
* Finit no longer parses `/proc/cmdline` for its options. Instead all
|
||||||
options are by default now read from `argv[]`, like a normal program,
|
options are by default now read from `argv[]`, like a normal program,
|
||||||
this is also what the kernel does by default. Please note, this may
|
this is also what the kernel does by default. Please note, this may
|
||||||
@@ -45,6 +48,9 @@ trigger external programs.
|
|||||||
`rtc.so`, `urandom.so`, you may also want to disable `hotplug.so`.
|
`rtc.so`, `urandom.so`, you may also want to disable `hotplug.so`.
|
||||||
They are all enabled by default, as in Finit 4.0, but may be moved
|
They are all enabled by default, as in Finit 4.0, but may be moved
|
||||||
to external tools or entries in `finit.conf` in Finit 5.0
|
to external tools or entries in `finit.conf` in Finit 5.0
|
||||||
|
* Added support for reading `PRETTY_NAME` from `/etc/os-release` to use
|
||||||
|
as heading in progress output, unless `--with-heading=GREET` is used.
|
||||||
|
* Added manual pages for finit(8), initctl(8), and finit.conf(5)
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
* Stricter interface name validation in netlink plugin, modeled after
|
* Stricter interface name validation in netlink plugin, modeled after
|
||||||
@@ -66,6 +72,11 @@ trigger external programs.
|
|||||||
* Fix `/etc/fstab` parser to properly check for 'ro' to not remount the
|
* Fix `/etc/fstab` parser to properly check for 'ro' to not remount the
|
||||||
root filesystem at boot. The wrong field was read, so a root mounted
|
root filesystem at boot. The wrong field was read, so a root mounted
|
||||||
by an initramfs, or by lxc for a container, had their root remounted
|
by an initramfs, or by lxc for a container, had their root remounted
|
||||||
|
* Fix SIGCHLD handler, `waitpd()` may be interrupted by a signal
|
||||||
|
* Reset `starting` flag of services being stopped. When a service
|
||||||
|
is started and then stopped before it has created its pid file,
|
||||||
|
it could be left forever in the stopping state, unless we reset
|
||||||
|
the starting flag.
|
||||||
* Fix #170: detect loss of default route when interfaces go down. This
|
* Fix #170: detect loss of default route when interfaces go down. This
|
||||||
emulates the missing kernel netlink message to remove the condition
|
emulates the missing kernel netlink message to remove the condition
|
||||||
net/default/route to allow stopping dependent services
|
net/default/route to allow stopping dependent services
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
SUBDIRS = plugins src test
|
SUBDIRS = man plugins src test
|
||||||
doc_DATA = README.md LICENSE contrib/finit.conf
|
doc_DATA = README.md LICENSE contrib/finit.conf
|
||||||
EXTRA_DIST = README.md LICENSE ChangeLog.md contrib/finit.conf
|
EXTRA_DIST = README.md LICENSE ChangeLog.md contrib/finit.conf
|
||||||
|
|
||||||
|
|||||||
@@ -22,19 +22,19 @@
|
|||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Finit is a simple alternative to [SysV init][4] and [systemd][6]. It
|
Fast init for Linux systems. Reverse engineered from the [EeePC
|
||||||
was reverse engineered from the [EeePC fastinit][] over ten years ago
|
fastinit][] over ten years ago by [Claudio Matsuoka][] — "gaps filled
|
||||||
by [Claudio Matsuoka][] — "gaps filled with frog DNA …"
|
with frog DNA …"
|
||||||
|
|
||||||

|

|
||||||
*Figure 1: Screenshot showing Finit booting [Alpine Linux](https://www.alpinelinux.org/).*
|
*Figure 1: Screenshot showing Finit booting [Alpine Linux](https://www.alpinelinux.org/).*
|
||||||
|
|
||||||
Features include:
|
Features include:
|
||||||
|
|
||||||
* Runlevels
|
* Runlevels, defined per service
|
||||||
* One-shot tasks, daemons, or SysV init scripts
|
* One-shot tasks, services (daemons), or [SysV init][4] start/stop scripts
|
||||||
* Runparts and rc.local
|
* Runparts and `/etc/rc.local` support
|
||||||
* Process supervision
|
* Process supervision similar to [systemd][]
|
||||||
* Sourcing environment files
|
* Sourcing environment files
|
||||||
* Conditions for network/process/custom dependencies
|
* Conditions for network/process/custom dependencies
|
||||||
* Pre/Post script actions
|
* Pre/Post script actions
|
||||||
@@ -581,8 +581,6 @@ and proposed extensions.
|
|||||||
[3]: http://smarden.org/runit/
|
[3]: http://smarden.org/runit/
|
||||||
[4]: http://en.wikipedia.org/wiki/Init
|
[4]: http://en.wikipedia.org/wiki/Init
|
||||||
[5]: http://en.wikipedia.org/wiki/Runlevel
|
[5]: http://en.wikipedia.org/wiki/Runlevel
|
||||||
[6]: https://www.freedesktop.org/wiki/Software/systemd/
|
|
||||||
[9]: https://github.com/troglobit/troglos
|
|
||||||
[RFC862]: https://tools.ietf.org/html/rfc862
|
[RFC862]: https://tools.ietf.org/html/rfc862
|
||||||
[RFC863]: https://tools.ietf.org/html/rfc863
|
[RFC863]: https://tools.ietf.org/html/rfc863
|
||||||
[RFC864]: https://tools.ietf.org/html/rfc864
|
[RFC864]: https://tools.ietf.org/html/rfc864
|
||||||
|
|||||||
+8
-5
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT(Finit, 4.1-rc2, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
|
AC_INIT(Finit, 4.1, 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])
|
||||||
@@ -11,6 +11,7 @@ AC_CONFIG_FILES([Makefile
|
|||||||
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile
|
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile
|
||||||
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
|
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
|
man/Makefile
|
||||||
plugins/Makefile
|
plugins/Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
test/test.env
|
test/test.env
|
||||||
@@ -86,7 +87,7 @@ 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(heading,
|
AC_ARG_WITH(heading,
|
||||||
AS_HELP_STRING([--with-heading=GREET], [Display GREET instead of Finit version at boot]),
|
AS_HELP_STRING([--with-heading=GREET], [Heading for boot progress. Default: PRETTY_NAME from /etc/os-release, fallback to "Finit vX.YY"]),
|
||||||
[heading=$withval], [heading=yes])
|
[heading=$withval], [heading=yes])
|
||||||
|
|
||||||
AC_ARG_WITH(config,
|
AC_ARG_WITH(config,
|
||||||
@@ -170,9 +171,8 @@ AS_IF([test "x$with_sysconfig" != "xno"], [
|
|||||||
[System environment, default /etc/default & /etc/conf.d])])])
|
[System environment, default /etc/default & /etc/conf.d])])])
|
||||||
|
|
||||||
AS_IF([test "x$with_heading" != "xno"], [
|
AS_IF([test "x$with_heading" != "xno"], [
|
||||||
AS_IF([test "x$heading" = "xyes"], [
|
AS_IF([test "x$heading" = "xyes"], [heading=""])
|
||||||
heading="$PACKAGE_NAME v$PACKAGE_VERSION"])])
|
AC_DEFINE_UNQUOTED(INIT_OSHEADING, "$heading", [Displayed by Finit at boot, defaults to /etc/os-release PRETTY_NAME])])
|
||||||
AC_DEFINE_UNQUOTED(INIT_HEADING, "$heading", [Displayed by Finit at boot])
|
|
||||||
|
|
||||||
AS_IF([test "x$with_hostname" != "xno"], [
|
AS_IF([test "x$with_hostname" != "xno"], [
|
||||||
AS_IF([test "x$hostname" = "xyes"], [
|
AS_IF([test "x$hostname" = "xyes"], [
|
||||||
@@ -222,6 +222,9 @@ AC_DEFINE_UNQUOTED(RESCUE_CONF, "$rescue_conf", [Finit rescue mode .conf])
|
|||||||
AC_EXPAND_DIR(sample_conf, "$libdir/finit/sample.conf")
|
AC_EXPAND_DIR(sample_conf, "$libdir/finit/sample.conf")
|
||||||
AC_DEFINE_UNQUOTED(SAMPLE_CONF, "$sample_conf", [Finit sameple.conf for initctl create])
|
AC_DEFINE_UNQUOTED(SAMPLE_CONF, "$sample_conf", [Finit sameple.conf for initctl create])
|
||||||
|
|
||||||
|
AS_IF([test "$heading" = ""], [heading="<DEFAULT>"])
|
||||||
|
AS_IF([test "$heading" = "no"], [heading="<NONE>"])
|
||||||
|
|
||||||
# Generate all files
|
# Generate all files
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
SUBDIRS = finit.d
|
SUBDIRS = finit.d
|
||||||
docsdir := @docdir@/contrib/alpine
|
docsdir := @docdir@/contrib/alpine
|
||||||
docs_DATA = README.md finit.conf alpine-release build.sh install.sh rc.local
|
docs_DATA = README.md finit.conf build.sh install.sh rc.local
|
||||||
EXTRA_DIST = $(docs_DATA)
|
EXTRA_DIST = $(docs_DATA)
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
3.6.2
|
|
||||||
@@ -18,7 +18,7 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
|
|||||||
--sysconfdir=/etc --localstatedir=/var \
|
--sysconfdir=/etc --localstatedir=/var \
|
||||||
--enable-dbus-plugin --enable-x11-common-plugin \
|
--enable-dbus-plugin --enable-x11-common-plugin \
|
||||||
--enable-alsa-utils-plugin --with-watchdog \
|
--enable-alsa-utils-plugin --with-watchdog \
|
||||||
--with-heading="Alpine Linux" --with-keventd
|
--with-keventd
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "*** Building ..."
|
echo "*** Building ..."
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ if [ "x`id -u`" != "x0" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Adjust base directory
|
# Adjust base directory
|
||||||
if [ -e alpine-release ]; then
|
grep -q alpine Makefile 2>/dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
cd ../..
|
cd ../..
|
||||||
elif [ ! -e configure.ac ]; then
|
elif [ ! -e configure.ac ]; then
|
||||||
echo "*** Please run this script from the Finit base directory."
|
echo "*** Please run this script from the Finit base directory."
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
SUBDIRS = finit.d
|
SUBDIRS = finit.d
|
||||||
docsdir := @docdir@/contrib/debian
|
docsdir := @docdir@/contrib/debian
|
||||||
docs_DATA = README.md finit.conf os-release build.sh install.sh
|
docs_DATA = README.md finit.conf build.sh install.sh
|
||||||
EXTRA_DIST = $(docs_DATA)
|
EXTRA_DIST = $(docs_DATA)
|
||||||
|
|||||||
@@ -47,12 +47,13 @@ comands to `initctl`, followed by `reload` to activate your changes.
|
|||||||
You can also use a standard [/etc/rc.local](rc.local) for one-shot tasks
|
You can also use a standard [/etc/rc.local](rc.local) for one-shot tasks
|
||||||
and initialization like keyboard language etc.
|
and initialization like keyboard language etc.
|
||||||
|
|
||||||
If you want to use the X Window system, `sudo apt install elogind`
|
> **NOTE:** X Window system, you may need to `sudo apt install elogind`
|
||||||
(Bullseye and later). Followed by `initctl reload` (enabled by default)
|
> (Bullseye and later), followed by `initctl reload` to activate it (it
|
||||||
and logout/login again. The elogind daemon ensures a regular non-root
|
> is enabled by default), and logout/login again. The elogind daemon
|
||||||
user can start and interact with an X session, otherwise keyboard and
|
> ensures a regular non-root user can start and interact with an X
|
||||||
mouse won't work. When you're happy, you can enable the lightdm.conf,
|
> session, otherwise keyboard and mouse won't work. When you're happy,
|
||||||
change the default runlevel to 3, and presto! you have a desktop again.
|
> you can enable the lightdm.conf, change the default runlevel to 3, and
|
||||||
|
> presto! you have a desktop again.
|
||||||
|
|
||||||
|
|
||||||
Have fun!
|
Have fun!
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ echo
|
|||||||
--sysconfdir=/etc --localstatedir=/var \
|
--sysconfdir=/etc --localstatedir=/var \
|
||||||
--enable-dbus-plugin --enable-x11-common-plugin \
|
--enable-dbus-plugin --enable-x11-common-plugin \
|
||||||
--enable-alsa-utils-plugin --with-keventd \
|
--enable-alsa-utils-plugin --with-keventd \
|
||||||
--with-random-seed=/var/lib/urandom/random-seed \
|
--with-random-seed=/var/lib/urandom/random-seed
|
||||||
--with-heading="Debian GNU/Linux"
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo
|
echo
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
SUBDIRS = available
|
SUBDIRS = available
|
||||||
docsdir := @docdir@/contrib/debian/finit.d
|
docsdir := @docdir@/contrib/debian/finit.d
|
||||||
d_LINKS = acpid.conf apparmor.conf avahi-demon.conf \
|
d_LINKS = acpid.conf apparmor.conf avahi-daemon.conf \
|
||||||
bluetooth.conf console-setup.conf elogind.conf \
|
bluetooth.conf console-setup.conf elogind.conf \
|
||||||
getty.conf keyboard-setup.conf modules.conf \
|
getty.conf keyboard-setup.conf modules.conf \
|
||||||
rsyslogd.conf sshd.conf
|
plymouth-quit.conf rsyslogd.conf sshd.conf
|
||||||
|
|
||||||
install-exec-hook:
|
install-exec-hook:
|
||||||
@$(MKDIR_P) $(DESTDIR)$(docsdir)/available
|
@$(MKDIR_P) $(DESTDIR)$(docsdir)/available
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ docsdir := @docdir@/contrib/debian/finit.d/available
|
|||||||
docs_DATA = acpid.conf apparmor.conf avahi-daemon.conf bluetooth.conf \
|
docs_DATA = acpid.conf apparmor.conf avahi-daemon.conf bluetooth.conf \
|
||||||
console-setup.conf elogind.conf getty.conf \
|
console-setup.conf elogind.conf getty.conf \
|
||||||
keyboard-setup.conf lightdm.conf modules.conf sntpd.conf \
|
keyboard-setup.conf lightdm.conf modules.conf sntpd.conf \
|
||||||
rsyslogd.conf sshd.conf syslogd.conf xdm.conf
|
plymouth-quit.conf rsyslogd.conf sshd.conf syslogd.conf \
|
||||||
|
xdm.conf
|
||||||
EXTRA_DIST = $(docs_DATA)
|
EXTRA_DIST = $(docs_DATA)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# Need to stop plymouth, or it'll block stdin on tty1
|
||||||
|
task [S] /usr/bin/plymouth quit -- Stopping Plymouth Boot Screen
|
||||||
@@ -8,7 +8,7 @@ if [ "x`id -u`" != "x0" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Adjust base directory
|
# Adjust base directory
|
||||||
grep -q Debian os-release 2>/dev/null
|
grep -q debian Makefile 2>/dev/null
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
cd ../..
|
cd ../..
|
||||||
elif [ ! -e configure.ac ]; then
|
elif [ ! -e configure.ac ]; then
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
|
|
||||||
NAME="Debian GNU/Linux"
|
|
||||||
VERSION_ID="8"
|
|
||||||
VERSION="8 (jessie)"
|
|
||||||
ID=debian
|
|
||||||
HOME_URL="http://www.debian.org/"
|
|
||||||
SUPPORT_URL="http://www.debian.org/support"
|
|
||||||
BUG_REPORT_URL="https://bugs.debian.org/"
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
SUBDIRS = finit.d
|
SUBDIRS = finit.d
|
||||||
docsdir := @docdir@/contrib/void
|
docsdir := @docdir@/contrib/void
|
||||||
docs_DATA = README.md finit.conf build.sh install.sh rc.local xbps
|
docs_DATA = README.md finit.conf build.sh install.sh rc.local
|
||||||
EXTRA_DIST = $(docs_DATA)
|
EXTRA_DIST = $(docs_DATA)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
|
|||||||
--sysconfdir=/etc --localstatedir=/var \
|
--sysconfdir=/etc --localstatedir=/var \
|
||||||
--enable-dbus-plugin --enable-x11-common-plugin \
|
--enable-dbus-plugin --enable-x11-common-plugin \
|
||||||
--enable-alsa-utils-plugin --with-watchdog \
|
--enable-alsa-utils-plugin --with-watchdog \
|
||||||
--with-heading="Void Linux" --with-keventd
|
--with-keventd
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "*** Building ..."
|
echo "*** Building ..."
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ if [ "x`id -u`" != "x0" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Adjust base directory
|
# Adjust base directory
|
||||||
if [ -e xbps ]; then
|
grep -q void Makefile 2>/dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
cd ../..
|
cd ../..
|
||||||
elif [ ! -e configure.ac ]; then
|
elif [ ! -e configure.ac ]; then
|
||||||
echo "*** Please run this script from the Finit base directory."
|
echo "*** Please run this script from the Finit base directory."
|
||||||
|
|||||||
+8
-2
@@ -21,11 +21,17 @@ Some of these are also registered in the issue tracker on GitHub.
|
|||||||
* Allow running as non-pid1 => read .conf and RCSD form cmdline
|
* Allow running as non-pid1 => read .conf and RCSD form cmdline
|
||||||
* Add `finit.conf` support for UPS notification (SIGPWR) to start a task
|
* Add `finit.conf` support for UPS notification (SIGPWR) to start a task
|
||||||
using, e.g. <sys/power/{ok,fail,low}> conditions. More info in sig.c
|
using, e.g. <sys/power/{ok,fail,low}> conditions. More info in sig.c
|
||||||
|
|
||||||
|
As of Finit v4.1 SIGPWR generates <sys/power/fail> condition and it
|
||||||
|
is up to a task to check why and take appropriate action.
|
||||||
* Add `finit.conf` support for ctrl-alt-delete (SIGINT) and kbrequest,
|
* Add `finit.conf` support for ctrl-alt-delete (SIGINT) and kbrequest,
|
||||||
i.e. KeyboardSignal, (SIGWINCH) behavior. Using conditions to a task,
|
i.e. KeyboardSignal, (SIGWINCH) behavior. Using conditions to a task,
|
||||||
e.g, <sys/key/ctrlaltdel> and <sys/key/signal> like SIGPWR handling.
|
e.g, <sys/key/ctrlaltdel> and <sys/key/signal> like SIGPWR handling.
|
||||||
* Write man pages for finit and `finit.conf`, steal from the excellent
|
|
||||||
`pimd` man pages ...
|
As of Finit v4.1 SIGINT generates <sys/key/ctrlaltdel>, but there is
|
||||||
|
no check if the signal actually originates from the kernel. To get
|
||||||
|
this verification, a new libuEv release is needed. As of June 6 -21
|
||||||
|
that functionality is not yet released.
|
||||||
|
|
||||||
|
|
||||||
Initctl
|
Initctl
|
||||||
|
|||||||
+1
-2
@@ -83,8 +83,7 @@ Then configure, build and install:
|
|||||||
```shell
|
```shell
|
||||||
$ ./configure --prefix=/usr --exec-prefix= \
|
$ ./configure --prefix=/usr --exec-prefix= \
|
||||||
--sysconfdir=/etc --localstatedir=/var \
|
--sysconfdir=/etc --localstatedir=/var \
|
||||||
--with-keventd --with-watchdog \
|
--with-keventd --with-watchdog
|
||||||
--with-heading="Alpine Linux" --with-hostname=alpine
|
|
||||||
$ make
|
$ make
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
|
|||||||
+17
-15
@@ -43,13 +43,13 @@ Not all configuration directives are available in `/etc/finit.d/*.conf`
|
|||||||
and some directives are only available at [bootstrap][], runlevel `S`,
|
and some directives are only available at [bootstrap][], runlevel `S`,
|
||||||
see the section [Limitations](#limitations) below for details.
|
see the section [Limitations](#limitations) below for details.
|
||||||
|
|
||||||
To add a new service, simply drop a `.conf` file in `/etc/finit.d` and
|
To add a new service, drop a `.conf` file in `/etc/finit.d` and run
|
||||||
run `initctl reload`. (It is also possible to `SIGHUP` to PID 1, or
|
`initctl reload`. (It is also possible to `SIGHUP` to PID 1, or call
|
||||||
call `finit q`, but that has been deprecated with the `initctl` tool).
|
`finit q`, but that has been deprecated with the `initctl` tool). Finit
|
||||||
Finit monitors all known active `.conf` files, so if you want to force
|
monitors all known active `.conf` files, so if you want to force a
|
||||||
a restart of any service you can simply touch its corresponding `.conf`
|
restart of any service you can touch its corresponding `.conf` file in
|
||||||
file in `/etc/finit.d` and call `initctl reload`. Finit handle any
|
`/etc/finit.d` and call `initctl reload`. Finit handle any and all
|
||||||
and all conditions and dependencies between services automatically.
|
conditions and dependencies between services automatically.
|
||||||
|
|
||||||
It is also possible to drop `.conf` files in `/etc/finit.d/available/`
|
It is also possible to drop `.conf` files in `/etc/finit.d/available/`
|
||||||
and use `initctl enable` to enable a service `.conf` file. This may be
|
and use `initctl enable` to enable a service `.conf` file. This may be
|
||||||
@@ -154,7 +154,7 @@ Top-level group configuration.
|
|||||||
cgroup system cpu.weight:9800
|
cgroup system cpu.weight:9800
|
||||||
|
|
||||||
Adding an extra cgroup `maint/` will require you to adjust the weight of
|
Adding an extra cgroup `maint/` will require you to adjust the weight of
|
||||||
the above three. We leave `init/` and `user /` as-is reducing weight of
|
the above three. We leave `init/` and `user/` as-is reducing weight of
|
||||||
`system/` to 9700.
|
`system/` to 9700.
|
||||||
|
|
||||||
cgroup system cpu.weight:9700
|
cgroup system cpu.weight:9700
|
||||||
@@ -184,7 +184,7 @@ The latter form also allows per-stanza limits on the form:
|
|||||||
|
|
||||||
Notice the comma separation and the `mem.` exception to the rule: every
|
Notice the comma separation and the `mem.` exception to the rule: every
|
||||||
cgroup setting maps directly to cgroup v2 syntax. I.e., `cpu.max` maps
|
cgroup setting maps directly to cgroup v2 syntax. I.e., `cpu.max` maps
|
||||||
to the file `/sys/fs/cgroup/maint/foo/cpu.max`. There is not filtering,
|
to the file `/sys/fs/cgroup/maint/foo/cpu.max`. There is no filtering,
|
||||||
except for expanding the shorthand `mem.` to `memory.`, if the file is
|
except for expanding the shorthand `mem.` to `memory.`, if the file is
|
||||||
not available, either the cgroup controller is not available in your
|
not available, either the cgroup controller is not available in your
|
||||||
Linux kernel, or the name is misspelled.
|
Linux kernel, or the name is misspelled.
|
||||||
@@ -473,8 +473,9 @@ size limit is reached.
|
|||||||
`tty [LVLS] <COND> [notty] [rescue]`
|
`tty [LVLS] <COND> [notty] [rescue]`
|
||||||
|
|
||||||
The first variant of this option uses the built-in getty on the given
|
The first variant of this option uses the built-in getty on the given
|
||||||
TTY device DEV, in the given runlevels. The DEV may be the special
|
TTY device DEV, in the given runlevels. DEV may be the special keyword
|
||||||
keyword `@console`, or `console`, useful on embedded systems.
|
`@console`, which is expanded from `/sys/class/tty/console/active`,
|
||||||
|
useful on embedded systems.
|
||||||
|
|
||||||
The default baud rate is 0, i.e., keep kernel default.
|
The default baud rate is 0, i.e., keep kernel default.
|
||||||
|
|
||||||
@@ -555,8 +556,8 @@ One can also use the `service` stanza to start a stand-alone shell:
|
|||||||
### Non-privileged Services
|
### Non-privileged Services
|
||||||
|
|
||||||
Every `run`, `task`, or `service` can also list the privileges the
|
Every `run`, `task`, or `service` can also list the privileges the
|
||||||
`/path/to/cmd` should be executed with. Simply prefix the path with
|
`/path/to/cmd` should be executed with. Prefix the command with
|
||||||
`[@USR[:GRP]]` like this:
|
`@USR[:GRP]`, group is optional, like this:
|
||||||
|
|
||||||
run [2345] @joe:users logger "Hello world"
|
run [2345] @joe:users logger "Hello world"
|
||||||
|
|
||||||
@@ -654,8 +655,9 @@ Limitations
|
|||||||
-----------
|
-----------
|
||||||
|
|
||||||
As of Finit v4 there are no limitations to where `.conf` settings can be
|
As of Finit v4 there are no limitations to where `.conf` settings can be
|
||||||
placed. Except for the system/global `rlimit`, which can only be set
|
placed. Except for the system/global `rlimit` and `cgroup` top-level
|
||||||
from `/etc/finit.conf`, since it is the first `.conf` file Finit reads.
|
group declarations, which can only be set from `/etc/finit.conf`, since
|
||||||
|
it is the first `.conf` file Finit reads.
|
||||||
|
|
||||||
Originally, `/etc/finit.conf` was the only way to set up a Finit system.
|
Originally, `/etc/finit.conf` was the only way to set up a Finit system.
|
||||||
Today it is mainly used for bootstrap settings like system hostname,
|
Today it is mainly used for bootstrap settings like system hostname,
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
dist_man8_MANS = finit.8 initctl.8
|
||||||
|
dist_man5_MANS = finit.conf.5
|
||||||
+178
@@ -0,0 +1,178 @@
|
|||||||
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
|
.\" First parameter, NAME, should be all caps
|
||||||
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
|
.Dd June 6, 2021
|
||||||
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
|
.Dt FINIT 8 SMM
|
||||||
|
.Os Linux
|
||||||
|
.Sh NAME
|
||||||
|
.Nm finit
|
||||||
|
.Nd Fast init for Linux systems
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm /sbin/finit
|
||||||
|
.Op finit.status_style=classic
|
||||||
|
.Op finit.show_status=[on,off]
|
||||||
|
.Op finit.debug
|
||||||
|
.Op rescue | recover
|
||||||
|
.Op single | S
|
||||||
|
.Nm /sbin/telinit
|
||||||
|
.Op Fl hv
|
||||||
|
.Op q | Q | 0-9
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
Fast init for Linux systems. Reverse engineered from the EeePC
|
||||||
|
fastinit, 10+ years ago by Claudio Matsuoka, "gaps filled with frog
|
||||||
|
DNA ...". Focus is on small and embedded systems, although Finit is
|
||||||
|
fully usable on server and desktop systems as well.
|
||||||
|
.Pp
|
||||||
|
Features include:
|
||||||
|
.Bl -bullet -width 1n -compact
|
||||||
|
.It
|
||||||
|
Runlevels, defined per service
|
||||||
|
.It
|
||||||
|
One-shot tasks, services (daemons), or SysV init start/stop scripts
|
||||||
|
.It
|
||||||
|
Runparts and
|
||||||
|
.Pa /etc/rc.local
|
||||||
|
support
|
||||||
|
.It
|
||||||
|
Process supervision similar to
|
||||||
|
.Xr systemd 8
|
||||||
|
.It
|
||||||
|
Sourcing environment files
|
||||||
|
.It
|
||||||
|
Conditions for network/process/custom dependencies
|
||||||
|
.It
|
||||||
|
Pre/Post script actions
|
||||||
|
.It
|
||||||
|
Tooling to enable/disable services
|
||||||
|
.It
|
||||||
|
Built-in getty
|
||||||
|
.It
|
||||||
|
Built-in watchdog, with support for hand-over to
|
||||||
|
.Lk https://troglobit.com/watchdogd.html watchdogd
|
||||||
|
.It
|
||||||
|
Built-in support for Debian/BusyBox
|
||||||
|
.Pa /etc/network/interfaces
|
||||||
|
.It
|
||||||
|
Cgroups v2, both configuration and monitoring in `initctl top`
|
||||||
|
.It
|
||||||
|
Plugin support for customization
|
||||||
|
.It
|
||||||
|
Proper rescue mode with bundled `sulogin` for protected maintenance shell
|
||||||
|
.El
|
||||||
|
.Sh BOOTING
|
||||||
|
.Pp
|
||||||
|
Before laucnhing services, the system needs to be bootstrapped. This
|
||||||
|
involves mounting all filesystems (not already mounted by an initramfs)
|
||||||
|
in
|
||||||
|
.Pa /etc/fstab ,
|
||||||
|
ensuring that necessary filesystems like:
|
||||||
|
.Pa /dev ,
|
||||||
|
.Pa /proc ,
|
||||||
|
.Pa /sys ,
|
||||||
|
and
|
||||||
|
.Pa /run
|
||||||
|
are available and can provide the system with the services required.
|
||||||
|
.Pp
|
||||||
|
With that out of the way, a set of plugins take over:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width bootmisc.so -offset indent
|
||||||
|
.It Cm bootmisc.so
|
||||||
|
Cleans up stale files from previous boots and default directories are
|
||||||
|
created in tmpfs filesystems
|
||||||
|
.It Cm modprobe.so
|
||||||
|
Probes kernel modules required by the system
|
||||||
|
.It Cm procps.so
|
||||||
|
Set kernel variables from
|
||||||
|
.Pa /etc/sysctl.conf
|
||||||
|
et al
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
When the plugins are done, finit reads
|
||||||
|
.Pa /etc/finit.conf
|
||||||
|
and all other enabled services in
|
||||||
|
.Pa /etc/finit.d/* .
|
||||||
|
First all services, run/tasks in runlevel S (bootStrap) are started,
|
||||||
|
When all run/tasks have completed, Finit changes to the configured
|
||||||
|
runlevel (default 2), Processes are started in parallel, in dependency
|
||||||
|
order according to their conditions.
|
||||||
|
.Pp
|
||||||
|
When all services and run/tasks have been started, the console progress
|
||||||
|
is disabled and all configured getty services are started.
|
||||||
|
.Sh CONDITIONS
|
||||||
|
The condition subysystem in Finit was initially created to track PID
|
||||||
|
files of daemons. If service/task B requires service A to have started,
|
||||||
|
Finit waits for the PID file of service A to be created/updated before
|
||||||
|
it starts service B. Conversely, if service A is stopped and its PID
|
||||||
|
file removed, service B is also stopped.
|
||||||
|
.Pp
|
||||||
|
The following condition families are availble today:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width pid -offset indent
|
||||||
|
.It Cm net
|
||||||
|
Linux netlink events, e.g. net/route/default, net/eth0/up, and
|
||||||
|
net/et0/running
|
||||||
|
.It Cm pid
|
||||||
|
PID files basd on the service declaration
|
||||||
|
.Cm name:id ,
|
||||||
|
gives the condition pid/name:id
|
||||||
|
.It Cm sys
|
||||||
|
System conditions, e.g. sys/key/ctrlaltdel and sys/pwr/fail
|
||||||
|
.It Cm usr
|
||||||
|
User conditions, assert and deassert using
|
||||||
|
.Cm initctl cond [set|clr] foo
|
||||||
|
.El
|
||||||
|
.Sh SIGNALS
|
||||||
|
PID 1 is the only process that by default blocks all signals. Finit
|
||||||
|
allows for the following signals to control operation, but recommends
|
||||||
|
instead using the
|
||||||
|
.Xr initctl 8
|
||||||
|
tool.
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width TERM
|
||||||
|
.It HUP
|
||||||
|
Tell
|
||||||
|
.Nm
|
||||||
|
to reload its configuration file(s), same as
|
||||||
|
.Cm initctl reload
|
||||||
|
.It USR1
|
||||||
|
Restart API
|
||||||
|
.Cm ( initctl )
|
||||||
|
socket.
|
||||||
|
.It USR2
|
||||||
|
Tell
|
||||||
|
.Nm
|
||||||
|
to perform a system shutdown, same as
|
||||||
|
.Cm initctl poweroff
|
||||||
|
.It TERM
|
||||||
|
Like SIGUSR2 but performs a reboot, same as
|
||||||
|
.Cm initctl reboot
|
||||||
|
.It INT
|
||||||
|
Sent from kernel when Ctrl-Alt-Del is pressed (on the console), this
|
||||||
|
asserts the sys/key/ctrlaltdel condition, which can be used to start
|
||||||
|
tasks or services
|
||||||
|
.It PWR
|
||||||
|
Sent from a a power daemon on changes to UPS status, Finit asserts
|
||||||
|
the sys/pwr/fail condition
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /etc/finit.d/available/*.conf -compact
|
||||||
|
.It Pa /etc/finit.conf
|
||||||
|
Main configuration file
|
||||||
|
.It Pa /etc/finit.d/*.conf
|
||||||
|
Static service definitions
|
||||||
|
.It Pa /etc/finit.d/available/*.conf
|
||||||
|
Available services
|
||||||
|
.It Pa /etc/finit.d/enabled/*.conf
|
||||||
|
Symlinks from available
|
||||||
|
.It Pa /run/finit/
|
||||||
|
Runtime files, including the condition subsystem
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr finit.conf 5
|
||||||
|
.Xr initctl 8
|
||||||
|
.Sh AUTHORS
|
||||||
|
.Nm
|
||||||
|
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
|
||||||
|
maintained by Joachim Wiberg, with contributions by many others.
|
||||||
@@ -0,0 +1,814 @@
|
|||||||
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
|
.\" First parameter, NAME, should be all caps
|
||||||
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
|
.Dd Oct 17, 2020
|
||||||
|
.Dt FINIT.CONF 5 SMM
|
||||||
|
.Os Linux
|
||||||
|
.Sh NAME
|
||||||
|
.Nm finit.conf
|
||||||
|
.Nd Finit configuration file format
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm /etc/finit.conf
|
||||||
|
.Nm /etc/finit.d/*.conf
|
||||||
|
.Nm /etc/finit.d/available/*.conf
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm finit
|
||||||
|
can be configured using only the original
|
||||||
|
.Pa /etc/finit.conf
|
||||||
|
file or in combination with
|
||||||
|
.Pa /etc/finit.d/*.conf .
|
||||||
|
Useful for package-based Linux distributions \(em each package can
|
||||||
|
provide its own "script" file.
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width /etc/finit.d/*.conf -offset indent -compact
|
||||||
|
.It Pa /etc/finit.conf
|
||||||
|
Main configuration file
|
||||||
|
.It Pa /etc/finit.d/*.conf
|
||||||
|
Snippets, usually one service per file
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Not all configuration directives are available in
|
||||||
|
.Pa /etc/finit.d/*.conf
|
||||||
|
and some directives are only available at bootstrap, runlevel
|
||||||
|
.Cm S ,
|
||||||
|
see the section
|
||||||
|
.Sx Limitations
|
||||||
|
below for details.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /etc/finit.d/available/*.conf -compact
|
||||||
|
.It Pa /etc/finit.conf
|
||||||
|
Main configuration file
|
||||||
|
.It Pa /etc/finit.d/*.conf
|
||||||
|
Static service definitions
|
||||||
|
.It Pa /etc/finit.d/available/*.conf
|
||||||
|
Available services
|
||||||
|
.It Pa /etc/finit.d/enabled/*.conf
|
||||||
|
Enabled services, symlinks from available
|
||||||
|
.El
|
||||||
|
.Sh FILE FORMAT
|
||||||
|
Lines starting with `#' are ignored. Note that end-of-line comments are
|
||||||
|
NOT supported, comments must be on a line of their own.
|
||||||
|
.Pp
|
||||||
|
A configuration stanza must be on a single (long) line and
|
||||||
|
.Em cannot
|
||||||
|
be broken up in multiple lines by use of a backslash as the last
|
||||||
|
character.
|
||||||
|
.Sh DIRECTIVES
|
||||||
|
This section lists all supported configuration directives. There also exist
|
||||||
|
deprecated directives, see the Markdown documentation for details on these.
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width 1n
|
||||||
|
.It Cm rlimit Oo hard|soft Oc Ar RESOURCE Aq LIMIT | unlimited
|
||||||
|
.Pp
|
||||||
|
Set the hard or soft limit for a resource, or both if that argument is
|
||||||
|
omitted.
|
||||||
|
.Ar RESOURCE
|
||||||
|
is the lower-case
|
||||||
|
.Cm RLIMIT_
|
||||||
|
string constants from
|
||||||
|
.Xr setrlimit 2 ,
|
||||||
|
without prefix. E.g. to set
|
||||||
|
.Cm RLIMIT_CPU ,
|
||||||
|
use
|
||||||
|
.Cm cpu .
|
||||||
|
.Pp
|
||||||
|
.Ar LIMIT
|
||||||
|
is an integer that depends on the resource being modified, see
|
||||||
|
the man page, or the kernel
|
||||||
|
.Pa /proc/PID/limits
|
||||||
|
file, for details.
|
||||||
|
Finit versions before v3.1 used
|
||||||
|
.Cm infinity
|
||||||
|
for
|
||||||
|
.Cm unlimited ,
|
||||||
|
which is still supported, albeit deprecated.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
# No process is allowed more than 8MB of address space
|
||||||
|
rlimit hard as 8388608
|
||||||
|
|
||||||
|
# Core dumps may be arbitrarily large
|
||||||
|
rlimit soft core infinity
|
||||||
|
|
||||||
|
# CPU limit for all services, soft & hard = 10 sec
|
||||||
|
rlimit cpu 10
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
.Cm rlimit
|
||||||
|
can be set globally, in
|
||||||
|
.Pa /etc/finit.conf ,
|
||||||
|
or locally per each
|
||||||
|
.Pa /etc/finit.d/*.conf
|
||||||
|
read. I.e., a set of task/run/service stanzas can share the same
|
||||||
|
rlimits if they are in the same .conf.
|
||||||
|
.It Cm runlevel Aq N
|
||||||
|
The system runlevel to go to after bootstrap (S) has completed.
|
||||||
|
.Cm N
|
||||||
|
is the runlevel number 0-9, where 6 is reserved for reboot and 0 for
|
||||||
|
halt. All other can be used by operating system administrators.
|
||||||
|
Default: 2
|
||||||
|
.Pp
|
||||||
|
.Sy Note:
|
||||||
|
only read and executed in runlevel S (bootstrap).
|
||||||
|
.It Cm run Oo LVLS Oc Ao COND Ac Ar /path/to/cmd ARGS Op -- Optional description
|
||||||
|
One-shot command to run in sequence when entering a runlevel, with
|
||||||
|
optional arguments and description.
|
||||||
|
.Pp
|
||||||
|
.Cm run
|
||||||
|
commands are guaranteed to be completed before running the next
|
||||||
|
command. Highly useful if true serialization is needed. Usually
|
||||||
|
only used in the bootstrap (S) runlevel.
|
||||||
|
.Pp
|
||||||
|
.Cm Aq COND
|
||||||
|
conditions are described in
|
||||||
|
.Xr finit 8 ,
|
||||||
|
see also the
|
||||||
|
.Sx Examples
|
||||||
|
section below.
|
||||||
|
.It Cm task Oo LVLS Oc Ao COND Ac Ar /path/to/cmd ARGS Op -- Optional description
|
||||||
|
One-shot like
|
||||||
|
.Cm run ,
|
||||||
|
but starts in parallel with the next command.
|
||||||
|
.Pp
|
||||||
|
Both
|
||||||
|
.Cm run
|
||||||
|
and
|
||||||
|
.Cm task
|
||||||
|
commands are run in a shell, so pipes and redirects can be freely used:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
task [s] echo "foo" | cat >/tmp/bar
|
||||||
|
.Ed
|
||||||
|
.It Cm sysv Oo LVLS Oc Ao COND Ac Ar /path/to/script ARGS Op -- Optional description
|
||||||
|
Similar to
|
||||||
|
.Cm task
|
||||||
|
is the
|
||||||
|
.Cm sysv
|
||||||
|
stanza, which can be used to call SysV style start/stop scripts. The
|
||||||
|
primary intention for this command is to be able to re-use much of
|
||||||
|
existing setup and init scripts in Linux distributions.
|
||||||
|
.Pp
|
||||||
|
When entering an allowed runlevel, Finit calls
|
||||||
|
.Cm init-script start ,
|
||||||
|
when entering a disallowed runlevel, Finit calls
|
||||||
|
.Cm init-script stop ,
|
||||||
|
and if the Finit .conf, where the
|
||||||
|
.Cm sysv
|
||||||
|
stanza is declared, is modified, Finit calls
|
||||||
|
.Cm init-script restart
|
||||||
|
on
|
||||||
|
.Cm initctl reload .
|
||||||
|
Similar to how
|
||||||
|
.Cm service
|
||||||
|
stanzas work.
|
||||||
|
.Pp
|
||||||
|
Forking services started with
|
||||||
|
.Cm sysv
|
||||||
|
scripts can be monitored by Finit by declaring the PID file to look for:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
sysv pid:!/path/to/pidfile.pid /path/to/script ...
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The leading '!' is to prevent Finit from managing the PID file, which is
|
||||||
|
the default behavior for the
|
||||||
|
.Cm pid:
|
||||||
|
command modifier.
|
||||||
|
.It Cm service Oo LVLS Oc Ao COND Ac Ar /path/to/daemon ARGS Op -- Optional description
|
||||||
|
Service, or daemon, to be monitored and automatically restarted if it
|
||||||
|
exits prematurely. Finit tries to restart services that die 10 times
|
||||||
|
before giving up, then you have to restart it manually:
|
||||||
|
.Cm initctl restart NAME
|
||||||
|
.Pp
|
||||||
|
For daemons that support it, we recommend appending
|
||||||
|
.Cm --foreground , --no-background , -n , -F ,
|
||||||
|
or similar command line argument to prevent them from forking off a
|
||||||
|
sub-process in the background. This is the most reliable way to monitor
|
||||||
|
a service.
|
||||||
|
.Pp
|
||||||
|
However, not all daemons support running in the foreground, or they may
|
||||||
|
start logging to the foreground as well, these are called forking
|
||||||
|
services and are supported using the same syntax as forking
|
||||||
|
.Cm sysv
|
||||||
|
services, using the
|
||||||
|
.Cm pid:!/path/to/pidfile.pid
|
||||||
|
command modifier syntax.
|
||||||
|
.Pp
|
||||||
|
.Sy Example: in the case of
|
||||||
|
.Cm ospfd
|
||||||
|
(below), we omit the
|
||||||
|
.Cm -d
|
||||||
|
flag (daemonize) to prevent it from forking to the background:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
service [2345] <pid/zebra> /sbin/ospfd -- OSPF daemon
|
||||||
|
.Ed
|
||||||
|
.Cm [2345]
|
||||||
|
denote the runlevels
|
||||||
|
.Cm ospfd
|
||||||
|
is allowed to run in, they are optional and default to runlevel 2-5 if
|
||||||
|
omitted.
|
||||||
|
.Pp
|
||||||
|
.Cm <pid/zebra>
|
||||||
|
is the condition for starting
|
||||||
|
.Cm ospfd .
|
||||||
|
In this example Finit waits for another service,
|
||||||
|
.Cm zebra ,
|
||||||
|
to have created its PID file in
|
||||||
|
.Pa /var/run/quagga/zebra.pid
|
||||||
|
before starting
|
||||||
|
.Cm ospfd .
|
||||||
|
Finit watches *all* files in
|
||||||
|
.Pa /var/run ,
|
||||||
|
for each file named
|
||||||
|
.Cm *.pid ,
|
||||||
|
.Cm */pid ,
|
||||||
|
Finit opens it and find the matching
|
||||||
|
.Cm NAME:ID
|
||||||
|
using the PID.
|
||||||
|
.Pp
|
||||||
|
Some services do not maintain a PID file and rather than patching each
|
||||||
|
application Finit provides a workaround. A
|
||||||
|
.Cm pid
|
||||||
|
modifier keyword can be set to have Finit automatically create (when
|
||||||
|
starting) and later remove (when stopping) the PID file. The file is
|
||||||
|
created in the
|
||||||
|
.Pa /var/run
|
||||||
|
directory using the
|
||||||
|
.Xr basename 3
|
||||||
|
of the service. The full syntax of the
|
||||||
|
.Cm pid
|
||||||
|
modifier is:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
pid[:[!][/path/to/]filename[.pid]]
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
For example, by adding
|
||||||
|
.Cm pid:/run/foo.pid
|
||||||
|
to the service
|
||||||
|
.Cm /sbin/bar ,
|
||||||
|
that PID file will, not only be created and removed automatically, but
|
||||||
|
also be used by the Finit condition subsystem. So a service/run/task
|
||||||
|
can depend on the
|
||||||
|
.Cm <pid/bar>
|
||||||
|
condition.
|
||||||
|
.Pp
|
||||||
|
If a service should not be automatically started, it can be configured
|
||||||
|
as manual with the
|
||||||
|
.Cm manual:yes
|
||||||
|
command modifier. The service can then be started at any time by
|
||||||
|
running
|
||||||
|
.Cm initctl start NAME
|
||||||
|
.Pp
|
||||||
|
The name of a service, shown by the
|
||||||
|
.Cm initctl
|
||||||
|
tool, defaults to the basename of the service executable. It can be
|
||||||
|
changed with the
|
||||||
|
.Cm name:foo
|
||||||
|
command modifier.
|
||||||
|
.Pp
|
||||||
|
When stopping a service (run/task/sysv/service), either manually or when
|
||||||
|
moving to another runlevel, Finit starts by sending SIGTERM, to allow
|
||||||
|
the process to shut down gracefully. If the process has not been
|
||||||
|
collected within 3 seconds, Finit sends SIGKILL. To halt the process
|
||||||
|
using a different signal, use the command modifier
|
||||||
|
.Cm halt:SIGNAL ,
|
||||||
|
e.g.,
|
||||||
|
.Cm halt:SIGPWR .
|
||||||
|
To change the delay between your halt signal and KILL, use the command
|
||||||
|
modifier
|
||||||
|
.Cm kill:SEC ,
|
||||||
|
e.g.,
|
||||||
|
.Cm kill:10
|
||||||
|
to wait 10 seconds before sending SIGKILL.
|
||||||
|
.Pp
|
||||||
|
Services support the
|
||||||
|
.Cm pre:script
|
||||||
|
and
|
||||||
|
.Cm post:script
|
||||||
|
command actions as well. These run as the same
|
||||||
|
.Cm @USER:GROUP
|
||||||
|
as the service itself, with any
|
||||||
|
.Cm env:file
|
||||||
|
sourced. The scripts must use an absolute path, but are executed from
|
||||||
|
the
|
||||||
|
.Cm $HOME
|
||||||
|
of the given user. The scripts are not called with any argument
|
||||||
|
(currently), but both get the
|
||||||
|
.Cm SERVICE_IDENT=foo
|
||||||
|
environment variable set. Here
|
||||||
|
.Cm foo
|
||||||
|
denotes the identity of the service, which if there are multiple
|
||||||
|
services named
|
||||||
|
.Cm foo ,
|
||||||
|
may be
|
||||||
|
.Cm foo:1 ,
|
||||||
|
or any unique identifier specified in the .conf file. The
|
||||||
|
.cm post:script
|
||||||
|
is called with an additional set of environment variables:
|
||||||
|
.Bl -tag -offset indent -width 1n
|
||||||
|
.It Cm EXIT_CODE=[exited,signal]
|
||||||
|
set to one of
|
||||||
|
.Cm exited
|
||||||
|
or
|
||||||
|
.Cm signal
|
||||||
|
.It Cm EXIT_STATUS=[num,SIGNAME]
|
||||||
|
set to one of exit status code from the program, if it exited normally,
|
||||||
|
or the signal name (HUP, TERM, etc.) if it exited due to signal
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The scripts have a default execution time of 3 seconds before they are
|
||||||
|
SIGKILLed, this can be adjusted using the
|
||||||
|
.Cm kill:SEC
|
||||||
|
modifier syntax.
|
||||||
|
.Pp
|
||||||
|
.Sy Note:
|
||||||
|
the
|
||||||
|
.Cm pre:script
|
||||||
|
.Em must
|
||||||
|
be idempotent, because a service can transition between READY and HALTED
|
||||||
|
states any number of times before going to RUNNING.
|
||||||
|
.It Cm runparts Aq DIR
|
||||||
|
Call
|
||||||
|
.Xr run-parts 8
|
||||||
|
on
|
||||||
|
.Cm DIR
|
||||||
|
to run start scripts. All executable files, or scripts, in the
|
||||||
|
directory are called, in alphabetic order. The scripts in this
|
||||||
|
directory are executed at the very end of bootstrap, runlevel S.
|
||||||
|
.Pp
|
||||||
|
It can be beneficial to use
|
||||||
|
.Cm S01name ,
|
||||||
|
.Cm S02othername ,
|
||||||
|
etc. if there is a dependency order between the scripts. Symlinks to
|
||||||
|
existing daemons can talso be used, but make sure they daemonize by
|
||||||
|
default.
|
||||||
|
.Pp
|
||||||
|
Similar to the
|
||||||
|
.Pa /etc/rc.local
|
||||||
|
shell script, make sure that all your services and programs either
|
||||||
|
terminate or start in the background or you will block Finit.
|
||||||
|
.Sy Note:
|
||||||
|
only read and executed in runlevel S (bootstrap).
|
||||||
|
.It Cm include Aq CONF
|
||||||
|
Include another configuration file. Absolute path required.
|
||||||
|
.It Cm log size:BYTES count:NUM
|
||||||
|
Log rotation for run/task/services using the
|
||||||
|
.Cm log
|
||||||
|
command modifier with redirection to a log file. Global setting,
|
||||||
|
applies to all services.
|
||||||
|
.Pp
|
||||||
|
The size can be given as bytes, without a specifier, or in `k`, `M`,
|
||||||
|
or `G`, e.g.
|
||||||
|
.Cm size:10M ,
|
||||||
|
or
|
||||||
|
.Cm size:3G .
|
||||||
|
A value of
|
||||||
|
.Cm size:0
|
||||||
|
disables log rotation. The default is
|
||||||
|
.Cm size:200k .
|
||||||
|
.Pp
|
||||||
|
The count value is recommended to be between 1-5, with a default 5.
|
||||||
|
Setting count to 0 means the logfile will be truncated when the MAX
|
||||||
|
size limit is reached.
|
||||||
|
.It Cm tty Oo LVLS Oc Ao COND Ac Ar DEV Oo BAUD Oc Oo noclear Oc Oo nowait Oc Oo nologin Oc Oo TERM Oc
|
||||||
|
This form of the
|
||||||
|
.Cm tty
|
||||||
|
stanza uses the built-in getty on the given TTY device
|
||||||
|
.Ar DEV ,
|
||||||
|
in the given runlevels.
|
||||||
|
.Ar DEV may be the special keyword
|
||||||
|
.Cm @console ,
|
||||||
|
or `console`, which is expanded from `/sys/class/tty/console/active`,
|
||||||
|
useful on embedded systems.
|
||||||
|
.Pp
|
||||||
|
The default baud rate is 0, i.e., keep kernel default.
|
||||||
|
.Pp
|
||||||
|
The `tty` stanza inherits runlevel, condition (and other feature)
|
||||||
|
parsing from the `service` stanza. So TTYs can run in one or many
|
||||||
|
runlevels and depend on any condition supported by Finit. This is
|
||||||
|
useful e.g. to depend on `<pid/elogind>` before starting a TTY.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
tty [12345] /dev/ttyAMA0 115200 noclear vt220
|
||||||
|
.Ed
|
||||||
|
.It Cm tty Oo LVLS Oc Ao COND Ac Ar CMD DEV Oo noclear Oc Oo nowait Oc
|
||||||
|
This form of the
|
||||||
|
.Cm tty
|
||||||
|
stanza is for using an external getty, like agetty or the BusyBox getty.
|
||||||
|
.Pp
|
||||||
|
By default, these first two syntax variants
|
||||||
|
.Em clear
|
||||||
|
the TTY and
|
||||||
|
.Em wait
|
||||||
|
for the user to press enter before starting getty.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
tty [12345] /sbin/getty -L 115200 /dev/ttyAMA0 vt100
|
||||||
|
tty [12345] /sbin/agetty -L ttyAMA0 115200 vt100 nowait
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Cm noclear
|
||||||
|
option disables clearing the TTY after each session. Clearing the TTY
|
||||||
|
when a user logs out is usually preferable.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Cm nowait
|
||||||
|
option disables the
|
||||||
|
.Cm Please press Enter to activate console
|
||||||
|
message before actually starting the getty program. On small and
|
||||||
|
embedded systems running multiple unused getty wastes both memory and
|
||||||
|
CPU cycles, so `wait` is the preferred default.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Cm nologin
|
||||||
|
option disables getty and
|
||||||
|
.Pa /bin/login ,
|
||||||
|
and gives the user a root (login) shell on the given TTY
|
||||||
|
.Cm DEV
|
||||||
|
immediately. Needless to say, this is a rather insecure option, but can
|
||||||
|
be very useful for developer builds, during board bringup, or similar.
|
||||||
|
.Pp
|
||||||
|
Notice the ordering, the
|
||||||
|
.Cm TERM
|
||||||
|
option to the built-in getty must be the last argument.
|
||||||
|
.Pp
|
||||||
|
Embedded systems may want to enable automatic `DEV` by supplying the
|
||||||
|
special
|
||||||
|
.Cm @console
|
||||||
|
device. This works regardless weather the system uses
|
||||||
|
.Cm ttyS0 , ttyAMA0 , ttyMXC0 ,
|
||||||
|
or anything else. Finit figures it out by querying sysfs:
|
||||||
|
.Pa /sys/class/tty/console/active .
|
||||||
|
The speed can be omitted to keep the kernel default.
|
||||||
|
.Pp
|
||||||
|
Most systems get by fine by just using `console`, which will evaluate
|
||||||
|
to
|
||||||
|
.Pa /dev/console .
|
||||||
|
If you have to use
|
||||||
|
.Cm @console
|
||||||
|
to get any output, you may have some issue with your kernel config.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
tty [12345] @console noclear vt220
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
On really bare bones systems, or for board bringup, Finit can give you a
|
||||||
|
shell prompt as soon as bootstrap is done, without opening any device
|
||||||
|
node:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
tty [12345789] notty
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
This should of course not be enabled on production systems. Because it
|
||||||
|
may give a user root access without having to log in. However, for
|
||||||
|
board bringup and system debugging it can come in handy.
|
||||||
|
.Pp
|
||||||
|
One can also use the
|
||||||
|
.Cm service
|
||||||
|
stanza to start a stand-alone shell:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
service [12345] /bin/sh -l
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
.It Cm tty Oo LVLS Oc Ao COND Ac Oo notty Oc Oo rescue Oc
|
||||||
|
The third
|
||||||
|
.Cm tty
|
||||||
|
form is for board bringup and the
|
||||||
|
.Cm rescue
|
||||||
|
boot mode. No device node is required in this variant, the same output
|
||||||
|
that the kernel uses is reused for stdio. If the
|
||||||
|
.Cm rescue
|
||||||
|
option is omitted, a shell is started. The flags
|
||||||
|
.Cm nologin , noclear ,
|
||||||
|
and
|
||||||
|
.Cm nowait
|
||||||
|
are implied. If the
|
||||||
|
.Cm rescue
|
||||||
|
option is set the bundled
|
||||||
|
.Pa /libexec/finit/sulogin
|
||||||
|
is started to present a bare-bones root login prompt. If the root
|
||||||
|
(uid:0, gid:0) user does not have a password set, no rescue is possible.
|
||||||
|
.El
|
||||||
|
.Sh COMMAND MODIFIERS
|
||||||
|
The run/task/tty/service/sysv stanzas take modifiers, or options, to
|
||||||
|
control their behavior. This section lists them with their limitations.
|
||||||
|
All modifiers must be placed between the stanza and its command.
|
||||||
|
.Bl -tag -width 1n
|
||||||
|
.It Cm @user:group
|
||||||
|
Every
|
||||||
|
.Cm run , task ,
|
||||||
|
or
|
||||||
|
.Cm service
|
||||||
|
can also list the privileges the
|
||||||
|
.Cm /path/to/cmd
|
||||||
|
should be executed with. Prefix the command with
|
||||||
|
.Cm @USR[:GRP] ,
|
||||||
|
group is optional, like this:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
run [2345] @joe:users logger "Hello world"
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
For multiple instances of the same command, e.g. a DHCP client or
|
||||||
|
multiple web servers, add
|
||||||
|
.Cm :ID
|
||||||
|
somewhere between the
|
||||||
|
.Cm run , task , service
|
||||||
|
keyword and the command, like this:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
service :80 [2345] httpd -f -h /http -p 80 -- Web server
|
||||||
|
service :8080[2345] httpd -f -h /http -p 8080 -- Old web server
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Without the
|
||||||
|
.Cm :ID
|
||||||
|
to the service the latter will overwrite the former and only the old web
|
||||||
|
server would be started and supervised.
|
||||||
|
.It Cm log:/path/to/file
|
||||||
|
Redirect stdout/stderr of a command to the given log file. See the
|
||||||
|
global log directive, above, for details on log rotation.
|
||||||
|
.It Cm log:console
|
||||||
|
Redirect stdout/stderr of a command to
|
||||||
|
.Pa /dev/console ,
|
||||||
|
only use this for debugging or bringup.
|
||||||
|
.It Cm log:null
|
||||||
|
Redirect stdout/stderr of a command to
|
||||||
|
.Pa /dev/null .
|
||||||
|
.It Cm log:prio:facility.level,tag:ident
|
||||||
|
Redirect stdout/stderr of a command to syslog using the given priority
|
||||||
|
and tag identity.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
service log:prio:user.warn,tag:ntpd /sbin/ntpd pool.ntp.org -- NTP daemon
|
||||||
|
.Ed
|
||||||
|
.It Cm log
|
||||||
|
Default
|
||||||
|
.Cm prio
|
||||||
|
is
|
||||||
|
.Cm daemon.info
|
||||||
|
and the default
|
||||||
|
.Cm tag
|
||||||
|
identity is the basename of the service or run/task command.
|
||||||
|
.El
|
||||||
|
.Sh RESCUE MODE
|
||||||
|
Finit supports a rescue mode which is activated by the
|
||||||
|
.Cm rescue
|
||||||
|
option on the kernel command line. The rescue mode comes in two
|
||||||
|
flavors:
|
||||||
|
.Em traditional
|
||||||
|
and
|
||||||
|
.Em fallback .
|
||||||
|
.Ss Traditional
|
||||||
|
This is what most users expect. A very early maintenance login prompt,
|
||||||
|
served by the bundled
|
||||||
|
.Pa /libexec/finit/sulogin
|
||||||
|
program, or the standard
|
||||||
|
.Cm sulogin
|
||||||
|
from util-linux or BusyBox is searched for in the UNIX default
|
||||||
|
.Cm $PATH .
|
||||||
|
If a successful login is made, or the user exits (Ctrl-D), the rescue
|
||||||
|
mode is ended and the system boots up normally.
|
||||||
|
.Pp
|
||||||
|
.Sy Note:
|
||||||
|
if the user (UID 0 and GID 0) does not have a password, or
|
||||||
|
.Em the account is locked ,
|
||||||
|
the user is presented with a password-less prompt:
|
||||||
|
.Cm "Press enter to enter maintenance mode." ,
|
||||||
|
which opens up a root shell.
|
||||||
|
.Ss Fallback
|
||||||
|
If no
|
||||||
|
.Cm sulogin
|
||||||
|
program is found, Finit tries to bring up as much of its own
|
||||||
|
functionality as possible, yet limiting many aspects, meaning; no
|
||||||
|
network, no`fsck` of file systems in
|
||||||
|
.Pa /etc/fstab ,
|
||||||
|
no
|
||||||
|
.Pa /etc/rc.local ,
|
||||||
|
no
|
||||||
|
.Cm runparts ,
|
||||||
|
and most plugins are skipped (except those that provide functionality
|
||||||
|
for the condition subsystem).
|
||||||
|
.Pp
|
||||||
|
Instead of reading
|
||||||
|
.Pa /etc/finit.conf
|
||||||
|
et al, system configuration is read from
|
||||||
|
.Pa /lib/finit/rescue.conf ,
|
||||||
|
which can be freely modified by the system administrator.
|
||||||
|
.Pp
|
||||||
|
The bundled default `rescue.conf` contains nothing more than:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
runlevel 1
|
||||||
|
tty [12345] rescue
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Cm tty
|
||||||
|
has the
|
||||||
|
.Cm rescue
|
||||||
|
option set, which works similar to the board bring-up tty option
|
||||||
|
.Cm notty .
|
||||||
|
The major difference being that `sulogin` is started to query for
|
||||||
|
root/admin password. If
|
||||||
|
.Cm sulogin
|
||||||
|
is not found,
|
||||||
|
.Cm rescue
|
||||||
|
behaves like
|
||||||
|
.Cm notty
|
||||||
|
and gives a plain root shell prompt.
|
||||||
|
.Pp
|
||||||
|
If Finit cannot find
|
||||||
|
.Pa /lib/finit/rescue.conf
|
||||||
|
it defaults to:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
tty [12345] rescue
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
There is no way to exit the
|
||||||
|
.Em fallback
|
||||||
|
rescue mode.
|
||||||
|
.Sh SERVICE ENVIRONMENT
|
||||||
|
Finit supports sourcing environment variables from
|
||||||
|
.Pa /etc/default/* ,
|
||||||
|
or similar. This is a common pattern from SysV init scripts, where the
|
||||||
|
start/stop script is a generic script for the given service,
|
||||||
|
.Cm foo ,
|
||||||
|
and the options for the service are sourced from the file
|
||||||
|
.Pa /etc/default/foo .
|
||||||
|
Like this:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
/etc/default/foo:
|
||||||
|
|
||||||
|
FOO_OPTIONS=--extra-arg="bar" -s -x
|
||||||
|
|
||||||
|
/etc/finit.conf:
|
||||||
|
|
||||||
|
service [2345] env:-/etc/default/foo foo -n $FOO_OPTIONS -- Example foo daemon
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Here the service
|
||||||
|
.Cm foo
|
||||||
|
is started with
|
||||||
|
.Op Fl -n ,
|
||||||
|
to make sure it runs in the foreground, and the with the options found
|
||||||
|
in the environment file. With the
|
||||||
|
.Cm ps
|
||||||
|
command we can see that the process is started with:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
foo -n --extra-arg=bar -s -x
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
.Sy Note:
|
||||||
|
the leading `-` determines if Finit should treat a missing environment
|
||||||
|
file as blocking the start of the service or not. When `-` is used, a
|
||||||
|
missing environment file does
|
||||||
|
.Em not
|
||||||
|
block the start.
|
||||||
|
.Sh SERVICE WRAPPER SCRIPTS
|
||||||
|
If your service requires to run additional commands, executed before the
|
||||||
|
service is actually started, like the systemd `ExecStartPre`, you can
|
||||||
|
use a wrapper shell script to start your service.
|
||||||
|
.Pp
|
||||||
|
The Finit service
|
||||||
|
.Cm .conf
|
||||||
|
file can be put into
|
||||||
|
.Pa /etc/finit.d/available ,
|
||||||
|
so you can control the service using
|
||||||
|
.Cm initctl .
|
||||||
|
Then use the path to the wrapper script in the Finit
|
||||||
|
.Cm .conf
|
||||||
|
service stanza. The following example employs a wrapper script in
|
||||||
|
.Pa /etc/start.d .
|
||||||
|
.Bd -unfilled
|
||||||
|
/etc/finit.d/available/program.conf:
|
||||||
|
|
||||||
|
service [235] <!> /etc/start.d/program -- Example Program
|
||||||
|
|
||||||
|
/etc/start.d/program:
|
||||||
|
|
||||||
|
#!/bin/sh
|
||||||
|
# Prepare the command line options
|
||||||
|
OPTIONS="-u $(cat /etc/username)"
|
||||||
|
|
||||||
|
# Execute the program
|
||||||
|
exec /usr/bin/program $OPTIONS
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
.Sy Note:
|
||||||
|
the example sets
|
||||||
|
.Cm <!>
|
||||||
|
to denote that it doesn't support SIGHUP. That way Finit will
|
||||||
|
stop/start the service instead of sending SIGHUP at restart/reload
|
||||||
|
events.
|
||||||
|
.Sh CGROUPS
|
||||||
|
There are three major cgroup configuration directives:
|
||||||
|
.Pp
|
||||||
|
.Bl -enum -offset indent -compact
|
||||||
|
.It
|
||||||
|
Global top-level group: init, system, user, or a custom group
|
||||||
|
.It
|
||||||
|
Selecting a top-level group for a set of run/task/services
|
||||||
|
.It
|
||||||
|
Per run/task/service limits
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Top-level group configuration.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
# Top-level cgroups and their default settings. All groups mandatory
|
||||||
|
# but more can be added, max 8 groups in total currently. The cgroup
|
||||||
|
# 'root' is also available, reserved for RT processes. Settings are
|
||||||
|
# as-is, only one shorthand 'mem.' exists, other than that it's the
|
||||||
|
# cgroup v2 controller default names.
|
||||||
|
cgroup init cpu.weight:100
|
||||||
|
cgroup user cpu.weight:100
|
||||||
|
cgroup system cpu.weight:9800
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Adding an extra cgroup
|
||||||
|
.Cm maint/
|
||||||
|
will require you to adjust the weight of the above three. We leave
|
||||||
|
.Cm init/
|
||||||
|
and
|
||||||
|
.Cm user/
|
||||||
|
as-is reducing weight of
|
||||||
|
.Cm system/
|
||||||
|
to 9700.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
cgroup system cpu.weight:9700
|
||||||
|
|
||||||
|
# Example extra cgroup 'maint'
|
||||||
|
cgroup maint cpu.weight:100
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
By default, the
|
||||||
|
.Cm system/
|
||||||
|
cgroup is selected for almost everything. The
|
||||||
|
.Cm init/
|
||||||
|
cgroup is reserved for PID 1 itself and its closest relatives. The
|
||||||
|
.Cm user/
|
||||||
|
cgroup is for local TTY logins spawned by getty.
|
||||||
|
.Pp
|
||||||
|
To select a different top-level cgroup, e.g.
|
||||||
|
.Cm maint/ ,
|
||||||
|
one can either define it for a group of run/task/service directives in a
|
||||||
|
.Cm .conf
|
||||||
|
or per each stanza:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
cgroup.maint
|
||||||
|
service [...] <...> /path/to/foo args -- description
|
||||||
|
service [...] <...> /path/to/bar args -- description
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
or
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
service [...] <...> cgroup.maint /path/to/foo args -- description
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The latter form also allows per-stanza limits on the form:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
service [...] <...> cgroup.maint:cpu.max:10000,mem.max:655360 /path/to/foo args -- description
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Notice the comma separation and the
|
||||||
|
.Cm mem.
|
||||||
|
exception to the rule: every cgroup setting maps directly to cgroup v2
|
||||||
|
syntax. I.e.,
|
||||||
|
.Cm cpu.max
|
||||||
|
maps to the file
|
||||||
|
.Pm /sys/fs/cgroup/maint/foo/cpu.max .
|
||||||
|
There is no filtering, except for expanding the shorthand
|
||||||
|
.Cm mem.
|
||||||
|
to
|
||||||
|
.Cm memory. ,
|
||||||
|
if the file is not available, either the cgroup controller is not
|
||||||
|
available in your Linux kernel, or the name is misspelled.
|
||||||
|
.Pp
|
||||||
|
Linux cgroups and details surrounding values are not explained in the
|
||||||
|
Finit documentation. The Linux admin-guide cover this well:
|
||||||
|
.Lk https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
|
||||||
|
.Sh LIMITATIONS
|
||||||
|
As of Finit v4 there are no limitations to where
|
||||||
|
.Cm .conf
|
||||||
|
settings can be placed. Except for the system/global
|
||||||
|
.Cm rlimit
|
||||||
|
and
|
||||||
|
.Cm cgroup
|
||||||
|
top-level group declarations, which can only be set from
|
||||||
|
.Pa /etc/finit.conf ,
|
||||||
|
since it is the first
|
||||||
|
.Cm .conf
|
||||||
|
file Finit reads.
|
||||||
|
.Pp
|
||||||
|
Originally,
|
||||||
|
.Pp /etc/finit.conf
|
||||||
|
was the only way to set up a Finit system. Today it is mainly used for
|
||||||
|
bootstrap settings like system hostname, early module loading for
|
||||||
|
watchdogd, network bringup and system shutdown. These can now also be
|
||||||
|
set in any
|
||||||
|
.Cm .conf
|
||||||
|
file in
|
||||||
|
.Pa /etc/finit.d .
|
||||||
|
.Pp
|
||||||
|
There is, however, nothing preventing you from having all configuration
|
||||||
|
settings in
|
||||||
|
.Pa /etc/finit.conf .
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr finit 8 ,
|
||||||
|
.Xr initctl 8
|
||||||
|
.Sh AUTHORS
|
||||||
|
.Nm finit
|
||||||
|
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
|
||||||
|
maintained by Joachim Wiberg, with contributions by many others.
|
||||||
+175
@@ -0,0 +1,175 @@
|
|||||||
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
|
.\" First parameter, NAME, should be all caps
|
||||||
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
|
.Dd June 6, 2021
|
||||||
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
|
.Dt INITCTL 8 SMM
|
||||||
|
.Os Linux
|
||||||
|
.Sh NAME
|
||||||
|
.Nm initctl
|
||||||
|
.Nd Control tool for Finit
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm /sbin/initctl
|
||||||
|
.Op Fl bcfhlpqtv
|
||||||
|
.Op COMMAND
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm
|
||||||
|
is the official tool for interacting with
|
||||||
|
.Xr finit 8 .
|
||||||
|
It comes with functions for showing status, querying health of services,
|
||||||
|
as well as editing, enabling and disabling services.
|
||||||
|
.Sh OPTIONS
|
||||||
|
This program follows the usual UNIX command line syntax, with long
|
||||||
|
options starting with two dashes (`-'). The options are as follows:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Fl b, -batch
|
||||||
|
Batch mode, no screen size probing.
|
||||||
|
.It Fl c, -create
|
||||||
|
Create missing paths (and files) as needed. Useful with the edit command.
|
||||||
|
.It Fl f, -force
|
||||||
|
Ignore missing files and arguments, never prompt.
|
||||||
|
.It Fl h, -help
|
||||||
|
Show built-in help text.
|
||||||
|
.It Fl 1, -once
|
||||||
|
Only one lap in commands like top.
|
||||||
|
.It Fl p, -plain
|
||||||
|
Use plain table headings, no ANSI control characters.
|
||||||
|
.It Fl q, -quiet
|
||||||
|
Silent, only return status of command.
|
||||||
|
.It Fl t, -no-heading
|
||||||
|
Skip table headings.
|
||||||
|
.It Fl v, -verbose
|
||||||
|
Verbose output, where applicable.
|
||||||
|
.El
|
||||||
|
.Sh COMMANDS
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Nm Ar debug
|
||||||
|
Toggle finit (daemon) debug to
|
||||||
|
.Pa /dev/console
|
||||||
|
.It Nm Ar help
|
||||||
|
Show built-in help text
|
||||||
|
.It Nm Ar version
|
||||||
|
Show Finit (daemon) version
|
||||||
|
.It Nm Ar ls | list
|
||||||
|
List all
|
||||||
|
.Cm *.conf
|
||||||
|
files in
|
||||||
|
.Pa /etc/finit.d
|
||||||
|
.It Nm Ar create Ar CONF
|
||||||
|
Create
|
||||||
|
.Cm .conf
|
||||||
|
in
|
||||||
|
.Pa /etc/finit.d/available
|
||||||
|
.It Nm Ar delete Ar CONF
|
||||||
|
Delete
|
||||||
|
.Cm .conf
|
||||||
|
in
|
||||||
|
.Pa /etc/finit.d/available
|
||||||
|
.It Nm Ar show Ar CONF
|
||||||
|
Show
|
||||||
|
.Cm .conf
|
||||||
|
in
|
||||||
|
.Pa /etc/finit.d/available
|
||||||
|
.It Nm Ar edit Ar CONF
|
||||||
|
Edit
|
||||||
|
.Cm .conf
|
||||||
|
in
|
||||||
|
.Pa /etc/finit.d/available
|
||||||
|
.It Nm Ar touch Ar CONF
|
||||||
|
Change (mark as modified)
|
||||||
|
.Cm .conf
|
||||||
|
in
|
||||||
|
.Pa /etc/finit.d/available ,
|
||||||
|
like
|
||||||
|
.Ar edit
|
||||||
|
this tells
|
||||||
|
.Nm finit
|
||||||
|
that a configuration has been changed and is a candidate to be restarted
|
||||||
|
(or SIGHUP'ed) on
|
||||||
|
.Cm initctl reload
|
||||||
|
.It Nm Ar enable Ar CONF
|
||||||
|
Enable
|
||||||
|
.Cm .conf
|
||||||
|
in
|
||||||
|
.Pa /etc/finit.d/available ,
|
||||||
|
i.e., add symlink in
|
||||||
|
.Pa /etc/finit.d/enabled
|
||||||
|
.It Nm Ar disable Ar CONF
|
||||||
|
Disable
|
||||||
|
.Cm .conf
|
||||||
|
in
|
||||||
|
.Pa /etc/finit.d/enabled ,
|
||||||
|
i.e., removes symlink
|
||||||
|
.It Nm Ar reload
|
||||||
|
Reload
|
||||||
|
.Cm *.conf in
|
||||||
|
.Pa /etc/finit.d ,
|
||||||
|
i.e., activates changes
|
||||||
|
.It Nm Ar cond set Ar COND
|
||||||
|
Set (assert) user-defined condition,
|
||||||
|
.Cm +usr/COND
|
||||||
|
.It Nm Ar cond clr | clear Ar COND
|
||||||
|
Clear (deassert) user-defined condition,
|
||||||
|
.Cm -usr/COND
|
||||||
|
.It Nm Ar cond status
|
||||||
|
Show condition status, default
|
||||||
|
.Cm cond
|
||||||
|
command.
|
||||||
|
.It Nm Ar cond dump
|
||||||
|
Dump all conditions and their status
|
||||||
|
.It Nm Ar log Op Cm NAME
|
||||||
|
Show ten last Finit, or
|
||||||
|
.Cm NAME ,
|
||||||
|
messages from syslog
|
||||||
|
.It Nm Ar start Cm NAME[:ID]
|
||||||
|
Start service by name, with optional ID, e.g.,
|
||||||
|
.Cm initctl start tty:1
|
||||||
|
.It Nm Ar stop Cm NAME[:ID]
|
||||||
|
Stop/Pause a running service by name
|
||||||
|
.It Nm Ar reload Cm NAME[:ID]
|
||||||
|
Reload service by name (SIGHUP or restart)
|
||||||
|
.It Nm Ar restart Cm NAME[:ID]
|
||||||
|
Restart (stop/start) service by name
|
||||||
|
.It Nm Ar status Cm NAME[:ID]
|
||||||
|
Show service status, by name
|
||||||
|
.It Nm Ar status
|
||||||
|
Show status of all services, default command
|
||||||
|
.It Nm Ar cgroup
|
||||||
|
List cgroup config overview
|
||||||
|
.It Nm Ar ps
|
||||||
|
List processes based on cgroups
|
||||||
|
.It Nm Ar top
|
||||||
|
Show top-like listing based on cgroups
|
||||||
|
.It Nm Ar runlevel Op Ar 0-9
|
||||||
|
Show or set runlevel: 0 halt, 6 reboot
|
||||||
|
.It Nm Ar reboot
|
||||||
|
Reboot system, default if
|
||||||
|
.Cm reboot
|
||||||
|
is symlinked to
|
||||||
|
.Nm
|
||||||
|
.It Nm Ar halt
|
||||||
|
Halt system, default if
|
||||||
|
.Cm halt
|
||||||
|
is symlinked to
|
||||||
|
.Nm
|
||||||
|
.It Nm Ar poweroff
|
||||||
|
Power-off system, default if
|
||||||
|
.Cm poweroff
|
||||||
|
is symlinked to
|
||||||
|
.Nm
|
||||||
|
.It Nm Ar suspend
|
||||||
|
Suspend system, default if
|
||||||
|
.Cm suspend
|
||||||
|
is symlinked to
|
||||||
|
.Nm
|
||||||
|
.It Nm Ar utmp show
|
||||||
|
Raw dump of UTMP/WTMP db
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr finit.conf 5
|
||||||
|
.Xr finit 8
|
||||||
|
.Sh AUTHORS
|
||||||
|
.Nm finit
|
||||||
|
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
|
||||||
|
maintained by Joachim Wiberg, with contributions by many others.
|
||||||
+16
-2
@@ -41,17 +41,31 @@ static int sys_add_path(struct iwatch *iw, char *path)
|
|||||||
return iwatch_add(iw, path, IN_ONLYDIR | IN_CLOSE_WRITE);
|
return iwatch_add(iw, path, IN_ONLYDIR | IN_CLOSE_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unlink conditions with no active task/service, otherwise they may
|
||||||
|
* trigger inadvertently when calling `initctl reload` to activate
|
||||||
|
* a new configuration.
|
||||||
|
*/
|
||||||
static void sys_update_conds(char *dir, char *name, uint32_t mask)
|
static void sys_update_conds(char *dir, char *name, uint32_t mask)
|
||||||
{
|
{
|
||||||
|
char path[256];
|
||||||
char *cond;
|
char *cond;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
cond = strstr(name, COND_BASE);
|
ptr = strrchr(name, '/');
|
||||||
|
if (ptr)
|
||||||
|
snprintf(path, sizeof(path), "%s/%s", dir, ++ptr);
|
||||||
|
else
|
||||||
|
snprintf(path, sizeof(path), "%s/%s", dir, name);
|
||||||
|
|
||||||
|
cond = strstr(path, COND_BASE);
|
||||||
if (!cond)
|
if (!cond)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cond += strlen(COND_BASE) + 1;
|
cond += strlen(COND_BASE) + 1;
|
||||||
_d("cond: %s set: %d", cond, mask & IN_CREATE ? 1 : 0);
|
_d("cond: %s set: %d", cond, mask & IN_CREATE ? 1 : 0);
|
||||||
cond_update(cond);
|
if (!cond_update(cond))
|
||||||
|
unlink(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* synthesize events in case of new run dirs */
|
/* synthesize events in case of new run dirs */
|
||||||
|
|||||||
+5
-1
@@ -164,18 +164,22 @@ int cond_set_path(const char *path, enum cond_state next)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Should only be used by cond_set*(), cond_clear(), and usr/sys plugins! */
|
/* Should only be used by cond_set*(), cond_clear(), and usr/sys plugins! */
|
||||||
void cond_update(const char *name)
|
int cond_update(const char *name)
|
||||||
{
|
{
|
||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
|
int affects = 0;
|
||||||
|
|
||||||
_d("%s", name);
|
_d("%s", name);
|
||||||
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 (!svc_has_cond(svc) || !cond_affects(name, svc->cond))
|
if (!svc_has_cond(svc) || !cond_affects(name, svc->cond))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
affects++;
|
||||||
_d("%s: match <%s> %s(%s)", name ?: "nil", svc->cond, svc->desc, svc->cmd);
|
_d("%s: match <%s> %s(%s)", name ?: "nil", svc->cond, svc->desc, svc->cmd);
|
||||||
service_step(svc);
|
service_step(svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return affects;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cond_set_noupdate(const char *name)
|
int cond_set_noupdate(const char *name)
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ enum cond_state cond_get (const char *name);
|
|||||||
enum cond_state cond_get_agg (const char *names);
|
enum cond_state cond_get_agg (const char *names);
|
||||||
int cond_affects (const char *name, const char *names);
|
int cond_affects (const char *name, const char *names);
|
||||||
|
|
||||||
void cond_update (const char *name);
|
int cond_update (const char *name);
|
||||||
int cond_set_path (const char *path, enum cond_state new);
|
int cond_set_path (const char *path, enum cond_state new);
|
||||||
void cond_set (const char *name);
|
void cond_set (const char *name);
|
||||||
void cond_set_oneshot (const char *name);
|
void cond_set_oneshot (const char *name);
|
||||||
|
|||||||
+17
-25
@@ -281,8 +281,12 @@ static void prepare_tty(char *tty, speed_t speed, char *procname, struct rlimit
|
|||||||
|
|
||||||
static int activate_console(int noclear, int nowait)
|
static int activate_console(int noclear, int nowait)
|
||||||
{
|
{
|
||||||
|
static const char msg[] = "\nPlease press Enter to activate this console.";
|
||||||
|
static const char clr[] = "\r\e[2K";
|
||||||
|
static const char cup[] = "\e[A";
|
||||||
struct termios orig;
|
struct termios orig;
|
||||||
int ret = 0;
|
char c;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (nowait || rescue)
|
if (nowait || rescue)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -301,36 +305,24 @@ static int activate_console(int noclear, int nowait)
|
|||||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &c);
|
tcsetattr(STDIN_FILENO, TCSAFLUSH, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!fexist(SYNC_SHUTDOWN)) {
|
dprint(STDERR_FILENO, clr, strlen(clr));
|
||||||
char c;
|
dprint(STDERR_FILENO, msg, strlen(msg));
|
||||||
static const char clr[] = "\r\e[2K";
|
while ((rc = read(STDIN_FILENO, &c, 1)) > 0 && c != '\r' && c != '\n')
|
||||||
static const char cup[] = "\e[A";
|
continue;
|
||||||
static const char msg[] = "\nPlease press Enter to activate this console.";
|
|
||||||
|
|
||||||
if (fexist(SYNC_STOPPED)) {
|
/* On any error (likely EINTR), we avoid starting getty */
|
||||||
sleep(5);
|
if (rc == -1)
|
||||||
continue;
|
rc = 0;
|
||||||
}
|
|
||||||
|
|
||||||
dprint(STDERR_FILENO, clr, strlen(clr));
|
/* Clear msg and move cursor up for next message/login: */
|
||||||
dprint(STDERR_FILENO, msg, strlen(msg));
|
dprint(STDERR_FILENO, clr, strlen(clr));
|
||||||
while (read(STDIN_FILENO, &c, 1) == 1 && c != '\r')
|
dprint(STDERR_FILENO, cup, strlen(cup));
|
||||||
continue;
|
|
||||||
|
|
||||||
if (fexist(SYNC_STOPPED))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dprint(STDERR_FILENO, clr, strlen(clr));
|
|
||||||
dprint(STDERR_FILENO, cup, strlen(cup));
|
|
||||||
ret = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore TTY */
|
/* Restore TTY */
|
||||||
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig) == -1)
|
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig) == -1)
|
||||||
ret = 0;
|
rc = 0; /* TTY in bad shape, restart */
|
||||||
|
|
||||||
return ret;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+9
-1
@@ -66,6 +66,7 @@ char *network = NULL;
|
|||||||
char *hostname = NULL;
|
char *hostname = NULL;
|
||||||
char *rcsd = FINIT_RCSD;
|
char *rcsd = FINIT_RCSD;
|
||||||
char *runparts = NULL;
|
char *runparts = NULL;
|
||||||
|
char *osheading = NULL;
|
||||||
|
|
||||||
uev_ctx_t *ctx = NULL; /* Main loop context */
|
uev_ctx_t *ctx = NULL; /* Main loop context */
|
||||||
svc_t *wdog = NULL; /* No watchdog by default */
|
svc_t *wdog = NULL; /* No watchdog by default */
|
||||||
@@ -90,7 +91,14 @@ static void banner(void)
|
|||||||
*/
|
*/
|
||||||
plugin_run_hooks(HOOK_BANNER);
|
plugin_run_hooks(HOOK_BANNER);
|
||||||
|
|
||||||
print_banner(INIT_HEADING);
|
#ifdef INIT_OSHEADING
|
||||||
|
osheading = INIT_OSHEADING;
|
||||||
|
if (osheading) {
|
||||||
|
if (!osheading[0])
|
||||||
|
osheading = release_heading();
|
||||||
|
print_banner(osheading);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ extern char *sdown;
|
|||||||
extern char *network;
|
extern char *network;
|
||||||
extern char *hostname;
|
extern char *hostname;
|
||||||
extern char *runparts;
|
extern char *runparts;
|
||||||
|
extern char *osheading;
|
||||||
extern uev_ctx_t *ctx;
|
extern uev_ctx_t *ctx;
|
||||||
|
|
||||||
#endif /* FINIT_H_ */
|
#endif /* FINIT_H_ */
|
||||||
|
|||||||
+9
-3
@@ -198,6 +198,7 @@ static int getty(char *tty, speed_t speed, char *term, char *user)
|
|||||||
{
|
{
|
||||||
const char cln[] = "\r\e[2K\n";
|
const char cln[] = "\r\e[2K\n";
|
||||||
char name[33]; /* useradd(1) limit at 32 chars */
|
char name[33]; /* useradd(1) limit at 32 chars */
|
||||||
|
pid_t sid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clean up tty name.
|
* Clean up tty name.
|
||||||
@@ -214,13 +215,18 @@ static int getty(char *tty, speed_t speed, char *term, char *user)
|
|||||||
restart:
|
restart:
|
||||||
stty(STDIN_FILENO, speed);
|
stty(STDIN_FILENO, speed);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
if (get_logname(tty, name, sizeof(name))) {
|
if (get_logname(tty, name, sizeof(name)))
|
||||||
sleep(5);
|
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
strlcpy(name, user, sizeof(name));
|
strlcpy(name, user, sizeof(name));
|
||||||
|
|
||||||
|
/* check current session associated with our tty */
|
||||||
|
sid = tcgetsid(0);
|
||||||
|
if (sid < 0 || getpid() != sid) {
|
||||||
|
if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) == -1)
|
||||||
|
err(1, "failed stealing controlling TTY");
|
||||||
|
}
|
||||||
|
|
||||||
if (term && term[0])
|
if (term && term[0])
|
||||||
setenv("TERM", term, 1);
|
setenv("TERM", term, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,49 @@ void show_progress(pstyle_t style)
|
|||||||
progress_onoff = style;
|
progress_onoff = style;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find PRETTY_NAME in /etc/os-release to use as heading at boot
|
||||||
|
* and on runlevel changes. Fallback: "Finit vX.YY"
|
||||||
|
*/
|
||||||
|
char *release_heading(void)
|
||||||
|
{
|
||||||
|
char *name = NULL;
|
||||||
|
char buf[256];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen("/etc/os-release", "r");
|
||||||
|
if (fp) {
|
||||||
|
while (fgets(buf, sizeof(buf), fp)) {
|
||||||
|
char *ptr = &buf[12];
|
||||||
|
|
||||||
|
if (strncmp(buf, "PRETTY_NAME=", 12))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (*ptr == '"' || *ptr == '\'') {
|
||||||
|
char *end = &ptr[strlen(ptr) - 1];
|
||||||
|
char q = *ptr;
|
||||||
|
|
||||||
|
while (end > ptr && isspace(*end))
|
||||||
|
*end-- = 0;
|
||||||
|
|
||||||
|
if (*end == q) {
|
||||||
|
*end = 0;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name = strdup(ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
name = strdup(PACKAGE_NAME " v" PACKAGE_VERSION);
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return screen length of string, not counting escape chars, and
|
* Return screen length of string, not counting escape chars, and
|
||||||
* accounting for unicode characters as only one screen byte wide
|
* accounting for unicode characters as only one screen byte wide
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ char *strip_line (char *line);
|
|||||||
void enable_progress (int onoff);
|
void enable_progress (int onoff);
|
||||||
void show_progress (pstyle_t style);
|
void show_progress (pstyle_t style);
|
||||||
|
|
||||||
|
char *release_heading (void);
|
||||||
|
|
||||||
speed_t stty_parse_speed(char *baud);
|
speed_t stty_parse_speed(char *baud);
|
||||||
void stty (int fd, speed_t speed);
|
void stty (int fd, speed_t speed);
|
||||||
|
|
||||||
|
|||||||
+9
-3
@@ -347,8 +347,7 @@ static void source_env(svc_t *svc)
|
|||||||
|
|
||||||
static int is_norespawn(void)
|
static int is_norespawn(void)
|
||||||
{
|
{
|
||||||
return sig_stopped() ||
|
return fexist("/mnt/norespawn") ||
|
||||||
fexist("/mnt/norespawn") ||
|
|
||||||
fexist("/tmp/norespawn");
|
fexist("/tmp/norespawn");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,6 +724,13 @@ static int service_stop(svc_t *svc)
|
|||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s stop' ...", svc->cmd);
|
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s stop' ...", svc->cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure we are no longer considering the service to be starting (if
|
||||||
|
* that was the case). service_monitor() might get confused otherwise, and
|
||||||
|
* leave the service in a lingering, "stopping", state.
|
||||||
|
*/
|
||||||
|
svc_started(svc);
|
||||||
|
|
||||||
svc_set_state(svc, SVC_STOPPING_STATE);
|
svc_set_state(svc, SVC_STOPPING_STATE);
|
||||||
|
|
||||||
if (!svc->desc[0])
|
if (!svc->desc[0])
|
||||||
@@ -1416,7 +1422,7 @@ void service_monitor(pid_t lost, int status)
|
|||||||
{
|
{
|
||||||
svc_t *svc;
|
svc_t *svc;
|
||||||
|
|
||||||
if (fexist(SYNC_SHUTDOWN) || lost <= 1)
|
if (lost <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
svc = svc_find_by_pid(lost);
|
svc = svc_find_by_pid(lost);
|
||||||
|
|||||||
@@ -96,11 +96,9 @@ extern svc_t *wdog;
|
|||||||
*/
|
*/
|
||||||
shutop_t halt = SHUT_DEFAULT;
|
shutop_t halt = SHUT_DEFAULT;
|
||||||
|
|
||||||
static int stopped = 0;
|
|
||||||
static uev_t sigterm_watcher, sigusr1_watcher, sigusr2_watcher;
|
static uev_t sigterm_watcher, sigusr1_watcher, sigusr2_watcher;
|
||||||
static uev_t sighup_watcher, sigint_watcher, sigpwr_watcher;
|
static uev_t sighup_watcher, sigint_watcher, sigpwr_watcher;
|
||||||
static uev_t sigchld_watcher;
|
static uev_t sigchld_watcher;
|
||||||
static uev_t sigstop_watcher, sigtstp_watcher, sigcont_watcher;
|
|
||||||
|
|
||||||
static struct sigmap {
|
static struct sigmap {
|
||||||
int num;
|
int num;
|
||||||
@@ -211,8 +209,6 @@ void do_kill(int signo)
|
|||||||
|
|
||||||
void do_shutdown(shutop_t op)
|
void do_shutdown(shutop_t op)
|
||||||
{
|
{
|
||||||
touch(SYNC_SHUTDOWN);
|
|
||||||
|
|
||||||
if (sdown)
|
if (sdown)
|
||||||
run_interactive(sdown, "Calling shutdown hook: %s", sdown);
|
run_interactive(sdown, "Calling shutdown hook: %s", sdown);
|
||||||
|
|
||||||
@@ -403,49 +399,17 @@ static void sigchld_cb(uev_t *w, void *arg, int events)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Reap all the children! */
|
/* Reap all the children! */
|
||||||
do {
|
while (1) {
|
||||||
pid = waitpid(-1, &status, WNOHANG);
|
pid = waitpid(-1, &status, WNOHANG);
|
||||||
if (pid > 0) {
|
if (pid <= 0) {
|
||||||
_d("Collected child %d", pid);
|
if (pid == -1 && errno == EINTR)
|
||||||
service_monitor(pid, status);
|
continue;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} while (pid > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
_d("Collected child %d", pid);
|
||||||
* SIGSTOP/SIGTSTP: Paused by user or netflash
|
service_monitor(pid, status);
|
||||||
*/
|
|
||||||
static void sigstop_cb(uev_t *w, void *arg, int events)
|
|
||||||
{
|
|
||||||
if (UEV_ERROR == events) {
|
|
||||||
_e("Unrecoverable error in signal watcher");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
touch(SYNC_STOPPED);
|
|
||||||
stopped++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SIGCONT: Restart service monitor
|
|
||||||
*/
|
|
||||||
static void sigcont_cb(uev_t *w, void *arg, int events)
|
|
||||||
{
|
|
||||||
if (UEV_ERROR == events) {
|
|
||||||
_e("Unrecoverable error in signal watcher");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
stopped = 0;
|
|
||||||
erase(SYNC_STOPPED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Is SIGSTOP asserted?
|
|
||||||
*/
|
|
||||||
int sig_stopped(void)
|
|
||||||
{
|
|
||||||
return stopped;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -535,10 +499,6 @@ void sig_setup(uev_ctx_t *ctx)
|
|||||||
|
|
||||||
_d("Setup signals");
|
_d("Setup signals");
|
||||||
|
|
||||||
/* Cleanup any stale finit control files */
|
|
||||||
erase(SYNC_SHUTDOWN);
|
|
||||||
erase(SYNC_STOPPED);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Standard SysV init calls ctrl-alt-delete handler
|
* Standard SysV init calls ctrl-alt-delete handler
|
||||||
* We need to disable kernel default so it sends us SIGINT
|
* We need to disable kernel default so it sends us SIGINT
|
||||||
@@ -561,11 +521,6 @@ void sig_setup(uev_ctx_t *ctx)
|
|||||||
/* After initial bootstrap of Finit we call the service monitor to reap children */
|
/* After initial bootstrap of Finit we call the service monitor to reap children */
|
||||||
uev_signal_init(ctx, &sigchld_watcher, sigchld_cb, NULL, SIGCHLD);
|
uev_signal_init(ctx, &sigchld_watcher, sigchld_cb, NULL, SIGCHLD);
|
||||||
|
|
||||||
/* Stopping init is a bit tricky. */
|
|
||||||
uev_signal_init(ctx, &sigstop_watcher, sigstop_cb, NULL, SIGSTOP);
|
|
||||||
uev_signal_init(ctx, &sigtstp_watcher, sigstop_cb, NULL, SIGTSTP);
|
|
||||||
uev_signal_init(ctx, &sigcont_watcher, sigcont_cb, NULL, SIGCONT);
|
|
||||||
|
|
||||||
setsid();
|
setsid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <uev/uev.h>
|
#include <uev/uev.h>
|
||||||
|
|
||||||
#define SYNC_SHUTDOWN "/var/run/finit/.shutdown"
|
|
||||||
#define SYNC_STOPPED "/var/run/finit/.stopped"
|
|
||||||
|
|
||||||
#define SETSIG(sa, sig, fun, flags) \
|
#define SETSIG(sa, sig, fun, flags) \
|
||||||
do { \
|
do { \
|
||||||
sa.sa_sigaction = fun; \
|
sa.sa_sigaction = fun; \
|
||||||
@@ -69,7 +66,6 @@ typedef enum {
|
|||||||
extern shutop_t halt;
|
extern shutop_t halt;
|
||||||
|
|
||||||
void do_shutdown (shutop_t op);
|
void do_shutdown (shutop_t op);
|
||||||
int sig_stopped (void);
|
|
||||||
int sig_num (const char *name);
|
int sig_num (const char *name);
|
||||||
void sig_init (void);
|
void sig_init (void);
|
||||||
void sig_unblock (void);
|
void sig_unblock (void);
|
||||||
|
|||||||
@@ -150,7 +150,10 @@ restart:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_d("Setting new runlevel --> %d <-- previous %d", runlevel, prevlevel);
|
_d("Setting new runlevel --> %d <-- previous %d", runlevel, prevlevel);
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "%s, entering runlevel %d", INIT_HEADING, runlevel);
|
if (osheading)
|
||||||
|
logit(LOG_CONSOLE | LOG_NOTICE, "%s, entering runlevel %d", osheading, runlevel);
|
||||||
|
else
|
||||||
|
logit(LOG_CONSOLE | LOG_NOTICE, "Entering runlevel %d", runlevel);
|
||||||
runlevel_set(prevlevel, runlevel);
|
runlevel_set(prevlevel, runlevel);
|
||||||
|
|
||||||
/* Disable login in single-user mode as well as shutdown/reboot */
|
/* Disable login in single-user mode as well as shutdown/reboot */
|
||||||
|
|||||||
Reference in New Issue
Block a user