Compare commits

..
Author SHA1 Message Date
Jacques de Laval 50c99762f1 Add run target for running Finit as a stand alone unprivileged process
It could be very useful, during development, to be able to run Finit on a
host system without having to provision a full VM. We have all the building
blocks for easily containerizing Finit - in the test framework - so adding
a "run" target that does the orchestration makes sense.

Signed-off-by: Jacques de Laval <jacques@de-laval.se>
2021-03-05 01:39:42 +01:00
Jacques de Laval 067043b298 test: Use STDOUT of parent process instead of a pipe as tty for finit
Signed-off-by: Jacques de Laval <jacques@de-laval.se>
2021-03-05 01:24:31 +01:00
358 changed files with 6909 additions and 29700 deletions
+5 -5
View File
@@ -9,9 +9,9 @@ For email questions/requests/alerts there is always the risk of memory
exhaustion on the part of the maintainer(s).
If you are unsure of what to do, or how to implement an idea or bugfix,
open an issue with `"[RFC: Unsure if this is a bug ... ?"`, or use the
GitHub discussions forum, so we can discuss it. Talking about the code
first is the best way to get started before submitting a pull request.
open an issue with `"[RFC: Unsure if this is a bug ... ?"`, or similar,
so we can discuss it. Talking about the code first is the best way to
get started before submitting a pull request.
Either way, when sending an email, patch, or pull request, start by
stating the version the change is made against, what it does, and why.
@@ -24,8 +24,7 @@ the maintainer(s) and make it easier for them to include your code.
Coding Style
------------
> [!TIP]
> Always submit code that follows the style of surrounding code!
> **Tip:** Always submit code that follows the style of surrounding code!
First of all, lines are allowed to be longer than 72 characters these
days. In fact, there exist no enforced maximum, but keeping it around
@@ -74,6 +73,7 @@ It is expected of everyone engaging in the project to, in the words of
Bill & Ted; [be excellent to each other][conduct].
[github]: https://github.com/troglobit/finit/
[KNF]: https://en.wikipedia.org/wiki/Kernel_Normal_Form
[gitbook]: https://git-scm.com/book/ch5-2.html
[conduct]: CODE-OF-CONDUCT.md
+1 -1
View File
@@ -5,7 +5,7 @@
finit is a small project, as such we have no possibility to support older versions.
The only supported version is the latest released on GitHub:
<https://github.com/finit-project/finit/releases>
<https://github.com/troglobit/finit/releases>
## Reporting a Vulnerability
-87
View File
@@ -1,87 +0,0 @@
name: Bob the Builder
# Run on all branches, including all pull requests, except the 'dev'
# branch since that's where we run Coverity Scan (limited tokens/day)
on:
push:
branches:
- '**'
- '!dev'
pull_request:
types: [opened, synchronize, reopened, labeled]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
build:
# Verify we can build on latest Ubuntu with both gcc and clang
name: ${{ matrix.compiler }}
runs-on: ubuntu-latest
# Skip redundant builds for PRs - prefer PR builds over push builds
if: github.event_name != 'push' || github.ref == 'refs/heads/master'
strategy:
matrix:
compiler: [gcc, clang]
fail-fast: false
env:
CC: ${{ matrix.compiler }}
steps:
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config tree jq libcap-dev
sudo apt-get -y install pkg-config
wget https://github.com/troglobit/libuev/releases/download/v2.4.1/libuev-2.4.1.tar.xz
wget https://github.com/troglobit/libite/releases/download/v2.6.2/libite-2.6.2.tar.gz
tar xf libuev-2.4.1.tar.xz
tar xf libite-2.6.2.tar.gz
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
sudo ldconfig
- uses: actions/checkout@v4
- name: Static Finit
run: |
./autogen.sh
./configure --prefix= --enable-static
make -j9 V=1
- name: Regular Finit
run: |
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var \
--enable-x11-common-plugin --enable-testserv-plugin --with-watchdog \
--with-keventd --with-libsystemd \
CFLAGS="-fsanitize=address -ggdb"
make -j9 clean
make -j9 V=1
- name: Install to /tmp
run: |
DESTDIR=/tmp make install-strip
tree /tmp || true
- name: Check dependencies
run: |
ldd /tmp/sbin/finit
size /tmp/sbin/finit
ldd /tmp/sbin/initctl
size /tmp/sbin/initctl
ldd /tmp/sbin/reboot
size /tmp/sbin/reboot
- name: Verify starting and showing usage text
run: |
sudo /tmp/sbin/finit -h
sudo /tmp/sbin/initctl -h
- name: Enable unprivileged userns (unshare)
run: |
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
- name: Run Unit Tests
run: |
make -j1 check || (cat test/test-suite.log; false)
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: finit-test-${{ matrix.compiler }}
path: test/*.log
-92
View File
@@ -1,92 +0,0 @@
name: Coverity Scan
on:
push:
branches:
- 'dev'
workflow_dispatch:
permissions:
contents: read
env:
PROJECT_NAME: finit
CONTACT_EMAIL: troglobit@gmail.com
COVERITY_NAME: troglobit-finit
COVERITY_PROJ: troglobit%2Ffinit
jobs:
coverity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fetch latest Coverity Scan MD5
id: var
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
wget -q https://scan.coverity.com/download/cxx/linux64 \
--post-data "token=$TOKEN&project=${COVERITY_PROJ}&md5=1" \
-O coverity-latest.tar.gz.md5
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
- uses: actions/cache@v4
id: cache
with:
path: coverity-latest.tar.gz
key: ${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
restore-keys: |
${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
${{ runner.os }}-coverity-
${{ runner.os }}-coverity
- name: Download Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
if [ ! -f coverity-latest.tar.gz ]; then
wget -q https://scan.coverity.com/download/cxx/linux64 \
--post-data "token=$TOKEN&project=${COVERITY_PROJ}" \
-O coverity-latest.tar.gz
else
echo "Latest Coverity Scan available from cache :-)"
md5sum coverity-latest.tar.gz
fi
mkdir coverity
tar xzf coverity-latest.tar.gz --strip 1 -C coverity
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config libcap-dev
wget https://github.com/troglobit/libuev/releases/download/v2.4.1/libuev-2.4.1.tar.xz
wget https://github.com/troglobit/libite/releases/download/v2.6.2/libite-2.6.2.tar.gz
tar xf libuev-2.4.1.tar.xz
tar xf libite-2.6.2.tar.gz
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
sudo ldconfig
- name: Configure
run: |
./autogen.sh
./configure --prefix= --enable-x11-common-plugin --with-watchdog \
--with-keventd --with-libsystemd
- name: Build
run: |
export PATH=`pwd`/coverity/bin:$PATH
cov-build --dir cov-int make
- name: Submit results to Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
tar czvf ${PROJECT_NAME}.tgz cov-int
curl \
--form project=${COVERITY_NAME} \
--form token=$TOKEN \
--form email=${CONTACT_EMAIL} \
--form file=@${PROJECT_NAME}.tgz \
--form version=trunk \
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
https://scan.coverity.com/builds?project=${COVERITY_PROJ}
- name: Upload build.log
uses: actions/upload-artifact@v4
with:
name: coverity-build.log
path: cov-int/build-log.txt
-100
View File
@@ -1,100 +0,0 @@
name: Dotty the Documenteer
on:
push:
branches:
- master
paths:
- 'doc/**'
- 'README.md'
- 'mkdocs.yml'
- '.github/workflows/docs.yml'
pull_request:
types: [opened, synchronize, reopened, labeled]
paths:
- 'doc/**'
- 'README.md'
- 'mkdocs.yml'
- '.github/workflows/docs.yml'
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed for git-revision-date-localized plugin
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pipx install mkdocs
pipx inject mkdocs mkdocs-material
pipx inject mkdocs pymdown-extensions
pipx inject mkdocs mkdocs-callouts
pipx inject mkdocs mkdocs-glightbox
- name: Build documentation
run: mkdocs build --clean
- name: Upload site artifact
uses: actions/upload-artifact@v4
with:
name: site
path: site/
deploy:
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
needs: build
runs-on: ubuntu-latest
steps:
- name: Download site artifact
uses: actions/download-artifact@v4
with:
name: site
path: site/
- name: Checkout pages repo
uses: actions/checkout@v4
with:
repository: finit-project/finit-project.github.io
path: pages
ssh-key: ${{ secrets.DOCS_DEPLOY_KEY }}
persist-credentials: true
- name: Setup SSH for push
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
ssh-keyscan github.com >> ~/.ssh/known_hosts
- name: Sync site to pages repo
run: |
rsync -a --delete --exclude .git site/ pages/
- name: Commit and push
run: |
cd pages/
if [ -z "$(git status --porcelain)" ]; then
exit 0
fi
SRC_REPO="${GITHUB_REPOSITORY}"
SRC_REF="${GITHUB_SHA::7}"
SRC_URL="https://github.com/${SRC_REPO}/commit/${SRC_REF}"
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add -A
git commit -m "docs: update from ${SRC_REPO}@${SRC_REF}" \
-m "For details, see ${SRC_URL}"
git push
-82
View File
@@ -1,82 +0,0 @@
name: Release General
on:
push:
tags:
- '[0-9]+.[0-9]+*'
permissions:
contents: write
jobs:
release:
name: Build and upload release tarball
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Installing dependencies ...
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config jq libcap-dev
wget https://github.com/troglobit/libuev/releases/download/v2.4.1/libuev-2.4.1.tar.xz
wget https://github.com/troglobit/libite/releases/download/v2.6.2/libite-2.6.2.tar.gz
tar xf libuev-2.4.1.tar.xz
tar xf libite-2.6.2.tar.gz
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
sudo ldconfig
- name: Setting release variables ...
id: build
run: |
ver=${GITHUB_REF#refs/tags/}
echo "ver=${ver}" >> $GITHUB_OUTPUT
if echo $ver | grep -qE '^[0-9]+\.[0-9]+(\.[0-9]+)?(-alpha|-beta|-rc)[0-9]*$'; then
echo "pre=true" >> $GITHUB_OUTPUT
else
echo "pre=false" >> $GITHUB_OUTPUT
fi
if echo $ver | grep -qE '^[0-9.]+\.[0-9.]+(\.[0-9]+)?$'; then
echo "latest=true" >> $GITHUB_OUTPUT
else
echo "latest=false" >> $GITHUB_OUTPUT
fi
- name: Creating Makefiles ...
run: |
./autogen.sh
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc \
--localstatedir=/var --enable-x11-common-plugin \
--enable-testserv-plugin --with-watchdog \
--with-keventd --with-libsystemd
- name: Enable unprivileged userns (unshare)
run: |
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
- name: Build release ...
run: |
# Get version for finding distcheck build directory
./configure --version | head -1
ver=$(./configure --version | head -1 | awk '{print $NF}')
dir=finit-$ver/_build/sub
make -j1 release || (cat $dir/test/test-suite.log; false)
ls -lF ../
mkdir -p artifacts/
mv ../*.tar.* artifacts/
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: finit-release-test-logs
path: finit-*/_build/sub/test/*.log
- name: Extract ChangeLog entry ...
run: |
awk '/-----*/{if (x == 1) exit; x=1;next}x' doc/ChangeLog.md \
|head -n -1 > release.md
cat release.md
- uses: ncipollo/release-action@v1
with:
name: Finit v${{ github.ref_name }}
prerelease: ${{ steps.build.outputs.pre }}
makeLatest: ${{ steps.build.outputs.latest }}
bodyFile: "release.md"
artifacts: "artifacts/*"
-67
View File
@@ -1,67 +0,0 @@
name: Weekly Distcheck
# Verify that `make distcheck` works as intended: all tests pass, and
# any new files are distributed in the tarballs
on:
schedule:
- cron: '0 0 * * 0'
workflow_dispatch:
permissions:
contents: read
jobs:
schedule:
runs-on: ubuntu-latest
outputs:
run: ${{ steps.schedule.outputs.run }}
steps:
- uses: actions/checkout@v4
- name: Check for any commits since last week
id: schedule
run: |
commits="$(git log --format=%H --since='1 week ago')"
if [ -z "$commits" ]; then
echo "run=true" >> $GITHUB_OUTPUT
else
echo "run=false" >> $GITHUB_OUTPUT
fi
distcheck:
needs: schedule
if: ${{ needs.schedule.outputs.run == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config jq libcap-dev
wget https://github.com/troglobit/libuev/releases/download/v2.4.1/libuev-2.4.1.tar.xz
wget https://github.com/troglobit/libite/releases/download/v2.6.2/libite-2.6.2.tar.gz
tar xf libuev-2.4.1.tar.xz
tar xf libite-2.6.2.tar.gz
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
sudo ldconfig
- uses: actions/checkout@v4
- name: Base run
run: |
./autogen.sh
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var
make -j9 V=1
- name: Install to /tmp
run: |
DESTDIR=/tmp make install-strip
- name: Enable unprivileged userns (unshare)
run: |
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
- name: Check dist tarball
run: |
ver=$(/tmp/sbin/initctl -V | awk '/Finit.*/ {print $2;}')
dir=finit-$ver/_build/sub
make -j1 distcheck || (cat $dir/test/test-suite.log; false)
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: finit-weekly-test-logs
path: finit-*/_build/sub/test/*.log
-7
View File
@@ -14,7 +14,6 @@ GTAGS
/autom4te.cache
/aclocal.m4
/ar-lib
/backup/
/compile
/config.cache
/config.h
@@ -37,9 +36,6 @@ GTAGS
/test-driver
/test-suite.log
# Misc
/.gdb_history
# TroglOS build system
/.config
/.stamp
@@ -49,6 +45,3 @@ GTAGS
/.autoconf
/.automake
/.built
# VS Code user settings
.vscode
-15
View File
@@ -1,15 +0,0 @@
# GNU Global .conf file, see /etc/gtags/gtags.conf for details.
# This configuration is optimized for the Finit project structure.
default:\
:tc=default@/etc/gtags/gtags.conf:\
:tc=common:
common:\
:skip=tags,TAGS,ID,y.tab.c,y.tab.h,gtags.files,cscope.files,cscope.out,cscope.po.out,cscope.in.out,\
{arch}/,autom4te.cache/,\
*.orig,*.rej,*.bak,*~,#*#,*.swp,*.tmp,*_flymake.*,*_flymake,\
*.o,*.a,*.so,*.lo,*.la,\
*.zip,*.gz,*.bz2,*.xz,*.lzh,*.Z,*.tgz,\
*.log,*.trs,test-suite.log,stamp-*,\
sysroot/:
+65
View File
@@ -0,0 +1,65 @@
# Travis CI integration -- https://travis-ci.org/troglobit/finit
# Defaults to GNU GCC and autotools: ./configure && make && make test
language: c
# Use docker for quicker builds, it now allows https://docs.travis-ci.com/user/apt/
sudo: false
# Use non-docker builds atm. to install libuEv and libite from source
#sudo: true
# Test build with both GCC and Clang (LLVM)
compiler:
- gcc
- clang
# The secure: declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
env:
global:
- PKG_CONFIG_PATH=/tmp/lib/pkgconfig
- CFLAGS="-W -Wall -Wextra"
- secure: "eOiuHs02lG2Uv146K9dMqucGTWUJFEhpz1oAtwe+kPrRXsXWc20hYMO+DSpMgD05vSvNeQA6p7h7LdRFQ+/g/Obj27TsOE+RKkUvRAtdwzxnKVyii9C/nmML8cFw7rIA0VS8O9mAkVYeyDxNDupBp3e9DPCibhKPvqCvioTnyy4="
addons:
apt:
packages:
- tree
coverity_scan:
project:
name: "troglobit/finit"
description: "finit | Fast & Extensible init for Linux"
notification_email: troglobit@gmail.com
build_command_prepend: "./autogen.sh && ./configure --prefix=/tmp"
build_command: "make"
branch_pattern: dev
install:
- wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
- wget https://github.com/troglobit/libite/releases/download/v2.3.1/libite-2.3.1.tar.gz
- tar xf libuev-2.3.2.tar.xz
- tar xf libite-2.3.1.tar.gz
- (cd libuev-2.3.2 && ./configure --prefix=/tmp && make && make install-strip)
- (cd libite-2.3.1 && ./configure --prefix=/tmp && make && make install-strip)
# Custom build script for the time being, no "make test" yet
script:
- ./autogen.sh
- ./configure --prefix=/tmp --enable-static
- make clean
- make V=1 -j5
- ./configure --prefix=/tmp --enable-x11-common-plugin --enable-fallback-shell --enable-watchdog --enable-logit
- cat config.log
- make clean
- make V=1 -j5
- make install-strip
- tree /tmp
- ldd /tmp/sbin/finit
- size /tmp/sbin/finit
- size /tmp/sbin/initctl
- size /tmp/sbin/reboot
- LD_LIBRARY_PATH=/tmp/lib /tmp/sbin/initctl -h
- unshare -V
- nsenter -V
- chroot --version
- 'LD_LIBRARY_PATH=/tmp/lib make distcheck || (cat finit-4.0-beta1/_build/sub/test/test-suite.log; exit 1)'
View File
+884
View File
@@ -0,0 +1,884 @@
Change Log
==========
All relevant changes are documented in this file.
[4.0][UNRELEASED] - 2021-02-21
------------------------------
This release became v4.0, and not v3.2, because of incompatible changes
to service conditions. There are other significant changes as well, so
make sure to read the whole changelog when upgrading.
### Changes
* The stand-alone `reboot` tool has been replaced with a symlink to
`initctl`, like its siblings: halt, shutdown, poweroff, and suspend.
Calling `reboot` & C:o now defaults to the corresponding `initctl cmd`
with a fallback to sending signals as per traditional SysV init. The
`-f` (force) flag remains, where `reboot(2)` is called directly
* Introducing Finit progress 𝓜𝓸𝓭𝓮𝓻𝓷
* Removed built-in inetd super server. If you need this functionality,
use an external inetd, like xinetd, instead. A pull request for a
stand-alone inetd, like watchdogd and getty, is most welcome!
* Incompatible `configure` script changes, i.e., you must give proper
path arguments to the script, no more guessing just GNU defaults.
There are examples in the documentation and the `contrib/` section
* Change service conditions from the non-obvious `<svc/path/to/foo>` to
`<pid/foo:id>`. This to hopefully make it clear that one service's
'pid:!foo' pidfile is another service's `<pid/foo>` condition
* Initial support for cgroups, every service now runs in its own cgroup
https://twitter.com/b0rk/status/1214341831049252870?s=20
* Major refactor of Finit's `main()` function to be able to start the
event loop earlier. This also facilitated factoring out functionality
previously hard-coded in Finit, e.g., starting the bundled watchdogd,
various distro packed udevd and other hotplugging tools
* Support for `sysv` start/stop scripts as well as monitoring forking
services, stared using `sysv` or `service` stanza
* Support for custom `kill:DELAY`, default 3 sec.
* Support for custom `halt:SIGNAL`, default SIGTERM
* Support for tracking custom PID files, using `pid:!/path/to/foo.pid`,
useful with new `sysv` or `service` which fork to background
* Support starting run/task/services without absolute path, trust `$PATH`
* Add support for `--disable-doc` and `--disable-contrib` to speed up
builds and work around issue with massively parallel builds
* Add support for `@console` also for external getty
* Add `-b`, batch mode, for non-interactive use to `initctl`
* Prefer udev to handle `/dev/` if mdev is also available
* Redirect dbus daemon output to syslog
* Set `$SHELL`, like `$PATH`, to a sane default value, needed by BusyBox
* Finit no longer automatically reloads its `*.conf` files after running
`/etc/rc.local` or run-parts. Use `initctl reload` instead.
* `initctl` without an argument or option now defaults to list services
* Convert built-in watchdog daemon to standalone mini watchdogd, issue #102
* Improved watchdog hand-over, now based on `svc_t` and not PID
* Extended bootstrap, runlevel S, timeout: 10 --> 120 sec. before services
not allowed in the runtime runlevel are unconditionally stopped
* Removed `HOOK_SVC_START` and `HOOK_SVC_LOST`, caused more problems
than they were worth. Users are encouraged to use accounting instead
* Skip displaying "Restarting ..." progress for bootstrap processes
* Added a simple work queue mechanism to queue up work at boot + runtime
- Postpone deletion of `svc_t` until any `SIGKILL` timer has elapsed
- As long as a stepped service changes state we queue another step all
event, because services may depend on each other
* Require new libuEv API: `uev_init1()` to reduce event cache so that
the kernel can invalidate deleted events before enqueing to userspace
* Rename `hwclock.so` plugin to `rtc.so` since it now is stand-alone
from the `hwclock` tool. Note: the kernel can also be set to load
and store RTC to/from system clock at boot/halt as well, issue #110
* New plugin to support cold plugging devices, auto-loading of modules
at boot. Detects required modules by reading `/sys/devices/*`
* New plugin for `/etc/modules-load.d/` by Robert Andersson, Atlas Copco
* New `name:foo` support for services, by Robert Andersson, Atlas Copco
* New `manual:yes` support for services, by Robert Andersson, Atlas Copco
* New `log:console` support for services, by Robert Andersson, Atlas Copco
* Support for `:ID` as a string, by Jonas Johansson, Westermo
* Support for auto-reload, instead of having to do `initctl reload`,
when a service configuration has changed. Disabled by default, but
can be enabled with `./configure --enable-auto-reload`
* Support for logging security related events, e.g., runlevel change,
star/stop or failure to start services, by Jonas Holmberg, Westermo
* Mount devtpts with recommended `ptxmode=0666`
* Mount /run tmpfs with nosuid,nodev,noexec for added security
* Support for `console` as alias for `@console` in tty stanzas
* Drop `--enable-rw-roots` configure option, use `rw` for your `/`
partition in `/etc/fstab` instead to trigger remount at boot
* Drop default tty speed (38400) and use 0 (kernel default) instead
* Make `:ID` optional, use NULL/zero internally this allows ...
* Handle use-cases where multiple services share the same PID filem
and thus the same condition path, e.g. different instances for
different runlevels. Allow custom condition path with `name:foo`
syntax, creates conditions w/o a path, and ...
* Always append `:ID` qualifier to conditions if set for a service
* The IPC socket has moved from `/run/finit.sock` to `/run/finit/socket`
officially only supported for use by the `initctl` tool
* Improved support for modern `/etc/network/interfaces`, which has
include statements. No more native `ifup` of individual interfaces,
Finit now calls `ifup -a`, or `ifdown -a`, delegating all details to
the operating system. Also, this is now done in the background, by
popular request
### Fixes
* Fix #96: Start udevd as a proper service
* Ensure we track run commands as well as task/service, once per runlevel
* Ensure run/tasks also go to stopping state on exit, like services,
otherwise it is unnecessarily hard to restart them
* Fix missing OS/Finit title bug, adds leading newline before banner
* Remove "Failed connecting to watchdog ..." error message on systems
that do not have a watchdog
* Fix #100: Early condition handling may not work if `/var/run` does
not yet exist (symlink to `/run`). Added compat layer for access
* Fix #103: Register multiple getty if `@console` resolves to >1 TTY,
* Fix #105: Only remove /etc/nologin when moving from runlevel 0, 1, 6
Fixed by Jonas Johansson, Westermo
* Fix #109: Support for PID files in sub-directories to `/var/run`
* Handle rename of PID files, by Robert Andersson, Atlas Copco
* Fix #120: Redirect `stdin` to `/dev/null` for services by default
* Fix #122: Switch to `nanosleep()` to achieve "signal safe" sleep,
fixed by Jacques de Laval, Westermo
* Fix #124: Lingering processes in process group when session leader
exits. E.g., lingering `logit` processes when parent dies
* Fix service name matching, e.g. for condition handling, may match with
wrong service, by Jonas Holmberg, Westermo
* Run all run-parts scripts using `/bin/sh -c foo` just like the standard
run-parts tool. Found by Magnus Malm, Westermo
* Fix `initctl [start | restart]`, should behave the same for services
that have crashed. Found by Mattias Walström, Westermo
* Wait for bootstrap phase to complete before cleaning out any bootstrap
processes that have stopped, they may be restarted again
* Reassert condition when an unmodified run/task/service goes from
WAITING back to RUNNING again after a reconfiguration event.
Found and fixed by Jonas Johansson, Westermo
* Restore Ctrl-D and Ctrl-U support in built-in getty
* Remove service condition when service is deleted
* Fix C++ compilation issues, by Robert Andersson, Atlas Copco
* Build fixes for uClibc
* Provide service description for built-in watchdog daemon
* Fix #138: Handle `SIGPWR` like `SIGSUR2`, i.e., power off the system
* Drop the '%m' GNUism, for compat with older musl libc
[3.1][] - 2018-01-23
--------------------
Improvements to `netlink.so` plugin, per-service `rlimit` support,
improved integration with `watchdogd`, auto-detect TTY console. Much
improved debug, rescue and logging support. Also, many fixes to both
big and small issues, most notably in the condition handling, which no
longer is sensitive to time skips.
This version requires at least libuEv v2.1.0 and libite v2.0.1
### Changes
* Support for more kernel command line settings:
- splash, enable boot progress
- debug, like `--debug` but also enable kernel debug
- single, single user mode (no network)
- rescue, new rescue mode
* Support for `IFF_RUNNING` to netlink plugin => `net/IFNAME/running`
* Support for restarting `initctl` API socket on `SIGHUP`
* Greatly updated `initctl status <JOB|NAME>` command
* Support for `rlimit` per service/run/task/inetd/tty, issue #45
* Support for setting `hard` and `soft` rlimit for a resource at once
* Support for auto-detecting serial console using Linux SysFS, the new
`tty @console` eliminates the need to keep track of different console
devices across embedded platforms: `/dev/ttyS0`, `/dev/ttyAMA0`, etc.
* Add TTY `nologin` option. Bypasses login and skips immediately to a
root shell. Useful during board bringup, in developer builds, etc.
* Support for calling run/tasks on Finit internal HOOK points, issue #18
* Removed support for long-since deprecated `console DEV` setting
* Cosmetic change to login, pressing enter at the `Press enter to ...`
prompt will now replace that line with the login issue text
* Calling `initctl` without any arguments or options now defaults to
show status of all enabled services, and run/task/inetd jobs
* Cosmetic change to boot messages, removed `Loading plugins ...`, start
of inetd services, and `Loading configuration ...`. No end user knows
what those plugins and configurations are, i.e. internal state+config
* Change kernel WDT timeout (3 --> 30 sec) for built-in watchdog daemon
* Advise watchdog dawmon on shutdown and reboot using `SIGPWR` and then
`SIGTERM`. It is recommended the daemon start a timer on the first
signal, in case the shutdown process somehow hangs.
* Handle `/etc/` OverlayFS, reload /etc/finit.d/*.conf after `mount -a`
* initctl: Add support for printing previous runlevel
* initctl: Support short forms of all commands
* initctl: Support for `initctl touch <CONF>` to be used with `reload`
* initctl: Improved output of `initctl show <SVC>`
* Support reloading `/etc/finit.conf`. The main finit.conf file
previously did not support reloading at runtime, as of v3.1 all
configuration directives supported in `/etc/finit.d/*.conf` are now
supported in `/etc/finit.conf`
* Change `.conf` dependency + reload handling. Finit no longer relies
on mtime of `.conf` files, instead an inotify handler tracks file
changes for time *insensitive* dependency tracking
* Change condition handling to not rely on mtime but a generation id.
* New configure script option `--enable-redirect` to automatically
redirect `stdout` and `stderr` of all applications to `/dev/null`
* New `pid` sub-option to services when a service does not create a PID
file, or when the PID file has another name. Issue #95
* Greatly improved `log` sub-option to service/run/tasks, selectively
redirect `stdout` and `stderr` using the new tool `logit` to either
syslog or a logfile. Issue #44
* Support for automatic log rotation of logfiles created by `log`
option. Use `configure --disable-logrotate` on systems with a
dedicated log rotation service. Issue #44
* Support for disabling service/run/task progress with empty ` --`
description. Note: no description separator gives a default desc.
* Create `/etc/mtab` symlink if missing on system (bootmisc plugin)
* New hook: `hook/mount/post` runs after `mount -a` but before the
`hook/mount/all`, where `bootmisc.so` runs. This provides the
possibility of running a second stage mount command before files in
`/run` and similar are created
* Skip `gdbserver` when unleashing the grim reaper at shutdown
* Distribute and install `doc/` and `contrib/` directories
### Fixes
* Reset TTY before restarting it. A program may manipulate the TTY in
various ways before the user logs out, Finit needs to reset the TTY to
a sane state before restarting it. Issue #84
* On .conf parse errors, do *not* default to set TTY speed 38400, reuse
current TTY speed instead
* Fix run/tasks, must be guaranteed to run once per declared runlevel.
All run/tasks on `[S]` with a condition `<...>` failed to run. Finit
now tracks run/tasks more carefully, waiting for them to finish before
switching to the configured runlevel at boot. Issue #86
* Allow inetd services to be registered with a unique ID, e.g. `:161`,
issue #87. Found by Westermo
* inetd: drop UDP packets from blocked interfaces, issue #88
* Handle obscure inter-plugin dependency issue by calling the netlink
plugin before the pidfile plugin on `HOOK_SVC_RECONF` events
* Handle event loop failure modes, issue found by Westermo
* Handle API socket errors more gracefully, restart socket
* Do not attempt to load kernel modules more than once at bootstrap
* Remove reboot symlinks properly on uninstall
* Fix regression in condition handling, reconf condition must be kept
as a reference point to previous reconfiguration, or bootstrap.
* Fix nasty race condition with internal service stop, abort kill if the
service has already terminated, otherwise we may do `kill(0, SIGKILL)`
* Fix reconfiguration issue with (very quick) systems that don't have
highres timers
* Fix formatting of runlevel string in `initctl show`
* Allow running `initctl` with `STDOUT` redirected
* Fix regression in `initctl start/stop <ID>`, using name worked not id
* Fix error handling in `initctl start/stop` without any argument
* Fix issue #81 properly, remove use of SYSV shm IPC completely. Finit
now use the API socket for all communication between PID 1 and initctl
* Fix segfault on x86_64 when started with kernel cmdline `--debug`
* Normalize condition paths on systems with `/run` instead of `/var/run`
[3.0][] - 2017-10-19
--------------------
Major release, support for conditions/dependencies between services,
optional built-in watchdog daemon, optional built-in getty, optional
built-in standard inetd services like echo server, rdate, etc.
Also, native support for Debian/BusyBox `/etc/network/interfaces`,
overhauled new configure based build system, logging to `/dev/kmsg`
before syslogd has started, massively improved support for Linux
distributions.
### Changes
* Added basic code of conduct covenant to project
* Added contribution guidelines document
* Removed `finit.conf` option `check DEV`, replaced entirely by automated
call to `fsck` for each device listed in `/etc/fstab`
* Removed deprecated and confusing `startx` and `user` settings. It is
strongly recommended to instead use xdm/gdb/lightdm etc.
* Add support for `initctl log <SVC>`, shows last 10 lines from syslog
* Add `initctl cond dump` for debugging conditions
* Ensure plugins always have a default name, file name
* Reorganization, move all source files to a `src/` sub-directory
* Add support for `initctl <list|enable|disable> <SVC>`, much needed by
distributions. See [doc/distro.md](doc/distro.md) for details
* Remove `UNUSED()` macro, mentioned here because it may have been used
by external plugin developers. Set `-Wno-unused-parameter` instead
* New table headings in `initctl`, using `top` style inverted text
* Allow `initctl show` to use full screen width for service descriptions
* New `HOOK_BANNER` for plugins to override the default `banner()`
* Allow loading TTYs from `/etc/finit.d`
* Improvements to built-in getty, ignore signals like `SIGINT`,
`SIGHUP`, support Ctrl-U to erase to beginning of line
* Add TTY `nowait` and `noclear` options
* Allow using both built-in getty and external getty:
tty [12345] /dev/ttyAMA0 115200 noclear vt220
tty [12345] /sbin/getty -L 115200 /dev/ttyAMA0 vt100
tty [12345] /sbin/agetty -L ttyAMA0 115200 vt100 nowait
* Silent boot is now the default, use `--enable-progress` to get the old
Finit style process progress. I.e., `--enable-silent` is no more
* Support for `configure --enable-emergency-shell`, debug-only mode
* Support for a fallback shell on console if none of the configured TTYs
can be started, `configure --enable-fallback-shell`
* All debug messages to console when Finit `--debug` is enabled
* Prevent login, by touching `/etc/nologin`, during runlevel changes
* A more orderly shutdown. On reboot/halt/poweroff Finit now properly
goes to runlevel 0/6 to first stop all processes.
* Perform sync before remounting as read-only, at shutdown
* Clean up `/tmp`, `/var/run`, and `/var/lock` at boot on systems which
have these directories on persistent storage
* Call udev triggers at boot, on systems with udev
* Add missing `/var/lock/subsys` directory for dbus
* Add support for `poweroff`
* Add support for a built-in miniature watchdog daemon
* Remove GLIBC:isms like `__progname`
* Manage service states based on user defined conditions
* Manage dependencies between services, w/ conditions (pidfile plugin)
* Manage service dependencies on network events (netlink plugin)
* Support for dynamically reloading Finit configuration at runtime
* Refactor to use GNU configure and build system
* New hooks for for detecting lost and started services (lost plugin)
* External libraries, libuEv and libite, now build requirements
* Early logging support to `/dev/kmsg` instead of console
* Support for redirecting stdout/stderr of services to syslog
* Support for managing resource limits for Finit and its processes
* Add optional built-in inetd services: echo server, chargen, etc.
* Add simple built-in getty
* Greatly improved accounting support, both UTMP and WTMP fixes+features
* Improved udev support, on non-embedded systems
* Improved shutdown and file-system unmount support (Debian)
* Support SysV init `/etc/rc.local`
* Inetd protection against UDP looping attacks
* Support systems with `/run` instead of `/var/run` (bootmisc plugin)
* Adopted BusyBox init signals for halt/reboot/poweroff
* SysV init compat support for reboot (setenv)
* Compat support for musl libc
* Add OpenRC-like support for sysctl.d/*.conf
* Add support for Debian/BusyBox `/etc/network/interfaces`
* Add support for running fsck on file systems in `/etc/fstab`
* Added example configs + HowTos for Debian and Alpine Linux
to support latest releases of both distributions
* Lots of documentation updates
### Fixes
* Fix race-condition at configuration reload due to too low resolution.
Thanks to Mattias Walström, Westermo
* Fix to handle long process (PID) dependency chains, re-run reconf
callback until no more applications are in flux.
Thanks to Mattias Walström, Westermo
* Clear `reconf` condition when `initctl reload` has finished
* Skip automatic reload of `/etc/finit.d/*.conf` files when changing
runlevel to halt or reboot
* Fix issue #54: Allow halt and poweroff commands even if watchdog is enabled
* Fix issue #56: Check existence of device before trying to start getty
* Fix issue #60: `initctl` should display error and return error code
for non-existing services should the operator try to start/stop them.
* Fix issue #61: Reassert `net/*` conditions after `initctl reload`
* Fix issue #64: Skip `fsck` on already mounted devices
* Fix issue #66: Log rotate and gzip `/var/log/wtmp`, created by Finit
* Fix issue #72: Check `ifup` exists before trying to bring up networking,
also set `$PATH` earlier to simplify `run()` et al -- no longer any need
to use absolute paths for system tools called from Finit. Thanks to crazy
* Fix issue #73: Remove double `ntohl()` in inetd handling, prevents matches.
Thanks to Petrus Hellgren, Westermo
* Fix issue #76: Reap zombie processes in emergency shell mode
* Fix issue #80: FTBFS on Arch Linux, missing `stdarg.h` in `helpers.h`,
thanks to Jörg Krause
* Fix issue #81: Workaround for systems w/o SYSV shm IPC support in kernel
* Always collect bootstrap-only tasks when done, we will never re-run them.
Also, make sure to never reload bootstrap-only tasks at runtime
* Remove two second block (!) of Finit when stopping TTYs
[2.4][] - 2015-12-04
--------------------
Bug fix release.
### Changes
* Add support for status/show service by `name:id`
* Enforce terse mode after boot, if verbose mode is disabled
* Reenable verbose mode at reboot, if disabled at boot
* Update section mentioning BusyBox getty
* Update debugging documentation
* Allow debug to override terse mode
* Revert confusing change in service state introduced in [v2.3][2.3].
As of [v2.4][2.4] services are listed as "halted" and "stopped", when
they have been halted due to a runlevel changed or stopped by the
user, respectively.
### Fixes
* Fix system freeze at reconfiguration. Changed services that
all support `SIGHUP` caused a freeze due to Finit waiting for
them to stop.
* Make sure to start and/or `SIGHUP` services after reconfiguration
when there was no services to stop.
[2.3][] - 2015-11-28
--------------------
Bug fix release.
### Changes
* Add support for stop/start/restart/reload service by `name:id`
* Refactor service status listed in `initctl show`, show actual status
### Fixes
* Remove bootstrap-only tasks/services when leaving runlevel 'S'
* Fix reference counting issue with already stopped and removed services
when the user performs `initctl reload` to change system configuration
* Revert semantic change in behavior of `initctl restart`: users expect
service to be stopped/started, not reloaded with `SIGHUP` even if the
service supports it
* Fix `NULL` pointer dereference causing kernel panic when user calls
`initctl reload` after change of system configuration
* Fix column alignment in output of `initctl show` for services not in
current runlevel
[2.2][] - 2015-11-23
--------------------
Lots of fixes to handle static builds, but also fixes for dynamic event
handling and reconfiguration at runtime.
### Changes
* Upgrade to libuEv v1.2.4, to handle static builds
* Upgrade to libite (LITE) v1.2.0, to handle static builds
* Clarify how to select different plugins with the configure script
* Improve urandom plugin for embedded systems w/o random seed
* Add `--debug` flag to `initctl`
* The runlevels listed for services in `initctl show` now hightlight the
active runlevel.
* Clarify in the README and in `initctl help` that the GW event to
listen for in service declarations is `GW:UP`
### Fixes
* Build fixes for `configure --disable-inetd`
* Fixed issue #14: Improved support for static Finit builds
* Misc. fixes to silence warnings when building a static Finit
* Default to register services as `SIGHUP`'able, regression in v2.0
* Call `HOOK_SVC_RECONF` only when all processes have been stopped
* On reload/reconf we must wait for all services to stop first
* Only trigger on events that matches the service's specification,
fix by Tobias Waldekranz
[2.1][] - 2015-10-16
--------------------
### Changes
* Add hook point for fstab mount failure
* Set hostname on dynamic reload
* Upgrade to libite v1.1.1
### Fixes
* Fix service callback coredump checks and simplify callback exit
* Do not use `-Os` use `-O2` as default optimization level. Many cross
compiler toolchains are known to have problems with `-Os`
* Do not allow build VERSION to be overloaded by an environment variable
* Fix too small MAX arguments and too few argments in `svc_t` for
reading currently running services with `initctl show`
* Unblock blocked signals after forking off a child
[2.0][] - 2015-09-20
--------------------
Support for multiple instances and event based services, as well as the
introduction of an `initctl` tool.
**Note:** Incompatible change to syntax for custom `inetd` services,
c.f. Finit v[1.12][].
### Changes
* The most notable change is the support for multiple instances. A must
have when running multiple DHCP clients, OpenVPN tunnels, or anything
that means using the same command only with different arguments. Now
simply add a `:ID` after the `service` keyword, where `ID` is a unique
instance number for that service.
service :1 [2345] /sbin/httpd -f -h /http -p 80 -- Web server
service :2 [2345] /sbin/httpd -f -h /http -p 8080 -- Old web server
* Another noteworthy new feature is support for starting/stopping
services on Netlink events:
service :1 [2345] <!IFUP:eth0,GW> /sbin/dropbear -R -F -p 22 -- SSH daemon
Here the first instance `:1` of the SSH daemon is declared to run in
runlevels 2-5, but only if eth0 `IFUP:eth0` is up and a gateway `GW`
is set. When the configuration changes, a new gateway is set, or if
somehow a new `IFUP` event for eth0 is received, then dropbear is not
SIGHUP'ed, but instead stop-started `<!>`. The latter trick applies
to all services, even those that do not define any events.
* Support for reloading `*.conf` files in `/etc/finit.d/` on SIGHUP.
All `task`, `service` and `run` statements can be used in these .conf
files. Use the `telinit q` command, `initctl reload` or simply send
`SIGHUP` to PID 1 to reload them. Finit automatically does reload of
these `*.conf` files when changing runlevel.
* Support for a modern `initctl` tool which can stop/start/reload and
list status of all system services. Also, the old client tool used
to change runlevel is now also available as a symlink: `telinit`.
initctl [-v] <status|stop|start|reload|restart> [JOB]
* Add concept of "jobs". This is a unique identifier, composed of a
service and instance number, `SVC:ID`
initctl <stop|start|reload|restart> JOB
* Support for *deny filters* in `inetd` services.
inetd service/proto[@iface,!iface,...] </path/to/cmd | internal[.service]>
Internal services on a custom port must use the `internal.service`
syntax so Finit can properly bind the inetd service to the correct
plugin. Here follows a few examples:
inetd time/udp wait [2345] internal -- UNIX rdate service
inetd time/tcp nowait [2345] internal -- UNIX rdate service
inetd 3737/tcp nowait [2345] internal.time -- UNIX rdate service
inetd telnet/tcp@*,!eth1,!eth0, nowait [2345] /sbin/telnetd -i -F -- Telnet service
inetd 2323/tcp@eth1,eth2,eth0 nowait [2345] /sbin/telnetd -i -F -- Telnet service
inetd 222/tcp@eth0 nowait [2345] /sbin/dropbear -i -R -F -- SSH service
inetd ssh/tcp@*,!eth0 nowait [2345] /sbin/dropbear -i -R -F -- SSH service
Access to telnet on port `2323` is only possible from interfaces
`eth0`, `eth1` and `eth2`. The standard telnet port (`23`) is
available from all other interfaces, but also `eth2`. The `*`
notation used in the ssh stanza means *any* interface, however, here
`eth0` is not allowed.
**NOTE:** This change breaks syntax compatibility with Finit v[1.12].
* Support for a more user-friendly configure script rather than editing
the top Makefile, or setting environment variables at build time.
* Support for building Finit statically, no external libraries. This
unfortunately means that some plugins cannot be built, at all.
Big thanks goes to James Mills for all help testing this out!
* Support for disabling the built-in inetd server with `configure`.
* Support for two new hook points: `HOOK_SVC_RECONF` and
`HOOK_RUNLEVEL_CHANGE`. See the source for the exact location.
* The `include <FILE>` option now needs an absolute path to `FILE`.
### Fixes
* Rename `patches/` to `contrib/` to simplify integration in 3rd party
build systems.
* Fix for unwanted zombies ... when receiving SIGCHLD we must reap *all*
children. We only receive one signal, but multiple processes may have
exited and need to be collected.
[1.12][] - 2015-03-04
---------------------
The inetd release.
### Changes
* Add support for built-in inetd super server -- launch services on
demand. Supports filtering per interface and custom Inet ports.
* Upgrade to [libuEv] v1.1.0 to better handle error conditions.
* Allow mixed case config directives in `finit.conf`
* Add support for RFC 868 (rdate) time plugin, start as inetd service.
* Load plugins before parsing `finit.conf`, this makes it possible to
extend finit even with configuration commands. E.g., the `time.so`
plugin must be loaded for the `inetd time/tcp internal` service to be
accepted when parsing `finit.conf`.
* Slight change in TTY fallback behavior, if no TTY is listed in the
system `finit.conf` first inspect the `console` setting and only if
that too is unset fall back to `/bin/sh`
* When falling back to the `console` TTY or `/bin/sh`, finit now marks
this fallback as console. Should improve usability in some use cases.
### Fixes
* Revert "Use vfork() instead of fork() before exec()" from v1.11. It
turned out to not work so well after all. For instance, launching
TTYs in a background process completely blocked inetd services from
even starting up listening sockets ... proper fork seems to work fine
though. This is the casue for *yanking* the [1.11] release, below.
* Trap segfaults caused by external plugins/callbacks in a sub-process.
This prevents a single programming mistake in by a 3rd party developer
from taking down the entire system.
* Fix Coverity CID 56281: dlopen() resource leak by storing the pointer.
For the time being we do not support unloading plugins.
* Set hostname early, so bootstrap processes like syslog can use it.
* Only restart *lost daemons* when recovering from a SIGSTOP/norespawn.
[1.11][] - 2015-01-24 [YANKED]
------------------------------
The [libuEv] release.
**Note:** This release has been *yanked* from distribution due to a
regression in launching background processes and TTY's. Fixed in
Finit v[1.12].
### Changes
* Now using the asynchronous libuEv library for handling all events:
signals, timers and listening to sockets or file descriptors.
* Rename NEWS.md --> CHANGELOG.md, with symlinks for `make install`
* Attempt to align with http://keepachangelog.com/ for this file.
* Travis CI now only invokes Coverity Scan from the 'dev' branch. This
means that all development, except documentation updates, must go into
that branch.
### Fixes
* Fix bug with finit dying when no `tty` is defined in `finit.conf`, now
even the fallback shell has control over its TTY, see fix in GIT
commit [dea3ae8] for this.
[1.10][] - 2014-11-27
---------------------
Major bug fix release.
### Changes
* Project now relies on static code analysis from Coverity, so this
release contains many serious bug fixes.
* Convert to use Markdown for README, NEWS and TODO.
* Serious update to README and slight pruning of finished TODO items.
### Fixes
* Fix serious file descriptor and memory leaks in the following
functions. In particular the leaks in `run_interactive()` are very
serious since that function is called every time a service is started
and/or restarted! For details, see the GIT log:
* `helpers.c:run()`
* `helpers.c:run_interactive()`
* `helpers.c:set_hostname()`
* `helpers.c:procname_kill()`
* `svc.c:svc_start()`: Fix swapped arguments to dup2() and add close(fd)
to prevent descriptor leak.
* `svc.c:svc_start()`: Fix out of bounds write to local stack variable,
wrote off-by-one outside array.
* Several added checks for return values to `mknod()`, `mkdir()`,
`remove()`, etc.
[1.9][] - 2014-04-21
--------------------
### Changes
* Add support for an include directive to `.conf` files
* Fallback to `/bin/sh` if user forgets tty setting
* Initial support for restarting lost services during `norespwan`
### Fixes
* Bug fixes, code cleanup
* Handle `SIGHUP` from service callback properly when switching runlevel
* Misc. major (memleak) and minor fixes and additions to `libite/lite.h`
[1.8][] - 2013-06-07
--------------------
### Changes
* Support for runlevels, with a bootstrap runlevel 'S'
* Support for saving previous and current runlevel to UTMP
* Support for new `finit.conf` commands: run, task, and runlevel
* Support for tty and console commands in `finit.conf`, like services
but for launching multiple getty logins
* New tty plugin to monitor TTYs coming and going, like USB TTYs
### Fixes
* Bugfixes to libite
[1.7][] - 2012-10-08
--------------------
### Changes
* Show `__FILE__` in `_d()` debug messages, useful for plugins with
similarily named callbacks. Also, only in debug mode anyway
* Make sure to cleanup recorded PID when a service is lost. Required by
service plugins for their callbacks to work.
* Only clear screen when in verbose mode. Maybe this should be removed
altogether?
### Fixes
* Bugfix: Do not `free()` static string in `finit.conf` parser
[1.6][] - 2012-10-06
--------------------
### Changes
* Skip `.` and `..` in plugin loader and display error when failing to
load plugins
* Support for overriding `/etc/finit.d` with `runparts DIR` in
`finit.conf`
* Revoke support for starting services not starting with a slash.
* Prevent endless restart of non-existing services in `finit.conf`
* Support for sysvinit style startstop scripts in `/etc/finit.d`
### Fixes
* Minor fix to alsa-utils plugin to silence on non-existing cards
[1.5][] - 2012-10-03
--------------------
### Changes
* Use bootmisc plugin to setup standard FHS 2.3 structure in `/var`
* Added `FLOG_WARN()` syslog macro, for plugins
* Add plugin dependency resolver. Checks `plugin_t` for `.depends`
[1.4][] - 2012-10-02
--------------------
### Changes
* Start refactoring helpers.c into a libite.so (-lite). This means
other user space applications/daemons can make use of the neat toolbox
available in finit
* Use short-form -s/-w -u to work with BusyBox hwclock as well
* Use RTLD_GLOBAL flag to tell dynamic loader to load dependent .so
files as well. Lets other plugins use global symbols.
* Greatly simplify svc hook for external plugins and cleanup plugin API.
* And more ... see the GIT log for more details.
### Fixes
* Fix I/O plugin watcher and load plugins earlier for a new hook
[1.3][] - 2012-09-28
--------------------
### Changes
* Cleanup public plugin API a bit and add new pid/pidfile funcs
* Add plugin hook to end of service startup
* Remove finit.h from svc.h, plugins should not need this.
* Move utility macros etc. to helpers.h
* Make `finit.h` daemon internal, only
* Move defines of FIFO, conf and rcS.d to Makefile => correct paths
* Add support for installing required headers in system include dir
* Better support for distributions and packagers with install-exec,
install-data, and install-dev targets in Makefile. Useful if you want
to call targets with different `$DESTDIR`!
* Makefile fixes for installation, paths encoded wrong
* Strip binaries + .so files, support for `$(CROSS)` toolchain strip
* Default install is now to `/sbin/finit` and `/usr/`
* Note change in `$PLUGIN_DIR` environemnt variable to `$plugindir`
[1.2][] - 2012-09-27
--------------------
### Changes
* Update README with section on building and enviroment variables
### Fixes
* Fix installation paths encoded in finit binary
[1.1][] - 2012-09-27
--------------------
### Changes
* Rename signal.[ch]-->sig.[ch] to avoid name clash w/ system headers
### Fixes
* Build fixes for ARM eabi/uClibc
[1.0][] - 2012-09-26
--------------------
### Changes
* New plugin based system for all odd extensions
* New service monitor that restarts services if they die
* New maintainer at GitHub http://github.com/troglobit/finit
* Add standard LICENSE and AUTHORS files
* New focus: embedded systems and small headless servers
[0.6][] - 2010-06-14
--------------------
* Don't start consolekit manually, dbus starts it (rtp)
* Unmount all filesystems before rebooting
* Disable `USE_VAR_RUN_RESOLVCONF` for Mandriva
* Unset terminal type in Mandriva before running X
* Remove extra sleep in finit-alt before calling services.sh (caio)
[0.5][] - 2008-08-21
--------------------
* Add option to start dbus and consolekit before the X server
* finit-alt listens to `/dev/initctl` to work with `reboot(8)` (smurfy)
* Write runlevel to utmp, needed by Printerdrake (Pascal Terjan)
* Fix ownership of `/var/run/utmp` (reported by Pascal Terjan)
* Remove obsolete code to load AGP drivers
* Conditional build of `/etc/resolveconf/run` support
* Add support to `/var/run/resolvconf` in Mandriva (blino)
[0.4][] - 2008-05-16
--------------------
* Default username for finit-alt configurable in Makefile
* Create loopback device node in finit-alt (for squashfs)
* Add option to use built-in run-parts instead of `/bin/run-parts`
* Ignore signal instead of setting to an empty handler (Metalshark)
* Handle pam_console permissions in finit-alt for Mandriva
* Add services.sh example and nash-hotplug patch for Mandriva
* Mount `/proc/bus/usb` in Mandriva
* Add runtime debug to finit-alt if finit_debug parameter is specified
* Read configuration from `/etc/finit.conf`
* Run getty with openvt on the virtual terminal
[0.3][] - 2008-02-23
--------------------
* Change poweroff method to `reboot(RB_POWER_OFF)` (Metalshark)
* Remove duplicate `unionctl()` reimplementation error
* Fix string termination in path creation
* Mount `/var/lock` and `/var/run` as tmpfs
[0.2][] - 2008-02-19
--------------------
* Replace `system("touch")` with `touch()` in finit-mod (Metalshark)
* Disable `NO_HCTOSYS` by default to match stock Eeepc kernel
* Drop `system("rm -f")` to clean `/tmp`, its a fresh mounted tmpfs
* Write ACPI sleep state to `/sys/power/state` instead of
`/proc/acpi/sleep` (Metalshark)
* Use direct calls to set loopback instead of `system("ifconfig")`
* Replace `system("cat")` and `system("dd")` with C implementation
* Moved finit-mod and finit-alt helpers to `helpers.c`
* Replace `system("echo;cat")` to draw shutdown splash with C calls
0.1 - 2008-02-14
----------------
* Initial release
[UNRELEASED]: https://github.com/troglobit/finit/compare/3.1...HEAD
[4.0]: https://github.com/troglobit/finit/compare/3.1...4.0
[3.1]: https://github.com/troglobit/finit/compare/3.0...3.1
[3.0]: https://github.com/troglobit/finit/compare/2.4...3.0
[2.4]: https://github.com/troglobit/finit/compare/2.3...2.4
[2.3]: https://github.com/troglobit/finit/compare/2.2...2.3
[2.2]: https://github.com/troglobit/finit/compare/2.1...2.2
[2.1]: https://github.com/troglobit/finit/compare/2.0...2.1
[2.0]: https://github.com/troglobit/finit/compare/1.12...2.0
[1.12]: https://github.com/troglobit/finit/compare/1.11...1.12
[1.11]: https://github.com/troglobit/finit/compare/1.10...1.11
[1.10]: https://github.com/troglobit/finit/compare/1.9...1.10
[1.9]: https://github.com/troglobit/finit/compare/1.8...1.9
[1.8]: https://github.com/troglobit/finit/compare/1.7...1.8
[1.7]: https://github.com/troglobit/finit/compare/1.6...1.7
[1.6]: https://github.com/troglobit/finit/compare/1.5...1.6
[1.5]: https://github.com/troglobit/finit/compare/1.4...1.5
[1.4]: https://github.com/troglobit/finit/compare/1.3...1.4
[1.3]: https://github.com/troglobit/finit/compare/1.2...1.3
[1.2]: https://github.com/troglobit/finit/compare/1.1...1.2
[1.1]: https://github.com/troglobit/finit/compare/1.0...1.1
[1.0]: https://github.com/troglobit/finit/compare/0.9...1.0
[0.9]: https://github.com/troglobit/finit/compare/0.8...0.9
[0.8]: https://github.com/troglobit/finit/compare/0.7...0.8
[0.7]: https://github.com/troglobit/finit/compare/0.6...0.7
[0.6]: https://github.com/troglobit/finit/compare/0.5...0.6
[0.5]: https://github.com/troglobit/finit/compare/0.4...0.5
[0.4]: https://github.com/troglobit/finit/compare/0.3...0.4
[0.3]: https://github.com/troglobit/finit/compare/0.2...0.3
[0.2]: https://github.com/troglobit/finit/compare/0.1...0.2
[libuEv]: https://github.com/troglobit/libuev
[dea3ae8]: https://github.com/troglobit/finit/commit/dea3ae8
<!--
-- Local Variables:
-- mode: markdown
-- End:
-->
+1 -1
View File
@@ -1,5 +1,5 @@
Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
Copyright (c) 2008-2025 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
of this software and associated documentation files (the "Software"), to deal
+18 -17
View File
@@ -1,6 +1,7 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = man plugins src system tmpfiles.d
dist_doc_DATA = README.md LICENSE contrib/finit.conf
SUBDIRS = plugins src test
doc_DATA = README.md LICENSE contrib/finit.conf
EXTRA_DIST = README.md LICENSE ChangeLog.md contrib/finit.conf
if CONTRIB
SUBDIRS += contrib
@@ -8,17 +9,6 @@ endif
if DOC
SUBDIRS += doc
endif
if LIBSYSTEMD
SUBDIRS += libsystemd
endif
if LIBSYSTEMD
SUBDIRS += test
# Explicit dependency to ensure libsystemd is built before test
test: libsystemd
else
SUBDIRS += test
endif
# Compat hook
install-dev:
@@ -40,7 +30,18 @@ release: distcheck
printf "$$file.sha256\t"; cat ../$$file.sha256 | cut -f1 -d' '; \
done
DISTCHECK_CONFIGURE_FLAGS = --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
--enable-testserv-plugin --enable-x11-common-plugin \
--with-watchdog --with-keventd --with-fstab=/etc/fstab \
--with-libsystemd --with-bash-completion-dir=no
run:
srcdir=@srcdir@/test \
top_builddir=@top_builddir@ \
TENV_ROOT=$(tenv_root) \
@srcdir@/test/setup-root.sh
mkdir -p $(dir $(tenv_root)/@FINIT_CONF@)
echo 'tty [12345] @console linux noclear nologin' > $(tenv_root)/@FINIT_CONF@
-TENV_ROOT=$(tenv_root) \
TESTENV_PATH=@sbindir@:/bin \
FINIT_RCSD=@FINIT_RCSD@ \
test/tenv/start.sh finit
run : tenv_root ?= @abs_top_builddir@/run-rootfs
+464 -36
View File
@@ -1,50 +1,478 @@
[![License Badge][]][License] [![Release Badge][]][Release] [![GitHub Status][]][GitHub] [![Coverity Status][]][Coverity Scan]
<img align="right" src="doc/img/finit3.png" alt="Finit: Fast Init">
[![License Badge][]][License] [![Travis Status]][Travis] [![Coverity Status]][Coverity Scan]
<img align="right" src="img/finit3.png" alt="Finit: Fast Init">
Finit is a fast, simple alternative to [SysV init](https://en.wikipedia.org/wiki/Init)
and [systemd](https://systemd.io), designed for small and embedded Linux systems.
It can also run on desktop and server systems, like [finix][].
* [Introduction](#introduction)
* [Features](#features)
* [Bootstrap](doc/bootstrap.md#bootstrap)
* [Runlevels](#runlevels)
* [Syntax](doc/config.md#syntax)
* [Runparts & /etc/rc.local](#runparts--etcrclocal)
* [Hooks, Callbacks & Plugins](doc/plugins.md#hooks-callbacks--plugins)
* [Rebooting & Halting](#rebooting--halting)
* [Commands & Status](#commands--status)
* [Tips & Tricks with the kernel cmdline](doc/cmdline.md)
* [Building](doc/build.md#building)
* [Running](doc/build.md#running)
* [Recovery](doc/build.md#recovery)
* [Debugging](doc/build.md#debugging)
* [Requirements](#requirements)
* [Origin & References](#origin--references)
> Reverse engineered from the [EeePC fastinit][]
> "gaps filled with frog DNA …"
> — [Claudio Matsuoka][]
For detailed information, explore our extensive documentation
:books: **<http://finit-project.github.io>**
Introduction
------------
<div align="center">
<img src="doc/img/alpine-screenshot2.png" alt="Alpine screenshot"><br/>
</div>
Finit is a simple alternative to [SysV init][4] and [systemd][6]. It
was reverse engineered from the [EeePC fastinit][] over ten years ago
by [Claudio Matsuoka][] — "gaps filled with frog DNA …"
For working examples, see the :rocket: [contrib/](contrib/) section or these
tutorials:
Focus is on small and embedded systems, although Finit is fully usable
on server and desktop systems as well. For working examples, see the
[contrib/](contrib/) section with tutorials for:
* :hammer_and_wrench: [Buildroot embedded Linux][br2demo],
* :package: [Debian GNU/Linux](contrib/debian/),
* :mountain: [Alpine Linux](contrib/alpine/), and
* :milky_way: [Void Linux](contrib/void/)
* [Void Linux](contrib/void/),
* [Alpine Linux](contrib/alpine/), and
* [Debian GNU/Linux](contrib/debian/)
> [!NOTE]
> Finit can run on various Linux distributions, but the bundled install
> scripts are examples only. They have been tested on amd64 (x86_64) systems
> with standard configurations.
>
> For embedded systems, see these [Buildroot][]-based examples:
> [myLinux][], [Infix][], or [br2-finit-demo][].
![Alpine screenshot](img/alpine-screenshot.png)
The screenshot shows [Alpine Linux](https://www.alpinelinux.org/).
[finix]: https://github.com/finix-community/finix
[Buildroot]: https://buildroot.org
[Infix]: https://kernelkit.github.io
[myLinux]: https://github.com/troglobit/myLinux/
[br2demo]: https://troglobit.com/post/2022-12-26-buildroot-demo-of-fastinit-finit/
Example
-------
This example `/etc/finit.conf` can also be split up in multiple `.conf`
files in `/etc/finit.d`. Available, but not yet enabled, services can
be placed in `/etc/finit.d/available` and enabled by an operator using
the [initctl](#commands--status) tool.
```ApacheConf
# Fallback if /etc/hostname is missing
host default
# Runlevel to start after bootstrap, 'S', default: 2
runlevel 2
# Max file size for each log file: 100 kiB, rotate max 4 copies:
# log => log.1 => log.2.gz => log.3.gz => log.4.gz
log size=100k count=4
# Services to be monitored and respawned as needed
service [S12345] watchdogd -L -f -- System watchdog daemon
service [S12345] syslogd -n -b 3 -D -- System log daemon
service [S12345] <pid/syslogd> klogd -n -- Kernel log daemon
service [2345] lldpd -d -c -M1 -H0 -i -- LLDP daemon (IEEE 802.1ab)
# The BusyBox ntpd does not use syslog when running in the foreground
# So we use this trick to redirect stdout/stderr to a log file. The
# log file is rotated with the above settings. The condition declares
# a dependency on a system default route (gateway) to be set. A single
# <!> at the beginning means ntpd does not respect SIGHUP for restart.
service [2345] log:/var/log/ntpd.log <!net/route/default> ntpd -n -l -I eth0 -- NTP daemon
# For multiple instances of the same service, add :ID somewhere between
# the service/run/task keyword and the command.
service :80 [2345] merecat -n -p 80 /var/www -- Web server
service :8080 [2345] merecat -n -p 8080 /var/www -- Old web server
# Alternative method instead of below runparts, can also use /etc/rc.local
#task [S] /etc/init.d/keyboard-setup start -- Setting up preliminary keymap
#task [S] /etc/init.d/acpid start -- Starting ACPI Daemon
#task [S] /etc/init.d/kbd start -- Preparing console
# Run start scripts from this directory
# runparts /etc/start.d
# Virtual consoles run BusyBox getty, keep kernel default speed
tty [12345] /sbin/getty -L 0 /dev/tty1 linux
tty [12345] /sbin/getty -L 0 /dev/tty2 linux
tty [12345] /sbin/getty -L 0 /dev/tty3 linux
# Use built-in getty for serial port and USB serial
tty [12345] /dev/ttyAMA0 noclear nowait
tty [12345] /dev/ttyUSB0 noclear
# Just give me a shell, I need to debug this embedded system!
tty [12345] @console noclear nologin
```
The `service` stanza, as well as `task`, `run` and others are described
in full in [doc/config.md](doc/config.md). Here's a quick overview of
some of the most common components needed to start a UNIX daemon:
```
service [LVLS] <COND> log env:[-]/etc/default/daemon daemon ARGS -- Daemon daemon
^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | `-- Optional description
| | | | | | `----------- Daemon arguments
| | | | | `-------------------------- Path to daemon
| | | | `---------------------------------------------------- Optional env. file
| | | `-------------------------------------------------------- Redirect output to log
| | `--------------------------------------------------------------- Optional conditions
| `---------------------------------------------------------------------- Optional Runlevels
`------------------------------------------------------------------------------ Monitored application
```
Some components are optional: runlevel(s), condition(s) and description,
making it easy to create simple start scripts and still possible for more
advanced uses as well:
service sshd -D
Dependencies are handled using [conditions](doc/conditions.md). One of
the most common conditions is to wait for basic networking to become
available:
service <net/route/default> nginx -- High performace HTTP server
Here is another example where we instruct Finit to not start BusyBox
`ntpd` until `syslogd` has started properly. Finit waits for `syslogd`
to create its PID file, by default `/var/run/syslogd.pid`.
service [2345] log <!pid/syslogd> ntpd -n -N -p pool.ntp.org
service [S12345] syslogd -n -- Syslog daemon
Notice the `log` keyword, BusyBox `ntpd` uses `stderr` for logging when
run in the foreground. With `log` Finit redirects `stdout` + `stderr`
to the system log daemon using the command line `logger(1)` tool.
A service, or task, can have multiple dependencies listed. Here we wait
for *both* `syslogd` to have started and basic networking to be up:
service [2345] log <pid/syslogd,net/route/default> ntpd -n -N -p pool.ntp.org
If either condition fails, e.g. loss of networking, `ntpd` is stopped
and as soon as it comes back up again `ntpd` is restarted automatically.
**Note:** Make sure daemons *do not* fork and detach themselves from the
controlling TTY, usually an `-n` or `-f` flag, or `-D` as in the case
of OpenSSH above. If it detaches itself, Finit cannot monitor it and
will instead try to restart it.
Features
--------
**Process Supervision**
Start, monitor and restart services should they fail.
**Getty**
Finit supports external getty but also comes with a limited built-in
Getty, useful for really small systems. A getty sets up the TTY and
waits for user input before handing over to `/bin/login`, which is
responsible for handling the actual authentication.
```conf
tty [12345] /dev/tty1 nowait linux
tty [12345] /dev/ttyAMA0 noclear vt100
tty [12345] /sbin/getty -L /dev/ttyAMA0 vt100
```
Users of embedded systems may want to enable automatic serial console
with the special `@console` device. This works regardless weather the
system uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else. Finit
figures it out by querying sysfs: `/sys/class/tty/console/active`.
```conf
tty [12345] @console linux noclear
```
Notice the optional `noclear`, `nowait`, and `nologin` flags. The
latter is for skipping the login process entirely. For more information,
see [doc/config.md](doc/config.md#syntax).
**Runlevels**
Support for SysV init-style [runlevels][5] is available, in the same
minimal style as everything else in Finit. The `[2345]` syntax can be
applied to service, task, run, and TTY stanzas.
Reserved runlevels are 0 and 6, halt and reboot, respectively just like
SysV init. Runlevel 1 can be configured freely, but is recommended to
be kept as the system single-user runlevel since Finit will not start
networking here. The configured `runlevel NUM` from `/etc/finit.conf`
is what Finit changes to after bootstrap, unless 'single' (or 'S') is
given on the kernel cmdline, in which case runlevel 1 is started.
All services in runlevel S(0) are started first, followed by the desired
run-time runlevel. Run tasks in runlevel S can be started in sequence
by using `run [S] cmd`. Changing runlevels at runtime is done like any
other init, e.g. <kbd>init 4</kbd>, but also using the more advanced
`intictl` tool.
**Plugins**
Plugins can *extend* the functionality of Finit and *hook into* the
different stages of the boot process and at runtime. Plugins are
written in C and compiled into a dynamic library loaded automatically by
finit at boot. A basic set of plugins are bundled in the `plugins/`
directory.
Capabilities:
- **Hooks**
Hook into the boot at predefined points to extend Finit
- **I/O**
Listen to external events and control Finit behavior/services
Extensions and functionality not purely related to what an `/sbin/init`
needs to start a system are available as a set of plugins that either
hook into the boot process or respond to various I/O.
For more information, see [doc/plugins.md](doc/plugins.md).
**Automatic Reload**
By default, Finit monitors `/etc/finit.d/` and `/etc/finit.d/enabled/`
registering any changes to `.conf` files. To activate a change the user
must call `initctl reload`, which reloads all modified files, stops any
removed services, starts new ones, and restarts any modified ones, with
SIGHUP if the process supports it.
For some use-cases the extra step of calling `initctl reload` creates an
unnecessary overhead, which can be removed at build-time using:
configure --enable-auto-reload
Runparts & /etc/rc.local
------------------------
At the end of the boot, when all bootstrap (`S`) tasks and services have
started, but not networking, Finit calls its built-in [run-parts(8)][]
command on any configured `runparts <DIR>` directory. This happens just
before changing to the configured runlevel (default 2). (Networking is
enabled just prior to changing from single user mode.)
```shell
runparts /etc/rc.d/
```
Right after the runlevel change when all services have started properly,
`/etc/rc.local` is called.
No configuration stanza in `/etc/finit.conf` is required for `rc.local`.
If it exists and is an executable shell script Finit calls it at the very
end of the boot, before calling the `HOOK_SYSTEM_UP`. See more on hooks
in [doc/plugins.md](doc/plugins.md#hooks), and about the system bootstrap
in [doc/bootstrap.md](doc/bootstrap.md).
Runlevels
---------
Basic support for [runlevels][5] is included in Finit from v1.8. By
default all services, tasks, run commands and TTYs listed without a set
of runlevels get a default set `[234]` assigned. The default runlevel
after boot is 2.
Finit supports runlevels 0-9, and S, with 0 reserved for halt, 6 reboot
and S for services to only run at bootstrap. Runlevel 1 is the single
user level, where usually no networking is enabled. In Finit this is
more of a policy for the user to define. Normally only runlevels 1-6
are used, and even more commonly, only the default runlevel is used.
To specify an allowed set of runlevels for a `service`, `run` command,
`task`, or `tty`, add `[NNN]` to your `/etc/finit.conf`, like this:
```
service [S12345] syslogd -n -x -- System log daemon
run [S] /etc/init.d/acpid start -- Starting ACPI Daemon
task [S] /etc/init.d/kbd start -- Preparing console
service [S12345] <pid/syslogd> klogd -n -x -- Kernel log daemon
tty [12345] /dev/tty1
tty [2] /dev/tty2
tty [2] /dev/tty3
tty [2] /dev/tty4
tty [2] /dev/tty5
tty [2] /dev/tty6
```
In this example syslogd is first started, in parallel, and then acpid is
called using a conventional SysV init script. It is called with the run
command, meaning the following task command to start the kbd script is
not called until the acpid init script has fully completed. Then the
keyboard setup script is called in parallel with klogd as a monitored
service.
Again, tasks and services are started in parallel, while run commands
are called in the order listed and subsequent commands are not started
until a run command has completed. Also, task and run commands are run
in a shell, so pipes and redirects can be used.
The following examples illustrate this. Bootstrap task and run commands
are also removed when they have completed, `initctl show` will not list
them.
```
task [S] echo "foo" | cat >/tmp/bar
run [S] echo "$HOME" >/tmp/secret
```
Switching between runlevels can be done by calling init with a single
argument, e.g. <kbd>init 5</kbd>, or using `initctl runlevel 5`, both
switch to runlevel 5. When changing runlevels Finit also automatically
reloads all `.conf` files in the `/etc/finit.d/` directory. So if you
want to set a new system config, switch to runlevel 1, change all config
files in the system, and touch all `.conf` files in `/etc/finit.d`
before switching back to the previous runlevel again — that way Finit
can both stop old services and start any new ones for you, without
rebooting the system.
Rebooting & Halting
-------------------
Traditionally, rebooting and halting a UNIX system is done by changing
its runlevel. Finit comes with its own tooling providing: `shutdown`,
`reboot`, `poweroff`, and `suspend`, but also the `initctl` tool,
detailed in the next section.
For compatibility reasons Finit listens to the same set of signals as
BusyBox init. This is not 100% compatible with SysV init, but clearly
the more common combination for Finit. For more details, see
[doc/signals.md](doc/signals.md).
Commands & Status
-----------------
Finit also implements a modern API to query status, and start/stop
services, called `initctl`. Unlike `telinit` the `initctl` tool does
not return until the given command has fully completed.
```shell
~ $ initctl -h
Usage: initctl [OPTIONS] [COMMAND]
Options:
-v, --verbose Verbose output
-h, --help This help text
Commands:
debug Toggle Finit (daemon) debug
help This help text
version Show Finit version
list List all .conf in /etc/finit.d/
enable <CONF> Enable .conf in /etc/finit.d/available/
disable <CONF> Disable .conf in /etc/finit.d/[enabled/]
touch <CONF> Mark .conf in /etc/finit.d/ for reload
reload Reload *.conf in /etc/finit.d/ (activates changes)
cond show Show condition status
cond dump Dump all conditions and their status
log [NAME] Show ten last Finit, or NAME, messages from syslog
start <JOB|NAME>[:ID] Start service by job# or name, with optional ID
stop <JOB|NAME>[:ID] Stop/Pause a running service by job# or name
restart <JOB|NAME>[:ID] Restart (stop/start) service by job# or name
status <JOB|NAME>[:ID] Show service status, by job# or name
status | show Show status of services, default command
runlevel [0-9] Show or set runlevel: 0 halt, 6 reboot
reboot Reboot system
halt Halt system
poweroff Halt and power off system
utmp show Raw dump of UTMP/WTMP db
```
For services *not* supporting `SIGHUP` the `<!>` notation in the .conf
file must be used to tell Finit to stop and start it on `reload` and
`runlevel` changes. If `<>` holds more [conditions](doc/conditions.md),
these will also affect how a service is maintained.
**Note:** even though it is possible to start services not belonging in
the current runlevel these services will not be respawned automatically
by Finit if they exit (crash). Hence, if the runlevel is 2, the below
Dropbear SSH service will not be restarted if it is killed or exits.
```shell
~ $ initctl status -v
1 running 476 [S12345] /sbin/watchdog -T 16 -t 2 -F /dev/watchdog
2 running 477 [S12345] /sbin/syslogd -n -b 3 -D
3 running 478 [S12345] /sbin/klogd -n
4:1 inetd 0 [2345] internal time allow *:37,!eth0
4:2 inetd 0 [2345] internal time allow eth0:3737
5:1 inetd 0 [2345] /sbin/telnetd allow *:23 deny eth0,eth1
5:2 inetd 0 [2345] /sbin/telnetd allow eth0:2323,eth2:2323,eth1:2323
6:1 inetd 0 [345] /sbin/dropbear allow eth0:222
6:2 inetd 0 [345] /sbin/dropbear allow *:22 deny eth0
```
Requirements
------------
Finit is capable of running on both desktop/server systems with udev and
embedded systems that usually come with BusyBox mdev. Some systems have
systemd-udev or eudev today instead of the original udev, Finit probes
for all of them at runtime and expects `/dev/` to be a writable file
system using `devtmpfs`. It is also possible to run on a statically set
up `/dev` if needed. It is however not a good idea to have both udev
and mdev installed at the same time, this will lead to unpredictable
results.
At boot Finit calls either `mdev` or `udevd` to populate `/dev`, this is
done slightly differently and on systems with udev you might want to add
the following one-shot task early in your `/etc/finit.conf`:
```conf
run [S] udevadm settle --timeout=120 -- Waiting for udev
```
Finit has a built-in Getty for TTYs, but requires a working `/bin/login`
or `/bin/sh`, if no TTYs are configured in `/etc/finit.conf`.
For a fully operational system `/var`, `/run` and `/tmp` must be set up
properly in `/etc/fstab` -- which is iterated over at boot.
Origin & References
-------------------
This project is based on the [original finit][] by [Claudio Matsuoka][]
which was reverse engineered from syscalls of the [EeePC fastinit][] —
"gaps filled with frog DNA …"
Finit is developed and maintained by [Joachim Wiberg][] at [GitHub][].
Please file bug reports, clone it, or send pull requests for bug fixes
and proposed extensions.
[1]: https://en.wikipedia.org/wiki/Process_supervision
[2]: http://cr.yp.to/daemontools.html
[3]: http://smarden.org/runit/
[4]: http://en.wikipedia.org/wiki/Init
[5]: http://en.wikipedia.org/wiki/Runlevel
[6]: https://www.freedesktop.org/wiki/Software/systemd/
[9]: https://github.com/troglobit/troglos
[RFC862]: https://tools.ietf.org/html/rfc862
[RFC863]: https://tools.ietf.org/html/rfc863
[RFC864]: https://tools.ietf.org/html/rfc864
[RFC867]: https://tools.ietf.org/html/rfc867
[RFC868]: https://tools.ietf.org/html/rfc868
[init]: http://en.wikipedia.org/wiki/Init
[upstart]: http://upstart.ubuntu.com/
[systemd]: http://www.freedesktop.org/wiki/Software/systemd/
[openrc]: http://www.gentoo.org/proj/en/base/openrc/
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
[original finit]: http://helllabs.org/finit/
[EeePC fastinit]: https://web.archive.org/web/20071208212450/http://wiki.eeeuser.com/boot_process:the_boot_process
[Claudio Matsuoka]: https://github.com/cmatsuoka
[Joachim Wiberg]: http://troglobit.com
[GitHub]: https://github.com/troglobit/finit
[License]: https://en.wikipedia.org/wiki/MIT_License
[License Badge]: https://img.shields.io/badge/License-MIT-teal.svg
[Release]: https://github.com/finit-project/finit/releases
[Release Badge]: https://img.shields.io/github/v/release/finit-project/finit
[GitHub]: https://github.com/finit-project/finit/actions/workflows/build.yml/
[GitHub Status]: https://github.com/finit-project/finit/actions/workflows/build.yml/badge.svg
[Travis]: https://travis-ci.org/troglobit/finit
[Travis Status]: https://travis-ci.org/troglobit/finit.png?branch=master
[Coverity Scan]: https://scan.coverity.com/projects/3545
[Coverity Status]: https://scan.coverity.com/projects/3545/badge.svg
[br2-finit-demo]: https://github.com/finit-project/br2-finit-demo
+71 -254
View File
@@ -1,25 +1,20 @@
AC_INIT([Finit], [4.17-rc1], [https://github.com/finit-project/finit/issues],
[finit], [https://http://finit-project.github.io/])
AC_INIT(Finit, 4.0-rc1, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
AC_CONFIG_AUX_DIR(aux)
AM_INIT_AUTOMAKE([1.11 foreign subdir-objects])
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR([src/finit.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_FILES([Makefile
contrib/Makefile
contrib/alpine/Makefile contrib/alpine/finit.d/Makefile contrib/alpine/finit.d/available/Makefile
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile contrib/debian/grub.d/Makefile
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
doc/Makefile doc/config/Makefile
libsystemd/Makefile libsystemd/libsystemd.pc
man/Makefile
doc/Makefile
plugins/Makefile
src/Makefile
system/Makefile system/10-hotplug.conf
test/test.env test/Makefile
test/lib/Makefile test/src/Makefile
tmpfiles.d/Makefile])
test/test.env
test/Makefile])
# Older versions of autoconf (<2.58) do not have AC_CONFIG_MACRO_DIR()
#m4_include([m4/plugin.m4])
@@ -36,8 +31,9 @@ AC_PROG_INSTALL
AC_PROG_MKDIR_P
# Configuration.
AC_CHECK_HEADERS([termios.h sys/ioctl.h mntent.h sys/sysmacros.h])
AC_CHECK_FUNCS([strstr getopt getmntent getmntent_r])
AC_HEADER_STDC
AC_CHECK_HEADERS([fstaby.h termios.h])
AC_CHECK_FUNCS([strstr getopt getfsenty])
# Check for uint[8,16,32]_t
AC_TYPE_UINT8_T
@@ -48,44 +44,37 @@ AC_TYPE_UINT32_T
PKG_PROG_PKG_CONFIG
# Check for required libraries
PKG_CHECK_MODULES([uev], [libuev >= 2.4.1])
PKG_CHECK_MODULES([lite], [libite >= 2.6.1])
PKG_CHECK_MODULES([uev], [libuev >= 2.2.0])
PKG_CHECK_MODULES([lite], [libite >= 2.2.0])
# Check for configured Finit features
AC_ARG_ENABLE(emergency_shell,
AS_HELP_STRING([--enable-emergency-shell], [Experimental emergency fallback at boot.
Use only for debugging very early boot problems with Finit]),,[
enable_emergency_shell=no])
AC_ARG_ENABLE(fallback_shell,
AS_HELP_STRING([--enable-fallback-shell], [Start a shell if no TTYs can start]),,[
enable_fallback_shell=no])
AC_ARG_ENABLE(auto_reload,
AS_HELP_STRING([--enable-auto-reload], [Automatic reload on any .conf change]),,[
enable_auto_reload=no])
AC_ARG_ENABLE(kernel_cmdline,
AS_HELP_STRING([--enable-kernel-cmdline], [Parse init args from /proc/cmdline (don't use!)]),,[
enable_kernel_cmdline=no])
AC_ARG_ENABLE(fastboot,
AS_HELP_STRING([--enable-fastboot], [Skip fsck check on filesystems listed in /etc/fstab]),,[
enable_fastboot=no])
AC_ARG_ENABLE(fsckfix,
AS_HELP_STRING([--enable-fsckfix], [Run fsck fix mode (options: -yf) on filesystems listed in /etc/fstab]),,[
enable_fsckfix=no])
AC_ARG_ENABLE(cgroup,
AS_HELP_STRING([--disable-cgroup], [Disable cgroup v2 support, default: autodetect from /sys/fs/cgroup]),,[
enable_cgroup=yes])
AC_ARG_ENABLE(libcap,
AS_HELP_STRING([--disable-libcap], [Disable Linux capabilities support]),,[
enable_libcap=yes])
AC_ARG_ENABLE(watchdog,
AS_HELP_STRING([--enable-watchdog], [Enable built-in watchdog, uses /dev/watchdog]),,[
enable_watchdog=no])
AC_ARG_ENABLE(redirect,
AS_HELP_STRING([--disable-redirect], [Disable redirection of service output to /dev/null]),,[
enable_redirect=yes])
AS_HELP_STRING([--enable-redirect], [Redirect service output to /dev/null, default: no]),,[
enable_redirect_output=no])
AC_ARG_ENABLE(kernel_logging,
AS_HELP_STRING([--disable-kernel-logging], [Disable kernel logging to console (use 'quiet' instead!]),,[
enable_kernel_logging=yes])
AC_ARG_ENABLE(logit,
AS_HELP_STRING([--disable-logit], [Disable logit, used for log redirection, default: enable]),,[
enable_logit=yes])
AC_ARG_ENABLE(logrotate,
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp]),,[
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp, default enabled]),,[
enable_logrotate=yes])
AC_ARG_ENABLE(doc,
@@ -96,40 +85,19 @@ AC_ARG_ENABLE(contrib,
AS_HELP_STRING([--disable-contrib], [Disable build and install of contrib section]),,[
enable_contrib=yes])
AC_ARG_ENABLE([rescue],
AS_HELP_STRING([--disable-rescue], [Disable potentially unsafe rescue mode]),,
[enable_rescue=yes])
# Check for extra plugins to enable
AC_ARG_ENABLE(all_plugins,
AS_HELP_STRING([--enable-all-plugins], [Enable all plugins, default: auto]),
enable_all_plugins=$enableval, enable_all_plugins=auto)
enable_all_plugins=auto
AC_PLUGIN([alsa-utils], [no], [Save and restore ALSA sound settings using alsactl])
AC_PLUGIN([dbus], [no], [Setup and start system message bus, D-Bus])
AC_PLUGIN([modules-load], [no], [Scans /etc/modules-load.d for modules to load])
AC_PLUGIN([modprobe], [no], [Coldplug modules using modalias magic])
AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
AC_PLUGIN([x11-common], [no], [Console setup (for X)])
AC_PLUGIN([netlink], [yes], [Basic netlink plugin for IFUP/IFDN and GW events. Can be replaced with externally built plugin that links with libnl or similar.])
AC_PLUGIN([hook-scripts], [no], [Trigger script execution from hook points])
AC_PLUGIN([hotplug], [yes], [Start udevd or mdev kernel event datamon])
AC_PLUGIN([rtc], [yes], [Save and restore RTC using hwclock])
AC_PLUGIN([tty], [yes], [Automatically activate new TTYs, e.g. USB-to-serial])
AC_PLUGIN([urandom], [yes], [Setup and save random seed at boot/shutdown])
AC_PLUGIN([plymouth], [no], [Plymouth boot splash integration])
AC_PLUGIN([testserv], [no], [Test plugin to start test serv daemon])
AC_PLUGIN([hotplug], [yes], [Setup and start udev or mdev hotplug daemon])
# Check for extra arguments or packages
AC_ARG_WITH([bash-completion-dir],
AS_HELP_STRING([--with-bash-completion-dir[=PATH]], [Directory to install Bash completion, default: auto]),
[bash_dir=$withval], [bash_dir=yes])
AC_ARG_WITH(fstab,
AS_HELP_STRING([--with-fstab=FILE], [System default fstab, default $sysconfdir/fstab]),
[fstab=$withval], [fstab=yes])
AC_ARG_WITH(heading,
AS_HELP_STRING([--with-heading=GREET], [Heading for boot progress. Default: PRETTY_NAME from /etc/os-release, fallback to "Finit vX.YY"]),
AS_HELP_STRING([--with-heading=GREET], [Display GREET instead of Finit version at boot]),
[heading=$withval], [heading=yes])
AC_ARG_WITH(config,
@@ -148,108 +116,44 @@ AC_ARG_WITH(sysconfig,
AS_HELP_STRING([--with-sysconfig=DIR], [System environment directory, sourced by .conf files, default /etc/default & /etc/conf.d]),
[sysconfig=$withval], [sysconfig=default])
AC_ARG_WITH(group,
AS_HELP_STRING([--with-group=NAME], [Group for /run/finit/socket (initctl), default: root]),
[group=$withval], [group=root])
AC_ARG_WITH(hostname,
AS_HELP_STRING([--with-hostname=NAME], [If /etc/hostname is missing, default: noname]),
[hostname=$withval], [hostname=yes])
AC_ARG_WITH(runlevel,
AS_HELP_STRING([--with-runlevel=N], [Runlevel to switch to after bootstrap [1-9], default: 2]),
AS_HELP_STRING([--with-runlevel=N], [Runlevel to switch to after bootstrap, default: 2]),
[runlevel=$withval], [runlevel=yes])
AC_ARG_WITH(random-seed,
AS_HELP_STRING([--with-random-seed=FILE], [Save a random seed for /dev/urandom across reboots, default /var/lib/misc/random-seed]),
[random_seed=$withval], [random_seed=yes])
AC_ARG_WITH(keventd,
AS_HELP_STRING([--with-keventd], [Enable built-in keventd, default: no]),, [with_keventd=no])
AC_ARG_WITH(sulogin,
AS_HELP_STRING([--with-sulogin@<:@=USER@:>@], [Enable built-in sulogin, optional USER to request password for (default root), default: no.]),[sulogin=$withval],[with_sulogin=no])
AC_ARG_WITH(watchdog,
AS_HELP_STRING([--with-watchdog@<:@=DEV@:>@], [Enable built-in watchdog, default: /dev/watchdog]),
[watchdog=$withval], [with_watchdog=no watchdog=])
AC_ARG_WITH(libsystemd,
AS_HELP_STRING([--with-libsystemd], [Build replacement libsystemd library, default: yes]),
[with_libsystemd=$withval], [with_libsystemd=no])
AC_ARG_WITH(hook-scripts-path,
AS_HELP_STRING([--with-hook-scripts-path=DIR], [Base directory for hook scripts, default $libexecdir/finit/hook]),
[hook_scripts_path=$withval], [hook_scripts_path=yes])
AC_ARG_WITH(plugin-path,
AS_HELP_STRING([--with-plugin-path=DIR], [Search path for external plugins, default /usr/lib/finit/plugins:/usr/local/lib/finit/plugins]),
[plugin_path=$withval], [plugin_path=yes])
AC_ARG_WITH(rtc-date,
AS_HELP_STRING([--with-rtc-date=DATE], [If RTC date/time is too old, restore to DATE, format "YYYY-MM-DD HH:MM:SS", default "2000-01-01 00:00:00"]),
[rtc_date=$withval], [rtc_date=no])
AC_ARG_WITH(rtc-file,
AS_HELP_STRING([--with-rtc-file=FILE], [If RTC is missing, save and restore system clock from this file, default: no]),
[rtc_file=$withval], [rtc_file=no])
### Enable features ###########################################################################
# Create config.h from selected features and fallback defaults
# Create config.h from selected features and fallback defautls
AS_IF([test "x$enable_emergency_shell" = "xyes"], [
AC_DEFINE(EMERGENCY_SHELL, 1, [Fork off init and let PID 1 wait and start /bin/sh if init crashes.])])
AS_IF([test "x$enable_fallback_shell" = "xyes"], [
AC_DEFINE(FALLBACK_SHELL, 1, [Start /bin/sh on console if no TTYs.])])
AS_IF([test "x$enable_auto_reload" = "xyes"], [
AC_DEFINE(AUTO_RELOAD, 1, [Finit automatically does `initctl reload` on any .conf change])])
AS_IF([test "x$enable_kernel_cmdline" = "xyes"], [
AC_DEFINE(KERNEL_CMDLINE, 1, [Dumpster diving after init args from /proc/cmdline])])
AS_IF([test "x$enable_kernel_logging" = "xyes"], [
AC_DEFINE(KERNEL_LOGGING, 1, [Keep kernel warn/err logs to console])])
AS_IF([test "x$enable_cgroup" = "xyes"], [
AC_DEFINE(CGROUP2_ENABLED, 1, [Autodetect cgroup v2 support from /sys/fs/cgroup])])
AS_IF([test "x$enable_libcap" = "xyes"], [
AC_CHECK_LIB([cap], [cap_from_text], [
AC_DEFINE(HAVE_LIBCAP, 1, [Have libcap for Linux capabilities support])
LIBS="$LIBS -lcap"
], [
AC_MSG_WARN([libcap not found, capabilities support disabled])
enable_libcap=no
])
])
AS_IF([test "x$enable_fastboot" = "xyes"], [
AC_DEFINE(FAST_BOOT, 1, [Skip fsck check on filesystems listed in /etc/fstab])])
AS_IF([test "x$enable_fsckfix" = "xyes"], [
AC_DEFINE(FSCK_FIX, 1, [Run fsck fix mode (options: -yf) on filesystems listed in /etc/fstab])])
AS_IF([test "x$enable_watchdog" = "xyes"], [
AC_DEFINE(BUILTIN_WATCHDOG, 1, [Enable built-in watchdog, kicks on /dev/watchdog])])
AS_IF([test "x$enable_redirect" = "xyes"], [
AC_DEFINE(REDIRECT_OUTPUT, 1, [Enable redirection of service output to /dev/null])])
### Disable features ###########################################################################
AS_IF([test "x$enable_logit" != "xno"], [
AC_DEFINE(LOGIT_ENABLED, 1, [Enable logit tool, used for log redirection by Finit])])
AS_IF([test "x$enable_logrotate" != "xno"], [
AC_DEFINE(LOGROTATE_ENABLED, 1, [Enable built-in rotation of /var/log/wtmp et al.])])
AS_IF([test "x$enable_rescue" != "xno"], [
AC_DEFINE([RESCUE_MODE], 1, [Define to enable support for rescue mode.])])
AM_CONDITIONAL(LOGROTATE, [test "x$enable_logrotate" = "xyes"])
### With features ##############################################################################
AS_IF([test "x$bash_dir" = "xyes"], [
PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0],
[BASH_DIR="$(pkg-config --variable=completionsdir bash-completion)"],
[BASH_DIR="$datadir/bash-completion/completions"])], [
BASH_DIR="$bash_dir"])
AS_IF([test "x$with_fstab" != "xno"], [
AS_IF([test "x$fstab" = "xyes"], [fstab=$sysconfdir/fstab])
AC_EXPAND_DIR(fstab_path, "$fstab")
AC_DEFINE_UNQUOTED(FINIT_FSTAB, "$fstab_path", [Built-in default: /etc/fstab])],[
AC_DEFINE_UNQUOTED(FINIT_FSTAB, NULL, [No built-in default fstab])])
AS_IF([test "x$with_config" != "xno"], [
AS_IF([test "x$conf" = "xyes"], [
conf=$sysconfdir/finit.conf])])
@@ -265,9 +169,10 @@ AC_DEFINE_UNQUOTED(FINIT_RCSD, "$rcsd_path", [Finit rcS.d/, default /etc/finit.d
AC_SUBST(FINIT_RCSD, "$rcsd_path")
AS_IF([test "x$with_rc_local" != "xno"], [
AS_IF([test "x$rclocal" = "xyes"], [rclocal=$sysconfdir/rc.local])
AC_EXPAND_DIR(rclocal_path, "$rclocal")
AC_DEFINE_UNQUOTED(FINIT_RC_LOCAL, "$rclocal_path", [Compat SysV /etc/rc.local file to run last at boot.])])
AS_IF([test "x$rclocal" = "xyes"], [
rclocal=$sysconfdir/rc.local])])
AC_EXPAND_DIR(rclocal_path, "$rclocal")
AC_DEFINE_UNQUOTED(FINIT_RC_LOCAL, "$rclocal_path", [Compat SysV /etc/rc.local file to run last at boot.])
AS_IF([test "x$with_sysconfig" != "xno"], [
AS_IF([test "x$sysconfig" != "xdefault"], [
@@ -276,13 +181,9 @@ AS_IF([test "x$with_sysconfig" != "xno"], [
[System environment, default /etc/default & /etc/conf.d])])])
AS_IF([test "x$with_heading" != "xno"], [
AS_IF([test "x$heading" = "xyes"], [heading=""])
AC_DEFINE_UNQUOTED(INIT_OSHEADING, "$heading", [Displayed by Finit at boot, defaults to /etc/os-release PRETTY_NAME])])
AS_IF([test "x$with_group" != "xno"], [
AS_IF([test "x$group" = "xyes"], [
group=root])])
AC_DEFINE_UNQUOTED(DEFGROUP, "$group", [For /run/finit/socket])
AS_IF([test "x$heading" = "xyes"], [
heading="$PACKAGE_NAME v$PACKAGE_VERSION"])])
AC_DEFINE_UNQUOTED(INIT_HEADING, "$heading", [Displayed by Finit at boot])
AS_IF([test "x$with_hostname" != "xno"], [
AS_IF([test "x$hostname" = "xyes"], [
@@ -301,100 +202,30 @@ AS_IF([test "x$with_random_seed" != "xno"], [
AC_EXPAND_DIR(random_path, "$random_seed")
AC_DEFINE_UNQUOTED(RANDOMSEED, "$random_path", [Improve random at boot by seeding it with sth from before.])])
AS_IF([test "x$rtc_date" != "xno"], [
AC_DEFINE_UNQUOTED(RTC_TIMESTAMP_CUSTOM, "$rtc_date", [Custom RTC restore date, default: 2000-01-01 00:00])], [
rtc_date=""])
AS_IF([test "x$rtc_file" != "xno"], [
AS_IF([test "x$rtc_file" = "xyes"], [
rtc_file=/var/lib/misc/rtc])
AC_EXPAND_DIR(rtcfile_path, "$rtc_file")
AC_DEFINE_UNQUOTED(RTC_FILE, "$rtcfile_path", [Save and restore system time from this file if /dev/rtc is missing.])],[
AC_DEFINE_UNQUOTED(RTC_FILE, NULL)])
AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes])
AS_IF([test "x$with_sulogin" != "xno"], [
AS_IF([test "x$sulogin" = "xyes"], [
sulogin=root])
with_sulogin=yes
AC_DEFINE_UNQUOTED(SULOGIN_USER, "$sulogin", [Built-in sulogin user, default: root])], [
sulogin=])
AS_IF([test "x$with_watchdog" != "xno"], [
AS_IF([test "x$watchdog" = "xyes"], [
watchdog=/dev/watchdog])
with_watchdog=yes
AC_DEFINE_UNQUOTED(WDT_DEVNODE, "$watchdog", [Built-in watchdog device node])], [
watchdog=])
AS_IF([test "x$with_libsystemd" != "xno"], [
AC_DEFINE(HAVE_LIBSYSTEMD, 1, [Build replacement libsystemd library support])])
AS_IF([test "x$enable_hook_scripts_plugin" != "xno"], [
AS_IF([test "x$hook_scripts_path" = "xyes"], [hook_scripts_path=$libexecdir/finit/hook])
AC_EXPAND_DIR(hook_scripts_path, "$hook_scripts_path")
AC_DEFINE_UNQUOTED(PLUGIN_HOOK_SCRIPTS_PATH, "$hook_scripts_path", [Built-in default: $libexecdir/finit])])
AS_IF([test "x$with_plugin_path" != "xno"], [
AS_IF([test "x$plugin_path" = "xyes"], [plugin_path=/usr/lib/finit/plugins:/usr/local/lib/finit/plugins])
AC_EXPAND_DIR(plugin_path, "$plugin_path")
AC_DEFINE_UNQUOTED(EXTERNAL_PLUGIN_PATH, "$plugin_path", [Built-in default: /usr/lib/finit/plugins:/usr/local/lib/finit/plugins])])
# Control build with automake flags
AM_CONDITIONAL(BASH, [test "x$bash_dir" != "xno"])
AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"])
AM_CONDITIONAL(KEVENTD, [test "x$with_keventd" != "xno"])
AM_CONDITIONAL(SULOGIN, [test "x$with_sulogin" != "xno"])
AM_CONDITIONAL(WATCHDOGD, [test "x$with_watchdog" != "xno"])
AM_CONDITIONAL(LIBSYSTEMD, [test "x$with_libsystemd" != "xno"])
AM_CONDITIONAL(DOC, [test "x$enable_doc" = "xyes"])
AM_CONDITIONAL(CONTRIB, [test "x$enable_contrib" = "xyes"])
AM_CONDITIONAL(TESTSERV, [test "x$enable_testserv_plugin" = "xyes"])
# Workaround for as-of-yet unreleased runstatedir support, planned for
# autoconf 2.70, which some major distros have backported.
AS_IF([test -z "$runstatedir"], runstatedir="$localstatedir/run")
AC_SUBST(runstatedir)
AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"])
AM_CONDITIONAL(WATCHDOGD, [test "x$enable_watchdog" = "xyes"])
AM_CONDITIONAL(LOGIT, [test "x$enable_logit" = "xyes"])
AM_CONDITIONAL(DOC, [test "x$enable_doc" = "xyes"])
AM_CONDITIONAL(CONTRIB, [test "x$enable_contrib" = "xyes"])
# Override default libdir, used for plugins and rescue.conf
pkglibdir=$libdir/finit
AC_SUBST(pkglibexecdir)
AC_EXPAND_DIR(pkglibexecdir, "$libexecdir/finit")
AC_DEFINE_UNQUOTED(FINIT_EXECPATH_, "$pkglibexecdir", [Finit libexec path])
AC_EXPAND_DIR(finit_runpath, "$runstatedir/finit/system")
AC_DEFINE_UNQUOTED(FINIT_RUNPATH_, "$finit_runpath", [Finit runtime dynamic system services])
AC_DEFINE_UNQUOTED(FINIT_LIBPATH_, "$pkglibexecdir", [Finit libexec path])
AC_EXPAND_DIR(plugin_path, "$pkglibdir/plugins")
AC_EXPAND_DIR(plugin_path, "$libdir/finit/plugins")
AC_SUBST(plugin_path)
AC_DEFINE_UNQUOTED(PLUGIN_PATH, "$plugin_path", [Finit plugin path])
AC_EXPAND_DIR(tmpfiles_path, "$libdir/tmpfiles.d")
AC_SUBST(tmpfiles_path)
AC_DEFINE_UNQUOTED(TMPFILES_PATH_, "$tmpfiles_path", [Main tmpfiles.d/, override in /etc])
AC_EXPAND_DIR(finit_tmpfiles, "$pkglibdir/tmpfiles.d")
AC_SUBST(finit_tmpfiles)
AC_DEFINE_UNQUOTED(FINIT_TMPFILES, "$finit_tmpfiles", [Finit tmpfiles.d/ .conf path])
AC_EXPAND_DIR(system_path, "$pkglibdir/system")
AC_SUBST(system_path)
AC_DEFINE_UNQUOTED(FINIT_SYSPATH_, "$system_path", [Static services, previously generated at runtime by plugins])
AC_EXPAND_DIR(rescue_conf, "$pkglibdir/rescue.conf")
AC_EXPAND_DIR(rescue_conf, "$libdir/finit/rescue.conf")
AC_DEFINE_UNQUOTED(RESCUE_CONF, "$rescue_conf", [Finit rescue mode .conf])
AC_EXPAND_DIR(sample_conf, "$pkglibdir/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_EXPAND_DIR(bash_completion_dir, "$BASH_DIR")
AC_SUBST(BASH_DIR, "$bash_completion_dir")
AS_IF([test "$heading" = ""], [heading="<DEFAULT>"])
AS_IF([test "$heading" = "no"], [heading="<NONE>"])
RTC_DATE=$rtc_date
AS_IF([test "$rtc_date" = ""], [RTC_DATE="<DEFAULT>"])
AS_IF([test "$rtc_date" = "no"], [RTC_DATE="<DEFAULT>"])
AC_EXPAND_DIR(path_stdpath, "$sbindir:$bindir:/usr/sbin:/usr/bin:/sbin:/bin")
AC_DEFINE_UNQUOTED(_PATH_STDPATH, "$path_stdpath", [Default PATH])
# Generate all files
AC_OUTPUT
@@ -403,16 +234,14 @@ cat <<EOF
------------------ Summary ------------------
$PACKAGE_NAME version $PACKAGE_VERSION
Prefix................: $(eval echo $prefix)
Exec prefix...........: $(eval echo $exec_prefix)
Libdir................: $(eval echo $libdir)
Prefix................: $prefix
Exec prefix...........: `eval echo $exec_prefix`
Sysconfdir............: `eval echo $sysconfdir`
Localstatedir.........: `eval echo $localstatedir`
Default fstab.........: `eval echo $fstab`
Finit config file.....: $conf_path
Finit config.d path...: $rcsd_path
Finit plugin path.....: $plugin_path
Compat rc.local path..: `eval echo $rclocal`
Compat rc.local path..: $rclocal_path
System environment....: ${sysconfig_path:-${sysconfig}}
Random seed path......: $random_path
C Compiler............: $CC $CFLAGS $CPPFLAGS $LDFLAGS $LIBS
@@ -421,28 +250,16 @@ cat <<EOF
Behavior:
Boot heading..........: $heading
Plugins...............: $plugins
RTC restore date......: $RTC_DATE
RTC fallback file.....: $rtc_file
Optional features:
Install doc/..........: $enable_doc
Install contrib/......: $enable_contrib
Bash completion.......: $bash_completion_dir
Built-in keventd......: $with_keventd
Built-in sulogin......: $with_sulogin $sulogin
Built-in watchdogd....: $with_watchdog $watchdog
Built-in watchdogd....: $enable_watchdog
Built-in logrotate....: $enable_logrotate
Replacement libsystemd: $with_libsystemd
Use cgroup v2.........: $enable_cgroup
Use libcap............: $enable_libcap
Parse kernel cmdline..: $enable_kernel_cmdline
Keep kernel logging...: $enable_kernel_logging
Skip fsck check.......: $enable_fastboot
Run fsck fix mode.....: $enable_fsckfix
Redirect output.......: $enable_redirect
Rescue mode...........: $enable_rescue
Scripting tool logit..: $enable_logit
Emergency shell.......: $enable_emergency_shell
Fallback shell........: $enable_fallback_shell
Default hostname......: $hostname
Default group.........: $group
Default runlevel......: $runlevel
------------- Compiler version --------------
-5
View File
@@ -3,8 +3,3 @@ bin_SCRIPT = service
docsdir := @docdir@/contrib
docs_DATA = README.md finit.conf procmon.sh
EXTRA_DIST = $(docs_DATA)
if BASH
bashdir = $(BASH_DIR)
dist_bash_DATA = initctl
endif
-1
View File
@@ -6,7 +6,6 @@ install and try out Finit on various Linux distributions.
* [Alpine](alpine/)
* [Debian](debian/)
* [Void](void/)
If you have ideas on how to simplify, extend, or even add new example
configurations for other distributions you are most welcome! :)
+1 -1
View File
@@ -1,5 +1,5 @@
SUBDIRS = finit.d
docsdir := @docdir@/contrib/alpine
docs_DATA = README.md finit.conf build.sh install.sh rc.local
docs_DATA = README.md finit.conf alpine-release build.sh install.sh rc.local
EXTRA_DIST = $(docs_DATA)
+2 -5
View File
@@ -1,8 +1,5 @@
HowTo: Finit on Alpine Linux 3.4...3.19
=======================================
> [!TIP]
> https://troglobit.com/post/2021-02-12-alpine-linux-with-finit/
HowTo: Finit on Alpine Linux 3.4-3.6
====================================
HowTo use Finit to boot an [Alpine Linux][] system. It is assumed that
the user has already installed make, a compiler, C library header files,
+1
View File
@@ -0,0 +1 @@
3.6.2
+3 -2
View File
@@ -17,8 +17,8 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
--prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--enable-dbus-plugin --enable-x11-common-plugin \
--enable-alsa-utils-plugin --without-watchdog \
--with-keventd --with-sulogin
--enable-alsa-utils-plugin --enable-watchdog \
--with-heading="Alpine Linux 3.13"
echo
echo "*** Building ..."
@@ -35,3 +35,4 @@ fi
echo
echo "*** Done"
echo
+1 -17
View File
@@ -5,22 +5,6 @@
# Default is 2
#runlevel 2
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
#cgroup init cpu.weight:100
#cgroup user cpu.weight:100
#cgroup system cpu.weight:9700
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
#task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
#task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
## Bootstrap services and tasks
# Can be listed here or in /etc/finit.d/*.conf
+2 -1
View File
@@ -1,7 +1,8 @@
SUBDIRS = available
docsdir := @docdir@/contrib/alpine/finit.d
d_LINKS = acpid.conf crond.conf dropbear.conf getty.conf \
keymap.conf modules.conf ntpd.conf syslogd.conf
keymap.conf modules.conf ntpd.conf \
klogd.conf syslogd.conf
install-exec-hook:
@$(MKDIR_P) $(DESTDIR)$(docsdir)/available
+2 -1
View File
@@ -1,4 +1,5 @@
docsdir := @docdir@/contrib/alpine/finit.d/available
docs_DATA = acpid.conf crond.conf dropbear.conf getty.conf keymap.conf \
lxdm.conf modules.conf ntpd.conf syslogd.conf watchdog.conf
lxdm.conf modules.conf ntpd.conf klogd.conf syslog.conf \
watchdog.conf
EXTRA_DIST = $(docs_DATA)
+3 -4
View File
@@ -1,5 +1,4 @@
# Consoles to start getty on when system is up
tty [12345] /dev/ttyS0 noclear
tty [12345] /dev/tty1 noclear nowait
tty [2345] /dev/tty2 noclear nowait
tty [2345] /dev/tty3 noclear nowait
tty [12345] /dev/tty1 noclear nowait
tty [2345] /dev/tty2 noclear nowait
tty [2345] /dev/tty3 noclear nowait
@@ -0,0 +1,2 @@
# Start klogd as soon as possible, after syslogd, should always run
service [S12345] <pid/syslogd> env:-/etc/conf.d/klogd klogd -n $KLOGD_OPTS -- Kernel log daemon
@@ -4,4 +4,3 @@
#module evdev
#module mousedev
#module 8139cp
#module softdog
@@ -0,0 +1,2 @@
# Start syslogd as soon as possible, should always run
service [S12345] env:-/etc/conf.d/syslog syslogd -n $SYSLOGD_OPTS -- Syslog daemon
@@ -1,4 +0,0 @@
# Start syslogd as soon as possible, should always run
# Start klogd as soon as possible, but after syslogd
service [S12345] env:-/etc/conf.d/syslog syslogd -n $SYSLOGD_OPTS -- Syslog daemon
service [S12345] <pid/syslogd> env:-/etc/conf.d/klogd klogd -n $KLOGD_OPTS -- Kernel log daemon
+28 -35
View File
@@ -1,53 +1,44 @@
#!/bin/sh
if [ "$(id -u)" != "0" ]; then
printf "\n\e[1m*** This script must run as root\e[0m\n\n"
if [ "x`id -u`" != "x0" ]; then
echo
echo "*** This script must run as root"
echo
exit 1
fi
# shellcheck disable=SC3037,SC3045,SC2154
yorn()
{
printf "\e[1m> %s (y/N)?\e[0m " "$*"
read -rn1 yorn
echo
if [ "$yorn" = "y" ] || [ "$yorn" = "Y" ]; then
return 0
fi
return 1
}
# Adjust base directory
if grep -q contrib/alpine Makefile 2>/dev/null; then
if [ -e alpine-release ]; then
cd ../..
fi
if [ ! -e configure.ac ]; then
printf "\n\e[1m*** Please run this script from the Finit base directory.\e[0m\n"
elif [ ! -e autogen.sh ]; then
echo "*** Please run this script from the Finit base directory."
exit 1
fi
printf "\n\e[1mInstall Finit on Alpine Linux\n"
printf "========================================================================\e[0m\n"
printf "/sbin/finit - PID 1\n"
printf "/lib/finit/plugins/* - All enabled Finit plugins\n"
printf "/etc/finit.conf - Finit configuration file\n"
printf "/etc/finit.d/ - Finit services\n"
echo
echo "*** Install Finit on Alpine Linux"
echo "========================================================================"
echo "/sbin/finit - PID 1"
echo "/lib/finit/plugins/* - All enabled Finit plugins"
echo "/etc/finit.conf - Finit configuration file"
echo "/etc/finit.d/ - Finit services"
echo
read -p "Do you want to continue (y/N)? " yorn
if yorn "Do you want to continue"; then
printf "\n\e[1m*** Installing Finit files ...\e[0m\n"
if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
echo
echo "*** Installing Finit files ..."
make install
cd /usr/share/doc/finit/contrib/alpine || exit 1
cd /usr/share/doc/finit/contrib/alpine
for file in finit.conf rc.local; do
install -vbD $file /etc/$file
done
cp -va finit.d /etc/
if yorn "Install Finit as the system default Init"; then
printf "\e[1m*** Updating /sbin/init symlink --> finit ...\e[0m\n"
cd /sbin || exit 1
read -p "*** Install Finit as the system default Init (y/N)? " yorn
if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
echo "*** Updating /sbin/init symlink --> finit ..."
cd /sbin
rm init
ln -s finit init
@@ -56,8 +47,10 @@ if yorn "Do you want to continue"; then
ln -s reboot shutdown
ln -s reboot suspend
fi
printf "\n\e[1m*** Done\e[0m\n"
echo "*** Done"
echo
else
printf "\n\e[1m*** Aborting install.\e[0m\n\n"
echo
echo "*** Aborting install."
echo
fi
+1 -1
View File
@@ -4,5 +4,5 @@
#
# Each line is run in sequence.
#
# NOTE: Remember to set the executable bit!
# NOTE: Remeber to set the executable bit!
#
+2 -2
View File
@@ -1,4 +1,4 @@
SUBDIRS = finit.d
SUBDIRS = finit.d grub.d
docsdir := @docdir@/contrib/debian
docs_DATA = README.md finit.conf build.sh install.sh
docs_DATA = README.md finit.conf os-release build.sh install.sh
EXTRA_DIST = $(docs_DATA)
+7 -22
View File
@@ -20,44 +20,29 @@ tools pre-systemd work as intended.
root@debian:~# apt install initscripts console-setup
> [!TIP]
> As of Debian 11 (Bullseye), libuev and libite are part of the main
> section of Debian. So just install the -dev packages :)
The following script can then be used to configure, build, install and
set up your system to run Finit:
user@debian:~/finit$ contrib/debian/build.sh
However, since `/sbin/init` already exists on your system, the script
creates another entry in your GRUB config by updating `$SUPPORTED_INITS`
in `/etc/grub.d/10_inux` and run `update-grub`. On reboot you will find
a (finit) entry in the "Advanced options for Debian GNU/Linux" section.
It is of course also possible to change the default init to Finit:
creates another entry in your GRUB config, in `/etc/grub.d/40_custom`,
where `init=/sbin/finit` is added to your kernel line. It is of course
also possible to change the default init to Finit, if you do you can
remove the custom Grub entry:
user@debian:~/finit# cd /sbin
user@debian:/sbin# sudo mv init oldinit
user@debian:/sbin# sudo rm init
user@debian:/sbin# sudo ln -s finit init
Before rebooting, check the default [/etc/finit.conf](finit.conf) and
`/etc/finit.d/*.conf` files. The build + install script above provides
a few sample `.conf` files. See `initctl ls` after boot for a list of
enabled and available services, you can then use `enable` and `disable`
comands to `initctl`, followed by `reload` to activate your changes.
a few sample `.conf` files. See `initctl list` after boot for a list of
enabled and available services.
You can also use a standard [/etc/rc.local](rc.local) for one-shot tasks
and initialization like keyboard language etc.
> [!NOTE]
> For the X Window system, you may need to `sudo apt install elogind`
> (Bullseye and later), followed by `initctl reload` to activate it (it
> is enabled by default), and logout/login again. The elogind daemon
> ensures a regular non-root user can start and interact with an X
> session, otherwise keyboard and mouse won't work. When you're happy,
> you can enable the lightdm.conf, change the default runlevel to 3, and
> presto! you have a desktop again.
Have fun!
/Joachim ツ
+6 -2
View File
@@ -25,8 +25,9 @@ echo
--prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--enable-dbus-plugin --enable-x11-common-plugin \
--enable-alsa-utils-plugin --with-keventd \
--with-random-seed=/var/lib/urandom/random-seed
--enable-alsa-utils-plugin \
--with-random-seed=/var/lib/urandom/random-seed \
--with-heading="Debian GNU/Linux"
if [ $? -ne 0 ]; then
echo
@@ -59,3 +60,6 @@ else
echo "*** Use 'sudo contrib/debian/install.sh' later to install Finit"
echo
fi
+1 -17
View File
@@ -5,22 +5,6 @@
# Default is 2
#runlevel 2
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
#cgroup init cpu.weight:100
#cgroup user cpu.weight:100
#cgroup system cpu.weight:9700
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
#task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
#task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
## Bootstrap services and tasks
# Can be listed here or in /etc/finit.d/*.conf
+2 -4
View File
@@ -1,9 +1,7 @@
SUBDIRS = available
docsdir := @docdir@/contrib/debian/finit.d
d_LINKS = acpid.conf apparmor.conf avahi-daemon.conf \
bluetooth.conf console-setup.conf elogind.conf \
getty.conf keyboard-setup.conf modules.conf \
plymouth-quit.conf rsyslogd.conf sshd.conf
d_LINKS = console-setup.conf getty.conf keyboard-setup.conf \
modules.conf rsyslogd.conf sshd.conf
install-exec-hook:
@$(MKDIR_P) $(DESTDIR)$(docsdir)/available
+3 -6
View File
@@ -1,8 +1,5 @@
docsdir := @docdir@/contrib/debian/finit.d/available
docs_DATA = acpid.conf apparmor.conf avahi-daemon.conf bluetooth.conf \
console-setup.conf elogind.conf getty.conf \
keyboard-setup.conf lightdm.conf modules.conf sntpd.conf \
plymouth-quit.conf rsyslogd.conf sshd.conf syslogd.conf \
xdm.conf
docs_DATA = acpid.conf console-setup.conf getty.conf keyboard-setup.conf \
lightdm.conf modules.conf rsyslogd.conf sntpd.conf \
sshd.conf syslogd.conf xdm.conf
EXTRA_DIST = $(docs_DATA)
@@ -1 +0,0 @@
task [2345] <sys/pwr/ac,pid/syslogd> halt:usr1 env:-/etc/default/anacron anacron -d -q $ANACRON_ARGS -- Anacron jobs
@@ -1,2 +0,0 @@
sysv [S] /etc/init.d/apparmor -- AppArmor initialization
@@ -1 +0,0 @@
service [2345] env:-/etc/default/avahi-daemon avahi-daemon -s $AVAHI_DAEMON_OPTS -- Avahi mDNS/DNS-SD Stack
@@ -1,3 +0,0 @@
# To ignore errors like "org.freedesktop.hostname1", update the env file with
# "--noplugin=hostname", i.e. append to BLUETOOTHD_OPTS
service [2345] log:null env:-/etc/default/bluetooth /usr/libexec/bluetooth/bluetoothd -n $BLUETOOTHD_OPTS -- Bluetooth service
@@ -1 +0,0 @@
service [2345] <sys/pwr/ac,pid/syslogd> env:-/etc/default/cron cron -f $EXTRA_OPTS -- Background job processing daemon
@@ -1,4 +0,0 @@
# On some systems, bootstrap can be really quick and cause elogind
# to not start before a user has managed to log in. To prevent
# this, add <pid/elogind> as condition to your TTYs in getty.conf
service [2345] <pid/syslogd> /usr/libexec/elogind -- Login manager
+2 -5
View File
@@ -1,7 +1,4 @@
# Consoles to start getty on when system is up
tty [12345] /dev/tty1 linux noclear nowait
tty [2345] /dev/tty2 linux nowait
tty [2345] /dev/tty3 linux nowait
tty [2345] /dev/tty4 linux nowait
tty [2345] /dev/tty5 linux nowait
tty [2345] /dev/tty6 linux nowait
tty [2345] /dev/tty2 linux noclear nowait
tty [2345] /dev/tty3 linux noclear nowait
@@ -1,2 +0,0 @@
# Need to stop plymouth, or it'll block stdin on tty1
task [S] /usr/bin/plymouth quit -- Stopping Plymouth Boot Screen
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry '$MENU with Finit' --class $TYPE --class gnu-linux --class gnu --class os --user {
insmod gzio
insmod part_msdos
insmod ext2
search --no-floppy --fs-uuid --set=root $BOOT
linux /vmlinuz root=UUID=$ROOT ro quiet init=/sbin/finit
initrd /initrd.img
}
+3
View File
@@ -0,0 +1,3 @@
docsdir := @docdir@/contrib/debian/grub.d
docs_DATA = 40_custom
EXTRA_DIST = $(docs_DATA)
+9 -15
View File
@@ -8,10 +8,10 @@ if [ "x`id -u`" != "x0" ]; then
fi
# Adjust base directory
grep -q debian Makefile 2>/dev/null
grep -q Debian os-release 2>/dev/null
if [ $? -eq 0 ]; then
cd ../..
elif [ ! -e configure.ac ]; then
elif [ ! -e autogen.sh ]; then
echo "*** Please run this script from the Finit base directory."
exit 1
fi
@@ -23,7 +23,7 @@ echo "/sbin/finit - PID 1"
echo "/lib/finit/plugins/* - All enabled Finit plugins"
echo "/etc/finit.conf - Finit configuration file"
echo "/etc/finit.d/ - Finit services"
echo "/etc/grub.d/10_linux - Add Finit to Grub's SUPPORTED_INITS"
echo "/etc/grub.d/40_custom - Add menu entry to the Grub boot loader"
echo
read -p "Do you want to continue (y/N)? " yorn
echo
@@ -38,18 +38,12 @@ if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
cp -va finit.d /etc/
echo "*** Setting up a GRUB boot entry ..."
fn=/etc/grub.d/10_linux
if [ -e $fn ]; then
if `grep SUPPORTED_INITS $fn |head -1 |grep -q finit`; then
echo "Already installed, done."
else
echo "Adding Finit to list of SUPPORTED_INITS ..."
sed -i 's/SUPPORTED_INITS="[^"]*/& finit:\/sbin\/finit/' $fn
update-grub
fi
else
echo "Cannot find $fn, you'll have to set up your bootloader on your own."
fi
MENU=`grep gnu-linux /boot/grub/grub.cfg |head -1 |sed "s/menuentry '\([^']*\).*/\1/"`
TYPE=`grep gnu-linux /boot/grub/grub.cfg |head -1 |sed "s/.*' --class \([a-z]*\).*/\1/"`
BOOT=`grep set=root /boot/grub/grub.cfg |head -1 |sed 's/.* \([a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*\).*/\1/'`
ROOT=`grep root=UUID /boot/grub/grub.cfg |head -1 |sed 's/.*UUID=\([a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*\).*/\1/'`
cat grub.d/40_custom | sed "s,\$BOOT,$BOOT,;s,\$ROOT,$ROOT,;s,\$TYPE,$TYPE,;s,\$MENU,$MENU," >/etc/grub.d/40_custom
update-grub
echo
echo "*** Done"
+8
View File
@@ -0,0 +1,8 @@
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/"
+2 -37
View File
@@ -8,18 +8,6 @@ module evdev
module loop
module psmouse
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
cgroup init cpu.weight:100
cgroup user cpu.weight:100
cgroup system cpu.weight:9700 cpu.max:50000
# Example extra cgroup
cgroup maint cpu.weight:100
# Runlevel to start after bootstrap, runlevel 'S'
runlevel 2
@@ -28,21 +16,13 @@ network service networking start
# Max file size for each log file: 100 kiB, rotate max 4 copies:
# log => log.1 => log.2.gz => log.3.gz => log.4.gz
log size:100k count:4
log size=100k count=4
# Virtual consoles to start getty on
tty /dev/tty1
tty /dev/tty2
tty /dev/tty3
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
# Alternative method instead of runparts
#task [S] /etc/init.d/keyboard-setup start -- Setting up preliminary keymap
#task [S] /etc/init.d/acpid start -- Starting ACPI Daemon
@@ -50,24 +30,9 @@ task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
#run [2] /etc/init.d/networking start -- Start networking
# Services to be monitored and respawned as needed
# klgod and syslogd are placed in the maint cgroup
cgroup.maint
service [2345] <pid/syslogd> klogd -n -- Kernel logging server
service [2345] syslogd -n -- Syslog server
# gdm in the system cgroup (default when read from it's own .conf file)
cgroup.system
service [3] cgroup:cpu.weight:250,mem.max:10M gdm -- GNOME Display Manager
# Start SSH daemon with opts from /etc/default/ssh (if available), move
# to user cgroup with cpu.weight:250. Default for services is system
# group. Default weight in user group is 100 (above). Max length of
# cgroup argument is (currently) 63 chars.
#
# Notice alternative syntax where current cgroup is only set for this
# particular service.
service [2345] cgroup.user:cpu.weight:250,mem.max:10M env:-/etc/default/ssh /usr/sbin/sshd -D $SSHD_OPTS -- OpenSSH daemon
service [3] gdm -- GNOME Display Manager
# The BusyBox ntpd does not use syslog when running in the foreground
# So we use this trick to redirect stdout/stderr to a log file. The
-141
View File
@@ -1,141 +0,0 @@
_cond()
{
initctl -pt cond dump | awk '{print $4}' | sed 's/<\(.*\)>/\1/'
}
_ident()
{
if [ -n "$1" ]; then
initctl ident | grep -q $1
else
initctl ident
fi
}
_svc()
{
initctl ls -pt | grep $1 | sed "s/.*\/\(.*\)/\1/g" | sort -u
}
_enabled()
{
echo "$(_svc enabled)"
}
_available()
{
all=$(mktemp)
ena=$(mktemp)
echo "$(_svc available)" >$all
echo "$(_svc enabled)" >$ena
grep -v -f $ena $all
rm $all $ena
}
# Determine first non-option word. Usually the command
_firstword() {
local firstword i
firstword=
for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
if [[ ${COMP_WORDS[i]} != -* ]]; then
firstword=${COMP_WORDS[i]}
break
fi
done
echo $firstword
}
# Determine last non-option word. Uusally a sub-command
_lastword() {
local lastword i
lastword=
for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
if [[ ${COMP_WORDS[i]} != -* ]] && [[ -n ${COMP_WORDS[i]} ]] && [[ ${COMP_WORDS[i]} != $cur ]]; then
lastword=${COMP_WORDS[i]}
fi
done
echo $lastword
}
_initctl()
{
local cur command
cur=${COMP_WORDS[COMP_CWORD]}
prev="${COMP_WORDS[COMP_CWORD-1]}"
firstword=$(_firstword)
lastword=$(_lastword)
commands="status cond debug help kill ls log version list enable \
disable touch show cat edit create delete reload start \
stop restart signal cgroup ps top plugins runlevel reboot \
halt poweroff suspend utmp"
cond_cmds="set get clear status dump"
cond_types="hook net pid service task usr"
signals="int term hup stop tstp cont usr1 usr2 pwr"
options="-b --batch \
-c --create \
-d --debug \
-f --force \
-h --help \
-j --json \
-n --noerr \
-1 --once \
-p --plain \
-q --quiet \
-t --no-heading \
-v --verbose \
-V --version"
case "${firstword}" in
enable)
COMPREPLY=($(compgen -W "$(_available)" -- $cur))
;;
disable|touch)
COMPREPLY=($(compgen -W "$(_enabled)" -- $cur))
;;
show|cat|edit|delete)
COMPREPLY=($(compgen -W "$(_svc .)" -- $cur))
;;
start|stop|restart|log|status)
COMPREPLY=($(compgen -W "$(_ident)" -- $cur))
;;
signal|kill)
if $(_ident "${prev}"); then
COMPREPLY=($(compgen -W "$signals" -- $cur))
else
COMPREPLY=($(compgen -W "$(_ident)" -- $cur))
fi
;;
cond)
case "${lastword}" in
set|clear)
compopt -o nospace
COMPREPLY=($(compgen -W "usr/" -- $cur))
;;
get)
COMPREPLY=($(compgen -W "$(_cond)" -- $cur))
;;
dump)
COMPREPLY=($(compgen -W "$cond_types" -- $cur))
;;
*)
COMPREPLY=($(compgen -W "$cond_cmds" -- $cur))
;;
esac
;;
*)
COMPREPLY=($(compgen -W "$commands" -- $cur))
;;
esac
if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W "$options" -- $cur))
fi
}
complete -F _initctl initctl
@@ -1,75 +0,0 @@
In Finit issue #196 we were reminded [1] of a missing inotify flag in
Linux older kernels, IN_MASK_CREATE. Finit makes use of this internally
for monitoring PID conditions, and more. This is a central mechanism to
synchronize services at boot and reload at runtime.
The following patch for Linux 4.9.0, was provided by Andy Savage for
other people that may want to run Finit on slightly older kernels.
[1]: https://github.com/troglobit/finit/issues/196
Index: fs/notify/inotify/inotify_user.c
===================================================================
--- fs.orig/notify/inotify/inotify_user.c
+++ fs/notify/inotify/inotify_user.c
@@ -522,6 +522,7 @@ static int inotify_update_existing_watch
__u32 old_mask, new_mask;
__u32 mask;
int add = (arg & IN_MASK_ADD);
+ int create = (arg & IN_MASK_CREATE);
int ret;
mask = inotify_arg_to_mask(arg);
@@ -529,6 +530,8 @@ static int inotify_update_existing_watch
fsn_mark = fsnotify_find_inode_mark(group, inode);
if (!fsn_mark)
return -ENOENT;
+ else if (create)
+ return -EEXIST;
i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
@@ -726,6 +729,10 @@ SYSCALL_DEFINE3(inotify_add_watch, int,
if (unlikely(!f.file))
return -EBADF;
+ /* IN_MASK_ADD and IN_MASK_CREATE don't make sense together */
+ if (unlikely((mask & IN_MASK_ADD) && (mask & IN_MASK_CREATE)))
+ return -EINVAL;
+
/* verify that this is indeed an inotify instance */
if (unlikely(f.file->f_op != &inotify_fops)) {
ret = -EINVAL;
@@ -814,7 +821,7 @@ static int __init inotify_user_setup(voi
BUILD_BUG_ON(IN_ISDIR != FS_ISDIR);
BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT);
- BUG_ON(hweight32(ALL_INOTIFY_BITS) != 21);
+ BUG_ON(hweight32(ALL_INOTIFY_BITS) != 22);
inotify_inode_mark_cachep = KMEM_CACHE(inotify_inode_mark, SLAB_PANIC);
Index: include/linux/inotify.h
===================================================================
--- include.orig/linux/inotify.h
+++ include/linux/inotify.h
@@ -17,6 +17,6 @@ extern struct ctl_table inotify_table[];
IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | \
IN_Q_OVERFLOW | IN_IGNORED | IN_ONLYDIR | \
IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD | \
- IN_ISDIR | IN_ONESHOT)
+ IN_MASK_CREATE | IN_ISDIR | IN_ONESHOT)
#endif /* _LINUX_INOTIFY_H */
Index: include/uapi/linux/inotify.h
===================================================================
--- include.orig/uapi/linux/inotify.h
+++ include/uapi/linux/inotify.h
@@ -52,6 +52,7 @@ struct inotify_event {
#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
#define IN_EXCL_UNLINK 0x04000000 /* exclude events on unlinked objects */
+#define IN_MASK_CREATE 0x10000000 /* only create watches */
#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */
#define IN_ISDIR 0x40000000 /* event occurred against dir */
#define IN_ONESHOT 0x80000000 /* only send event once */
+1 -1
View File
@@ -1,4 +1,4 @@
SUBDIRS = finit.d
docsdir := @docdir@/contrib/void
docs_DATA = README.md finit.conf build.sh install.sh rc.local
docs_DATA = README.md finit.conf build.sh install.sh rc.local xbps
EXTRA_DIST = $(docs_DATA)
+3 -2
View File
@@ -17,8 +17,8 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
--prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--enable-dbus-plugin --enable-x11-common-plugin \
--enable-alsa-utils-plugin --with-watchdog \
--with-keventd --with-sulogin
--enable-alsa-utils-plugin --enable-watchdog \
--with-heading="Void Linux"
echo
echo "*** Building ..."
@@ -35,3 +35,4 @@ fi
echo
echo "*** Done"
echo
-17
View File
@@ -5,22 +5,5 @@
# Default is 2
#runlevel 2
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
#cgroup init cpu.weight:100
#cgroup user cpu.weight:100
#cgroup system cpu.weight:9700
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
#task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
#task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
## Bootstrap services and tasks
# Can be listed here or in /etc/finit.d/*.conf
+2 -2
View File
@@ -1,5 +1,5 @@
docsdir := @docdir@/contrib/void/finit.d/available
docs_DATA = acpid.conf crond.conf dhcpcd.conf dmeventd.conf getty.conf \
keymap.conf lxdm.conf modules.conf ntpd.conf \
sshd.conf syslog.conf uuidd.conf
keymap.conf klogd.conf lxdm.conf modules.conf ntpd.conf \
sshd.conf syslogd.conf uuidd.conf
EXTRA_DIST = $(docs_DATA)
@@ -0,0 +1,2 @@
# Start klogd as soon as possible, should always run
service [S12345] <pid/syslogd> klogd -n -- Kernel log daemon
@@ -4,4 +4,3 @@
#module evdev
#module mousedev
#module 8139cp
module softdog
@@ -1,4 +0,0 @@
# Start syslogd as soon as possible, should always run
# Start klogd as soon as possible, but after syslogd
service [S12345] syslogd -n -- Syslog daemon
service [S12345] <pid/syslogd> klogd -n -- Kernel log daemon
@@ -0,0 +1,2 @@
# Start syslogd as soon as possible, should always run
service [S12345] syslogd -n -- Syslog daemon
+2 -3
View File
@@ -8,10 +8,9 @@ if [ "x`id -u`" != "x0" ]; then
fi
# Adjust base directory
grep -q void Makefile 2>/dev/null
if [ $? -eq 0 ]; then
if [ -e xbps ]; then
cd ../..
elif [ ! -e configure.ac ]; then
elif [ ! -e autogen.sh ]; then
echo "*** Please run this script from the Finit base directory."
exit 1
fi
+1 -1
View File
@@ -4,4 +4,4 @@
#
# Each line is run in sequence.
#
# NOTE: Remember to set the executable bit!
# NOTE: Remeber to set the executable bit!
-2054
View File
File diff suppressed because it is too large Load Diff
+4 -11
View File
@@ -1,11 +1,4 @@
SUBDIRS = config
EXTRA_DIST = AUTHORS ChangeLog.md
docsdir := @docdir@/doc
dist_docs_DATA = build.md cmdline.md commands.md conditions.md \
distro.md example.md features.md index.md initctl.md \
keventd.md plugins.md requirements.md runlevels.md \
runparts.md service.md signals.md state-machine.md \
watchdog.md
dist_docs_DATA += img/logo.png img/svc-machine.png img/svc-machine.svg \
img/alpine-screenshot2.png
docsdir := @docdir@/doc
docs_DATA = config.md conditions.md distro.md plugins.md \
service.md signals.md svc-machine.png cmdline.md
EXTRA_DIST = $(docs_DATA)
+1 -1
View File
@@ -1 +1 @@
index.md
config.md
+6 -18
View File
@@ -19,31 +19,19 @@ Some of these are also registered in the issue tracker on GitHub.
* Add new (complimentary) .svc file format to slowly migrate away
from the very terse one-liner format currently used
* Allow running as non-pid1 => read .conf and RCSD form cmdline
* When a process dies, and Finit does not restart it, we should collect
a `siginfo_t` from the SIGCHLD signal and supply to the user in case
`initctl status <process>` is called to debug the issue.
* Add `finit.conf` support for UPS notification (SIGPWR) to start a task
using, e.g. <sys/power/{ok,fail,low}> conditions. More info in sig.c
As of Finit v4.1 SIGPWR generates <sys/power/fail> condition and it
is up to a task to check why and take appropriate action.
* Add `finit.conf` support for ctrl-alt-delete (SIGINT) and kbrequest,
i.e. KeyboardSignal, (SIGWINCH) behavior. Using conditions to a task,
e.g, <sys/key/ctrlaltdel> and <sys/key/signal> like SIGPWR handling.
As of Finit v4.1 SIGINT generates <sys/key/ctrlaltdel>, but there is
no check if the signal actually originates from the kernel. To get
this verification, a new libuEv release is needed. As of June 6 -21
that functionality is not yet released.
Initctl
-------
* Add support for timed shutdown in Finit, including cancelled shutdown:
shutdown -h 03:35 "foobar was here"
* Write man pages for finit and `finit.conf`, steal from the excellent
`pimd` man pages ...
* Add support for timed shutdown in Finit, including cancelled shutdown
* Add support for JSON output, or similar, from `initctl show`, e.g.
`initctl show --json`
* Add support for `-s` to redirect all output to syslog, for scripting
Init
+56
View File
@@ -0,0 +1,56 @@
Bootstrap
=========
1. Prepare emergency shell, if enabled
2. Set up initial signal handlers
3. Set up default $PATH early
4. Mount `/proc` and `/sys`
5. Check kernel command line for `debug` to figure out log level
6. Load all `.so` plugins
7. Call `fsck` on file systems listed in `/etc/fstab`
8. Populate `/dev` using either udev or mdev, depending on system type
9. Parse `/etc/finit.conf` and all `/etc/finit.d/*.conf` files
10. Start built-in watchdog, if enabled
11. Set hostname
12. Remount `/` read-write if `/` is listed in `/etc/fstab` without `ro`
13. Call 1st level hooks, `HOOK_ROOTFS_UP`
14. Mount all file systems listed in `/etc/fstab` and swap, if available
15. Enable SysV init signals
16. Call 2nd level hooks, `HOOK_BASEFS_UP`
17. Cleanup stale files from `/tmp/*` et al, handled by `bootmisc` plugin
18. Load kernel params from `/etc/sysctl.d/*.conf`, `/etc/sysctl.conf`
et al. (Supports all locations that SysV init does.), handled by
`procps` plugin
19. Start all 'S' runlevel tasks and services
20. Bring up loopback interface and all `/etc/network/interfaces`, if
the `.conf` setting `network <SCRIPT>` is set, it is called instead
21. Call 3rd level hooks, `HOOK_NETWORK_UP`
22. If `runparts <DIR>` is set, [run-parts(8)][] is called on `<DIR>`
23. Switch to the configured runlevel from `/etc/finit.conf`, default 2.
At every runlevel change all `*.conf` files in `/etc/finit.d/` are
(re)loaded and new services, tasks, and blocking run commands are
started. Provided they are allowed in the new runlevel and all of
their conditions, if any, are set.
24. Call 4th level hooks, `HOOK_SVC_UP`
25. Call `/etc/rc.local`, if it exists and is an executable shell script
26. Call 5th level (last) hooks, `HOOK_SYSTEM_UP`
27. Start all configured TTYs, or a fallback shell on `/dev/console`
In (19) and (22) tasks and services defined in `/etc/finit.conf` and
`/etc/sysctl.d/*.conf` are started. Remember, all `service` and `task`
stanzas are started in parallel and `run` in sequence, and in the order
listed. Hence, to emulate a SysV `/etc/init.d/rcS` one could write a
long `finit.conf` with only `run` statements.
Notice the five hook points that are called at various point in the
bootstrap process. This is where plugins can extend the boot in any way
they please. There are other hook points, e.g. `HOOK_MOUNT_ERROR`, for
more on this see [plugins.md](plugins.md).
For instance, at `HOOK_BASEFS_UP` a plugin could read an XML file from a
USB stick, convert/copy its contents to the system's `/etc/` directory,
well before all 'S' runlevel tasks are started. This could be used with
system images that are created read-only and all configuration is stored
on external media.
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
+45 -63
View File
@@ -1,5 +1,15 @@
Building Finit
==============
Building
========
* [Introduction](#introduction)
* [Configure](#configure)
* [Example](#example)
* [Running](#running)
* [Debugging](#debugging)
Introduction
------------
Finit comes with a traditional configure script to control features and
optional plugins to enable. It depends on two external libraries:
@@ -7,21 +17,20 @@ optional plugins to enable. It depends on two external libraries:
- [libuEv][], the event loop
- [libite][] (-lite), much needed frog DNA
> [!IMPORTANT]
> Most free/open source software packages that use `configure` default
> to install to `/usr/local`. However, some Linux distributions do no
> longer search that path for installed software, e.g. Fedora and Alpine
> Linux. To get finit's configure script to find its dependencies you
> have to help the `pkg-config` tool a bit if you do not change the
> default prefix path:
>
> PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure
**NOTE:** Most free/open source software that uses `configure` default
to install to `/usr/local`. However, some Linux distributions do no
longer search that path for installed software, e.g. Fedora and Alpine
Linux. To get finit's configure script to find its dependencies you
have to help the `pkg-config` tool a bit if you do not change the
default prefix path:
PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure
The configure script checks for all dependencies, including the correct
version of the above mentioned libraries. Currently required versions:
version of the above mentioned libraries. Currently requried versions:
- libite v2.2.0, or later
- libuEv v2.2.0, or later
- libite v2.2.0
- libuEv v2.2.0
Configure
@@ -44,10 +53,6 @@ Below are a few of the main switches to configure:
built-ins (.o files) and all external libraries, except the C library
will be linked statically.
* `--enable-kernel-cmdline`: Enable Finit pre-4.1 parsing of init args from
`/proc/cmdline`, this is *not recommended* since Finit may be running as the
init for container apps that can see the host's `/proc` filesystem
* `--enable-alsa-utils-plugin`: Enable the optional `alsa-utils.so` sound plugin.
* `--enable-dbus-plugin`: Enable the optional D-Bus `dbus.so` plugin.
@@ -56,20 +61,8 @@ Below are a few of the main switches to configure:
* `--enable-x11-common-plugin`: Enable the optional X Window `x11-common.so` plugin.
* `--with-sulogin`: Enable bundled `sulogin` program. Default is to use the
system `sulogin(8)`. The sulogin shipped with Finit *allows password-less*
login if the `root` user is disabled or has no password at all.
For more configure flags, see <kbd>./configure --help</kbd>
> [!NOTE]
> The configure script is not available in the GIT sources. It is
> however included in (officially supported) released tarballs. The
> idea is that you should not need GNU autotools to build, only the
> above mentioned dependencies, a POSIX shell, a C compiler and make.
> Any contributing to Finit can generate it from `configure.ac` using
> the `autogen.sh` script.
Example
-------
@@ -77,16 +70,16 @@ Example
First, unpack the archive:
```shell
$ tar xf finit-4.3.tar.gz
$ cd finit-4.3/
$ tar xf finit-3.0.tar.xz
$ cd finit-3.0/
```
Then configure, build and install:
```shell
$ ./configure --prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--with-keventd --with-watchdog
$ ./configure --prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--with-heading="Alpine Linux 3.13" --with-hostname=alpine
$ make
.
.
@@ -94,24 +87,23 @@ $ make
$ 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-3.0.tar.xz][1] archive is unpacked to the
user's home directory, configured, built and installed to a temporary
staging directory. The environment variable `DESTDIR` controls the
destination directory when installing, very useful for building binary
standalone packages.
Finit 4.1 and later can detect if it runs on an embedded system, or a
Finit 3.0 and later can detect if it runs on an embedded system, or a
system that use BusyBox tools instead of udev & C:o. On such systems
`mdev` instead of `udev` is used. However, remember to also change the
Linux config to:
CONFIG_UEVENT_HELPER_PATH="/sbin/mdev"
> [!TIP]
> If you run into problems starting Finit, take a look at `finit.c`.
> One of the most common problems is a custom Linux kernel build that
> lack `CONFIG_DEVTMPFS`. Another is too much cruft in the system
> `/etc/fstab`.
**Note:** If you run into problems starting Finit, take a look at
`finit.c`. One of the most common problems is a custom Linux kernel
build that lack `CONFIG_DEVTMPFS`. Another is too much cruft in the
system `/etc/fstab`.
Running
@@ -150,42 +142,32 @@ enabled. The default Finit rescue mode configuration is installed into
By default the a root shell, without login, is started.
> [!IMPORTANT]
> In rescue mode `initctl` will not work, the same goes for `reboot`,
> `shutdown`, and `poweroff` commands, provided they are the Finit
> versions of these commands. Use the `-f` flag to force the action.
Debugging
---------
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
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
the following to your Finit .conf file:
tty [12345789] notty noclear
The `notty` option ensures reusing the stdin/stdout set up by the
kernel. Remember, this is only for debugging and would leave your
production system potentially wide open.
To debug startup issues, in particular issues with getty/login, try
`configure --enable-fallback-shell`. When no TTYs are detected, and
Finit is configured with this option, Finit will try to start a bare
`/bin/sh` on the boot console. Remember, this is only for debugging
and would leave your production system potentially wide open.
There is also a rescue shell available, in case Finit crashes and the
kernel usually reboots: `configure --enable-emergency-shell`. However,
the behavior of Finit is severely limited when this is enabled, so use
it only for debugging start up issues when Finit crashes.
> [!CAUTION]
> None of these options should be enabled on production systems since
> they can potentially give a user root access.
**NOTE:** Neither of these two configure options should be enabled on
production systems since they can potentially give a user root access.
[1]: https://github.com/finit-project/finit/releases/download/4.3/finit-4.3.tar.gz
[1]: ftp://troglobit.com/finit/finit-3.0.tar.xz
[libuEv]: https://github.com/troglobit/libuev
[libite]: https://github.com/troglobit/libite
+16 -89
View File
@@ -4,70 +4,17 @@ Tips & Tricks with the kernel cmdline
This document summarizes the different boot parameters that can be
passed on the Linux kernel command line. Not limited to Finit.
> [!IMPORTANT]
> Remember to use `--` to separate kernel parameters from parameters to
> init. E.g., `init=/sbin/finit -- finit.debug rescue`
The `bool` setting is one of `on, off, true false, 1, 0`.
* `debug`: Enable kernel debug. Debug messages are printed to the
console until Finit starts up, unless `loglevel=7` (below) is used.
* `fsck.mode=<auto,force,skip>`, default: `auto`, unless built with
`configure --enable-fastboot`, in which case the default is `skip`
* `fsck.repair=<preen,yes,no>`, default: `preen`, unless built with
`configure --enable-fsckfix`, in which case the default is `yes`.
This configure option also sets `fsck.mode=force`, unless fastboot
is selected at the same time. I.e., the `--enable-fastboot` build
option overrides the `fsck.mode` default value.
* `finit.cond=foo[,bar[,baz]]`: set `<boot/foo>` condition, optionally
multiple conditions can be set using the same option, separated with a
comma. Alternatively, multiple `foo.cond=arg` can be given. Each will
result in a `<boot/arg>` condition being set to control the rest of the
system bootstrap.
Very useful for selecting different boot modes, e.g. manufacturing test,
firmware upgrade, or [rescue mode][rescue].
> [!NOTE]
> `<boot/...>` conditions cannot be cleared with `initctl`!
* `finit.config=/path/to/alternative/finit.conf`: override the
compile-time bootstrap config file, default:
./configure --with-config=/etc/finit.conf
Useful when starting up in various [rescue mode][rescue], factory, or
production test setups. Use the top-level configuration file
directive `rcsd /path/to/finit.d` to override the default rcS.d
directory.
console until Finit starts up.
* `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
alternate `fstab` to mount the file system from. Remember, this file
must be on the `root=...` file system provided to Finit from the
kernel. By default the built-in fstab is used, which itself defaults
to `/etc/fstab`, but can be changed at build time with:
./configure --with-fstab=/path/to/fstab
It is even possible to disable a built-in default using:
./configure --without-fstab
Making `finit.fstab=/path/to/fstab` a *mandatory* command line option.
Note, if the command line fstab is missing, Finit falls back to the
built-in fstab, and if both are missing, the system treats this as a
bad `fsck` and thus calls `sulogin`. If, in turn, `sulogin` is not
available on the system, Finit calls reboot, which is also what will
happen when a user exits from `sulogin`.
* `finit.status[=bool]`: Control finit boot progress, including banner.
(Used to be `finit.show_status`, which works but is deprecated.)
* `finit.show_status[=bool]`: Control finit boot progress, including
banner.
* `finit.status_style=<classic,modern>`: Set Finit boot progress style,
when enabled.
@@ -75,45 +22,25 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
* `init=/bin/sh`: Bypass system default init and tell kernel to start a
shell. Note, this shell is very limited and does not support
signals and has no job control. Recommend using, and modifying,
[`rescue` mode][rescue] 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.
`rescue` mode instead.
* `panic=SEC`: By default the kernel does not reboot after a kernel
panic. This setting will cause a kernel reboot after SEC seconds.
* `quiet`: Suppress kernel logging to console, except for warnings and
errors. Also, see `loglevel` and `quiet` above.
errors.
* `rescue`: Start [rescue/maintenance mode][rescue]. If your system
comes with the bundled `sulogin` program (Finit, or from util-linux,
or Busybox), you will be given a root login to a maintenance shell.
However, if `sulogin` is missing, the file `/lib/finit/rescue.conf`
is read and the system booted in a limited fallback mode.
* `rescue`: Start Finit rescue mode; no network, no `fsck` of file
systems in `/etc/fstab`, no `/etc/rc.local`, no `runparts`. The
configuration is read from `/lib/finit/rescue.conf`, and can be
modified by the operator.
This option can be disabled with `configure --without-rescue`
* `single`, or `S`: Single user mode, runlevel 1, in Finit. Useful to
debug problems with the regular runlevel. All services and TTYs in
`[1]` will be started, so a `tty [1] @console nologin` configuration
presents you with a root console without login.
**Note:** in this mode `initctl` will not work. Correct the problem
and use `reboot -f` to force reboot.
For more on kernel boot paramaters, see the man page [bootparam(7)][].
* `single`, or `S`: Overrides the configured runlevel (default: 2) to go
to after bootstrap by forcing it to runlevel 1, this is also known
as single user mode. Useful to debug startup problems. All services
and TTYs in `[1]` will be started, so a `tty [1] @console nologin`
configuration presents you with a root console without login.
* `1-9`, except `6`: override the configured `runlevel`. Like the `S`
and `rescue`, giving a single number on the kernel command line tells
Finit to ignore any `runlevel` in `/etc/finit.conf` as well as the
configure fallback `--with-runlevel=N` setting. Remember, `6` is the
reboot runlevel and is not permitted. Any other values are ignored.
For more on kernel boot parameters, see the man page [bootparam(7)][].
[rescue]: config/rescue.md
[bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html
-13
View File
@@ -1,13 +0,0 @@
Rebooting & Halting
===================
Traditionally, rebooting and halting a UNIX system is done by switching
to the corresponding runlevel (0 or 6). Over time this has changed and
Finit comes with its own tooling providing: `shutdown`, `reboot`,
`poweroff`, and `suspend`. These commands are also available from the
[`initctl`](initctl.md) tool.
For compatibility reasons Finit listens to the same set of signals as
BusyBox init. This is not 100% compatible with SysV init, but clearly
the more common combination for Finit. For more details, see the
[Signal](signals.md) section.
+37 -155
View File
@@ -1,8 +1,21 @@
Conditions
==========
Finit Conditions
================
Conditions were added to Finit in v3 with the intention of providing a
mechanism for common synchronization problems. For example:
![The service state machine](svc-machine.png "The service state machine")
* [Introduction](#introduction)
* [Triggering](#triggering)
* [Built-in Conditions](#built-in--conditions)
* [Debugging](#debugging)
* [Internals](#internals)
Introduction
------------
Conditions are a new addition to Finit, introduced in v3, with the
intention of providing a mechanism for common synchronization problems.
For example:
- *"wait for service A to start before starting service B"*, or
- *"wait for basic network access to be available"*
@@ -14,16 +27,6 @@ specified separated by comma. Multiple conditions are logically AND'ed
during evaluation, i.e. all conditions must be satisfied in order for a
service to run.
Two special prefixes can be used inside the angle brackets:
- `!` -- service does not support `SIGHUP` (noreload), or run/task
should not block runlevel changes (i.e., bootstrap)
- `~` -- propagate reload from this dependency, see below
Finit guarantees by default that all run/tasks run (at least) once
per runlevel. For most tasks this is a good default, for example
checking SSH host keys or loading keymap. However, for conditions
that are unlikely to happen it is not. (See example below.)
### Example
@@ -32,85 +35,17 @@ that are unlikely to happen it is not. (See example below.)
In this example the Network monitor daemon `netd` is not started until
both the `pid/setupd` *and* `pid/zebra` conditions are satisfied. A
`pid/` condition is satisfied by the corresponding service's PID file
being created, i.e., the service's default readiness notification.
being created.
> [!IMPORTANT]
> Conditions also stop services when a condition is no longer asserted.
> I.e., if the `zebra` process above stops or restarts, `netd` will also
> stop or restart.
Another example is `dropbear`, it does not support `SIGHUP`, but we can
also see optional sourcing of arguments from an environment file:
service [2345789] <!> env:-/etc/default/dropbear dropbear -F -R $DROPBEAR_ARGS -- Dropbear SSH daemon
Finally, the weird "block runlevel changes" example. Here we see what
happens when Finit receives `SIGPWR`, sent from a power daemon like
[powstatd(8)][]. A condition is asserted and a user can set up their
own task to act on it. We do not want this task to block Finit from
moving to the next runlevel after bootstrap, so we set `<!>`:
task [S0123456789] <!sys/pwr/fail> name:pwrfail initctl poweroff -- Power failure, shutting down
Propagating Reload in Dependencies
-----------------------------------
By default, when a service reloads during `initctl reload`, dependent
services are paused (`SIGSTOP`) and simply resumed (`SIGCONT`) when the
condition is reasserted. This is correct for barrier-style dependencies
like `<pid/syslogd>`, where dependents just need syslogd running and do
not care if it reloads its config.
For services that need to react when their upstream reloads, the `~`
prefix propagates the reload from the dependency:
service <pid/svc_a> name:svc_b /sbin/svc_b -- Needs A (barrier)
service <!~pid/svc_b> name:svc_c /sbin/svc_c -- Propagate reload from B
Here, `<~pid/svc_b>` means: propagate a reload of `svc_b` to `svc_c`.
When `svc_b` reloads, `svc_c` will be restarted (because of `!`,
noreload) instead of merely resumed. If `svc_c` supported `SIGHUP`
(no `!` prefix), it would be sent `SIGHUP` instead.
This is similar to systemd's `PropagatesReloadTo=` directive, but
declared on the consumer side rather than the provider side.
**NOTE:** Conditions also stop services when a condition is no longer
asserted. I.e., if the Zebra process above stops or restarts, netd
will also stop or restart.
Triggering
----------
Conditions are mainly triggered (asserted) by built-in plugins, e.g.,
- `netlink.so`: provides `<net/...>`
- `pidfile.so`: provides `<pid/...>`
- Cmdline `finit.cond=arg`: provides `<boot/arg>`
See below for built-in conditions. Finit also supports user-defined
conditions, sometimes referred to as static or one-shot conditions.
They live in the `<usr/...>` namespace and are constrained to a flat
hierarchy without any sub-directories, unlike the pidfile plugin, for
instance.
User-defined conditions are controlled using the `initctl cond set` and
`initctl cond clear` commands:
initctl cond set foo
initctl cond clear foo
The purpose of user-defined conditions is to be able to start or stop
services, or run/task jobs, on external site-dependent stimuli.
**Example:**
service [2345] <usr/foo> alarm --arg foo -- Foo alarm
For convenience, prefixing with `usr/` is allowed, but any other slashes
or period characters are disallowed. E.g., to trigger the `Foo alarm`,
the same as above, can also be achieved like this:
initctl cond set usr/foo
initctl cond clear usr/foo
Conditions can only be triggered by built-in plugins.
Conditions retain their current state until the next reconfiguration or
runlevel change. At that point all set conditions transition into the
@@ -119,49 +54,19 @@ on this, see [Internals](#internals).) Thus, after a reconfiguration it
is up to the "owner" of the condition to convey the new (or possibly
unchanged) state of it.
Static (one-shot) conditions, like `usr/`, never enter the `flux` state.
> [!IMPORTANT]
> For `pid/` conditions it is expected that the service reassert, i.e.,
> "touch" or recreate, their PID file on `SIGHUP`. This can be done by
> calling `utimensat()` on the PID file. Provided, of course, that the
> service supports reloading on `SIGHUP`, otherwise it will be restarted
> by Finit when they instead exit on the signal. For such services, use
> `<!>` to tell Finit the service does not support `SIGHUP`.
> **Note:** For `pid/` conditions it is expected that services "touch"
> or recreate their PID file on `SIGHUP`.
Built-in Conditions
-------------------
Finit comes with a set of plugins for conditions:
- `devmon` (built-in)
- `netlink`
- `pidfile`
- `sys`
- `usr`
The `devmon` (built-in) plugin monitors `/dev` and `/dev/dir` for device
nodes being created and removed. It is active only when a run, task, or
service has declared a `<dev/foo>` or `<dev/dir/bar>` condition.
The `pidfile` plugin (recursively) watches `/run/` (recursively) for PID
files created by the monitored services, and sets a corresponding
condition in the `pid/` namespace.
Similarly, the `netlink` plugin provides basic conditions for when an
interface is brought up/down and when a default route (gateway) is set,
in the `net/` namespace.
The `sys` and `usr` plugins monitor are passive condition monitors where
the action is provided by `keventd`, signal handlers, and in the case of
`usr`, the end-user via the `initctl` tool.
Additionally, the various states of a run/task/sysv/service can also be
used as conditions, the image above shows the state names. The syntax
for a `service` type process: `<service/foo/STATE>`. The other types,
in particular run/task/sysv, there are the additional states `success`
and `failure`.
Finit comes with a `pidfile` and `netlink` plugin. When enabled, the
`pidfile` plugin watches `/var/run/` (recursively) for PID files created
by the monitored services, and sets a corresponding condition in the
`pid/` namespace. Similarily, the `netlink` plugin provides basic
conditions for when an interface is brought up/down and when a default
route (gateway) is set, in the `net/` namespace.
With the example listed above, finit does not start the `/sbin/netd`
daemon until `setupd` and `zebra` has started *and* created their PID
@@ -180,19 +85,10 @@ Built-in conditions:
- `net/<IFNAME>/exist`
- `net/<IFNAME>/up`
- `net/<IFNAME>/running`
- `service/<NAME[:ID]>/<STATE>`
- `{run, task, sysv}/<NAME[:ID]>/{<STATE>, success, failure}`
- `sys/pwr/ac`
- `sys/pwr/fail`
- `sys/key/ctrlaltdel`
- `usr/foo`
- `boot/arg`
- `dev/node` and `dev/dir/node`
> [!NOTE]
> Here, `up` means administratively up, the interface flag `IFF_UP`.
> `running` is the `IFF_RUNNING` flag, meaning operatively up. The
> difference is that `running` tells if the NIC has link.
**Note:** `up` means administratively up, the interface flag `IFF_UP`.
`running` is the `IFF_RUNNING` flag, meaning operatively up. The
difference is that `running` tells if the NIC has link.
Composition
@@ -218,19 +114,14 @@ When Finit configuration files are changed and the `initctl reload`
command is called, it is expected of services to touch their PID files
for Finit to reassert their conditions.
Similarly, when a single service is reloaded with `initctl reload NAME`,
its conditions are cleared and reasserted, ensuring dependent services
are properly updated.
Daemons that don't create PID files, or fail to touch them on reload,
can be worked around by using the `pid:/path/to/file.pid` syntax in
the service stanza for the daemon. It is far from optimal since any
synchronization of depending services may fail due to the daemon not
having reinitialized/created their IPC sockets, or similar.
> [!NOTE]
> In versions of Finit prior to v4, the PID conditions were called 'svc'
> conditions, and they were far more complex.
> **Note:** in versions of Finit prior to v4, the PID conditions were
> called 'svc' conditions, and they were far more complex.
Debugging
@@ -239,7 +130,7 @@ Debugging
If a service is not being started as it should, the problem might be
that one of its conditions is not in the expected state. Use the
command `initctl status` to inspect service status. Services in the
`waiting` state are pending a condition.
`ready` state are pending a condition.
In that situation, running `initctl cond show` reveals which of the
conditions that are not satisfied. Listed as `off` below.
@@ -256,7 +147,7 @@ PID IDENT STATUS CONDITION (+ ON, ~ FLUX, - OFF)
Here we can see that `netd` is allowed to run since both its conditions
are in the `on` state, as indicated by the `+`-prefix. `udhcpc` however
is not allowed to run since `net/vlan1/exist` condition is not satisfied.
is not allowed to run since `net/vlan1/exist` condition is not satsifed.
As indicated by the `-`-prefix.
To fake interface `vlan1` suddenly appearing, and test what happens to
@@ -293,8 +184,6 @@ A condition is always in one of three states:
All conditions that have not explicitly been set are interpreted as
being in the `off` state.
![The service state machine](img/svc-machine.png "The service state machine")
When a reconfiguration is requested, Finit transitions all conditions to
the `flux` state. As a result, services that depend on a condition are
sent `SIGSTOP`. Once the new state of the condition is asserted, the
@@ -305,14 +194,7 @@ This STOP/CONT handling minimizes the number of unnecessary service
restarts that would otherwise occur because a depending service was sent
`SIGHUP` for example.
Services with the `~` prefix are an exception to this rule: when their
conditions return to `on` after being in `flux`, the reload is propagated
-- the service is reloaded (SIGHUP) or restarted (noreload `!`) instead
of simply being resumed.
Therefore, any plugin that supplies Finit with conditions must ensure
that their state is updated after each reconfiguration. This can be
done by binding to the `HOOK_SVC_RECONF` hook. For an example of how
to do this, see `plugins/pidfile.c`.
[powstatd(8)]: https://manpages.ubuntu.com/manpages/trusty/en/man8/powstatd.8.html
+510
View File
@@ -0,0 +1,510 @@
Configuration
=============
* [Introduction](#introduction)
* [Service Wrapper Scripts](#service-wrapper-scripts)
* [Configuration File Syntax](#configuration-file-syntax)
* [Hostname](#hostname)
* [Kernel Modules](#kernel-modules)
* [Networking](#networking)
* [Resource Limits](#resource-limits)
* [Runlevels](#runlevels)
* [One-shot Commands (sequence)](#one-shot-commands--sequence-)
* [One-shot Commands (parallel)](#one-shot-commands--parallel-)
* [SysV Init Scripts](#sysv-init-scripts)
* [Services](#services)
* [Run-parts Scripts](#run-parts-scripts)
* [Including Finit Configs](#including-finit-configs)
* [General Logging](#general-logging)
* [TTYs and Consoles](#ttys-and-consoles)
* [Non-privileged Services](#non-privileged-services)
* [Redirecting Output](#redirecting-output)
* [Limitations](#limitations)
* [/etc/finit.conf](#etcfinitconf)
* [/etc/finit.d](#etcfinitd)
Introduction
------------
Finit can be configured using only the original `/etc/finit.conf` file
or in combination with `/etc/finit.d/*.conf`. Useful for package-based
Linux distributions -- each package can provide its own "script" file.
- `/etc/finit.conf`: main configuration file
- `/etc/finit.d/*.conf`: snippets, usually one service per file
Not all configuration directives are available in `/etc/finit.d/*.conf`
and some directives are only available at bootstrap, runlevel `S`, see
the section [Limitations](#limitations) below for details.
To add a new service, simply drop a `.conf` file in `/etc/finit.d` and
run `initctl reload`. (It is also possible to `SIGHUP` to PID 1, or
call `finit q`, but that has been deprecated with the `initctl` tool).
Finit monitors all known active `.conf` files, so if you want to force
a restart of any service you can simply touch its corresponding `.conf`
file in `/etc/finit.d` and call `initctl reload`. Finit handle any
and all conditions and dependencies between services automatically.
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
useful in particular to Linux distributions that may want to install all
files for a package and let the user decide when to enable a service.
On `initctl reload` the following is checked for all services:
- If a service's `.conf` file has been removed, or its conditions are no
longer satisifed, the service is stopped.
- If the file is modified, or a service it depends on has been reloaded,
the service is reloaded (stopped and started).
- If a new service is added it is automatically started — respecting
runlevels and return values from any callbacks.
For more info on the different states of a service, see the separate
document [Finit Services](service.md).
> When running <kbd>make install</kbd> no default `/etc/finit.conf` is
> installed since system requirements differ too much. There are some
> examples in the `contrib/` directory, which can be used as a base.
Service Environment
-------------------
Finit supports sourcing environment variables from `/etc/default/*`, or
similar `--with-sysconfig=DIR`. This is a common pattern from SysV init
scripts, where the start-stop script is a generic script for the given
service, `foo`, and the options for the service are sourced from the
file `/etc/default/foo`. Like this:
* `/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
Here the service `foo` is started with `-n`, to make sure it runs in the
foreground, and the with the options found in the environment file. With
the `ps` command we can see that the process is started with:
foo -n --extra-arg=bar -s -x
> **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 *not* block the start.
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.
The Finit service `.conf` file can be put into `/etc/finit.d/available`,
so you can control the service using `initctl`. Then use the path to
the wrapper script in the Finit `.conf` service stanza. The following
example employs a wrapper script in `/etc/start.d`.
**Example:**
* `/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
> **Note:** the example sets `<!>` to denote that it doesn't support
> `SIGHUP`. That way Finit will stop/start the service
> instead of sending SIGHUP at restart/reload events.
Configuration File Syntax
-------------------------
### Hostname
**Syntax:** `host <NAME>`, or `hostname <NAME>`
Set system hostname to NAME, unless `/etc/hostname` exists in which case
the contents of that file is used.
Deprecated. We recommend using `/etc/hostname` instead.
> **Note:** only read and executed in runlevel S (bootstrap).
### Kernel Modules
**Syntax:** `module <MODULE> [ARGS]`
Load a kernel module, with optional arguments. Similar to `insmod`
command line tool.
Deprecated, there is both a `modules-load.so` and a `modprobe.so` plugin
that can handle module loading better. The former supports loading from
`/etc/modules-load.d/`, the latter uses kernel modinfo to automatically
load (or coldplug) every required module. For hotplug we recommend the
BusyBox mdev tool, add to `/etc/mdev.conf`:
$MODALIAS=.* root:root 0660 @modprobe -b "$MODALIAS"
> **Note:** only read and executed in runlevel S (bootstrap).
### Networking
**Syntax:** `network <PATH>`
Script or program to bring up networking, with optional arguments.
Deprecated. We recommend using dedicated task/run stanzas per runlevel,
or `/etc/network/interfaces` if you have a system with `ifupdown`, like
Debian, Ubuntu, Linux Mint, or an embedded BusyBox system.
> **Note:** only read and executed in runlevel S (bootstrap).
### Resource Limits
**Syntax:** `rlimit [hard|soft] RESOURCE <LIMIT|unlimited>`
Set the hard or soft limit for a resource, or both if that argument is
omitted. `RESOURCE` is the lower-case `RLIMIT_` string constants from
`setrlimit(2)`, without prefix. E.g. to set `RLIMIT_CPU`, use `cpu`.
LIMIT is an integer that depends on the resource being modified, see
the man page, or the kernel `/proc/PID/limits` file, for details.
Finit versions before v3.1 used `infinity` for `unlimited`, which is
still supported, albeit deprecated.
# 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
`rlimit` can be set globally, in `/etc/finit.conf`, or locally per
each `/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.
### Runlevels
**Syntax:** `runlevel <N>`
Defines the system runlevel to go to after bootstrap (S) has completed.
N is the runlevel number 0-9, where 6 is reserved for reboot and 0 for
halt.
Default: 2
> **Note:** only read and executed in runlevel S (bootstrap).
### One-shot Commands (sequence)
**Syntax:** `run [LVLS] <COND> /path/to/cmd ARGS -- Optional description`
One-shot command to run in sequence when entering a runlevel, with
optional arguments and description.
`run` commands are guaranteed to be completed before running the next
command. Highly useful if true serialization is needed.
> `<COND>` is described in the [Services](#services) section.
### One-shot Commands (parallel)
**Syntax:** `task [LVLS] <COND> /path/to/cmd ARGS -- Optional description`
One-shot like 'run', but starts in parallel with the next command.
Both `run` and `task` commands are run in a shell, so pipes and
redirects can be freely used:
task [s] echo "foo" | cat >/tmp/bar
> `<COND>` is described in the [Services](#services) section.
### SysV Init Scripts
**Syntax:** `sysv [LVLS] <COND> /path/to/init-script -- Optional description`
Similar to `task` is the `sysv` stanza, which can be used to call SysV
style scripts. The primary intention for this command is to be able to
re-use much of existing setup and init scripts in Linux distributions.
When entering an allowed runlevel, Finit calls `init-script start`, when
entering a disallowed runlevel, Finit calls `init-script stop`, and if
the Finit .conf, where `sysv` stanza is declared, is modified, Finit
calls `init-script restart` on `initctl reload`. Similar to how
`service` stanzas work.
Forking services started with `sysv` scripts can be monitored by Finit
by declaring the PID file to look for: `pid:!/path/to/pidfile.pid`.
> `<COND>` is described in the [Services](#services) section.
### Services
**Syntax:** `service [LVLS] <COND> /path/to/daemon ARGS -- 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 `initctl restart NAME` it manually.
For daemons that support it, we recommend appending `--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.
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 `sysv`
services, using the `pid:!/path/to/pidfile.pid` syntax.
**Example:**
In the case of `ospfd` (below), we omit the `-d` flag (daemonize) to
prevent it from forking to the background:
service [2345] <pid/zebra> /sbin/ospfd -- OSPF daemon
`[2345]` denote the runlevels `ospfd` is allowed to run in, they are
optional and default to level 2-5 if omitted.
`<...>` is the condition for starting `ospfd`. In this example Finit
waits for another service, `zebra`, to have created its PID file in
`/var/run/quagga/zebra.pid` before starting `ospfd`. Finit watches
*all* files in `/var/run`, for each file named `*.pid`, or `*/pid`,
Finit opens it and find the matching `NAME:ID` using the PID.
Some services do not maintain a PID file and rather than patching each
application Finit provides a workaround. A `pid` 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 `/var/run`
directory using the `basename(1)` of the service. The default can be
modified with an optional `pid:`-argument:
pid[:[/path/to/]filename[.pid]]
For example, by adding `pid:/run/foo.pid` to the service `/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 `<pid/bar>`.
> For a detailed description of conditions, and how to debug them,
> see the [Finit Conditions](conditions.md) document.
If a service should not be automatically started, it can be configured
as manual with the optional `manual` argument. The service can then be
started at any time by running `initctl start <service>`.
manual:yes
The name of a service, shown by the `initctl` tool, defaults to the
basename of the service executable. It can be changed with the
optional `name` argument:
name:<service-name>
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 option `halt:SIGNAL`, e.g.,
`halt:SIGPWR`. To change the delay between your halt signal and KILL,
use the option `kill:SEC`, e.g., `kill:10` to wait 10 seconds before
sending `SIGKILL`.
### Run-parts Scripts
**Syntax:** `runparts <DIR>`
Call [run-parts(8)][] on `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 runlevel
`S`, bootstrap.
It can be beneficial to use `S01name`, `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.
Similar to the `/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.
> **Note:** only read and executed in runlevel S (bootstrap).
### Including Finit Configs
**Syntax:** `include <CONF>`
Include another configuration file. Absolute path required.
### General Logging
**Syntax:** `log size:200k count:5`
Log rotation for run/task/services using the `log` sub-option with
redirection to a log file. Global setting, applies to all services.
The size can be given as bytes, without a specifier, or in `k`, `M`,
or `G`, e.g. `size:10M`, or `size:3G`. A value of `size:0` disables
log rotation. The default is `200k`.
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.
### TTYs and Consoles
**Syntax:** `tty [LVLS] <DEV> [BAUD] [noclear] [nowait] [nologin] [TERM]`
`tty [LVLS] <CMD> <ARGS> [noclear] [nowait]`
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
keyword `@console`, or `console`, useful on embedded systems.
The default baud rate is 0, i.e., keep kernel default.
**Example:**
tty [12345] /dev/ttyAMA0 115200 noclear vt220
The second `tty` syntax variant is for using an external getty, like
agetty or the BusyBox getty.
By default both variants *clear* the TTY and *wait* for the user to
press enter before starting getty.
**Example:**
tty [12345] /sbin/getty -L 115200 /dev/ttyAMA0 vt100
tty [12345] /sbin/agetty -L ttyAMA0 115200 vt100 nowait
The `noclear` option disables clearing the TTY after each session.
Clearing the TTY when a user logs out is usually preferable.
The `nowait` option disables the `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.
The `nologin` option disables getty and `/bin/login`, and gives the
user a root (login) shell on the given TTY `<DEV>` immediately.
Needless to say, this is a rather insecure option, but can be very
useful for developer builds, during board bringup, or similar.
Notice the ordering, the `TERM` option to the built-in getty must be
the last argument.
Embedded systems may want to enable automatic `DEV` by supplying the
special `@console` device. This works regardless weather the system
uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else. Finit figures
it out by querying sysfs: `/sys/class/tty/console/active`. The speed
can be omitted to keep the kernel default.
**Example:**
tty [12345] @console noclear vt220
On really bare bones systems Finit offers a fallback shell, which
should not be enabled on production systems since. This because it
may give a user root access without having to log in. However, for
bringup and system debugging it can come in handy:
configure --enable-fallback-shell
One can also use the `service` stanza to start a stand-alone shell:
service [12345] /bin/sh -l
### Non-privileged Services
Every `run`, `task`, or `service` can also list the privileges the
`/path/to/cmd` should be executed with. Simply prefix the path with
`[@USR[:GRP]]` like this:
run [2345] @joe:users logger "Hello world"
For multiple instances of the same command, e.g. a DHCP client or
multiple web servers, add `:ID` somewhere between the `run`, `task`,
`service` keyword and the command, like this:
service :80 [2345] httpd -f -h /http -p 80 -- Web server
service :8080[2345] httpd -f -h /http -p 8080 -- Old web server
Without the `:ID` to the service the latter will overwrite the former
and only the old web server would be started and supervised.
### Redirecting Output
The `run`, `task`, and `service` stanzas also allow the keyword `log` to
redirect `stderr` and `stdout` of the application to a file or syslog
using the native `logit` tool. This is useful for programs that do not
support syslog on their own, which is sometimes the case when running
in the foreground.
The full syntax is:
log:/path/to/file
log:prio:facility.level,tag:ident
log:console
log:null
log
Default `prio` is `daemon.info` and default `tag` is the basename of the
service or run/task command.
Log rotation is controlled using the global `log` setting.
**Example:**
service log:prio:user.warn,tag:ntpd /sbin/ntpd pool.ntp.org -- NTP daemon
Worth noting is that conditions is allowed for all these stanzas. For a
detailed description, see the [Conditions](conditions.md) document.
Limitations
-----------
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
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.
Today it is mainly used for bootstrap settings like system hostname,
network bringup and system shutdown. These can now also be set in any
`.conf` file in `/etc/finit.d`.
There is, however, nothing preventing you from having all configuration
settings in `/etc/finit.conf`.
> **Note:** The `/etc/finit.d` directory was previously the default
> Finit `runparts` directory. Finit no longer has a default
> `runparts`, make sure to update your setup, or the finit
> configuration, accordingly.
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
-6
View File
@@ -1,6 +0,0 @@
docsdir := @docdir@/doc/config
dist_docs_DATA = cgroups.md env.md files.md index.md limitations.md \
logging.md rescue.md runlevels.md runparts.md \
service-env.md service-opts.md service-sync.md \
service-wrappers.md services.md sysv.md \
task-and-run.md templating.md tty.md
-1
View File
@@ -1 +0,0 @@
index.md
-186
View File
@@ -1,186 +0,0 @@
Linux Capabilities
==================
Finit supports Linux capabilities, allowing services to run with minimal
required privileges instead of running as root. This significantly improves
system security by following the principle of least privilege.
## Overview
Linux capabilities divide the traditional root privileges into distinct units
that can be independently granted to processes. For example, a web server only
needs the capability to bind to privileged ports (< 1024), not full root access.
Finit uses the modern IAB (Inheritable, Ambient, Bounding) API from libcap,
which is the same approach used by other modern service managers like dinit.
## Basic Usage
Capabilities are specified using the `caps:` directive in service configuration:
```conf
service [2345] name:nginx \
@www-data:www-data \
caps:^cap_net_bind_service \
/usr/sbin/nginx -g 'daemon off;' \
-- Web server
```
This example allows nginx to bind to privileged ports (like 80 and 443) while
running as the unprivileged `www-data` user.
## IAB Format
The capability string uses the IAB (Inheritable, Ambient, Bounding) format
with the following prefixes:
- `^` **Ambient** (and Inheritable) - **Recommended for most use cases**
- Capabilities survive across `exec()` calls
- Automatically raised to effective after exec
- Example: `^cap_net_bind_service`
- `%` **Inheritable** only
- Requires the executed binary to have matching file capabilities
- Less common, more complex setup
- Example: `%cap_net_admin`
- `!` **Bounding** - Block capability from bounding set
- Prevents the service from ever acquiring this capability
- Useful for security hardening
- Example: `!cap_sys_admin`
Multiple capabilities can be specified as a comma-separated list:
```conf
caps:^cap_net_raw,^cap_net_admin,^cap_net_bind_service
```
## Common Use Cases
### Web Server (Privileged Ports)
Allow a web server to bind to ports 80 and 443 without running as root:
```conf
service [2345] name:webserver \
@www-data:www-data \
caps:^cap_net_bind_service \
/usr/sbin/nginx -g 'daemon off;'
```
### Network Monitoring (Raw Sockets)
Allow packet capture without root privileges:
```conf
service [2345] name:tcpdump \
@tcpdump \
caps:^cap_net_raw,^cap_net_admin \
/usr/sbin/tcpdump -i eth0 -w /var/log/capture.pcap
```
### NTP Daemon (System Time)
Allow time synchronization without full root:
```conf
service [2345] name:ntpd \
@ntp \
caps:^cap_sys_time,^cap_sys_nice \
/usr/sbin/ntpd -n
```
## Available Capabilities
Common capabilities include (see `man 7 capabilities` for the complete list):
- `cap_chown` - Make arbitrary changes to file UIDs and GIDs
- `cap_dac_override` - Bypass file read, write, and execute permission checks
- `cap_dac_read_search` - Bypass file read permission checks
- `cap_fowner` - Bypass permission checks on operations that normally require filesystem UID
- `cap_kill` - Bypass permission checks for sending signals
- `cap_net_admin` - Perform various network-related operations
- `cap_net_bind_service` - Bind to privileged ports (< 1024)
- `cap_net_raw` - Use RAW and PACKET sockets
- `cap_setgid` - Make arbitrary manipulations of process GIDs
- `cap_setuid` - Make arbitrary manipulations of process UIDs
- `cap_sys_admin` - Perform system administration operations (very powerful!)
- `cap_sys_module` - Load and unload kernel modules
- `cap_sys_nice` - Raise process nice value and change scheduling
- `cap_sys_time` - Set system clock
## Security Best Practices
1. **Use the minimum required capabilities**
- Only grant what the service actually needs
- Don't grant `cap_sys_admin` unless absolutely necessary
2. **Specify a user (preferably non-root)**
- The `@user` directive is **required** for `caps:` to take effect
- For ambient capabilities (`^`), use a non-root user (not `@root`)
- Example: `@www-data`, `@nginx`, `@tcpdump`
3. **Use ambient capabilities (`^`)**
- The `^` prefix ensures capabilities survive exec()
- Simpler than setting file capabilities on binaries
4. **Block dangerous capabilities**
- Use `!` to explicitly block capabilities you don't want
- Example: `!cap_sys_admin,!cap_sys_module`
5. **Test with `getpcaps`**
- After starting a service, verify its capabilities:
```bash
getpcaps $(pidof nginx)
```
- Should show only the capabilities you granted
## Verification
After configuring a service with capabilities, verify it works correctly:
```bash
# Start the service
initctl start webserver
# Check the process capabilities
getpcaps $(pidof nginx)
# Should show something like:
# 12345: cap_net_bind_service=eip
# Verify the user
ps -o user,pid,cmd -p $(pidof nginx)
# Should show the service running as the specified user
```
## Requirements
- Linux kernel 4.3+ (for ambient capabilities support)
- libcap library installed
- Finit built with `--enable-libcap`
## Limitations
- The `caps:` directive requires `@user` to be specified for it to take effect
- Without `@user`, the service runs as root with full capabilities and
the `caps:` configuration is silently ignored
- You can use `@root` with `caps:`, but see below about ambient capabilities
- For ambient capabilities (`^`, recommended), the user **must be non-root**
- Using `@root` with `caps:^...` will not work effectively, as ambient
capabilities are only added to the effective set when euid ≠ 0
- Use inheritable (`%`) or bounding (`!`) capabilities with `@root` if needed
- Services without `caps:` use standard privilege dropping:
- Services with `@user` (non-root) have no special capabilities
- Services without `@user` run as root with full capabilities
- Some very old binaries may not work correctly with ambient capabilities
- File system capabilities are not managed by Finit (use `setcap` for that)
## See Also
- [capabilities(7)](https://man7.org/linux/man-pages/man7/capabilities.7.html) - Linux capabilities overview
- [cap_iab(3)](https://man7.org/linux/man-pages/man3/cap_iab.3.html) - IAB capability API documentation
- [setcap(8)](https://man7.org/linux/man-pages/man8/setcap.8.html) - Set file capabilities
- [getcap(8)](https://man7.org/linux/man-pages/man8/getcap.8.html) - Query file capabilities
- [capsh(1)](https://man7.org/linux/man-pages/man1/capsh.1.html) - Capability shell wrapper
-215
View File
@@ -1,215 +0,0 @@
Finit provides three different cgroup directives for controlling resource allocation:
1. **Top-level cgroup definition**: `cgroup NAME settings`
- Defines a top-level cgroup (e.g., `init`, `system`, `user`) with default settings
- Space-separated syntax
- Example: `cgroup system cpu.weight:9700`
2. **Global cgroup selector**: `cgroup.NAME[,options]` (standalone directive)
- Sets the default cgroup for subsequent services in a `.conf` file
- Dot-separated with optional comma-separated options
- Example: `cgroup.maint` or `cgroup.system,delegate`
3. **Per-service cgroup option**: `cgroup.NAME[,options]` or `cgroup:options`
- Overrides the cgroup for a specific service
- Part of the service directive line
- Example: `service [...] cgroup.maint,mem.max:1G /path/to/cmd`
> [!NOTE]
> Linux cgroups and details surrounding values are not explained in the
> Finit documentation. The Linux admin-guide covers this well:
> <https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html>
Top-level Cgroup Definition
----------------------------
**Syntax:** `cgroup NAME settings`
# 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
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
`system/` to 9700.
cgroup system cpu.weight:9700
# Example extra cgroup 'maint'
cgroup maint cpu.weight:100
By default, the `system/` cgroup is selected for almost everything. The
`init/` cgroup is reserved for PID 1 itself and its closest relatives.
The `user/` cgroup is for local TTY logins spawned by getty.
Global Cgroup Selector
----------------------
**Syntax:** `cgroup.NAME[,options]` (standalone directive)
To select a different top-level cgroup, e.g. `maint/`, for a group of
run/task/service directives in a `.conf` file, use the `cgroup.NAME`
directive as a standalone line:
cgroup.maint
service [...] <...> /path/to/foo args -- description
service [...] <...> /path/to/bar args -- description
Both services will run in the `maint/` cgroup.
You can also include options with the global selector:
cgroup.system,delegate
service [...] <...> /path/to/foo args -- description
Per-Service Cgroup Option
--------------------------
**Syntax:** `cgroup.NAME[,options]` or `cgroup:options` (service option)
To override the cgroup for a specific service, use the `cgroup.NAME`
option within the service directive:
service [...] <...> cgroup.maint /path/to/foo args -- description
This form also allows per-service limits. Two syntaxes are supported:
**New comma-separated syntax (recommended):**
service [...] <...> cgroup.maint,cpu.max:10000,mem.max:655360 /path/to/foo args -- description
**Old colon-separated syntax (legacy):**
service [...] <...> cgroup.maint:cpu.max:10000,mem.max:655360 /path/to/foo args -- description
You can also apply options to the current default cgroup (without changing it)
using the `cgroup:options` syntax:
service [...] <...> cgroup:cpu.max:10000,mem.max:655360 /path/to/foo args -- description
Both syntaxes work identically. The new comma-separated syntax is recommended
as it's more consistent with other option parsing in Finit.
Note the `mem.` exception to the rule: every 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 no filtering, except for expanding the shorthand `mem.` to `memory.`.
If the file is not available, either the cgroup controller is not available
in your Linux kernel, or the name is misspelled.
### Overriding Cgroup Leaf Names
By default, the cgroup leaf directory name is derived from the service
configuration filename (without the `.conf` extension). For example, a
service defined in `system/10-hotplug.conf` would create a cgroup at
`/sys/fs/cgroup/system/10-hotplug/` by default.
To use a more descriptive name (recommended for clarity), you can specify
`name:` in the cgroup directive:
service [...] <...> cgroup.system,name:udevd /lib/systemd/systemd-udevd -- Device event daemon
This creates the cgroup at `/sys/fs/cgroup/system/udevd/` instead.
The syntax supports combining the name override with other options:
service [...] <...> cgroup.system,name:udevd,cpu.max:10000 /lib/systemd/systemd-udevd -- Device event daemon
Or with delegation:
service [2345] @podman:podman \
cgroup.containers,name:podman,delegate,mem.max:4G \
/usr/bin/podman system service -- Podman API
A daemon using `SCHED_RR` currently needs to run outside the default cgroups.
service [...] <...> cgroup.root /path/to/daemon arg -- Real-Time process
Cgroup Delegation
-----------------
For services that need to create their own child cgroups (container runtimes
like Docker, Podman, systemd-nspawn, LXC), use the `delegate` option:
service [2345] @dockerd:dockerd \
cgroup.system,delegate /usr/bin/dockerd -- Docker daemon
Or with the old colon syntax:
service [2345] @dockerd:dockerd \
cgroup.system:delegate /usr/bin/dockerd -- Docker daemon
This allows the container runtime to:
- Create child cgroups for containers
- Manage controller settings for containers
- Move processes between cgroups
When delegation is enabled, Finit:
1. Creates the service cgroup as a **domain group** (not a leaf)
2. Enables all available controllers in `cgroup.subtree_control`
3. Changes ownership of delegation files to the service user
4. Moves the service process to the cgroup root
5. Lets the container runtime manage its own subdirectories
**Requirements:**
- The service should specify `@user:group` for proper ownership
- Controllers are delegated from the parent cgroup
**Example with additional config (new syntax):**
service [2345] @podman:podman \
cgroup.containers,delegate,mem.max:4G \
/usr/bin/podman system service -- Podman API
**Or with old syntax:**
service [2345] @podman:podman \
cgroup.containers:delegate,mem.max:4G \
/usr/bin/podman system service -- Podman API
Both examples delegate the cgroup while also setting a 4GB memory limit.
**Container template example:**
Here's a real-world example from [Infix OS](https://github.com/kernelkit/infix)
for running rootful podman container instances using delegation:
sysv log:prio:local1,tag:%i kill:30 pid:!/run/container:%i.pid \
pre:0,/usr/sbin/container cleanup:0,/usr/sbin/container \
cgroup.system,delegate \
[2345] <!> :%i container -n %i -- container %i
This template uses `sysv` type with delegation, demonstrating that cgroup
delegation works with different service types, not just `service`.
**Cgroup structure with delegation:**
Initially, the service process runs directly in the cgroup root:
/sys/fs/cgroup/system/container@web/
├── cgroup.procs (service PID - owned by service user)
├── cgroup.subtree_control (+cpu +memory +io - owned by service user)
└── (container children will be created here)
Once the container runtime creates child cgroups (e.g., `libpod-*/`), cgroups v2
enforces the "no internal processes" rule. When Finit detects this (`EBUSY` error),
it automatically creates an `supervisor/` subdirectory and moves service-related
processes there:
/sys/fs/cgroup/system/container@web/
├── cgroup.procs (empty)
├── cgroup.subtree_control (+cpu +memory +io)
├── supervisor/ (service processes)
│ └── cgroup.procs (conmon PIDs, etc.)
└── libpod-$HASH/ (container processes)
└── cgroup.procs (container PIDs)
This happens automatically - no configuration needed. Without delegation, the
cgroup would be a leaf and the container runtime could not create child cgroups.
-31
View File
@@ -1,31 +0,0 @@
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 a service-local
environment is detailed in [Services Environment](service-env.md).
The syntax for global environment variables is straight forward. In
Finit v4.4 the `set` keyword was added for completeness, but the old
syntax (without the `set ` prefix) is still honored:
set foo=bar
set 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.
-208
View File
@@ -1,208 +0,0 @@
Files & Layout
==============
Originally Finit was configured using a single file, `/etc/finit.conf`,
and although still possible to use a single configuration file, today
the following layout is recommended:
/
|- etc/
| |- finit.d/
| | |- available/
| | | `- my-service.conf
| : |- enabled/
| : | `- my-service.conf -> ../available/my-service.conf
| : :
| : |- static-service.conf
| : `- another-static.conf
| :
| `- finit.conf
|- lib
| `- finit/
| `- system/
| |- 10-hotplug.conf
| `- ...
`- run/
`- finit/
`- system/
|- dbus.conf
|- keventd.conf
|- runparts.conf
|- watchdogd.conf
`- ...
Configuration files in `/etc` are provided by the user, or projects like
[finit-skel](https://github.com/finit-project/finit-skel) and extended by
the user.
The files in `/lib/finit/system/*.conf` are system critical services and
setup provided by Finit, e.g. udev/mdev that must run very early at system
bootstrap. This system directory was introduced in Finit v4.4 to replace
the hard-coded services provided by plugins before. All .conf files in this
directory be either replaced by a system administrator or overridden by a
file with the same name in `/etc/finit.d/`.
The files in `/run/finit/system/*.conf` are created by plugins and Finit
bundled services like runparts, [watchdog](../watchdog.md), and
[`keventd`](../keventd.md) if they are enabled. Like
`/lib/finit/system/*.conf`, these files can be overridden by file with
the same name in `/etc/finit.d/`.
Services in the `available/` and `enabled/` sub-directories are called
dynamic services, in contrast to static services -- the only difference
being where they are installed and if the `initctl` tool can manage them
with the `enable` and `disable` commands. An administrator can always
create files and symlinks manually.
At bootstrap, and `initctl reload`, all .conf files are read, starting
with `finit.conf`, then `/lib/finit/system/*.conf`, `finit.d/*.conf`,
and finally all `finit.d/enabled/*.conf` files. Each directory is a
unique group, where files within each group are sorted alphabetically.
**Example:**
/lib/finit/system/10-hotplug.conf
/lib/finit/system/90-testserv.conf
/run/finit/system/dbus.conf
/run/finit/system/runparts.conf
/etc/finit.d/10-abc.conf
/etc/finit.d/20-abc.conf
/etc/finit.d/enabled/1-aaa.conf
/etc/finit.d/enabled/1-abc.conf
The resulting combined configuration is read line by line, each `run`,
`task`, and `service` added to an ordered list that ensures they are
started in the same order. This is important because of the blocking
properties of the `run` statement. For an example on the relation of
`service` and `run` statements, and dependency handling between them,
see [Conditional Loading](services.md#conditional-loading), below.
> [!NOTE]
> The names `finit.conf` and `finit.d/` are only defaults. They can be
> changed at compile-time with two `configure` options:
> `--with-config=/etc/foo.conf` and `--with-rcsd=/var/foo.d`.
>
> They can also be overridden from the [kernel command line](../cmdline.md)
> using: `-- finit.config=/etc/bar.conf` and in that file use the
> top-level configuration directive `rcsd /path/to/finit.d`.
Filesystem Layout
-----------------
Finit is most comfortable with a traditional style Linux filesystem
layout, as specified in the [FHS][]:
/.
|- bin/
|- dev/ # Mounted automatically if devtmpfs is available
| |- pts/ # Mounted automatically by Finit if it exists
| `- shm/ # Mounted automatically by Finit if it exists
|- etc/
| |- finit.d/
| | |- available/
| | `- enabled/
| `- finit.conf
|- home/
|- lib/
|- libexec/
|- mnt/
|- proc/ # Mounted automatically by Finit if it exists
|- root/
|- run/ # Mounted automatically by Finit if it exists
| `- lock/ # Created automatically if Finit mounts /run
|- sbin/
|- sys/ # Mounted automatically by Finit if it exists
|- tmp/ # Mounted automatically by Finit if it exists
|- usr/
`- var/
|- cache/
|- db/
|- lib/
| `- misc/
|- lock/
|- log/
|- run -> ../run
|- spool/
`- tmp/
Finit starts by mounting the critical file systems `/dev`, `/proc/`, and
`/sys`, unless they are already mounted. When all plugins and other,
core Finit functions, have been set up, all relevant filesystems (where
`PASS > 0`) are checked and mounted from the selected `fstab`, either
the default `/etc/fstab`, or any custom one selected from the command
line, or at build time.
To provide a smooth ride, file system not listed in the given `fstab`,
e.g. `/tmp` and `/run`, are automatically mounted by Finit, as listed
above, provided their respective mount point exists.
With all filesystems mounted, Finit calls `swapon`.
> [!TIP]
> To see what happens when all filesystems are mounted, have a look at
> the [`bootmisc.so` plugin](../plugins.md).
At shutdown, and after having stopped all services and other lingering
processes have been killed, filesystems are unmounted in the reverse
order, and `swapoff` is called.
[FHS]: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
Managing Services
-----------------
Using `initctl disable my-service` the symlink (above) is removed and
the service is queued for removal. Several changes can be made to the
system, but it is not until `initctl reload` is called that the changes
are activated.
To add a new static service, drop a `.conf` file in `/etc/finit.d/` and
run `initctl reload`. (It is also possible to `SIGHUP` PID 1, or call
`finit q`, but that has been deprecated with the `initctl` tool). Finit
monitors all known active `.conf` files, so if you want to force a
restart of any service you can touch its corresponding `.conf` file in
`/etc/finit.d` and call `initctl reload`. Finit handles all conditions
and dependencies between services automatically, see the section on
[Service Synchronization](service-sync.md) for more details.
On `initctl reload` the following is checked for all services:
- If a service's `.conf` file has been removed, or its conditions are no
longer satisfied, the service is stopped.
- If the file is modified, or a service it depends on has been reloaded,
the service is reloaded (stopped and started).
- If a new service is added it is automatically started — respecting
runlevels and return values from any callbacks.
For more info on the different states of a service, see the separate
document [Finit Services](../service.md).
Alternate finit.d/
------------------
**Syntax:** `rcsd /path/to/finit.d`
The Finit rcS.d directory is set at compile time with:
./configure --with-rcsd=/etc/finit.d
A system with multiple use-cases may be bootstrapped with different
configurations, starting with the kernel command line option:
-- finit.config=/etc/factory.conf
This file in turn can use the `rcsd` directive to tell Finit to use
another set of .conf files, e.g.:
rcsd /etc/factory.d
> [!NOTE]
> This directive is only available from the top-level bootstrap .conf
> file, usually `/etc/finit.conf`.
Including Finit Configs
------------------------
**Syntax:** `include <CONF>`
Include another configuration file. Absolute path required.
-30
View File
@@ -1,30 +0,0 @@
This section provides an overview of Finit's configuration system. For
detailed information on specific topics, see the individual sections in
the navigation menu.
Configuration File Syntax
--------------------------
The file format is line based, empty lines and comments, lines starting
with `#`, are ignored. A configuration directive starts with a keyword
followed by a space and the rest of the line is treated as the value.
As of Finit v4.4, configuration directives can be broken up in multiple
lines using the continuation character `\`, and trailing comments are
also allowed. Example:
```aconf
# Escape \# chars if you want them literal in, e.g., descriptions
service name:sysklogd [S123456789] \
env:-/etc/default/sysklogd \
syslogd -F $SYSLOGD_ARGS \
-- System log daemon \# 1 # Comments allowed
```
The .conf files `/etc/finit.conf` and `/etc/finit.d/*` support many
directives. Some are restricted, e.g., only available at bootstrap,
runlevel `S`. Read on in [Files & Layout](files.md) for more on how
to structure your .conf files.
For details on restrictions, see [Limitations](limitations.md).
-21
View File
@@ -1,21 +0,0 @@
Limitations
===========
As of Finit v4 there are no limitations to where `.conf` settings can be
placed. Except for the system/global `rlimit` and `cgroup` top-level
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.
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 `.conf` file in `/etc/finit.d`.
There is, however, nothing preventing you from having all configuration
settings in `/etc/finit.conf`.
> [!IMPORTANT]
> The default `rcsd`, i.e., `/etc/finit.d`, was previously the Finit
> [runparts](runparts.md) directory. Finit >=v4.0 no longer has a
> default `runparts` directory, make sure to update your setup, or the
> finit configuration, accordingly.
-63
View File
@@ -1,63 +0,0 @@
General Logging
===============
**Syntax:** `log size:200k count:5`
Log rotation for run/task/services using the `log` sub-option with
redirection to a log file. Global setting, applies to all services.
The size can be given as bytes, without a specifier, or in `k`, `M`,
or `G`, e.g. `size:10M`, or `size:3G`. A value of `size:0` disables
log rotation. The default is `200k`.
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.
Redirecting Output
------------------
The `run`, `task`, and `service` stanzas also allow the keyword `log` to
redirect `stderr` and `stdout` of the application to a file or syslog
using the native `logit` tool. This is useful for programs that do not
support syslog on their own, which is sometimes the case when running
in the foreground.
The full syntax is:
log:/path/to/file
log:prio:facility.level,tag:ident
log:console
log:null
log
Default `prio` is `daemon.info` and default `tag` is the basename of the
service or run/task command.
Log rotation is controlled using the global `log` setting.
**Example:**
service log:prio:user.warn,tag:ntpd /sbin/ntpd pool.ntp.org -- NTP daemon
Output Buffering
----------------
When using the `log` directive, Finit redirects the service's stdout and
stderr to a pipe connected to a logger process. Programs detect this as
non-interactive output (i.e., `isatty()` returns false) and typically
switch from line-buffered to fully-buffered mode.
Most well-behaved daemons explicitly flush their output or use syslog
directly, so this is rarely an issue. However, if a service's log
messages appear delayed or batched, you can force line-buffered output
by wrapping the command with `stdbuf`:
service log /usr/bin/stdbuf -oL /path/to/command -- My service
The `-oL` option forces line-buffered output, and `-o0` forces unbuffered
output. See `stdbuf(1)` for details.
> [!NOTE]
> Using `stdbuf` is rarely necessary. Only use it if you observe actual
> buffering issues with a specific service.
-62
View File
@@ -1,62 +0,0 @@
Rescue Mode
===========
Finit supports a rescue mode which is activated by the `rescue` option
on the kernel command line. See [cmdline docs](../cmdline.md) for how to
activate it.
This rescue mode can be disabled at configure time using:
configure --without-rescue
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
-----------
This is what most users expect. A very early maintenance login prompt,
served by the system `sulogin` program from util-linux, or BusyBox. If
that is not found in `$PATH`, the bundled `/libexec/finit/sulogin`
program is used instead. If a successful login is made, or if the user
exits (Ctrl-D), the rescue mode is ended and the system boots up
normally.
> [!WARNING]
> The bundled sulogin in Finit can at configure time be given another
> user than the default (root). If the sulogin user does not have a
> password, or __the account is locked__, the user is presented with a
> prompt: `"Press enter to enter maintenance mode."`, which will open
> up a root shell *without prompting for password*!
Fallback
--------
If no `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 `/etc/fstab`, no `/etc/rc.local`,
no `runparts`, and most plugins are skipped (except those that provide
functionality for the condition subsystem).
Instead of reading `/etc/finit.conf` et al, system configuration is read
from `/lib/finit/rescue.conf`, which can be freely modified by the
system administrator.
The bundled default `rescue.conf` contains nothing more than:
runlevel 1
tty [12345] rescue
The `tty` has the `rescue` option set, which works similar to the board
bring-up tty option `notty`. The major difference being that `sulogin`
is started to query for root/admin password. If `sulogin` is not found,
`rescue` behaves like `notty` and gives a plain root shell prompt.
If Finit cannot find `/lib/finit/rescue.conf` it defaults to:
tty [12345] rescue
There is no way to exit the *fallback* rescue mode.
-187
View File
@@ -1,187 +0,0 @@
Runlevels
=========
Finit supports runlevels, but unlike other init systems runlevels are
declared per service/run/task/sysv command. When booting up a system
Finit pass through three phases:
1. Setting up the console, parsing any command line options, and other
housekeeping tasks like mounting all filesystems, and calling `fsck`
2. Starting all run/task/services in runlevel S, then waiting for all
services to have started, and all run/tasks to have completed
3. Go to runlevel 2, or whatever the user has set in the configuration
Available runlevels:
- ` S`: bootStrap
- ` 1`: Single user mode
- `2-5`: traditional multi-user mode
- ` 6`: reboot
- `7-9`: multi-user mode (extra)
- ` 0`: shutdown
Runlevel S (bootStrap), is for tasks supposed to run once at boot, and
services like `syslogd`, which need to start early and run throughout
the lifetime of your system.
Example:
task [S] /lib/console-setup/console-setup.sh
service [S12345] env:-/etc/default/rsyslog rsyslogd -n $RSYSLOGD_ARGS
When bootstrap has completed, Finit moves to runlevel 2. This can be
changed in `/etc/finit.conf` using the `runlevel N` directive, or by a
script running in runlevel S that calls, e.g., `initctl runlevel 9`.
The latter is useful if startup scripts detect problems outside of
Finit's control, e.g., critical services/devices missing or hardware
problems.
Each runlevel must be allowed to "complete". Meaning, all services in
runlevel S must have started and all run/tasks have been started and
collected (exited). Finit waits 120 seconds for all run/tasks in S to
complete before proceeding to 2.
Finit first stops everything that is not allowed to run in 2, and then
brings up networking. Networking is expected to be available in all
runlevels except: S, 1 (single user level), 6, and 0. Networking is
enabled either by the `network script` directive, or if you have an
`/etc/network/interfaces` file, Finit calls `ifup -a` -- at the very
least the loopback interface is brought up.
> [!NOTE]
> When moving from runlevel S to 2, all run/task/services that were
> constrained to runlevel S only are dropped from bookkeeping. So when
> reaching the prompt, `initctl` will not show these run/tasks. This is
> a safety mechanism to prevent bootstrap-only tasks from accidentally
> being run again. E.g., `console-setup.sh` above.
Runlevel Configuration
----------------------
**Syntax:** `runlevel <N>`
The system runlevel to go to after bootstrap (S) has completed. `N` is
the runlevel number 0-9, where 6 is reserved for reboot and 0 for halt.
Completed in this context means all services have been started and all
run/tasks have been started and collected.
It is recommended to keep runlevel 1 as single-user mode, because
Finit disables networking in this mode.
*Default:* 2
> [!NOTE]
> Only read and executed in runlevel S (bootstrap).
Networking
----------
**Syntax:** `network <PATH>`
Script or program to bring up networking, with optional arguments.
Deprecated. We recommend using dedicated task/run stanzas per runlevel,
or `/etc/network/interfaces` if you have a system with `ifupdown`, like
Debian, Ubuntu, Linux Mint, or an embedded BusyBox system.
> [!NOTE]
> Only read and executed in runlevel S (bootstrap).
System Hostname
---------------
**Syntax:** `host <NAME>`, or `hostname <NAME>`
Set system hostname to NAME, unless `/etc/hostname` exists in which case
the contents of that file is used.
Deprecated. We recommend using `/etc/hostname` instead.
> [!NOTE]
> Only read and executed in runlevel S (bootstrap).
Kernel Modules
--------------
**Syntax:** `module <MODULE> [ARGS]`
Load a kernel module, with optional arguments. Similar to `insmod`
command line tool.
Deprecated, there is both a `modules-load.so` and a `modprobe.so` plugin
that can handle module loading better. The former supports loading from
`/etc/modules-load.d/`, the latter uses kernel modinfo to automatically
load (or coldplug) every required module. For hotplug we recommend the
BusyBox mdev tool, add to `/etc/mdev.conf`:
$MODALIAS=.* root:root 0660 @modprobe -b "$MODALIAS"
> [!NOTE]
> Only read and executed in runlevel S (bootstrap).
Resource Limits
---------------
**Syntax:** `rlimit [hard|soft] RESOURCE <LIMIT|unlimited>`
Set the hard or soft limit for a resource, or both if that argument is
omitted. `RESOURCE` is the lower-case `RLIMIT_` string constants from
`setrlimit(2)`, without prefix. E.g. to set `RLIMIT_CPU`, use `cpu`.
LIMIT is an integer that depends on the resource being modified, see
[setrlimit(2)](https://man7.org/linux/man-pages/man2/setrlimit.2.html),
or the kernel `/proc/PID/limits` file, for details. Finit versions
before v3.1 used `infinity` for `unlimited`, which is still supported,
albeit deprecated.
# 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
`rlimit` can be set globally, in `/etc/finit.conf`, or locally per
each `/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.
Miscellaneous Settings
----------------------
**Syntax:** `reboot-delay <0-60>`
Optional delay at reboot (or shutdown or halt) to allow kernel
filesystem threads to complete after calling `sync(2)` before
rebooting. This applies primarily to filesystems that do not
have a reboot notifier implemented. At the point of writing,
the only known filesystems affected are: ubifs, jffs2.
*Default:* 0 (disabled)
When enabled (non-zero), this delay runs after file systems have been
unmounted and the root filesystem has been remounted read-only, and
sync(2) has been called, twice.
> "On Linux, sync is only guaranteed to schedule the dirty blocks for
> writing; it can actually take a short time before all the blocks are
> finally written.
**Syntax:** `reboot-watchdog <on|off|true|false|1|0>`
Controls whether the system should reboot via the watchdog timer (WDT)
or directly via the SoC/kernel. When enabled, Finit will:
1. Send `SIGPWR` to the registered watchdog daemon before shutdown
2. Send `SIGTERM` to the watchdog daemon and wait up to 10 seconds
for the watchdog to trigger a hardware reset
When disabled (default), Finit skips the watchdog reboot logic and
calls the kernel's `reboot(2)` syscall directly for a clean SoC reboot.
*Default:* off (reboot via SoC)
> [!NOTE]
> This setting only affects reboots. The watchdog daemon will still
> run and monitor the system during normal operation.
-51
View File
@@ -1,51 +0,0 @@
Run-parts Scripts
-----------------
**Syntax:** `runparts [progress] [sysv] <DIR>`
Call [run-parts(8)][] on `DIR` to run start scripts. All executable
files in the directory are called, in alphabetic order. The scripts in
this directory are executed at the very end of runlevel `S`.
A common use-case for runparts scripts is to create and enable/disable
services, which Finit will then apply when changing runlevel from S to
whatever the next runlevel is set to be (default 2). E.g., generate a
`/etc/chrony.conf` and call `initctl enable chronyd`.
**Options:**
- `progress`: display the progress of each script being executed
- `sysv`: run only SysV style scripts, i.e., `SNNfoo`, or `KNNbar`,
where `NN` is a number (0-99).
If global debug mode is enabled, the `runparts` program is also called
with the debug flag.
**Limitations:**
Scripts called from `runparts`, or hook scripts (see below), are limited
in their interaction with Finit. Like the standalone `run` stanza and
the `/etc/rc.local` shell script, Finit waits for their completion
before continuing. None of them can issue commands to start, stop, or
restart other services. Also, ensure all your services and programs
either terminate or start in the background or you will block Finit.
> [!NOTE]
> `runparts` scripts are only read and executed in runlevel S. See
> [hook scripts](../plugins.md#hooks) for other ways to run scripts at
> certain points during the complete lifetime of the system.
**Recommendations:**
It can be beneficial to use `01-name`, `02-othername`, etc., to ensure
the scripts are started in that order, e.g., if there is a dependency
order between scripts. Symlinks to existing daemons can talso be used,
but make sure they daemonize (background) themselves properly, otherwise
Finit will lock up.
If `S[0-9]foo` and `K[0-9]bar` style naming is used, the executable will
be called with an extra argument, `start` and `stop`, respectively.
E.g., `S01foo` will be called as `S01foo start`. Of course, `S01foo`
and `K01foo` may be a symlink to to `another/directory/foo`.
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
-27
View File
@@ -1,27 +0,0 @@
Service Environment
-------------------
Finit supports sourcing environment variables from `/etc/default/*`, or
similar `--with-sysconfig=DIR`. This is a common pattern from SysV init
scripts, where the start-stop script is a generic script for the given
service, `foo`, and the options for the service are sourced from the
file `/etc/default/foo`. Like this:
* `/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
Here the service `foo` is started with `-n`, to make sure it runs in the
foreground, and the with the options found in the environment file. With
the `ps` command we can see that the process is started with:
foo -n --extra-arg=bar -s -x
> [!NOTE]
> The leading `-` in `env:` 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 *not* block the start.
-141
View File
@@ -1,141 +0,0 @@
Service Options
===============
The run/task/tty/service/sysv directives take modifiers, or options, to
control their behavior. This section lists them with their limitations.
All modifiers must be placed between the directive and its command.
The name of a service, shown by the `initctl` tool, defaults to the
basename of the service executable. It can be changed with the `name:`
option:
name:<service-name>
For multiple instances of a service, with the same `name`, set the
identifier `:ID` to prevent Finit from replacing previous instances:
service name:ssdp :eth1 ssdpd eth1 -- Windows discovery on eth1
service name:ssdp :eth2 ssdpd eth2 -- Windows discovery on eth2
The [`initctl`](../initctl.md) tool will list these two services as:
- ssdp:eth1
- ssdp:eth2
Conflicting services that must be prevented from starting, use the
`conflict:` option:
service [S12345789] udevd -- Device event management daemon
run [S] conflict:udevd mdev -s -- Populating device tree
Multiple conflicting services can be separated using `,`:
service :1 abc
service :2 abc
service conflict:abc:1,abc:2 cde
If a service should not be automatically started, it can be configured
as manual with the optional `manual` argument. The service can then be
started at any time by running `initctl start <service>`.
manual:yes
Other run/task/service options are:
* `caps:...` -- see the [Linux Capabilities](capabilities.md) section
* `cgroup.NAME[,opts]` or `cgroup:opts` -- see the [Cgroups](cgroups.md) section
* `env:[-]/path/to/env` -- see the [Service Environment](service-env.md) section
* `log:...` -- see [Redirecting Output](logging.md#redirecting-output)
* `tty:<dev>` -- see [Controlling TTY](tty.md#controlling-tty)
* `nowarn` -- see [Conditional Loading](services.md#conditional-loading)
* `notify:...` -- see [Service Synchronization](service-sync.md)
* `if:...` -- see [Conditional Execution](services.md#conditional-execution)
* `type:forking` -- see description of the [service](services.md) directive
As mentioned previously, services are automatically started, restarted,
and stopped, depending on the configuration and conditions. Within the
confines of that the following options are available:
* `restart:NUM` -- number of times Finit tries to restart a crashing
service, default: 10, max: 255. When this limit is reached the
service is marked *crashed* and must be restarted manually with
`initctl restart NAME`
* `restart_sec:SEC` -- number of seconds before Finit tries to restart
a crashing service, default: 2 seconds for the first five retries,
then back-off to 5 seconds. The maximum of this configured value
and the above (2 and 5) will be used
* `restart:always` -- no upper limit on the number of times Finit
tries to restart a crashing service. Same as `restart:-1`
* `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
* `remain:yes` -- for `run` and `task` only. Prevents the task from
re-running on runlevel re-entry and ensures the `post:` script runs
when the task is explicitly stopped or leaves its valid runlevels.
Similar to systemd's `RemainAfterExit=yes`. See [Task and Run](task-and-run.md)
for more details
* `oncrash:reboot` -- when all retries have failed, and the service
has *crashed*, if this option is set the system is rebooted
* `oncrash:script` -- similarly, but instead of rebooting, call the
`post:script` action with exit code `crashed`, see below
* `reload:'script [args]'` -- some services do not support `SIGHUP` but
may have other ways to update the configuration of a running daemon.
When `reload:script` is defined it is preferred over `SIGHUP`. Like
systemd, Finit sets `$MAINPID` as a convenience to scripts, which in
effect also allow `reload:'kill -HUP $MAINPID'`
* `stop:'script [args]'` -- some services may require alternate methods
to be stopped. If a `stop:script` is defined it is preferred over
`SIGTERM` and `stop`, for `service` and `sysv`, respectively.
Similar to `reload:script`, Finit sets `$MAINPID`
> [!CAUTION]
> Both `reload:script` and `stop:script` are called as PID 1, without
> any timeout! Meaning, it is up to you to ensure the script is not
> blocking for seconds at a time or never terminates.
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 (unless a `stop:'script'` is used).
However, if the process has not been collected within 3 seconds, Finit
will send `SIGKILL`. To stop the process using a different signal than
`SIGTERM`, use `halt:SIGNAL`, e.g., `halt:SIGPWR`. To change the delay
between the stop signal and KILL, use the option `kill:<1-60>`, e.g.,
`kill:10` to wait 10 seconds before sending `SIGKILL`.
Services, including the `sysv` variant, support pre/post/ready and
cleanup scripts:
* `pre:[0-3600,]script` -- called before the sysv/service is stated
* `post:[0-3600,]script` -- called after the sysv/service has stopped
* `ready:[0-3600,]script` -- called when the sysv/service is ready
* `cleanup:[0-3600,]script` -- called when run/task/sysv/service is removed
The optional number (0-3600) is the timeout before Finit kills the
script, it defaults to the kill delay value and can be disabled by
setting it to zero. These scripts run as the same `@USER:GROUP` as the
service itself, with any `env:file` sourced. The scripts are executed
from the `$HOME` of the given user. The scripts are not called with any
argument, but get a set of environment variables:
* `SERVICE_IDENT=foo:1`
* `SERVICE_NAME=foo`
* `SERVICE_ID=1`
The `post:script` is called with an additional set of environment
variables. Yes, the text is correct, the naming was an accident:
- `EXIT_CODE=[exited,signal,crashed]`: normal exit, signaled, or
crashed
- `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
When a run/task/sys/service is removed (disable + reload) it is first
stopped and then removed from the runlevel. The `post:script` always
runs when the process has stopped, and the `cleanup:script` runs when
the the stanza has been removed from the runlevel.
> [!IMPORTANT]
> These script actions are intended for setup, cleanup, and readiness
> notification. It is up to the user to ensure the scripts terminate.
-74
View File
@@ -1,74 +0,0 @@
Service Synchronization
=======================
Finit was created for fast booting systems. Faster than a regular SysV
Init based system at the time. Early on the need for a guaranteed start
order of services (daemons) arose. I.e., service `A` must be guaranteed
to have started (and be ready!) before `B`. The model that was chosen
to determine this was very simple: PID files.
Early on in UNIX daemons were controlled with basic IPC like signals,
and the way for a user to know that a daemon was ready to respond to
signals (minimally having set up its signal handler), was to tell the
user;
> "Hey, you can send signals to me using the PID in this file:
> `/var/run/daemon.pid`".
Since most systems run fairly unchanged after boot, Finit could rely on
the PID file for `A` being created before launching `B`. This method
has worked well for a long time, and for systems based on Open Source it
was easy to either add PID file support to a daemon without support for
it, or fix ordering issues (PID file created before signal handler is
set up) in existing daemons.
However, with the advent of other Init systems (Finit is rather old),
most notably systemd and s6, other methods for signaling "readiness"
arrived and daemons were adapted to these new schemes to a larger
extent.
As of Finit v4.4 partial support for systemd and s6 style readiness
notification is available, and the native PID file mode of operation is,
as of Finit v4.6 optional, by default it is still enabled, but this can
be changed in `finit.conf`:
readiness none
This will be made the default in Finit 5.0. In this mode of operation,
every service needs to explicitly declare their readiness notification,
like this:
service notify:pid watchdogd
service notify:systemd foo
service notify:s6 bar
service notify:none qux
The `notify:none` syntax is for completeness in systems which run in
`readiness pid` mode (default). Services declared with `notify:none`
will transition to ready as soon as Finit has started them, e.g.,
`service/qux/ready`.
To synchronize two services the following condition can be used:
service notify:pid watchdogd
service <service/watchdogd/ready> stress-ng --cpu 8
For details on the syntax and options, see below.
> [!NOTE]
> On `initctl reload` conditions are set in "flux", while figuring out
> which services to stop, start or restart. Services that need to be
> restarted have their `ready` condition removed before Finit issue a
> SIGHUP (if they support that), or stop-starting them. A daemon is
> expected to reassert its readiness, e.g. systemd style daemons to
> write `READY=1\n`.
>
> However, the s6 notify mode does not support this because in s6 you
> are expected to close your notify descriptor after having written
> `\n`. This means s6 style daemons currently must be stop-started.
> (Declare the service with `<!>` in its condition statement.)
>
> For default, PID file style readiness notification, daemons are
> expected to either create their PID files, or touch it using
> `utimensat()` to reassert readiness. Triggering both the `<pid/>`
> and `<.../ready>` conditions.
-31
View File
@@ -1,31 +0,0 @@
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.
The Finit service `.conf` file can be put into `/etc/finit.d/available`,
so you can control the service using `initctl`. Then use the path to
the wrapper script in the Finit `.conf` service stanza. The following
example employs a wrapper script in `/etc/start.d`.
**Example:**
* `/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
> [!NOTE]
> The example sets `<!>` to denote that it doesn't support `SIGHUP`.
> That way Finit will stop/start the service instead of sending SIGHUP
> at restart/reload events.
-224
View File
@@ -1,224 +0,0 @@
Services
========
**Syntax:** `service [LVLS] <COND> /path/to/daemon ARGS -- Optional description`
Service, or daemon, to be monitored and automatically restarted if it
exits prematurely. Finit tries to restart services that die, by default
10 times before giving up and marking them as *crashed*. After which
they have to be manually restarted with `initctl restart NAME`. The
limits controlling this are configurable, see the options below.
> [!TIP]
> To allow endless restarts, see the [`respawn` option](service-opts.md)
For daemons that support it, we recommend appending `--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.
However, not all daemons support running in the foreground, or they may
start logging to the foreground as well, these are forking daemons and
are supported using the same syntax as forking `sysv` services, using
the `pid:!/path/to/pidfile.pid` syntax. There is an alternative syntax
that may be more intuitive, where Finit can also guess the PID file
based on the daemon's command name:
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:**
In the case of `ospfd` (below), we omit the `-d` flag (daemonize) to
prevent it from forking to the background:
service [2345] <pid/zebra> /sbin/ospfd -- OSPF daemon
`[2345]` denote the runlevels `ospfd` is allowed to run in, they are
optional and default to level 2-5 if omitted.
`<...>` is the condition for starting `ospfd`. In this example Finit
waits for another service, `zebra`, to have created its PID file in
`/var/run/quagga/zebra.pid` before starting `ospfd`. Finit watches
*all* files in `/var/run`, for each file named `*.pid`, or `*/pid`,
Finit opens it and find the matching `NAME:ID` using the PID.
The condition can be prefixed with `!` and/or `~`:
- `<!pid/zebra>` -- `ospfd` does not support `SIGHUP` (noreload)
- `<~pid/zebra>` -- propagate reload from `zebra` to `ospfd`
- `<!~pid/zebra>` -- both: noreload and propagate reload
For details, see the [Finit Conditions](../conditions.md) document.
Some services do not maintain a PID file and rather than patching each
application Finit provides a workaround. A `pid` 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 `/var/run`
directory using the `basename(1)` of the service. The default can be
modified with an optional `pid:`-argument:
pid[:[/path/to/]filename[.pid]]
For example, by adding `pid:/run/bar.pid` to the service `/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 `<pid/bar>`, like this foo will not be started until bar
has started:
service pid:/run/bar.pid bar -- Bar Service
service <pid/bar> foo -- Foo Service
Needless to say, it is better if `bar` creates its own PID file when it
has completed starting up and is ready for service.
As an alternative "readiness" notification, Finit supports both systemd
and s6 style notification. This can be enabled by using the `notify`
option:
* `notify:systemd` -- tells Finit the service uses the `sd_notify()`
API to signal PID 1 when it has completed its startup and is ready
to service events. The [sd_notify()][] API expects `NOTIFY_SOCKET`
to be set to the socket where the application can send `"READY=1\n"`
when it is starting up or has processed a `SIGHUP`.
* `notify:s6` -- puts Finit in s6 compatibility mode. Compared to the
systemd notification, [s6 expect][] compliant daemons to send `"\n"`
and then close their socket. Finit takes care of "hard-wiring" the
READY state as long as the application is running, events across any
`SIGHUP`. Since s6 can give its applications the descriptor number
(must be >3) on then command line, Finit provides the following
syntax (`%n` is replaced by Finit with then descriptor number):
service [S12345789] notify:s6 mdevd -O 4 -D %n
[sd_notify()]: https://www.freedesktop.org/software/systemd/man/sd_notify.html
[s6 expect]: https://skarnet.org/software/s6/notifywhenup.html
When a service is ready, either by Finit detecting its PID file, or
their respective readiness mechanism has been triggered, Finit creates
then service's ready condition which other services can depend on:
$ initctl -v cond get service/mdevd/ready
on
This can be used to synchronize the start of another run/task/service:
task [S] <service/mdevd/ready> @root:root mdevd-coldplug
Finit waits for `mdevd` to notify it, before starting `mdevd-coldplug`.
Notice how both start in runlevel S, and the coldplug task only runs in
S. When the system moves to runlevel 2 (the default), coldplug is no
longer part of the running configuration (`initctl show`), this is to
ensure that coldplug is not called more than once.
> For a detailed description of conditions, and how to debug them,
> see the [Finit Conditions](../conditions.md) document.
Non-privileged Services
-----------------------
Every `run`, `task`, or `service` can also list the privileges the
`/path/to/cmd` should be executed with. Prefix the command with
`@USR[:GRP[,SUPP,...]]`, where group and supplementary groups are
optional, like this:
run [2345] @joe:users logger "Hello world"
Finit reads the user's supplementary group membership from `/etc/group`
automatically. Any groups the user belongs to will be inherited by
the service.
To specify additional supplementary groups beyond those in `/etc/group`,
append them after the primary group, separated by commas:
service @caddy:caddy,ssl-cert /usr/bin/caddy run
This runs the `caddy` service as user `caddy`, with primary group
`caddy`, inheriting any groups `caddy` is a member of in `/etc/group`,
plus the additional `ssl-cert` group. This is useful when a service
needs access to resources owned by groups not listed in `/etc/group`.
For multiple instances of the same command, e.g. a DHCP client or
multiple web servers, add `:ID` somewhere between the `run`, `task`,
`service` keyword and the command, like this:
service :80 [2345] httpd -f -h /http -p 80 -- Web server
service :8080[2345] httpd -f -h /http -p 8080 -- Old web server
Without the `:ID` to the service the latter will overwrite the former
and only the old web server would be started and supervised.
Conditional Loading
-------------------
Finit support conditional loading of stanzas. The following example is
take from the `system/hotplug.conf` file in the Finit distribution.
Here we only show a simplified subset.
Starting with the `nowarn` option.
service nowarn name:udevd pid:udevd /lib/systemd/systemd-udevd
service nowarn name:udevd pid:udevd udevd
When loading the .conf file Finit looks for `/lib/systemd/systemd-udevd`
if that is not found Finit automatically logs a warning. The `nowarn`
option disables this warning so that the second line can be evaluated,
which also provides a service named `udevd`.
run nowarn if:udevd <pid/udevd> :1 udevadm settle -t 0
This line is only loaded if we know of a service named `udevd`. Again,
we do not warn if `udevadm` is not found, execution will also stop here
until the PID condition is asserted, i.e., Finit detecting udevd has
started.
run nowarn conflict:udevd [S] mdev -s -- Populating device tree
If `udevd` is not available, we try to run `mdev`, but if that is not
found, again we do not warn.
Conditional loading statements can also be negated, so the previous stanza
can also be written as:
run nowarn if:!udevd [S] mdev -s -- Populating device tree
The reason for using `conflict` in this example is that a conflict can be
resolved. Stanzas marked with `conflict:foo` are rechecked at runtime.
Conditional Execution
---------------------
Similar to conditional loading of stanzas there is conditional runtime
execution. This can be confusing at first, since Finit already has a
condition subsystem, but this is more akin to the qualification to a
runlevel. E.g., a `task [123]` is qualified to run only in runlevel 1,
2, and 3. It is not considered for other runlevels.
Conditional execution qualify a run/task/service based on a condition.
Consider this (simplified) example from the Infix operating system:
run [S] name:startup <pid/sysrepo> confd -b --load startup-config
run [S] if:<usr/fail-startup> name:failure <pid/sysrepo> confd --load failure-config
The two run statements reside in the same .conf file so Finit runs them
in true sequence. If loading the file `startup-config` fails confd sets
the condition `usr/fail-startup`, thus allowing the next run statement
to load `failure-config`.
Notice the critical difference between the `<pid/sysrepo>` condition and
`if:<usr/fail-startup>`. The former is a condition for starting and the
latter is a condition to check if a run/task/service is qualified to
even be considered.
Conditional execution statements can also be negated, so provided the
file loaded did the opposite, i.e., set a condition on success, the
previous stanza can also be written as:
run [S] if:<!usr/startup-ok> name:failure <pid/sysrepo> confd ...
-94
View File
@@ -1,94 +0,0 @@
SysV Init Compatibility
=======================
It is not possible to run unmodified SysV init systems with Finit. This
was never the intention and is not the strength of Finit. However, it
comes with a few SysV Init compatibility features to ease the transition
from a serialized boot process.
SysV Init Scripts
-----------------
**Syntax:** `sysv [LVLS] <COND> /path/to/init-script -- Optional description`
> `<COND>` is described in the [Services](services.md) section.
Similar to `task` is the `sysv` stanza, which can be used to call SysV
style scripts. The primary intention for this command is to be able to
reuse much of existing setup and init scripts in Linux distributions.
When entering an allowed runlevel, Finit calls `init-script start`, when
entering a disallowed runlevel, Finit calls `init-script stop`, and if
the Finit .conf, where `sysv` stanza is declared, is modified, Finit
calls `init-script restart` on `initctl reload`. Similar to how
`service` stanzas work.
Forking services started with `sysv` scripts can be monitored by Finit
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`.
> [!TIP]
> See also [SysV Init Compatibility](#sysv-init-compatibility).
`runparts DIRECTORY`
--------------------
For a directory with traditional start/stop scripts that should run, in
order, at bootstrap, Finit provides the `runparts` directive. It runs
in runlevel S, at the very end of it (before calling `/etc/rc.local`)
making it perfect for most scenarios.
For syntax details, see the [Run-parts Scripts](runparts.md) section.
Here is an example take from a Debian installation:
runparts /etc/rc2.d
Files in these directories are usually named `SNNfoo` and `KNNfoo`,
which Finit knows about and automatically appends the correct argument:
/bin/sh -c /etc/rc2.d/S01openbsd-inetd start
or
/bin/sh -c /etc/rc0.d/K01openbsd-inetd stop
Files that do not match this pattern are started similarly but without
the extra command line argument.
Start/Stop Scripts
------------------
For syntax details, see [SysV Init Scripts](#sysv-init-scripts), above.
Here follows an example taken from a Debian installation:
sysv [2345] <pid/syslogd> /etc/init.d/openbsd-inetd -- OpenBSD inet daemon
The init script header could be parsed to extract `Default-Start:` and
other parameters for the `sysv` command to Finit. There is currently no
way to detail a generic syslogd dependency in Finit, so `Should-Start:`
in the header must be mapped to the condition system in Finit using an
absolute reference, here we depend on the sysklogd project's syslogd.
`/etc/rc.local`
---------------
One often requested feature, early on, was a way to run a site specific
script to set up, e.g., static routes or firewall rules. A user can add
a `task` or `run` command in the Finit configuration for this, but for
compatibility reasons the more widely know `/etc/rc.local` is used if
it exists, and is executable. It is called very late in the boot process
when the system has left runlevel S, stopped all old and started all new
services in the target runlevel (default 2).
> In Finit releases before v4.5 this script blocked Finit execution and
> made it as good as impossible to call `initctl` during that time.
`init q`
--------
When `/sbin/finit` is installed as `/sbin/init`, it is possible to use
`init q` to reload the configuration. This is the same as calling
`initctl reload`.
-87
View File
@@ -1,87 +0,0 @@
run (sequence)
--------------
**Syntax:** `run [LVLS] <COND> /path/to/cmd ARGS -- Optional description`
> `<COND>` is described in the [Services](services.md) section.
One-shot command to run in sequence when entering a runlevel, with
optional arguments and description. `run` commands are guaranteed to be
completed before running the next command. Useful when serialization is
required.
> [!WARNING]
> Try to avoid the `run` command. It blocks much of the functionality
> in Finit, like (re)starting other (perhaps crashing) services while a
> `run` task is executing. Use other synchronization mechanisms
> instead, like conditions.
Incomplete list of unsupported `initctl` commands in `run` tasks:
- `initctl runlevel N`, setting runlevel
- `initctl reboot`
- `initctl halt`
- `initctl poweroff`
- `initctl suspend`
To prevent `initctl` from calling Finit when enabling and disabling
services from inside a `run` task, use the `--force` option. See
also the `--quiet` and `--batch` options.
task (parallel)
---------------
**Syntax:** `task [LVLS] <COND> /path/to/cmd ARGS -- Optional description`
> `<COND>` is described in the [Services](services.md) section.
One-shot like 'run', but starts in parallel with the next command.
Both `run` and `task` commands are run in a shell, so basic pipes and
redirects can be used:
task [s] echo "foo" | cat >/tmp/bar
Please note, `;`, `&&`, `||`, and similar are *not supported*. Any
non-trivial constructs are better placed in a separate shell script.
remain:yes
----------
By default, a `run` or `task` will re-run each time its runlevel is
entered, and its `post:` script does not run on completion.
With `remain:yes`, the task runs once and does not re-run on runlevel
re-entry:
task [2345] remain:yes /usr/sbin/setup-firewall -- Firewall setup
This has the following effects:
* The task does not re-run on runlevel re-entry
* The `post:` script runs when:
- The task is explicitly stopped (`initctl stop NAME`)
- The task leaves its valid runlevels (e.g., runlevel change)
This is useful for tasks that set up persistent state where:
* Cleanup should only happen on explicit stop or when leaving valid runlevels
* The setup should not be re-run on every runlevel entry
**Example:** Setting up firewall rules with cleanup on shutdown:
```
task [2345] remain:yes \
post:/usr/sbin/teardown-firewall \
/usr/sbin/setup-firewall -- Firewall setup
```
The firewall rules are created once. The `post:` script runs when
entering runlevel 0 (halt) or 6 (reboot), or on explicit stop.
> [!NOTE]
> The `remain:yes` option is not supported for bootstrap-only tasks
> (tasks with only runlevel S). Bootstrap tasks are deleted immediately
> after completion, and their `post:` scripts never run. A warning is
> logged if `remain:yes` is used on such tasks.
-39
View File
@@ -1,39 +0,0 @@
Templating
==========
Finit comes with rudimentary support for templating, similar to that of
systemd. Best illustrated with an example:
$ initctl show avahi-autoipd@
service :%i avahi-autoipd --syslog %i -- ZeroConf for %i
To enable ZeroConf for, e.g., `eth0`, use
$ initctl enable avahi-autoipd@eth0.conf
The enabled symlink will be set up to `avahi-autoipd@.conf` and every
instance of `%i` will in the instantiated directive be replaced with
`eth0`. Inspect the resulting instantiated template with `initctl show
avahi-autoipd:eth0` and check the status of a running instance with:
```
$ initctl status avahi-autoipd:eth0
Status : running
Identity : avahi-autoipd:eth0
Description : ZeroConf for eth0
Origin : /etc/finit.d/enabled/avahi-autoipd@eth0.conf
Environment : -/etc/default/avahi-autoipd-eth0
Command : avahi-autoipd $AVAHI_AUTOIPD_ARGS eth0
PID file : /run/avahi-autoipd.eth0.pid
PID : 4190
User : root
Group : root
Uptime : 24 sec
Restarts : 0 (0/10)
Runlevels : [---2345-789]
Memory : 20.0k
CGroup : /system/avahi-autoipd@eth0 cpu 0 [100, max] mem [0, max]
└─ 4190 avahi-autoipd: [eth0] bound 169.254.1.9
Jul 8 11:51:42 infix-c0-ff-ee finit[1]: Starting avahi-autoipd:eth0[4190]
```
-113
View File
@@ -1,113 +0,0 @@
TTYs and Consoles
=================
**Syntax:** `tty [LVLS] <COND> DEV [BAUD] [noclear] [nowait] [nologin] [TERM]`
`tty [LVLS] <COND> CMD <ARGS> [noclear] [nowait]`
`tty [LVLS] <COND> [notty] [rescue]`
The first variant of this option uses the built-in getty on the given
TTY device DEV, in the given runlevels. DEV may be the special keyword
`@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 `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.
**Example:**
tty [12345] /dev/ttyAMA0 115200 noclear vt220
The second `tty` syntax variant is for using an external getty, like
agetty or the BusyBox getty.
The third variant is for board bringup and the `rescue` boot mode. No
device node is required in this variant, the same output that the kernel
uses is reused for stdio. If the `rescue` option is omitted, a shell is
started (`nologin`, `noclear`, and `nowait` are implied), if the rescue
option is set the bundled `/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. For more information,
see the [Rescue Mode](rescue.md) section.
By default, the first two syntax variants *clear* the TTY and *wait* for
the user to press enter before starting getty.
**Example:**
tty [12345] /sbin/getty -L 115200 /dev/ttyAMA0 vt100
tty [12345] /sbin/agetty -L ttyAMA0 115200 vt100 nowait
The `noclear` option disables clearing the TTY after each session.
Clearing the TTY when a user logs out is usually preferable.
The `nowait` option disables the `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.
The `nologin` option disables getty and `/bin/login`, and gives the
user a root (login) shell on the given TTY `<DEV>` immediately.
Needless to say, this is a rather insecure option, but can be very
useful for developer builds, during board bringup, or similar.
Notice the ordering, the `TERM` option to the built-in getty must be
the last argument.
Embedded systems may want to enable automatic `DEV` by supplying the
special `@console` device. This works regardless weather the system
uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else. Finit figures
it out by querying sysfs: `/sys/class/tty/console/active`. The speed
can be omitted to keep the kernel default.
> Most systems get by fine by just using `console`, which will evaluate
> to `/dev/console`. If you have to use `@console` to get any output,
> you may have some issue with your kernel config.
**Example:**
tty [12345] @console noclear vt220
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:
tty [12345789] notty
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.
One can also use the `service` stanza to start a stand-alone shell:
service [12345] /bin/sh -l
Controlling TTY for Services
----------------------------
The `tty:<dev>` option gives a `run`, `task`, or `service` a controlling
terminal on the given device. The device is opened, set as the
controlling terminal for the session (after `setsid()`), and connected to
the process's stdin, stdout, and stderr. A default `TERM` environment
variable is set based on the device type: `vt102` for serial lines and
`linux` for virtual terminals.
`<dev>` may be a device node like `/dev/ttyS0`, or the special keyword
`@console` (see above). Note that `@console` expands only to the
first console, not all.
When `tty:` is combined with `log:`, stdout and stderr are redirected
to the log sink instead of the TTY, but stdin remains connected to the
TTY device.
> The `tty:<dev>` option is for `run`, `task`, and `service` stanzas only.
> The `tty` directive itself (for getty/login) has its own syntax, see
> above.
**Example:**
service [2345] tty:/dev/ttyS0 /usr/sbin/foo -- Foo on serial console
task [S] tty:@console my-setup-script -- Board bringup on console
+45 -105
View File
@@ -1,139 +1,79 @@
Distro Recommendations
======================
Finit supports two directory layouts for managing service configurations:
1. **Simple layout** - all configuration files directly in `/etc/finit.d/`
2. **Distro layout** - separate `available/` and `enabled/` directories
The distro layout is recommended for distributions that need clear
separation between installed and enabled services, and want to use the
`initctl enable/disable` commands for service management.
## Simple Layout
Finit supports using a flat directory structure:
By default Finit uses the following directories for configuration files:
```
/etc/
|-- finit.d/ -- All enabled services
|-- finit.d/ -- Regular (enabled) services
| |-- lighttpd.conf
| `- *.conf
|-- finit.conf -- Bootstrap tasks and services
:
```
In this layout, you enable a service by placing its `.conf` file in
`/etc/finit.d/` and disable it by removing the file. This works well for
embedded systems or custom setups where services are managed by other tools
or generated dynamically.
To enable a service one simply drops a small configuration file in the
`/etc/finit.d/` directory. This practice works with systems that
keep disabled services elsewhere, or generates them as needed from some
other tool.
> [!NOTE] No tooling support
> The `initctl enable/disable` commands **do not work** with this layout.
> You must manually manage files in `/etc/finit.d/`.
Distributions, however, may want a clearer separation of enabled and
available (installed but not enabled) services. They may even want to
customize the directories used, for brand labeling or uniformity.
## Distro Layout
To that end Finit allows for a sub-directory `/etc/finit.d/available/`
where installed but disabled services can reside. Adding a symlink to a
configuration in this sub-directory enables the service, but it will not
be started.
Distributions typically want clearer separation between available (installed)
and enabled services. Finit supports this through the `available/` and
`enabled/` subdirectories:
```
/etc/
|-- finit.d/
| |-- available/ -- Installed but disabled services
| | |-- httpd.conf
| | |-- ntpd.conf
| | `-- sshd.conf
| |-- enabled/ -- Enabled services (symlinks)
| | `- sshd.conf -- Symlink to ../available/sshd.conf
|-- finit.conf -- Bootstrap tasks and services
:
```
In this layout:
- **available/** contains all installed service configurations
- **enabled/** contains symlinks to configurations that should start at boot
- Services are enabled/disabled by creating/removing symlinks
> [!IMPORTANT] Recommended
> This is the recommended layout. In fact, the `initctl enable/disable`
> commands **require** this layout with both `available/` and `enabled/`
> directories and will not work without it.
## Managing Services with initctl
When using the distro layout, the `initctl` tool provides convenient commands
for managing service configurations:
```
list List all .conf in /etc/finit.d/
enable <CONF> Enable .conf by creating symlink in enabled/
disable <CONF> Disable .conf by removing symlink from enabled/
reload Reload *.conf in /etc/finit.d/ (activate changes)
```
Example usage:
```bash
# Enable sshd (creates enabled/sshd.conf -> ../available/sshd.conf)
initctl enable sshd
# Disable httpd (removes enabled/httpd.conf symlink)
initctl disable httpd
# Apply changes (reload configuration and start/stop services)
initctl reload
```
The `.conf` suffix is optional - `initctl` adds it automatically if missing.
> [!NOTE] Remember `initctl reload`
> Changes made with `enable`/`disable` take effect only after running
> `initctl reload`, unless Finit was built with `--enable-auto-reload`
> which automatically detects and applies configuration changes.
### Service Overrides
The `initctl` tool only operates on symlinks in the `enabled/` directory.
If you place a regular (non-symlink) `.conf` file directly in the parent
directory (e.g., `/etc/finit.d/`), `initctl` will ignore it. This allows
you to create system-level overrides that cannot be accidentally disabled
by package management tools.
## Customizing Directory Paths
Distributions can customize the directory names and locations at build time
using the Finit `configure` script:
To change the default configuration directory and configuration file
names the Finit `configure` script offers the following two options at
build time:
```sh
./configure --with-rcsd=/etc/init.d --with-config=/etc/init.d/init.conf
```
This changes the default `/etc/finit.d/` to `/etc/init.d/` and moves the
bootstrap configuration file accordingly.
> **Note:** remember `--prefix` et al as well, the default is likely
> *not* what you want. See the [build docs][1] for details.
> [!IMPORTANT] Remember to set `--prefix`
> Remember to set `--prefix` and related options appropriately. The default
> prefix is `/usr/local`, which is likely not what you want for a system
> init. See the [build documentation][1] for details.
Example with custom paths:
The resulting directory structure is depicted below. Please notice how
`/etc/finit.conf` now resides in the same sub-directory as a non-symlink
`/etc/init.d/init.conf`:
```
/etc/
|-- init.d/
| |-- available/ -- Installed services
| |-- available/ -- Regular (disabled) services
| | |-- httpd.conf
| | |-- ntpd.conf
| | `-- sshd.conf
| |-- enabled/ -- Enabled services (symlinks)
| | `- sshd.conf -- Symlink to ../available/sshd.conf
| |-- sshd.conf -- Symlink to available/sshd.conf
| `- init.conf -- Bootstrap tasks and services
:
```
Notice how both the service directory and bootstrap configuration file now
use the custom `/etc/init.d/` path specified at build time.
To facilitate the task of managing configurations, be it a service,
task, run, or other stanza, the `initctl` tool has a a few built-in
commands:
```
list List all .conf in /etc/finit.d/
enable <CONF> Enable .conf in /etc/finit.d/available/
disable <CONF> Disable .conf in /etc/finit.d/[enabled/]
reload Reload *.conf in /etc/finit.d/ (activates changes)
```
To enable a service like `sshd.conf`, above, use
initctl enable sshd
The `.conf` suffix is not needed, `initctl` adds it implicitly if it is
missing. The `disable` command works in a similar fashion.
Note, however, that `initctl` only operates on symlinks and it always
requires the `available/` sub-directory. Any non-symlink in the parent
directory, here `/etc/init.d/`, will be considered a system override by
`initctl`.
[1]: build.md#configure
-137
View File
@@ -1,137 +0,0 @@
Configuration Example
=====================
This example `/etc/finit.conf` can also be split up in multiple `.conf`
files in `/etc/finit.d`. Available, but not yet enabled, services can
be placed in `/etc/finit.d/available` and enabled by an operator using
the [initctl](initctl.md) tool.
See the [contrib/][contrib] directory on GitHub for examples, or take a
peek at systems using Finit, like [Infix OS][infix] and [myLinux][].
> [!TIP]
> As of Finit v4.4, `.conf` lines can be broken up using the standard UNIX
> continuation character (`\`), trailing comments are also supported. The
> latter means you must escape any hashes used in directives and descriptions
> (`\#`). For more on this and examples, see the [finit.conf(5)][] manual or
> the [Configuration](config/index.md) section.
```ApacheConf
# Fallback if /etc/hostname is missing
host default
# Runlevel to start after bootstrap, 'S', default: 2
#runlevel 2
# Support for setting global environment variables, using foo=bar syntax
# be careful though with variables like PATH, SHELL, LOGNAME, etc.
#PATH=/usr/bin:/bin:/usr/sbin:/sbin
# Max file size for each log file: 100 kiB, rotate max 4 copies:
# log => log.1 => log.2.gz => log.3.gz => log.4.gz
log size=100k count=4
# Services to be monitored and respawned as needed
service [S12345] env:-/etc/conf.d/watchdog watchdog $WATCHDOG_OPTS $WATCHDOG_DEV -- System watchdog daemon
service [S12345] env:-/etc/conf.d/syslog syslogd -n $SYSLOGD_OPTS -- System log daemon
service [S12345] <pid/syslogd> env:-/etc/conf.d/klogd klogd -n $KLOGD_OPTS -- Kernel log daemon
service [2345] env:-/etc/conf.d/lldpd lldpd -d $LLDPD_OPTS -- LLDP daemon (IEEE 802.1ab)
# The BusyBox ntpd does not use syslog when running in the foreground
# So we use this trick to redirect stdout/stderr to a log file. The
# log file is rotated with the above settings. The condition declares
# a dependency on a system default route (gateway) to be set. A single
# <!> at the beginning means ntpd does not respect SIGHUP for restart.
service [2345] log:/var/log/ntpd.log <!net/route/default> ntpd -n -l -I eth0 -- NTP daemon
# For multiple instances of the same service, add :ID somewhere between
# the service/run/task keyword and the command.
service :80 [2345] merecat -n -p 80 /var/www -- Web server
service :8080 [2345] merecat -n -p 8080 /var/www -- Old web server
# Alternative method instead of below runparts, can also use /etc/rc.local
#sysv [S] /etc/init.d/keyboard-setup -- Setting up preliminary keymap
#sysv [S] /etc/init.d/acpid -- Starting ACPI Daemon
#task [S] /etc/init.d/kbd -- Preparing console
# Hidden from boot progress, using empty `--` description
#sysv [S] /etc/init.d/keyboard-setup --
#sysv [S] /etc/init.d/acpid --
#task [S] /etc/init.d/kbd --
# Run start scripts from this directory
# runparts /etc/start.d
# Virtual consoles run BusyBox getty, keep kernel default speed
tty [12345] /sbin/getty -L 0 /dev/tty1 linux nowait noclear
tty [2345] /sbin/getty -L 0 /dev/tty2 linux nowait noclear
tty [2345] /sbin/getty -L 0 /dev/tty3 linux nowait noclear
# Use built-in getty for serial port and USB serial
#tty [12345] /dev/ttyAMA0 noclear nowait
#tty [12345] /dev/ttyUSB0 noclear
# Just give me a shell, I need to debug this embedded system!
#tty [12345] console noclear nologin
```
The `service` stanza, as well as `task`, `run` and others are described in
full in the [Services Syntax](config/services.md) section.
Here's a quick overview of some of the most common components needed to start
a UNIX daemon:
```
service [LVLS] <COND> log env:[-]/etc/default/daemon daemon ARGS -- Example daemon
^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | `---------- Optional description
| | | | | | `------------------ Daemon arguments
| | | | | `------------------------- Path to daemon
| | | | `---------------------------------------------------- Optional env. file
| | | `-------------------------------------------------------- Redirect output to log
| | `--------------------------------------------------------------- Optional conditions
| `---------------------------------------------------------------------- Optional Runlevels
`------------------------------------------------------------------------------ Supervised program (daemon)
```
Some components are optional: runlevel(s), condition(s) and description,
making it easy to create simple start scripts and still possible for more
advanced uses as well:
service /usr/sbin/sshd -D
Dependencies are handled using [conditions](conditions.md). One of
the most common conditions is to wait for basic networking to become
available:
service <net/route/default> nginx -- High performance HTTP server
Here is another example where we instruct Finit to not start BusyBox
`ntpd` until `syslogd` has started properly. Finit waits for `syslogd`
to create its PID file, by default `/var/run/syslogd.pid`.
service [2345] log <!pid/syslogd> ntpd -n -N -p pool.ntp.org
service [S12345] syslogd -n -- Syslog daemon
Notice the `log` keyword, BusyBox `ntpd` uses `stderr` for logging when
run in the foreground. With `log` Finit redirects `stdout` + `stderr`
to the system log daemon using the command line `logger(1)` tool.
A service, or task, can have multiple dependencies listed. Here we wait
for *both* `syslogd` to have started and basic networking to be up:
service [2345] log <pid/syslogd,net/route/default> ntpd -n -N -p pool.ntp.org
If either condition fails, e.g. loss of networking, `ntpd` is stopped
and as soon as it comes back up again `ntpd` is restarted automatically.
> [!NOTE]
> Make sure daemons do *not* fork and detach themselves from the controlling
> TTY, usually an `-n` or `-f` flag, or `-D` as in the case of OpenSSH above.
> If it detaches itself, Finit cannot monitor it and will instead try to
> restart it.
[finit.conf(5)]: https://man.troglobit.com/man5/finit.conf.5.html
[infix]: https://kernelkit.github.io
[myLinux]: https://github.com/troglobit/myLinux/
[contrib]: https://github.com/finit-project/finit/tree/master/contrib
-11
View File
@@ -1,11 +0,0 @@
.md-header__topic:first-child {
font-weight: 500;
font-style: italic;
}
.md-header__title {
font-size: 1.1rem;
font-style: italic;
font-weight: 500;
line-height: 2.6rem;
}
-314
View File
@@ -1,314 +0,0 @@
Finit Features
==============
This page highlights some of Finit's key features with examples and usage
scenarios. For complete documentation, configuration syntax, and advanced
options, see the [Configuration](config/index.md) section.
**Process Supervision**
Start, monitor and restart services should they fail.
**Getty**
Finit supports external getty but also comes with a limited built-in
Getty, useful for really small systems. A getty sets up the TTY and
waits for user input before handing over to `/bin/login`, which is
responsible for handling the actual authentication.
```conf
tty [12345] /dev/tty1 nowait linux
tty [12345] /dev/ttyAMA0 noclear vt100
tty [12345] /sbin/getty -L /dev/ttyAMA0 vt100
```
Users of embedded systems may want to enable automatic serial console
with the special `@console` device. This works regardless whether the
system uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else. Finit
figures it out by querying sysfs: `/sys/class/tty/console/active`.
```conf
tty [12345] @console linux noclear
```
Notice the optional `noclear`, `nowait`, and `nologin` flags. The
latter is for skipping the login process entirely. For more information,
see the [TTY and Consoles](config/tty.md) section.
**Runlevels**
Support for SysV init-style [runlevels][5] is available, in the same
minimal style as everything else in Finit. The `[2345]` syntax can be
applied to service, task, run, and TTY stanzas.
Reserved runlevels are 0 and 6, halt and reboot, respectively just like
SysV init. Runlevel 1 can be configured freely, but is recommended to
be kept as the system single-user runlevel since Finit will not start
networking here. The configured `runlevel NUM` from `/etc/finit.conf`
is what Finit changes to after bootstrap, unless 'single' (or 'S') is
given on the kernel cmdline, in which case runlevel 1 is started.
All services in runlevel S) are started first, followed by the desired
run-time runlevel. Run tasks in runlevel S can be started in sequence
by using `run [S] cmd`. Changing runlevels at runtime is done like any
other init, e.g. <kbd>init 4</kbd>, but also using the more advanced
[`initctl`](initctl.md) tool.
**Conditions**
As mentioned previously, Finit has an advanced dependency system to
handle synchronization, called [conditions](conditions.md). It can
be used in many ways; depend on another service, network availability,
etc.
One *really cool* example useful for embedded systems is to run certain
scripts if a board has a certain feature encoded in its device tree. At
bootstrap we run the following `ident` script:
```sh
#!/bin/sh
conddir=/var/run/finit/cond/hw/model
dtmodel=/sys/firmware/devicetree/base/model
if ! test -e $dtmodel; then
exit 0
fi
model=$(cat $dtmodel | tr "[A-Z] " "[a-z]-")
mkdir -p $conddir && ln -s ../../reconf $conddir/$model
```
Provided the device tree node exists, and is a string, we can then use
the condition `<hw/model/foo>` when starting other scripts. Here is an
example:
```
run [S] /path/to/ident --
task [2] <hw/model/foo> /path/to/foo-init -- Initializing Foo board
```
> [!TIP]
> Notice the trick with an empty description to hide the call to `ident`
> in the Finit progress output.
**Plugins**
Plugins can *extend* the functionality of Finit and *hook into* the
different stages of the boot process and at runtime. Plugins are
written in C and compiled into a dynamic library loaded automatically by
finit at boot. A basic set of plugins are bundled in the `plugins/`
directory.
Capabilities:
- **Hooks**
Hook into the boot at predefined points to extend Finit
- **I/O**
Listen to external events and control Finit behavior/services
Extensions and functionality not purely related to what an `/sbin/init`
needs to start a system are available as a set of plugins that either
hook into the boot process or respond to various I/O.
For more information, see the [Plugins](plugins.md) section.
**Automatic Reload**
By default, Finit monitors `/etc/finit.d/` and `/etc/finit.d/enabled/`
registering any changes to `.conf` files. To activate a change the user
must call `initctl reload`, which reloads all modified files, stops any
removed services, starts new ones, and restarts any modified ones. If the
command line arguments of a service have changed, the process will be
terminated and then started again with the updated arguments. If the arguments
have not been modified and the process supports SIGHUP, the process will
receive a SIGHUP rather than being terminated and started.
For some use-cases the extra step of calling `initctl reload` creates an
unnecessary overhead, which can be removed at build-time using:
configure --enable-auto-reload
**Linux Capabilities**
Finit supports Linux capabilities, allowing services to run with minimal
required privileges instead of running as root. This improves security by
following the principle of least privilege.
```conf
service [2345] name:nginx \
www-data:www-data \
caps:^cap_net_bind_service \
/usr/sbin/nginx -g 'daemon off;'
```
In this example, nginx runs as the unprivileged `www-data` user but retains
the ability to bind to privileged ports (80, 443) through the
`cap_net_bind_service` capability.
The `caps:` directive uses the IAB (Inheritable, Ambient, Bounding) format:
- `^` = Ambient (recommended) - capabilities survive exec()
- `%` = Inheritable only - requires file capabilities
- `!` = Bounding - block from acquiring capability
Multiple capabilities can be specified as comma-separated:
```conf
caps:^cap_net_raw,^cap_net_admin,!cap_sys_admin
```
See the [Linux Capabilities](config/capabilities.md) section for detailed
information, examples, and security best practices.
**Supplementary Groups**
Finit supports supplementary groups for services, allowing them to access
resources owned by multiple groups without running as root. This complements
capabilities for fine-grained privilege control.
```conf
service @caddy:caddy,ssl-cert /usr/bin/caddy run
```
In this example, the Caddy web server runs as user `caddy` with primary group
`caddy`, but also has access to resources owned by the `ssl-cert` group (such
as TLS certificates).
Finit automatically reads the user's supplementary group membership from
`/etc/group`. Additional groups can be specified explicitly using the syntax
`@user:group,sup1,sup2,...`.
See the [Non-privileged Services](config/services.md#non-privileged-services)
section for more information.
**Cgroups**
Finit supports cgroups v2 and comes with the following default groups in
which services and user sessions are placed in:
/sys/fs/cgroup
|-- init/ # cpu.weight:100
|-- system/ # cpu.weight:9800
`-- user/ # cpu.weight:100
Finit itself and its helper scripts and services are placed in the
top-level leaf-node group `init/`, which also is _reserved_.
All run/task/service/sysv processes are placed in their own sub-group
in `system/`. The name of each sub-group is taken from the respective
`.conf` file from `/etc/finit.d`.
All getty/tty processes are placed in their own sub-group in `user/`.
The name of each sub-group is taken from the username.
A fourth group also exists, the `root` group. It is also _reserved_ and
primarily intended for RT tasks. If you have RT tasks they need to be
declared as such in their service stanza like this:
service [...] <...> cgroup.root /path/to/foo args -- description
or
cgroup.root
service [...] <...> /path/to/foo args -- description
service [...] <...> /path/to/bar args -- description
See the [Cgroups](config/cgroups.md) section for more information, e.g.,
how to configure per-group limits.
The `initctl` tool has three commands to help debug and optimize the
setup and monitoring of cgroups. See the `ps`, `top`, and `cgroup`
commands for details.
> [!NOTE]
> Systems that do not support cgroups, specifically version 2, are
> automatically detected. On such systems the above functionality is
> disabled early at boot.
**Service Management**
Finit includes the `initctl` tool for managing services and system state at
runtime. Key capabilities include:
- **Enable/Disable services**: Manage which services start at boot by moving
configuration files between `/etc/finit.d/available` and
`/etc/finit.d/enabled`
- **Start/Stop/Restart**: Control individual services without requiring a
full system reboot
- **Status monitoring**: View service state, PID, uptime, and resource usage
- **Condition management**: Set and clear user-defined conditions to control
service dependencies
- **Cgroup monitoring**: Real-time process and resource monitoring with
`initctl top`, similar to the traditional `top` command but cgroup-aware
Example commands:
```bash
initctl enable myservice # Enable service for next boot
initctl start myservice # Start service now
initctl status # Show all services
initctl top # Interactive resource monitor
initctl cond set usr/custom # Set custom condition
```
See the [Commands & Status](initctl.md) section for complete documentation.
**Rescue Mode**
Finit provides a built-in rescue mode for system recovery and maintenance.
When booting with the `rescue` kernel parameter, the system enters a
protected maintenance shell.
If the bundled `sulogin` program is available (from Finit, util-linux, or
BusyBox), you'll be prompted for the root password before accessing the
maintenance shell. This provides secure access for system recovery.
If `sulogin` is not available, Finit falls back to reading
`/lib/finit/rescue.conf` and boots the system in a limited maintenance mode.
```
# Kernel command line
linux /vmlinuz root=/dev/sda1 rescue
```
In rescue mode, `initctl` will not work. After fixing the problem, use
`reboot -f` to force reboot.
Rescue mode can be disabled at build time with `configure --without-rescue`.
See the [Rescue Mode](config/rescue.md) section for more information.
**Switch Root**
Finit supports switching from an initramfs to a real root filesystem using
the built-in `initctl switch-root` command. This allows Finit to serve as
the init system in an initramfs for early boot tasks (LUKS unlock, LVM
activation, network boot) before transitioning to the real root.
```bash
# In initramfs, after mounting the real root:
initctl switch-root /mnt/root
```
The switch-root operation:
1. Runs the `HOOK_SWITCH_ROOT` hook for cleanup
2. Stops all services gracefully
3. Moves virtual filesystems (`/dev`, `/proc`, `/sys`, `/run`) to the new root
4. Deletes initramfs contents to free memory
5. Pivots to the new root and execs the new init
See the [Switch Root](switchroot.md) section for complete documentation.
[5]: https://en.wikipedia.org/wiki/Runlevel
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

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