Relocate all docs from doc/* to docs/*, integrates better w/ GitHub

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2018-01-10 02:28:33 +01:00
1 parent 68ef6ec108
commit 4011b5a3b8
16 files changed
+21 -21

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
# Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of
fostering an open and welcoming community, we pledge to respect all
people who contribute through reporting issues, posting feature
requests, updating documentation, submitting pull requests or patches,
and other activities.
We are committed to making participation in this project a
harassment-free experience for everyone, regardless of level of
experience, gender, gender identity and expression, sexual orientation,
disability, personal appearance, body size, race, ethnicity, age,
religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic
addresses, without explicit permission
* Other unethical or unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct. By adopting
this Code of Conduct, project maintainers commit themselves to fairly
and consistently applying these principles to every aspect of managing
this project. Project maintainers who do not follow or enforce the Code
of Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public
spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may
be reported by opening an issue or contacting one or more of the project
maintainers.
This Code of Conduct is adapted from the [Contributor Covenant][1],
[version 1.2.0][2].
[1]: http://contributor-covenant.org
[2]: http://contributor-covenant.org/version/1/2/0/
+89
View File
@@ -0,0 +1,89 @@
Contributing to Finit
=====================
We welcome any and all help in the form of bug reports, fixes, patches
for new features -- *preferably as GitHub pull requests*. Other methods
are of course also possible: emailing the maintainer a patch or even a
raw file, or simply emailing a feature request or an alert of a problem.
For email questions/requests/alerts there is always the risk of memory
exhaustion on the part of the maintainer(s).
If you are unsure of what to do, or how to implement an idea or bugfix,
open an issue with `"[RFC: Unsure if this is a bug ... ?"`, or similar,
so we can discuss it. Talking about the code first is the best way to
get started before submitting a pull request.
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.
Please take care to ensure you follow the project coding style and the
commit message format. If you follow these recommendations you help
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!
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
100 chars is OK.
The coding style itself is strictly Linux [KNF][].
Commit Messages
---------------
Commit messages exist to track *why* a change was made. Try to be as
clear and concise as possible in your commit messages, and always, be
proud of your work and set up a proper GIT identity for your commits:
git config --global user.name "Jane Doe"
git config --global user.email jane.doe@example.com
Example commit message from the [Pro Git][gitbook] online book, notice
how `git commit -s` is used to automatically add a `Signed-off-by`:
Brief, but clear and concise summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as
the subject of an email and the rest of the text as the body. The
blank line separating the ummary from the body is critical (unless
you omit the body entirely); tools like rebase can get confused if
you run the two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, preceded
by a single space, with blank lines in between, but conventions
vary here
Signed-off-by: Jane Doe <jane.doe@example.com>
Another good *counter* example [is this][rambling] ...
Code of Conduct
---------------
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
[rambling]: http://stopwritingramblingcommitmessages.com/
[conduct]: https://github.com/troglobit/finit/blob/master/CODE-OF-CONDUCT.md
<!--
-- Local Variables:
-- mode: markdown
-- End:
-->
+117
View File
@@ -0,0 +1,117 @@
Goals of Finit
==============
The intent of finit is to monitor not just processes, but to supervise
an entire system and the behavior of certain processes that declare
themselves to be finit compliant. Similar to launchd, the goal of
finit is to be a replacement for:
* init
* inetd
* crond
* watchdogd
A small and simple replacement, primarily for embedded systems, with a
low dependency on external packages. A compliant software is one that
can run as a damon in the foreground. If it can also touch its PID file
after a reconfiguration (`initctl reload`), the Finit dependency system
can also be used.
General
-------
* Add support for timed shutdown in Finit, including cancelled shutdown,
possibly using an at-job, see [crond section](#Crond) below
* 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
* 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.
* Add support for JSON output, or similar, from `initctl show`, e.g.
`initctl show --json`
* [Solaris SMF][] (Service Management Facility) has some interesting
features that may be well worth looking into adopting:
svcs enable -rt svc:/network/ssh:default
That is: (r)esolve dependencies and only enable ssh (t)emporary
in the default runlevel when networking is available.
* `initctl add /sbin/service -n -- Service description`, for details
see above [Solaris SMF][] featuer, issue #55 and issue #69,
https://github.com/troglobit/finit/issues/69#issuecomment-287907610
Init
----
Finit in itself is not SysV Init compatible, it doesn't use `/etc/rc.d`
and `/etc/inet.d` scripts to boot the system. However, a plausible way
to achieve compatibility would be to add a plugin to finit which reads
`/etc/inittab` to be able to start standard Linux systems.
Inetd
-----
* Add support for throttling connections.
* Optimize interface filtering by using socket filter. The functions
`inet_*_peek()` and `inetd_is_allowed()` used for interace filtering
should be possible to rewrite as socket filters.
* Optimize HTTP/HTTPS inetd connections by adding basic support for the
`inetd` variant `redir http/tcp@eth0 nowait [2345] 127.0.0.1:8080`,
which would reduce the overhead of spawn the web server on each HTTP
connection, yet still provide a means of filtering access per iface.
Crond
-----
Requirements are quite rudimentary, basic cron functionality, mainly
system-level timed periodic tasks:
* Periodically run a task, in a matching runlevel
* Optionally run as non-root (`crontab -e` as operator)
Proposed syntax:
# Crontab
cron @SPEC [LVLS] /path/to/cmd [ARGS] -- Optional descr
# One-shot 'at' command
at @YY-mm-ddTHH:MM [LVLS] /path/to/cmd [ARGS] -- Optional descr
Notice the ISO date in the `at` notation. The `cron @SPEC` could use
are mo loose notation, e.g. `@hourly`, `@midnight`, `@daily`, `@weekly`,
`@reboot`, etc. The runlevels is extra filtering sugar. E.g., if cron
service is only allowed in runlevels two or three it will not start if
system currently is in runlevel four.
To run a command as another user the `.conf` file must have a that
owner. E.g., `/etc/finit.d/extra.conf` may be owned by operator and
only hold `cron ...` lines.
What would be extremely useful is if `initctl`, or a homegrown `at`,
could support the basic functionality of the `at` command directly from
the shell -- that way setting up one-time jobs would not entail
re-reading `/etc/finit.conf`
Documentation
-------------
* Write man pages for finit and `finit.conf`, steal from the excellent
`pimd` man pages ...
* Add simple, *very* simple, `finit-simple.conf` example. To illustrate
how close Finit3 still is to the original easy-to-use Finit0 :)
[libwdt]: http://www.wehavemorefun.de/fritzbox/Libwdt.so
[Fritz!Box source dump]: ftp://ftp.avm.de/fritz.box/fritzbox.fon_wlan_7170/x_misc/opensrc/
[Solaris SMF]: http://www.oracle.com/technetwork/articles/servers-storage-admin/intro-smf-basics-s11-1729181.html
<!--
-- Local Variables:
-- mode: markdown
-- End:
-->
+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. Pivot root, or remount `/` read-write, depending on system type
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
+172
View File
@@ -0,0 +1,172 @@
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:
- [libuEv][], the event loop
- [libite][] (-lite), much needed frog DNA
**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 requried versions:
- libite v2.0.1
- libuEv v2.1.0
Configure
---------
Below are a few of the main switches to configure:
* `--disable-inetd`: Disable the built-in inetd server.
* `--enable-rw-rootfs`: Most desktop and server systems boot with the
root file stystem read-only. With this setting Finit will remount it
as read-write early at boot so the `bootmisc.so` plugin can run.
Usually not needed on embedded systems.
* `--enable-static`: Build Finit statically. The plugins will be
built-ins (.o files) and all external libraries, except the C library
will be linked statically.
* `--enable-alsa-utils-plugin`: Enable the optional `alsa-utils.so` sound plugin.
* `--enable-dbus-plugin`: Enable the optional D-Bus `dbus.so` plugin.
* `--enable-lost-plugin`: Enable noisy example plugin for `HOOK_SVC_LOST`.
* `--enable-resolvconf-plugin`: Enable the `resolvconf.so` optional plugin.
* `--enable-x11-common-plugin`: Enable the optional X Window `x11-common.so` plugin.
For more configure flags, see <kbd>./configure --help</kbd>
Example
-------
First, unpack the archive:
```shell
$ tar xf finit-3.0.tar.xz
$ cd finit-3.0/
```
Then configure, build and install:
```shell
$ ./configure --enable-rw-rootfs --enable-inetd-echo-plugin \
--enable-inetd-chargen-plugin --enable-inetd-daytime-plugin \
--enable-inetd-discard-plugin --enable-inetd-time-plugin \
--with-heading="Alpine Linux 3.4" --with-hostname=alpine
$ make
.
.
.
$ DESTDIR=/tmp/finit make install
```
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 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"
**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
-------
Having successfully built Finit it is now be time to take it for a test
drive. The `make install` attempts to set up finit as the system system
init, `/sbin/init`, but this is usually a symlink pointing to the
current init.
So either change the symlink, or change your boot loader (GRUB, LOADLIN,
LILO, U-Boot/Barebox or RedBoot) configuration to append the following
to the kernel command line:
```shell
append="init=/sbin/finit"
```
Remember to also set up an initial `/etc/finit.conf` before rebooting!
Recovery
--------
To rescue a system with Finit, append the following to the kernel
command line:
```shell
append="init=/sbin/finit rescue"
```
This tells Finit to start in a very limited recovery mode, no services
are loaded, no filesystems are mounted or checked, and no networking is
enabled. The default Finit rescue mode configuration is installed into
`/lib/finit/rescue.conf`, which can be safely removed or changed.
By default the a root shell, without login, is started.
Debugging
---------
Edit, or append to, the kernel command line: remove `quiet` to enable
kernel messages and add `debug` to enable Finit debug messages.
```shell
append="init=/sbin/finit debug"
```
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.
**NOTE:** Neither of these two configure options should be enabled on
production systems since they can potentially give a user root access.
[1]: ftp://troglobit.com/finit/finit-3.0.tar.xz
[libuEv]: https://github.com/troglobit/libuev
[libite]: https://github.com/troglobit/libite
+176
View File
@@ -0,0 +1,176 @@
Finit Conditions
================
![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:
- *"do not start this service until another process has started"*, or
- *"do not starty until basic network access is available"*
Conditions are similar in syntax to declaring runlevels per service.
They are specified within angle brackets `<>` and can be applied to any
of the `service`, `task`, or `run` stanza. Multiple conditions may be
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.
### Example
```shell
service [2345] <svc/sbin/setupd,svc/sbin/zebra> /sbin/netd -- Network monitor
```
In this example the Network monitor daemon `netd` is not started until
both the `svc/sbin/setupd` *and* `svc/sbin/zebra` conditions are
satisfied. An `svc` condition is satisfied by the corresponding
service's PID file being created.
**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 triggered by built-in plugins, but can for debugging
purposes also be controlled using the `cond set` and `cond clear`
sub-commands to the `initctl` control tool:
* `initctl cond set your/cond/here`
To set a condition
* `initctl cond clear your/cond/here`
To clear a condition
Conditions retain their current state until the next reconfiguration or
runlevel change. At that point all set conditions transition into the
`flux` state, meaning the condition's state is unknown. (For more info
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.
Built-in Conditions
-------------------
Finit is distributed with a `pidfile` and `netlink` plugin. If enabled,
the `pidfile` plugin watches `/var/run/` for PID files created by the
monitored services, and sets a corresponding condition in the `svc/`
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
files. Which they do when they have completed their initial set up and
are ready to receive signals.
The full path to the dependency is needed by finit to match the PID file
to a monitored process. Finit expects monitored services to touch their
PID files, i.e. update the mtime, when they reload their configuration
files after a `SIGHUP`. Some services do not support `SIGHUP` and are
instead restarted, which is a crude but effective way to have the PID
file touched (re-created).
Built-in conditions:
- `svc/<PATH>`
- `net/route/default`
- `net/<IFNAME>/exist`
- `net/<IFNAME>/up`
- `net/<IFNAME>/running`
**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.
Debugging
---------
If a service is not being started as it should, the problem might be
that one of its conditions is not in the expected state. Use the
command `initctl status` to inspect service status. Services in the
`ready` state are pending a condition.
In that situation, running `initctl cond show` reveals which of the
conditions that are not satisfied. Listed as `off` below.
**Example:**
```shell
~ # initctl cond show
PID Service Status Condition (+ on, ~ flux, - off)
===============================================================================
1419 /sbin/netd on <+svc/sbin/setupd,+svc/sbin/zebra>
0 /sbin/udhcpc off <-net/vlan1/exist>
```
Here we can see that `netd` is allowed to run since both its conditions
are in the `on` state, as indicated by the `+`-prefix. `udhcpc` however
is not allowed to run since `net/vlan1/exist` condition is not satsifed.
As indicated by the `-`-prefix.
To fake interface `vlan1` suddenly appearing, and test what happens to
`udhcpc` we can enable debug mode and assert the condition, like this:
```shell
~ # initctl debug
~ # initctl cond set net/vlan1/exist
```
Then watch the console for the debug messages and then check the output
from `initctl cond show` again. (The client will likely have failed to
start, but at least the condition is now satisfied.)
There is also the `initctl cond dump` command, which dumps all known
conditions and their current status.
Internals
---------
Conditions are implemented as simple files in the file system, in the
`/var/run/finit/cond/` sub-directory. Use the `initctl cond set/clear`
commands to add/remove files in this hierarchy.
A condition is always in one of three states:
* ` on` (+): The condition is asserted.
* ` off` (-): The condition is deasserted.
* `flux` (~): The conditions state is unknown.
All conditions that have not explicitly been set are interpreted as
being in the `off` state.
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
service receives `SIGCONT`. If the condition is no longer satisfied the
service will then be stopped, otherwise no further action is taken.
This STOP/CONT handling minimizes the number of unnecessary service
restarts that would otherwise occur because a depending service was sent
`SIGHUP` for example.
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`.
+344
View File
@@ -0,0 +1,344 @@
Configuration
=============
* [Introduction](#introduction)
* [Syntax](#syntax)
* [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`. Finit 3 can even start a
system using only `/etc/finit.d/*.conf`, highly 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).
### Execute pre commands for a service
If your service requires to run additional commands that are executed before
the service is actually started (something like systemds `ExecStartPre`) you
can use a wrapper shell script which runs the additional commands before
executing the service.
The Finit service .conf file can be put into `/etc/finit.d/available` so you
can control the service using `initctl`. Just place in the service .conf file
the path to the wrapper shell script, e.g. if the wrapper is located in
`/etc/start.d`:
**Example:**
`/etc/finit.d/available/program.conf`:
```conf
service [235] <!> /etc/start.d/program -- Example Program
```
**Example:**
`/etc/start.d/program:`
```shell
#!/bin/sh
# Prepare the command line options
OPTIONS="-u $(cat /etc/username)"
# Execute the program
exec /usr/bin/program $OPTIONS
```
*Note, that the example sets `<!>` to denote that it doesn't support SIGHUP. That
way Finit will stop/start such the service instead of sending SIGHUP at
restart/reload.*
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.
* `module <MODULE> [ARGS]`
Load a kernel module, with optional arguments
* `network <PATH>`
Script or program to bring up networking, with optional arguments
* `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 the 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.
```shell
# 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
```
* `runlevel <N>`
N is the runlevel number 1-9, where 6 is reserved for reboot.
Default is 2.
* `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.
* `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:
```shell
task [s] echo "foo" | cat >/tmp/bar
```
* `service [LVLS] <COND> /path/to/daemon ARGS -- Optional description`
Service, or daemon, to be monitored and automatically restarted if it
exits prematurely. Please note that you often need to provide a
`--foreground` or `--no-background` argument to most daemons to
prevent them from forking off a sub-process in the background.
```shell
service [2345] <svc/sbin/zebra> /sbin/ospfd -- OSPF daemon
```
The `[2345]` is the runlevels `ospfd` is allowed to run in, they are
optional and default to level 2-5 if left out.
The `<...>` is the condition for starting `ospfd`. In this example
Finit waits for another service, `/sbin/zebra`, to have created its
PID file in `/var/run/zebra.pid` before starting `ospfd`.
For a detailed description of conditions, and how to debug them,
see the [Finit Conditions](conditions.md) document.
* `inetd service/proto[@iflist] <wait|nowait> [LVLS] /path/to/daemon args`
Launch a daemon when a client initiates a connection on an Internet
port. Available services are listed in the UNIX `/etc/services` file.
Finit can filter access to from a list of interfaces, `@iflist`, per
inetd service as well as listen to custom ports.
```shell
inetd ftp/tcp nowait @root /usr/sbin/uftpd -i -f
inetd tftp/udp wait @root /usr/sbin/uftpd -i -t
```
The following example listens to port 2323 for telnet connections and
only allows clients connecting from `eth0`:
```shell
inetd 2323/tcp@eth0 nowait [2345] /sbin/telnetd -i -F
```
The interface list, `@iflist`, is of the format `@iface,!iface,iface`,
where a single `!` means to deny access. Notice how interfaces are
comma separated with no spaces.
The `inetd` directive can also have ` -- Optional Description`, only
Finit does not output this text on the console when launching inetd
services. Instead this text is sent to syslog and also shown by the
`initctl` tool. More on inetd below.
* `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.
* `include <CONF>`
Include another configuration file. Absolute path required.
* `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`, which is very useful on embedded systems. Default
baud rate is `38400`.
**Example:**
```conf
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:**
```conf
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`.
**Example:**
```conf
tty [12345] @console 115200 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:
```shell
configure --enable-fallback-shell
```
One can also use the `service` stanza to start a stand-alone shell:
```conf
service [12345] /bin/sh -l
```
When running <kbd>make install</kbd> no default `/etc/finit.conf` will
be installed since system requirements differ too much. Try out the
Debian 6.0 example `/usr/share/doc/finit/finit.conf` configuration that
is capable of service monitoring SSH, sysklogd, gdm and getty!
Every `run`, `task`, `service`, or `inetd` can also list the privileges
the `/path/to/cmd` should be executed with. Simply prefix the path with
`[@USR[:GRP]]` like this:
```shell
run [2345] @joe:users /usr/bin/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:
```shell
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
```
Without the `:ID` to the service the latter will overwrite the former
and only the old web server would be started and supervised.
The `run`, `task`, `service`, or `inetd` stanzas also allow the keyword
`log` to redirect `stderr` and `stdout` of the application to syslog,
using `logger`.
Worth noting is that conditions is allowed for all these stanzas. For a
detailed description, see the [Conditions](conditions.md) document.
Limitations
-----------
To understand the limitations of `finit.conf` vs `finit.d` it is useful
to picture the different phases of the system: bootstrap, runtime, and
shutdown.
### /etc/finit.conf
This file used to be the only way to set up and boot a Finit system.
Today it is mainly used for pre-runtime settings like system hostname,
network bringup and shutdown:
- `host`, only at bootstrap, (runlevel `S`)
- `mknod`, only at bootstrap
- `network`, only at bootstrap
- `runparts`, only at bootstrap
- `include`
- `shutdown`
- `runlevel`, only at bootstrap
- ... and all configuration stanzas from `/etc/finit.d` below
### /etc/finit.d
Support for per-service `.conf` files in `/etc/finit.d` was added in
v3.0 to handle changes of the system configuration at runtime. As of
v3.1 `finit.conf` is also handled at runtime, except of course for any
stanza that only runs at bootstrap. However, a `/etc/finit.d/*.conf`
does *not support* the above `finit.conf` settings described above, only
the following:
- `module`, but only at bootstrap
- `service`
- `task`
- `run`
- `inetd`
- `rlimit`
- `tty`
**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
+75
View File
@@ -0,0 +1,75 @@
Distro Recommendations
======================
By default Finit uses the following directories for configuration files:
```
/etc/
|-- finit.d/ -- Regular (enabled) services
| |-- lighttpd.conf
| `- *.conf
|-- finit.conf -- Bootstrap tasks and services
:
```
To enable a service one simply drops a small configuration file in the
`/etc/finit.d/` directory. This practice works will with systems that
keep disabled services elsewhere, or generates them as needed from some
other tool.
Disitributions, 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 labling or uniformity.
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.
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
```
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/ -- Regular (disabled) services
| | |-- httpd.conf
| | |-- ntpd.conf
| | `-- sshd.conf
| |-- sshd.conf -- Symlink to available/sshd.conf
| `- init.conf -- Bootstrap tasks and services
:
```
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`.
+125
View File
@@ -0,0 +1,125 @@
Internet Super Server
=====================
Inetd
-----
A built-in *Internet Super Server* support was added in Finit v1.12 and
v1.13, along with an internal `time` inetd service, RFC 868 (rdate).
The latter is supplied as a plugin to illustrate how simple it is to
extend finit with more internal inetd services. Today more built-in
services are available.
> Please note, not all UNIX daemons are prepared to run as inetd services.
> In the example below `sshd` also need the command line argument `-i`.
The inetd support in finit is quite advanced. Not only does it launch
services on demand, it can do so on custom ports and also filter inbound
traffic using a poor man's [TCP wrappers][]. The syntax is very similar
to the traditional `/etc/inetd.conf`, yet keeping with the style of
Finit:
```shell
# Launch SSH on demand, in runlevels 2-5 as root
inetd ssh/tcp nowait [2345] @root:root /usr/sbin/sshd -i
```
A more advanced example is listed below, please note the *incompatible
syntax change* that was made between Finit v1.12 and v1.13 to support
deny filters:
```shell
# Start sshd if inbound connection on eth0, port 222, or
# inbound on eth1, port 22. Ignore on other interfaces.
inetd 222/tcp@eth0 nowait [2345] /usr/sbin/sshd -i
inetd ssh/tcp@eth1,eth1 nowait [2345] /usr/sbin/sshd -i
```
If `eth0` is your Internet interface you may want to avoid using the
default port. To run ssh on port 222, and all others on port 22:
```shell
inetd 222/tcp@eth0 nowait [2345] /usr/sbin/sshd -i
inetd ssh/tcp@*,!eth0 nowait [2345] /usr/sbin/sshd -i
```
Compared to Finit v1.12 you must *explicitly deny* access from `eth0`!
To protect against looping attacks, the inetd server will refuse UDP
service if the reply port corresponds to any internal service. Similar
to how the FreeBSD inetd operates.
**Internal Services**
Like the original `inetd`, Finit has a few standard services built-in.
They are realized as plugins to provide a simple means of testing the
inetd functionality stand-alone. But this also provides both a useful
network testing/availability, as well as a rudimentary time server for
`rdate` clients.
- echo
- chargen
- daytime
- discard
- time
For security reasons they are all disabled by default and have to be
enabled with both the `configure` script and a special `inetd` stanza in
the `finit.conf` or `finit.d/*.conf` like this:
```shell
inetd echo/udp wait [2345] internal
inetd echo/tcp nowait [2345] internal
inetd chargen/udp wait [2345] internal
inetd chargen/tcp nowait [2345] internal
inetd daytime/udp wait [2345] internal
inetd daytime/tcp nowait [2345] internal
inetd discard/udp wait [2345] internal
inetd discard/tcp nowait [2345] internal
inetd time/udp wait [2345] internal
inetd time/tcp nowait [2345] internal
```
Then call `rdate` from a remote machine (or use localhost):
```shell
rdate -p <IP>
rdate -up <IP>
```
Or `echoping` to reach the echo service:
```shell
echoping -v <IP>
echoping -uv <IP>
```
Or `echoping -d` to reach the discard service:
```shell
echoping -dv <IP>
echoping -duv <IP>
```
Or `echoping -c` to reach the chargen service:
```shell
echoping -cv <IP>
echoping -cuv <IP>
```
If you use `time/udp` you must use the standard rdate implementation and
then call it with `rdate -up` to connect using UDP. Without the `-p`
argument rdate will try to set the system clock. Please note that rdate
has been deprecated by the NTP protocol and this plugin should only be
used for testing or environments where NTP for some reason is blocked.
Also, remember the UNIX year 2038 bug, or in the case of RFC 868 (and
some NTP implementations), year 2036!
**Note:** There is currently no verification that the same port is used
more than once. So a standard `inetd http/tcp` service will clash
with an ssh entry for the same port `inetd 80/tcp` …
[TCP Wrappers]: https://en.wikipedia.org/wiki/TCP_Wrapper
+131
View File
@@ -0,0 +1,131 @@
Hooks & Plugins
===============
* [Plugins](#plugins)
* [Hooks](#hooks)
* [Bootstrap Hooks](#bootstrap-hooks)
* [Runtime Hooks](#runtime-hooks)
* [Shutdown Hooks](#shutdown-hooks)
Finit can be extended to add general functionality in the form of I/O
monitors, built-in inetd services, or hook plugins.
The following sections detail existing plugins and hook points. For
more information, see the plugins listed below.
Plugins
-------
For your convenience a set of *optional* plugins are available:
* *alsa-utils.so*: Restore and save ALSA sound settings on
startup/shutdown. _Optional plugin._
* *bootmisc.so*: Setup necessary files and system directories for, e.g.,
UTMP (tracks logins at boot). This plugin is central to get a working
system and runs at `HOOK_BASEFS_UP`. The `/var`, `/run`, and `/dev`
file systems must be writable for this plugin to work.
Note: On an embedded system both `/var` and `/run` can be `tmpfs` RAM
disks and `/dev` is usually a `devtmpfs`. This must be defined in the
`/etc/fstab` file and in the Linux kernel config.
* *dbus.so*: Setup and start system message bus, D-Bus, at boot.
_Optional plugin._
* *echo.so*: RFC 862 plugin. Start as inetd service, like time below.
* *chargen.so*: RFC 864 plugin. Start as inetd service, like time below.
* *daytime.so*: RFC 867 plugin. Start as inetd service, like time below.
* *discard.so*: RFC 863 plugin. Start as inetd service, like time below.
* *hwclock.so*: Restore and save system clock from/to RTC on
startup/shutdown.
* *initctl.so*: Extends finit with a traditional `initctl` functionality.
* *lost.so*: Very simple `HOOK_SVC_LOST` example. Logs process ID and
name to syslog. _Optional plugin._
* *netlink.so*: Listens to Linux kernel Netlink events for gateway and
interfaces. These events are then sent to the Finit service monitor
for services that may want to be SIGHUP'ed on new default route or
interfaces going up/down.
* *resolvconf.so*: Setup necessary files for `resolvconf` at startup.
_Optional plugin._
* *time.so*: RFC 868 (rdate) plugin. Start as inetd service. Useful
for testing inetd filtering — BusyBox has an rdate (TCP) client.
* *tty.so*: Watches `/dev`, using inotify, for new device nodes (TTY's)
to start/stop getty consoles on them on demand. Useful when plugging
in a usb2serial converter to login to your embedded device.
* *urandom.so*: Setup random seed at startup.
* *x11-common.so*: Setup necessary files for X-Window. _Optional plugin._
Usually you want to hook into the boot process once, simple hook plugins
like `bootmisc.so` are great for that purpose. They are called at each
hook point in the boot process, useful to insert some pre-bootstrap
mechanisms, like generating configuration files, restoring HW device
state, etc. Available hook points are:
Hooks
-----
### Bootstrap Hooks
* `HOOK_ROOTFS_UP`: When `finit.conf` has been read and `/` has is
mounted — very early
* `HOOK_BASEFS_UP`: All of `/etc/fstab` is mounted, swap is available
and default init signals are setup
* `HOOK_NETWORK_UP`: System bootstrap, runlevel S, has completed and
networking is up (`lo` is up and the `network` script has run)
* `HOOK_SVC_UP`: All services in the active runlevel has been launched
* `HOOK_SYSTEM_UP`: All services *and* everything in `/etc/finit.d`
has been launched
### Runtime Hooks
* `HOOK_SVC_RECONF`: Called when the user has changed something in the
`/etc/finit.d` directory and issued `SIGHUP`. The hook is called when
all modified/removed services have been stopped. When the hook has
completed, Finit continues to start all modified and new services.
* `HOOK_SVC_LOST`: Called when a process is lost. When reconfiguring
services at runtime this hook may be called a lot. However, it may be
a quite useful hook to monitor a system post bootstrap when no, or
few, services are expected to exit. A default plugin `lost.so` is
available in the `plugins/` subdirectory as an example.
**NOTE:** This hook callback gets the lost PID as argument.
* `HOOK_SVC_START`: Like `HOOK_SVC_LOST`, but called when a process is
started. Same caveats apply.
**NOTE:** This hook callback gets the new PID as argument.
* `HOOK_RUNLEVEL_CHANGE`: Called when the user has issued a runlevel
change. The hook is called when services not matching the new
runlevel have been been stopped. When the hook has completed, Finit
continues to start all services in the new runlevel.
### Shutdown Hooks
* `HOOK_SHUTDOWN`: Called at shutdown/reboot, right before all
services are sent `SIGTERM`
Plugins like `initctl.so` and `tty.so` extend finit by acting on events,
they are called I/O plugins and are called from the finit main loop when
`poll()` detects an event. See the source code for `plugins/*.c` for
more help and ideas.
+33
View File
@@ -0,0 +1,33 @@
Finit Services
==============
![The service state machine](svc-machine.png "The service state machine")
State Machine
-------------
A service is bound to a state machine that is in one of six (6) states.
For `run`s and `task`s there is an additional end state called `DONE`,
not shown in the diagram for brevity. Services start in the `HALTED`
state.
The current state depends on the two following conditions:
* `E`: Service enabled. In order for `E` to be satisfied, the service
must be allowed to run in the current runlevel and not be stopped.
A service may be stopped, or blocked, for several reasons:
- The user has manually stopped the service using `initctl stop JOB`
- The program exits immediately. I.e. keeps crashing (make sure to use
the 'run this service in the foreground' command line option)
- The binary is missing in the filesystem
* `C`: Service conditions are satisfied:
- `on` (+): The condition is asserted.
- `off` (-): The condition is deasserted.
- `flux` (~): The condition state is unknown.
For a detailed description of conditions, and how to debug them,
see the [Finit Conditions](conditions.md) document.
+36
View File
@@ -0,0 +1,36 @@
Finit Signals
=============
Finit is often used on embedded and small Linux systems with BusyBox.
Though Finit comes with its own tools for (poweroff, halt, reboot), for
compatibility with the existing BusyBox toolset the following signals
have been adopted:
* `SIGHUP`
Same effect as `finit q`, `init q`, or `initctl reload`, reloads all
*.conf files in `/etc/finit.d/`
* `SIGUSR1`
Calls shutdown hooks, including `HOOK_SHUTDOWN`, stopping all running
processes, and unmounts all file systems. Then tells kernel to halt.
Most people these days want `SIGUSR2` though.
SysV init and systemd use this to re-open their FIFO/D-Bus.
* `SIGUSR2`
Like SIGUSR1, but tell kernel to power-off the system, if ACPI
or similar exists to actually do this. If the kernel fails
power-off, Finit falls back to halt.
SysV init N/A, systemd dumps its internal state to log.
* `SIGTERM`
Like `SIGUSR1`, but tell kernel to reboot the system when done.
SysV init N/A, systemd rexecutes itself.
* `SIGINT`
Sent from kernel when the CTRL-ALT-DEL key combo is pressed.
SysV init and systemd default to reboot with `shutdown -r`.
Finit currently forwards this to `SIGTERM`.
* `SIGPWR`
Sent from a power daemon, like `powstatd(8)`, on changes to the
UPS status. Traditionally SysV init read /etc/powerstatus and
acted on "OK", "FAIL", or "LOW" and then removed the file.
Finit currently forwards this to `SIGUSR2`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB