{"id":13751424,"url":"https://github.com/troglobit/finit","last_synced_at":"2025-05-15T05:08:45.146Z","repository":{"id":4633597,"uuid":"5778132","full_name":"troglobit/finit","owner":"troglobit","description":"Fast init for Linux. Cookies included","archived":false,"fork":false,"pushed_at":"2025-05-05T05:27:43.000Z","size":7232,"stargazers_count":654,"open_issues_count":23,"forks_count":65,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-05-05T05:32:05.214Z","etag":null,"topics":["boot","boot-process","c","finit","getty","init","init-system","linux","pid1","runlevel","supervisor","watchdog"],"latest_commit_sha":null,"homepage":"https://troglobit.com/projects/finit/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/troglobit.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["troglobit"]}},"created_at":"2012-09-12T10:07:53.000Z","updated_at":"2025-05-05T04:47:38.000Z","dependencies_parsed_at":"2023-02-19T09:16:18.333Z","dependency_job_id":"f32b1355-5306-4c27-97b8-0b12798633ca","html_url":"https://github.com/troglobit/finit","commit_stats":{"total_commits":3563,"total_committers":42,"mean_commits":84.83333333333333,"dds":"0.12152680325568344","last_synced_commit":"74f0fcfccda97a33bba56e4c0c1c051a4406b8cf"},"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troglobit%2Ffinit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troglobit%2Ffinit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troglobit%2Ffinit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troglobit%2Ffinit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/troglobit","download_url":"https://codeload.github.com/troglobit/finit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254276464,"owners_count":22043868,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boot","boot-process","c","finit","getty","init","init-system","linux","pid1","runlevel","supervisor","watchdog"],"created_at":"2024-08-03T09:00:44.637Z","updated_at":"2025-05-15T05:08:40.138Z","avatar_url":"https://github.com/troglobit.png","language":"C","readme":"[![License Badge][]][License] [![GitHub Status][]][GitHub] [![Coverity Status][]][Coverity Scan]\n\u003cimg align=\"right\" src=\"img/finit3.png\" alt=\"Finit: Fast Init\"\u003e\n\n* [Introduction](#introduction)\n* [Features](#features)\n* [Runlevels](#runlevels)\n* [Syntax](doc/config.md#syntax)\n  * [Runparts \u0026 /etc/rc.local](#runparts--etcrclocal)\n  * [Hooks, Callbacks \u0026 Plugins](doc/plugins.md#hooks-callbacks--plugins)\n* [Rebooting \u0026 Halting](#rebooting--halting)\n* [Commands \u0026 Status](#commands--status)\n* [Tips \u0026 Tricks with the kernel cmdline](doc/cmdline.md)\n* [Building](doc/build.md#building)\n  * [Running](doc/build.md#running)\n  * [Recovery](doc/build.md#recovery)\n  * [Debugging](doc/build.md#debugging)\n* [Requirements](#requirements)\n* [Origin \u0026 References](#origin--references)\n\n\nIntroduction\n------------\n\nFast init for Linux systems.  Reverse engineered from the [EeePC\nfastinit][] by [Claudio Matsuoka][] — \"gaps filled with frog DNA …\"\n\n![Alpine screenshot](img/alpine-screenshot2.png)  \n*Figure 1: Screenshot of Finit booting [Alpine Linux (HowTo)](https://github.com/troglobit/finit/tree/master/contrib/alpine).*\n\nFeatures include:\n\n  * Runlevels, defined per service\n  * One-shot tasks, services (daemons), or [SysV init][4] start/stop scripts\n  * Runparts and `/etc/rc.local` support\n  * Process supervision similar to [systemd][]\n  * Sourcing environment files\n  * Conditions for network/process/custom dependencies\n  * Readiness notification; PID files (native) for synchronizing system\n    startup, support for systemd [sd_notify()][], or [s6 style][] too\n  * Limited support for [tmpfiles.d(5)][] (no aging, attributes, or subvolumes)\n  * Pre/Post script actions\n  * Rudimentary [templating support](doc/config.md#templating)\n  * Tooling to enable/disable services\n  * Built-in getty\n  * Built-in watchdog, with support for hand-over to [watchdogd](https://troglobit.com/watchdogd.html)\n  * Built-in support for Debian/BusyBox `/etc/network/interfaces`\n  * Cgroups v2, both configuration and monitoring in `initctl top`\n  * Plugin support for customization\n  * Proper rescue mode with bundled `sulogin` for protected maintenance shell\n  * Integration with [watchdogd][] for full system supervision\n  * Logging to kernel ring buffer before `syslogd` has started, see the\n    recommended [sysklogd][] project for complete logging integration\n\tand how to log to the kernel ring buffer from scripts using `logger`\n\nFocus is on small and embedded systems, although Finit is fully usable\non server and desktop systems as well.  For working examples, see the\n[contrib/](contrib/) section with tutorials for the following Linux\ndistributions:\n\n  * [Void Linux](contrib/void/),\n  * [Alpine Linux](contrib/alpine/), and\n  * [Debian GNU/Linux](contrib/debian/), also works on Ubuntu/Linux Mint\n\n\u003e [!NOTE]\n\u003e Support for various Linux distributions does not mean Finit installs\n\u003e easily on all architectures.  The bundled install scripts are examples\n\u003e for standard installations, tested on amd64 (x86_64) systems.  Custom\n\u003e setups, e.g., for embedded systems, can be found in the following\n\u003e [Buildroot][] based examples: [myLinux][], [Infix][], or the plain\n\u003e [br2-finit-demo](https://github.com/troglobit/br2-finit-demo).\n\n\nExample\n-------\n\nThis example `/etc/finit.conf` can also be split up in multiple `.conf`\nfiles in `/etc/finit.d`.  Available, but not yet enabled, services can\nbe placed in `/etc/finit.d/available` and enabled by an operator using\nthe [initctl](#commands--status) tool.  See the above mentioned Linux\ndistributions, or [myLinux][].\n\n\u003e [!TIP]\n\u003e As of Finit v4.4, `.conf` lines can be broken up using the standard\n\u003e UNIX continuation character (`\\`), trailing comments are now also\n\u003e supported.  The latter means you need to escape any hashes used in\n\u003e directives and descriptions (`\\#`).  For more on this and examples,\n\u003e see the [finit.conf(5)][] manual or [doc/config.md](doc/config.md).\n\n```ApacheConf\n# Fallback if /etc/hostname is missing\nhost default\n\n# Runlevel to start after bootstrap, 'S', default: 2\n#runlevel 2\n\n# Support for setting global environment variables, using foo=bar syntax\n# be careful though with variables like PATH, SHELL, LOGNAME, etc.\n#PATH=/usr/bin:/bin:/usr/sbin:/sbin\n\n# Max file size for each log file: 100 kiB, rotate max 4 copies:\n# log =\u003e log.1 =\u003e log.2.gz =\u003e log.3.gz =\u003e log.4.gz\nlog size=100k count=4\n\n# Services to be monitored and respawned as needed\nservice [S12345] env:-/etc/conf.d/watchdog watchdog $WATCHDOG_OPTS $WATCHDOG_DEV -- System watchdog daemon\nservice [S12345] env:-/etc/conf.d/syslog syslogd -n $SYSLOGD_OPTS          -- System log daemon\nservice [S12345] \u003cpid/syslogd\u003e env:-/etc/conf.d/klogd klogd -n $KLOGD_OPTS -- Kernel log daemon\nservice   [2345] env:-/etc/conf.d/lldpd lldpd -d $LLDPD_OPTS               -- LLDP daemon (IEEE 802.1ab)\n\n# The BusyBox ntpd does not use syslog when running in the foreground\n# So we use this trick to redirect stdout/stderr to a log file.  The\n# log file is rotated with the above settings.  The condition declares\n# a dependency on a system default route (gateway) to be set.  A single\n# \u003c!\u003e at the beginning means ntpd does not respect SIGHUP for restart.\nservice [2345] log:/var/log/ntpd.log \u003c!net/route/default\u003e ntpd -n -l -I eth0 -- NTP daemon\n\n# For multiple instances of the same service, add :ID somewhere between\n# the service/run/task keyword and the command.\nservice :80   [2345] merecat -n -p 80   /var/www -- Web server\nservice :8080 [2345] merecat -n -p 8080 /var/www -- Old web server\n\n# Alternative method instead of below runparts, can also use /etc/rc.local\n#sysv [S] /etc/init.d/keyboard-setup       -- Setting up preliminary keymap\n#sysv [S] /etc/init.d/acpid                -- Starting ACPI Daemon\n#task [S] /etc/init.d/kbd                  -- Preparing console\n\n# Hidden from boot progress, using empty `--` description\n#sysv [S] /etc/init.d/keyboard-setup       --\n#sysv [S] /etc/init.d/acpid                --\n#task [S] /etc/init.d/kbd                  --\n\n# Run start scripts from this directory\n# runparts /etc/start.d\n\n# Virtual consoles run BusyBox getty, keep kernel default speed\ntty [12345] /sbin/getty -L 0 /dev/tty1  linux nowait noclear\ntty [2345]  /sbin/getty -L 0 /dev/tty2  linux nowait noclear\ntty [2345]  /sbin/getty -L 0 /dev/tty3  linux nowait noclear\n\n# Use built-in getty for serial port and USB serial\n#tty [12345] /dev/ttyAMA0 noclear nowait\n#tty [12345] /dev/ttyUSB0 noclear\n\n# Just give me a shell, I need to debug this embedded system!\n#tty [12345] console noclear nologin\n```\n\nThe `service` stanza, as well as `task`, `run` and others are described\nin full in [doc/config.md](doc/config.md).  Here's a quick overview of\nsome of the most common components needed to start a UNIX daemon:\n\n```\nservice [LVLS] \u003cCOND\u003e log env:[-]/etc/default/daemon daemon ARGS -- Daemon daemon\n^       ^      ^      ^   ^                          ^      ^       ^\n|       |      |      |   |                          |      |        `---------- Optional description\n|       |      |      |   |                          |       `------------------ Daemon arguments\n|       |      |      |   |                           `------------------------- Path to daemon\n|       |      |      |    `---------------------------------------------------- Optional env. file\n|       |      |       `-------------------------------------------------------- Redirect output to log\n|       |       `--------------------------------------------------------------- Optional conditions\n|        `---------------------------------------------------------------------- Optional Runlevels\n `------------------------------------------------------------------------------ Monitored application\n```\n\nSome components are optional: runlevel(s), condition(s) and description,\nmaking it easy to create simple start scripts and still possible for more\nadvanced uses as well:\n\n    service /usr/sbin/sshd -D\n\nDependencies are handled using [conditions](doc/conditions.md).  One of\nthe most common conditions is to wait for basic networking to become\navailable:\n\n    service \u003cnet/route/default\u003e nginx -- High performance HTTP server\n\nHere is another example where we instruct Finit to not start BusyBox\n`ntpd` until `syslogd` has started properly.  Finit waits for `syslogd`\nto create its PID file, by default `/var/run/syslogd.pid`.\n\n    service [2345] log \u003c!pid/syslogd\u003e ntpd -n -N -p pool.ntp.org\n    service [S12345] syslogd -n -- Syslog daemon\n\nNotice the `log` keyword, BusyBox `ntpd` uses `stderr` for logging when\nrun in the foreground.  With `log` Finit redirects `stdout` + `stderr`\nto the system log daemon using the command line `logger(1)` tool.\n\nA service, or task, can have multiple dependencies listed.  Here we wait\nfor *both* `syslogd` to have started and basic networking to be up:\n\n    service [2345] log \u003cpid/syslogd,net/route/default\u003e ntpd -n -N -p pool.ntp.org\n\nIf either condition fails, e.g. loss of networking, `ntpd` is stopped\nand as soon as it comes back up again `ntpd` is restarted automatically.\n\n**Note:** Make sure daemons *do not* fork and detach themselves from the\n  controlling TTY, usually an `-n` or `-f` flag, or `-D` as in the case\n  of OpenSSH above.  If it detaches itself, Finit cannot monitor it and\n  will instead try to restart it.\n\n\nFeatures\n--------\n\n**Process Supervision**\n\nStart, monitor and restart services should they fail.\n\n\n**Getty**\n\nFinit supports external getty but also comes with a limited built-in\nGetty, useful for really small systems.  A getty sets up the TTY and\nwaits for user input before handing over to `/bin/login`, which is\nresponsible for handling the actual authentication.\n\n```conf\ntty [12345] /dev/tty1    nowait  linux\ntty [12345] /dev/ttyAMA0 noclear vt100\ntty [12345] /sbin/getty  -L /dev/ttyAMA0 vt100\n```\n\nUsers of embedded systems may want to enable automatic serial console\nwith the special `@console` device.  This works regardless weather the\nsystem uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else.  Finit\nfigures it out by querying sysfs: `/sys/class/tty/console/active`.\n\n```conf\ntty [12345] @console linux noclear\n```\n\nNotice the optional `noclear`, `nowait`, and `nologin` flags.  The\nlatter is for skipping the login process entirely. For more information,\nsee [doc/config.md](doc/config.md#syntax).\n\n\n**Runlevels**\n\nSupport for SysV init-style [runlevels][5] is available, in the same\nminimal style as everything else in Finit.  The `[2345]` syntax can be\napplied to service, task, run, and TTY stanzas.\n\nReserved runlevels are 0 and 6, halt and reboot, respectively just like\nSysV init.  Runlevel 1 can be configured freely, but is recommended to\nbe kept as the system single-user runlevel since Finit will not start\nnetworking here.  The configured `runlevel NUM` from `/etc/finit.conf`\nis what Finit changes to after bootstrap, unless 'single' (or 'S') is\ngiven on the kernel cmdline, in which case runlevel 1 is started.\n\nAll services in runlevel S) are started first, followed by the desired\nrun-time runlevel.  Run tasks in runlevel S can be started in sequence\nby using `run [S] cmd`.  Changing runlevels at runtime is done like any\nother init, e.g. \u003ckbd\u003einit 4\u003c/kbd\u003e, but also using the more advanced\n`intictl` tool.\n\n\n**Conditions**\n\nAs mentioned previously, Finit has an advanced dependency system to\nhandle synchronization, called [conditions](doc/conditions.md).  It can\nbe used in many ways; depend on another service, network availability,\netc.\n\nOne *really cool* example useful for embedded systems is to run certain\nscripts if a board has a certain feature encoded in its device tree.  At\nbootstrap we run the following `ident` script:\n\n```sh\n#!/bin/sh\nconddir=/var/run/finit/cond/hw/model\ndtmodel=/sys/firmware/devicetree/base/model\n\nif ! test -e $dtmodel; then\n    exit 0\nfi\n\nmodel=$(cat $dtmodel | tr \"[A-Z] \" \"[a-z]-\")\nmkdir -p $conddir \u0026\u0026 ln -s ../../reconf $conddir/$model\n```\n\nProvided the device tree node exists, and is a string, we can then use\nthe condition `\u003chw/model/foo\u003e` when starting other scripts.  Here is an\nexample:\n\n```\nrun  [S]                /path/to/ident    --\ntask [2] \u003chw/model/foo\u003e /path/to/foo-init -- Initializing Foo board\n```\n\n\u003e [!TIP]\n\u003e Notice the trick with an empty description to hide the call to `ident`\n\u003e in the Finit progress output.\n\n\n**Plugins**\n\nPlugins can *extend* the functionality of Finit and *hook into* the\ndifferent stages of the boot process and at runtime.  Plugins are\nwritten in C and compiled into a dynamic library loaded automatically by\nfinit at boot.  A basic set of plugins are bundled in the `plugins/`\ndirectory.\n\nCapabilities:\n\n- **Hooks**  \n  Hook into the boot at predefined points to extend Finit\n- **I/O**  \n  Listen to external events and control Finit behavior/services\n\nExtensions and functionality not purely related to what an `/sbin/init`\nneeds to start a system are available as a set of plugins that either\nhook into the boot process or respond to various I/O.\n\nFor more information, see [doc/plugins.md](doc/plugins.md).\n\n\n**Automatic Reload**\n\nBy default, Finit monitors `/etc/finit.d/` and `/etc/finit.d/enabled/`\nregistering any changes to `.conf` files.  To activate a change the user\nmust call `initctl reload`, which reloads all modified files, stops any\nremoved services, starts new ones, and restarts any modified ones.  If the\ncommand line arguments of a service have changed, the process will be\nterminated and then started again with the updated arguments. If the arguments\nhave not been modified and the process supports SIGHUP, the process will\nreceive a SIGHUP rather than being terminated and started.\n\nFor some use-cases the extra step of calling `initctl reload` creates an\nunnecessary overhead, which can be removed at build-time using:\n\n    configure --enable-auto-reload\n\n\n**Cgroups**\n\nFinit supports cgroups v2 and comes with the following default groups in\nwhich services and user sessions are placed in:\n\n     /sys/fs/cgroup\n       |-- init/               # cpu.weight:100\n       |-- system/             # cpu.weight:9800\n       `-- user/               # cpu.weight:100\n\nFinit itself and its helper scripts and services are placed in the\ntop-level leaf-node group `init/`, which also is _reserved_.\n\nAll run/task/service/sysv processes are placed in their own sub-group\nin `system/`.  The name of each sub-group is taken from the respective\n`.conf` file from `/etc/finit.d`.\n\nAll getty/tty processes are placed in their own sub-group in `user/`.\nThe name of each sub-group is taken from the username.\n\nA fourth group also exists, the `root` group.  It is also _reserved_ and\nprimarily intended for RT tasks.  If you have RT tasks they need to be\ndeclared as such in their service stanza like this:\n\n    service [...] \u003c...\u003e cgroup.root /path/to/foo args -- description\n\nor\n\n    cgroup.root\n    service [...] \u003c...\u003e /path/to/foo args -- description\n    service [...] \u003c...\u003e /path/to/bar args -- description\n\nSee [doc/config.md](doc/config.md#cgroups) for more information, e.g.,\nhow to configure per-group limits.\n\nThe `initctl` tool has three commands to help debug and optimize the\nsetup and monitoring of cgroups.  See the `ps`, `top`, and `cgroup`\ncommands for details.\n\n\u003e [!NOTE]\n\u003e Systems that do not support cgroups, specifically version 2, are\n\u003e automatically detected.  On such systems the above functionality is\n\u003e disabled early at boot.\n\n\nRunparts \u0026 /etc/rc.local\n------------------------\n\nAt the end of the boot, when all bootstrap (`S`) tasks and services have\nstarted, but not networking, Finit calls its built-in [run-parts(8)][]\ncommand on any configured `runparts \u003cDIR\u003e` directory.  This happens just\nbefore changing to the configured runlevel (default 2).  (Networking is\nenabled just prior to changing from single user mode.)\n\n```shell\nrunparts /etc/rc.d/\n```\n\nRight after the runlevel change when all services have started properly,\n`/etc/rc.local` is called.\n\nNo configuration stanza in `/etc/finit.conf` is required for `rc.local`.\nIf it exists and is an executable shell script Finit calls it at the very\nend of the boot, before calling the `HOOK_SYSTEM_UP`.  See more on hooks\nin [doc/plugins.md](doc/plugins.md#hooks).\n\n\n### Limitations\n\nIt is not possible to call Finit via signals or use `initctl` in any\nrunparts or `/etc/rc.local` script.  This because Finit is single\nthreaded and is calling these scripts in a blocking fashion at the end\nof runlevel S, at which point the event loop has not yet been started.\n\nThe event loop is the whole thing which Finit is built around, except\nfor runlevel S, which remains a slow procession through a lot of set up,\nwith a few hooks and blocking call outs to external scripts.\n\nHowever, not all `initctl` commands are prohibited. Supported commands:\n\n - `inictl cond`: only operate of files in `/run/finit/cond`\n - `initctl enable/disable`: enabled run/task/service is activated on\n   the runlevel change from S to 2\n - `initctl touch/show/create/delete/list`: `create`, provided the\n   non-interactive mode is used, again changes take effect in the\n   runlevel change directly after bootstrap\n - `initctl -f reboot/poweroff/halt`: provided the `-f` flag is used to\n   force direct kernel commands\n\n**Example:** you can set a `usr/` condition in `/etc/rc.local` and have\na service/task in runlevel 2 depend on it to execute.\n\n\nRunlevels\n---------\n\nBasic support for [runlevels][5] is included in Finit from v1.8.  By\ndefault all services, tasks, run commands and TTYs listed without a set\nof runlevels get a default set `[234]` assigned.  The default runlevel\nafter boot is 2.\n\nFinit supports runlevels 0-9, and S, with 0 reserved for halt, 6 reboot\nand S for services to only run at bootstrap.  Runlevel 1 is the single\nuser level, where usually no networking is enabled.  In Finit this is\nmore of a policy for the user to define.  Normally only runlevels 1-6\nare used, and even more commonly, only the default runlevel is used.\n\nTo specify an allowed set of runlevels for a `service`, `run` command,\n`task`, or `tty`, add `[NNN]` to your `/etc/finit.conf`, like this:\n\n```\nservice [S12345] syslogd -n -x             -- System log daemon\nrun     [S]      /etc/init.d/acpid start   -- Starting ACPI Daemon\ntask    [S]      /etc/init.d/kbd start     -- Preparing console\nservice [S12345] \u003cpid/syslogd\u003e klogd -n -x -- Kernel log daemon\n\ntty     [12345]  /dev/tty1\ntty     [2]      /dev/tty2\ntty     [2]      /dev/tty3\ntty     [2]      /dev/tty4\ntty     [2]      /dev/tty5\ntty     [2]      /dev/tty6\n```\n\nIn this example syslogd is first started, in parallel, and then acpid is\ncalled using a conventional SysV init script.  It is called with the run\ncommand, meaning the following task command to start the kbd script is\nnot called until the acpid init script has fully completed.  Then the\nkeyboard setup script is called in parallel with klogd as a monitored\nservice.\n\nAgain, tasks and services are started in parallel, while run commands\nare called in the order listed and subsequent commands are not started\nuntil a run command has completed.  Also, task and run commands are run\nin a shell, so pipes and redirects can be used.\n\nThe following examples illustrate this.  Bootstrap task and run commands\nare also removed when they have completed, `initctl show` will not list\nthem.\n\n```\ntask [S] echo \"foo\" | cat \u003e/tmp/bar\nrun  [S] echo \"$HOME\" \u003e/tmp/secret\n```\n\nSwitching between runlevels can be done by calling init with a single\nargument, e.g. \u003ckbd\u003einit 5\u003c/kbd\u003e, or using `initctl runlevel 5`, both\nswitch to runlevel 5.  When changing runlevels Finit also automatically\nreloads all `.conf` files in the `/etc/finit.d/` directory.  So if you\nwant to set a new system config, switch to runlevel 1, change all config\nfiles in the system, and touch all `.conf` files in `/etc/finit.d`\nbefore switching back to the previous runlevel again — that way Finit\ncan both stop old services and start any new ones for you, without\nrebooting the system.\n\n\nRebooting \u0026 Halting\n-------------------\n\nTraditionally, rebooting and halting a UNIX system is done by changing\nits runlevel.  Finit comes with its own tooling providing: `shutdown`,\n`reboot`, `poweroff`, and `suspend`, but also the `initctl` tool,\ndetailed in the next section.\n\nFor compatibility reasons Finit listens to the same set of signals as\nBusyBox init.  This is not 100% compatible with SysV init, but clearly\nthe more common combination for Finit.  For more details, see\n[doc/signals.md](doc/signals.md).\n\n\nCommands \u0026 Status\n-----------------\n\nFinit also implements a modern API to query status, and start/stop\nservices, called `initctl`.  Unlike `telinit` the `initctl` tool does\nnot return until the given command has fully completed.\n\n```\nUsage: initctl [OPTIONS] [COMMAND]\n\nOptions:\n  -b, --batch               Batch mode, no screen size probing\n  -c, --create              Create missing paths (and files) as needed\n  -f, --force               Ignore missing files and arguments, never prompt\n  -h, --help                This help text\n  -j, --json                JSON output in 'status' and 'cond' commands\n  -1, --once                Only one lap in commands like 'top'\n  -p, --plain               Use plain table headings, no ctrl chars\n  -q, --quiet               Silent, only return status of command\n  -t, --no-heading          Skip table headings\n  -v, --verbose             Verbose output\n  -V, --version             Show program version\n\nCommands:\n  debug                     Toggle Finit (daemon) debug\n  help                      This help text\n  version                   Show program version\n\n  ls | list                 List all .conf in /etc/finit.d\n  create   \u003cCONF\u003e           Create   .conf in /etc/finit.d/available\n  delete   \u003cCONF\u003e           Delete   .conf in /etc/finit.d/available\n  show     \u003cCONF\u003e           Show     .conf in /etc/finit.d/available\n  edit     \u003cCONF\u003e           Edit     .conf in /etc/finit.d/available\n  touch    \u003cCONF\u003e           Change   .conf in /etc/finit.d/available\n  enable   \u003cCONF\u003e           Enable   .conf in /etc/finit.d/available\n  disable  \u003cCONF\u003e           Disable  .conf in /etc/finit.d/enabled\n  reload                    Reload  *.conf in /etc/finit.d (activate changes)\n\n  cond     set   \u003cCOND\u003e     Set (assert) user-defined conditions     +usr/COND\n  cond     get   \u003cCOND\u003e     Get status of user-defined condition, see $? and -v\n  cond     clear \u003cCOND\u003e     Clear (deassert) user-defined conditions -usr/COND\n  cond     status           Show condition status, default cond command\n  cond     dump  [TYPE]     Dump all, or a type of, conditions and their status\n\n  log      [NAME]           Show ten last Finit, or NAME, messages from syslog\n  start    \u003cNAME\u003e[:ID]      Start service by name, with optional ID\n  stop     \u003cNAME\u003e[:ID]      Stop/Pause a running service by name\n  reload   \u003cNAME\u003e[:ID]      Reload service as if .conf changed (SIGHUP or restart)\n                            This allows restart of run/tasks that have already run\n                            Note: Finit .conf file(s) are *not* reloaded!\n  restart  \u003cNAME\u003e[:ID]      Restart (stop/start) service by name\n  signal   \u003cNAME\u003e[:ID] \u003cS\u003e  Send signal S to service by name, with optional ID\n  ident    [NAME]           Show matching identities for NAME, or all\n  status   \u003cNAME\u003e[:ID]      Show service status, by name\n  status                    Show status of services, default command\n\n  cgroup                    List cgroup config overview\n  ps                        List processes based on cgroups\n  top                       Show top-like listing based on cgroups\n\n  plugins                   List installed plugins\n\n  runlevel [0-9]            Show or set runlevel: 0 halt, 6 reboot\n  reboot                    Reboot system\n  halt                      Halt system\n  poweroff                  Halt and power off system\n  suspend                   Suspend system\n\n  utmp     show             Raw dump of UTMP/WTMP db\n```\n\nFor services *not* supporting `SIGHUP` the `\u003c!\u003e` notation in the .conf\nfile must be used to tell Finit to stop and start it on `reload` and\n`runlevel` changes.  If `\u003c\u003e` holds more [conditions](doc/conditions.md),\nthese will also affect how a service is maintained.\n\n\u003e [!NOTE]\n\u003e Even though it is possible to start services not belonging in the\n\u003e current runlevel these services will not be respawned automatically by\n\u003e Finit if they exit (crash).  Hence, if the runlevel is 2, the below\n\u003e Dropbear SSH service will not be restarted if it is killed or exits.\n\nThe `status` command is the default, it displays a quick overview of all\nmonitored run/task/services.  Here we call `initctl -p`, suitable for\nscripting and documentation:\n\n```\nalpine:~# initctl -p\nPID   IDENT     STATUS   RUNLEVELS     DESCRIPTION\n======================================================================\n1506  acpid     running  [---2345----] ACPI daemon\n1509  crond     running  [---2345----] Cron daemon\n1489  dropbear  running  [---2345----] Dropbear SSH daemon\n1511  klogd     running  [S-12345----] Kernel log daemon\n1512  ntpd      running  [---2345----] NTP daemon\n1473  syslogd   running  [S-12345----] Syslog daemon\n\nalpine:~# initctl -pv\nPID   IDENT     STATUS   RUNLEVELS     COMMAND\n======================================================================\n1506  acpid     running  [---2345----] acpid -f\n1509  crond     running  [---2345----] crond -f -S $CRON_OPTS\n1489  dropbear  running  [---2345----] dropbear -R -F $DROPBEAR_OPTS\n1511  klogd     running  [S-12345----] klogd -n $KLOGD_OPTS\n1512  ntpd      running  [---2345----] ntpd -n $NTPD_OPTS\n1473  syslogd   running  [S-12345----] syslogd -n\n```\n\nThe environment variables to each of the services above are read from,\nin the case of Alpine Linux, `/etc/conf.d/`.  Other distributions may\nhave other directories, e.g., Debian use `/etc/default/`.\n\nThe `status` command takes an optional `NAME:ID` argument.  Here we\ncheck the status of `dropbear`, which only has one instance in this\nsystem:\n\n```\nalpine:~# initctl -p status dropbear\n     Status : running\n   Identity : dropbear\nDescription : Dropbear SSH daemon\n     Origin : /etc/finit.d/enabled/dropbear.conf\nEnvironment : -/etc/conf.d/dropbear\nCondition(s):\n    Command : dropbear -R -F $DROPBEAR_OPTS\n   PID file : !/run/dropbear.pid\n        PID : 1485\n       User : root\n      Group : root\n     Uptime : 2 hour 46 min 56 sec\n  Runlevels : [---2345----]\n     Memory : 1.2M\n     CGroup : /system/dropbear cpu 0 [100, max] mem [--.--, max]\n              |- 1485 dropbear -R -F\n              |- 2634 dropbear -R -F\n              |- 2635 ash\n              `- 2652 initctl -p status dropbear\n\nApr  8 12:19:49 alpine authpriv.info dropbear[1485]: Not backgrounding\nApr  8 12:37:45 alpine authpriv.info dropbear[2300]: Child connection from 192.168.121.1:47834\nApr  8 12:37:46 alpine authpriv.notice dropbear[2300]: Password auth succeeded for 'root' from 192.168.121.1:47834\nApr  8 12:37:46 alpine authpriv.info dropbear[2300]: Exit (root) from \u003c192.168.121.1:47834\u003e: Disconnect received\nApr  8 15:02:11 alpine authpriv.info dropbear[2634]: Child connection from 192.168.121.1:48576\nApr  8 15:02:12 alpine authpriv.notice dropbear[2634]: Password auth succeeded for 'root' from 192.168.121.1:48576\n```\n\n\nRequirements\n------------\n\nFinit is capable of running on both desktop/server systems with udev and\nembedded systems that usually come with BusyBox mdev.  Some systems have\nsystemd-udev or eudev today instead of the original udev, Finit probes\nfor all of them at runtime and expects `/dev/` to be a writable file\nsystem using `devtmpfs`.  It is also possible to run on a statically set\nup `/dev` if needed.  It is however not a good idea to have both udev\nand mdev installed at the same time, this will lead to unpredictable\nresults.\n\nAt boot Finit calls either `mdev` or `udevd` to populate `/dev`, this is\ndone slightly differently and on systems with udev you might want to add\nthe following one-shot task early in your `/etc/finit.conf`:\n\n```conf\nrun [S] udevadm settle --timeout=120 -- Waiting for udev\n```\n\nFinit has a built-in Getty for TTYs, but requires a working `/bin/login`\nor `/bin/sh`, if no TTYs are configured in `/etc/finit.conf`.\n\nFor a fully operational system `/var`, `/run` and `/tmp` must be set up\nproperly in `/etc/fstab` -- which is iterated over at boot.\n\n\nOrigin \u0026 References\n-------------------\n\nThis project is based on the [original finit][] by [Claudio Matsuoka][]\nwhich was reverse engineered from syscalls of the [EeePC fastinit][] —\n\"gaps filled with frog DNA …\"\n\nFinit is developed and maintained by [Joachim Wiberg][] at [GitHub][6].\nPlease file bug reports, clone it, or send pull requests for bug fixes\nand proposed extensions.\n\n\n[1]:                https://en.wikipedia.org/wiki/Process_supervision\n[2]:                https://cr.yp.to/daemontools.html\n[3]:                https://smarden.org/runit/\n[4]:                https://en.wikipedia.org/wiki/Init\n[5]:                https://en.wikipedia.org/wiki/Runlevel\n[6]:                https://github.com/troglobit/finit\n[RFC862]:           https://tools.ietf.org/html/rfc862\n[RFC863]:           https://tools.ietf.org/html/rfc863\n[RFC864]:           https://tools.ietf.org/html/rfc864\n[RFC867]:           https://tools.ietf.org/html/rfc867\n[RFC868]:           https://tools.ietf.org/html/rfc868\n[init]:             https://en.wikipedia.org/wiki/Init\n[upstart]:          https://upstart.ubuntu.com/\n[systemd]:          https://www.freedesktop.org/wiki/Software/systemd/\n[openrc]:           https://www.gentoo.org/proj/en/base/openrc/\n[sd_notify()]:      https://www.freedesktop.org/software/systemd/man/sd_notify.html\n[s6 style]:         https://skarnet.org/software/s6/notifywhenup.html\n[run-parts(8)]:     https://manpages.debian.org/cgi-bin/man.cgi?query=run-parts\n[tmpfiles.d(5)]:    https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html\n[original finit]:   http://helllabs.org/finit/\n[EeePC fastinit]:   https://web.archive.org/web/20071208212450/http://wiki.eeeuser.com/boot_process:the_boot_process\n[Claudio Matsuoka]: https://github.com/cmatsuoka\n[Joachim Wiberg]:   https://troglobit.com\n[Buildroot]:        https://buildroot.org\n[Infix]:            https://kernelkit.github.io\n[finit.conf(5)]:    https://man.troglobit.com/man5/finit.conf.5.html\n[License]:          https://en.wikipedia.org/wiki/MIT_License\n[License Badge]:    https://img.shields.io/badge/License-MIT-teal.svg\n[myLinux]:          https://github.com/troglobit/myLinux/\n[watchdogd]:        https://github.com/troglobit/watchdogd/\n[sysklogd]:         https://github.com/troglobit/sysklogd/\n[GitHub]:           https://github.com/troglobit/finit/actions/workflows/build.yml/\n[GitHub Status]:    https://github.com/troglobit/finit/actions/workflows/build.yml/badge.svg\n[Coverity Scan]:    https://scan.coverity.com/projects/3545\n[Coverity Status]:  https://scan.coverity.com/projects/3545/badge.svg\n","funding_links":["https://github.com/sponsors/troglobit"],"categories":["C"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroglobit%2Ffinit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftroglobit%2Ffinit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroglobit%2Ffinit/lists"}