mirror of
https://github.com/pygos/init.git
synced 2024-11-24 12:00:42 +01:00
Cleanup and update documentation
Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
This commit is contained in:
parent
066efaa33e
commit
0ed964c8a5
8 changed files with 568 additions and 167 deletions
71
README.md
71
README.md
|
@ -1,43 +1,66 @@
|
||||||
# About
|
# About
|
||||||
|
|
||||||
This directory contains the source code for a tiny init devised for
|
This directory contains the source code for a tiny service supervision
|
||||||
the Pygos system.
|
framework devised for the Pygos system, consisting of an init daemon,
|
||||||
|
a small syslog daemon and various command line utilities.
|
||||||
|
|
||||||
The main goal of this project is to create a simple framework for:
|
The individual parts of the framework are designed to be independent of
|
||||||
|
each other (for instance, the tiny syslogd is intended to work with *any*
|
||||||
- system boot up and initialization
|
init system and other components of the framework don't depend on the presence
|
||||||
- service supervision
|
of this *specific* syslog implementation) and everything that is not strictly
|
||||||
|
part of the init system (such as the syslog daemon) can be disabled through
|
||||||
With the additional aims of having something that:
|
the configure script.
|
||||||
|
|
||||||
- simply works
|
|
||||||
- is easy to understand
|
|
||||||
- is easy to configure and maintain
|
|
||||||
|
|
||||||
|
|
||||||
The init process is intended to run on top of Linux and makes use of some
|
The programs of this package are developed first and foremost for GNU/Linux
|
||||||
Linux specific features (e.g. signalfd), but if sufficient interest exists,
|
systems, so there are some GNU and some Linux extensions used and some of the
|
||||||
it should still be possible to make it run on some BSDs or whatever else.
|
code may unintentionally rely on Linux specific behavior.
|
||||||
|
|
||||||
|
Nevertheless, if sufficient interest exists, it should be possible to make it
|
||||||
|
run on BSDs or other Unix-like systems, but some effort may be required.
|
||||||
|
|
||||||
|
|
||||||
The init system tries to mimic the concept of unit files from systemd as those
|
The init system tries to mimic the concept of unit files from systemd as those
|
||||||
were considered to be a good design choice.
|
were considered to be a good design choice.
|
||||||
|
|
||||||
Those parameterizeable service description files are stored in `/usr/share/init`
|
In a typical setup, the parameterizeable service description files are stored
|
||||||
by default. Services are enabled by creating a symlink in `/etc/init.d`. This
|
in `/usr/share/init` by default. Services are enabled by creating a symlink
|
||||||
can be done using the `service` command line tool.
|
in `/etc/init.d`. This can be done more conveniently using the `service`
|
||||||
|
command line tool.
|
||||||
|
|
||||||
See [docs/services.md](docs/services.md) for more information on service
|
|
||||||
description files.
|
|
||||||
|
|
||||||
See [docs/bootup.md](docs/bootup.md) for more information on what the init
|
A default setup is provided, as needed for the Pygos system, including helper
|
||||||
daemon does during system boot.
|
scripts for setting up mount points and for network configuration. If you want
|
||||||
|
to use the init daemon for another system, you may have to toss out or adapt
|
||||||
|
some of the default configuration and make your own.
|
||||||
|
|
||||||
|
|
||||||
Right now, the system is in a "basically works" proof of concept stage and
|
Right now, the system is in a "basically works" proof of concept stage and
|
||||||
needs some more work to become usable.
|
needs some more work to become usable.
|
||||||
|
|
||||||
There are plans for *maybe* *eventually* adding support for Linux name
|
There are plans for *maybe* *eventually* adding more fancy features like
|
||||||
spaces, seccomp filters and cgroups as needed in the medium future.
|
support for Linux name spaces, seccomp filters and cgroups or network
|
||||||
|
back ends for the syslog daemon, but right now, features are added only
|
||||||
|
when the need arises.
|
||||||
|
|
||||||
|
|
||||||
|
See [docs/init.md](docs/init.md) for more information on the design,
|
||||||
|
implementation and caveats of the init daemon.
|
||||||
|
|
||||||
|
See [docs/cmdline.md](docs/cmdline.md) for an explanation on the available
|
||||||
|
command line tools.
|
||||||
|
|
||||||
|
See [docs/services.md](docs/services.md) for more information on service
|
||||||
|
description files.
|
||||||
|
|
||||||
|
See [docs/network.md](docs/network.md) for information on how the network
|
||||||
|
configuration works.
|
||||||
|
|
||||||
|
See [docs/defconfig.md](docs/defconfig.md) for an explanation on the default
|
||||||
|
services and configuration provided with this package.
|
||||||
|
|
||||||
|
See [docs/usyslogd.md](docs/usyslogd.md) for details on the tiny syslog
|
||||||
|
implementation.
|
||||||
|
|
||||||
|
|
||||||
## Why
|
## Why
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
# System Bootup Process
|
|
||||||
|
|
||||||
## Initial Ram Disk to Rootfs transition
|
|
||||||
|
|
||||||
After mounting the root filesystem, either the kernel or the initial ram disk
|
|
||||||
startup process is expected to exec the init program from the root filesystem.
|
|
||||||
|
|
||||||
At the current time, there is no support for re-scanning the service files
|
|
||||||
*yet*, so when init is started, the final configuration in `/etc/init.d` has to
|
|
||||||
be present. As a result, we currently cannot perform mounting of `/etc/` or
|
|
||||||
packing init into the initial ram disk and doing the rootfs transition.
|
|
||||||
|
|
||||||
Also, as a result of this, changing the service configuration requires a system
|
|
||||||
reboot to be effective.
|
|
||||||
|
|
||||||
This _will_ change in the future.
|
|
||||||
|
|
||||||
|
|
||||||
## Processing Service Descriptions
|
|
||||||
|
|
||||||
The init process reads service description files from `/etc/init.d` which are
|
|
||||||
usually symlinks to actual files in `/usr/share/init`.
|
|
||||||
|
|
||||||
The exact locations may be changed through configure flags when compiling init.
|
|
||||||
|
|
||||||
Service files specify a *target* which is basically like a SystemV runlevel and
|
|
||||||
can be one of the following:
|
|
||||||
|
|
||||||
* boot
|
|
||||||
* reboot
|
|
||||||
* shutdown
|
|
||||||
* ctrlaltdel
|
|
||||||
|
|
||||||
After parsing the configuration files, the init process starts running the
|
|
||||||
services for the `boot` target in a topological order as determined by their
|
|
||||||
*before* and *after* dependencies.
|
|
||||||
|
|
||||||
Services can be of one of the following *types*:
|
|
||||||
|
|
||||||
* wait
|
|
||||||
* once
|
|
||||||
* respawn
|
|
||||||
|
|
||||||
Services of type `wait` are started exactly once and the init process waits
|
|
||||||
until they terminate before continuing with other services.
|
|
||||||
|
|
||||||
The type `once` also only runs services once, but immediately continues
|
|
||||||
starting other services in the mean time without waiting.
|
|
||||||
|
|
||||||
Services of type `respawn` also don't stall the init process and are re-started
|
|
||||||
whenever they terminate.
|
|
||||||
|
|
||||||
## Service Process Setup
|
|
||||||
|
|
||||||
If a service description contains only a single `exec` line, the init process
|
|
||||||
forks and then execs the command directly in the child process.
|
|
||||||
|
|
||||||
If the service description contains a `tty` field, the specified device file
|
|
||||||
is opened in the child process and standard I/O is redirected to it before
|
|
||||||
calling exec. Also, a new session is created.
|
|
||||||
|
|
||||||
|
|
||||||
If a service description contains multiple `exec` lines, the init process forks
|
|
||||||
off to a single child process that does the same setup as above, and then runs
|
|
||||||
the command lines sequentially by forking a second time for each one, followed
|
|
||||||
by an exec in the grand child and a wait in the original child.
|
|
||||||
|
|
||||||
If a single command line returns something other than `EXIT_SUCCESS`,
|
|
||||||
processing of multiple command lines is immediately stopped and the offending
|
|
||||||
exit status is returned to init.
|
|
||||||
|
|
||||||
|
|
||||||
The init process reads environment variables from `/etc/initd.env`.
|
|
||||||
|
|
43
docs/cmdline.md
Normal file
43
docs/cmdline.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# Available Command Line Tools
|
||||||
|
|
||||||
|
## The service command
|
||||||
|
|
||||||
|
The `service` utility can be used for control and administration of services.
|
||||||
|
|
||||||
|
It is composed of several sub commands run by issuing
|
||||||
|
`service <command> [arguments..]`.
|
||||||
|
|
||||||
|
Currently available service commands are:
|
||||||
|
|
||||||
|
* enable - enable a service with the given list of arguments.
|
||||||
|
* disable - disable a service. If the service is parameterized, requires the
|
||||||
|
same arguments used for enabling, to disable the specific instance of the
|
||||||
|
service.
|
||||||
|
* dumpscript - generate an equivalent shell script from the `exec` lines of
|
||||||
|
a service after applying all parameter substitutions.
|
||||||
|
* list - list all enabled service. A target can be specified to only list
|
||||||
|
services for the specified target.
|
||||||
|
* help - display a short help text and a list of available commands.
|
||||||
|
|
||||||
|
|
||||||
|
## shutdown and reboot
|
||||||
|
|
||||||
|
The programs `shudown` and `reboot` can be used to signal to the `init` program
|
||||||
|
that it should transition to the `shutdown` or `reboot` target respectively.
|
||||||
|
|
||||||
|
The option `-f` or `--force` can be used to by pass the init system entirely
|
||||||
|
and force a hard reset or power off by directly signalling the kernel.
|
||||||
|
|
||||||
|
Running any one of those programs requires superuser privileges.
|
||||||
|
|
||||||
|
|
||||||
|
## syslog
|
||||||
|
|
||||||
|
If the `usyslogd` service is built as part of this package, a program called
|
||||||
|
`syslog` is built that can be used from the command line to send syslog
|
||||||
|
messages.
|
||||||
|
|
||||||
|
This can for instance be used to produce log messages from shell scripts.
|
||||||
|
|
||||||
|
The log level, facility and identity string can be specified.
|
||||||
|
See `syslog --help` for more information.
|
106
docs/defconfig.md
Normal file
106
docs/defconfig.md
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
# Default Service Configuration
|
||||||
|
|
||||||
|
## Pseudo Services
|
||||||
|
|
||||||
|
The default configuration contains a number of "pseudo services" in the boot
|
||||||
|
target that don't actually do anything but are merely used as anchors in
|
||||||
|
service dependencies, i.e. they indicate that some sort of milestone in the
|
||||||
|
boot sequence has been reached. Everything that is part of that milestone
|
||||||
|
specifies that it should be run *before* that pseudo service and everything
|
||||||
|
that requires that this milestone has been reached, specifies that it wants
|
||||||
|
to run afterwards.
|
||||||
|
|
||||||
|
The pseudo targets are (in the order that they are executed):
|
||||||
|
|
||||||
|
* vfs
|
||||||
|
|
||||||
|
All services that do mount point setup go before this, all service that
|
||||||
|
depend on the fully mounted rootfs go after this.
|
||||||
|
|
||||||
|
* sysinit
|
||||||
|
|
||||||
|
The system has reached a sane state, i.e. the hostname is set, the system
|
||||||
|
clock has a sane value, modules and kernel parameters are loaded, some
|
||||||
|
very basic, fundamental services are running (e.g. syslog).
|
||||||
|
Everything that is part of that setup process goes between `vfs` and
|
||||||
|
`sysinit`, everything that requires a sane setup goes *after* `sysinit`.
|
||||||
|
|
||||||
|
* network
|
||||||
|
|
||||||
|
Network configuration is done. All services that do network configuration
|
||||||
|
should position themselves between `sysinit` and `network`. Everything that
|
||||||
|
requires a fully configured networking setup should go *after* `network`.
|
||||||
|
|
||||||
|
## Default Bootup Services
|
||||||
|
|
||||||
|
This section outlines the services for the boot target that are enabled by
|
||||||
|
default.
|
||||||
|
|
||||||
|
|
||||||
|
The following services are enabled by default and run *before* the `vfs` target
|
||||||
|
for filesystem setup:
|
||||||
|
|
||||||
|
* procfs - mount `procfs` to `/proc` and try to mount additional pseudo
|
||||||
|
filesystems in `/proc` such as `binfmt_misc`
|
||||||
|
* tmpfs - mount a `tmpfs` to `/tmp`
|
||||||
|
* sysfs - mount `sysfs` to `/sys` and try to mount additional pseudo
|
||||||
|
filesystems in `/sys` (e.g. `securityfs`, `configfs`, ...)
|
||||||
|
* devfs - mount `devtmpfs` to `/dev`, try to mount additional pseudo
|
||||||
|
filesystems in `/dev` (e.g. `devpts`, `mqueue`, ...) and try to create
|
||||||
|
some additional device nodes and symlinks.
|
||||||
|
|
||||||
|
|
||||||
|
The following services are enabled by default and configured to run *after*
|
||||||
|
the `vfs` target and *before* the `sysinit` target:
|
||||||
|
|
||||||
|
* hostname - reload hostname `/etc/hostname`
|
||||||
|
* loopback - bring the loopback device up
|
||||||
|
* usyslogd - if the `usyslogd` services is compiled with this package, this
|
||||||
|
service is enabled by default and starts `usyslogd`.
|
||||||
|
* modules - iterate over the file `/etc/modules` and try to load each module
|
||||||
|
using modprobe.
|
||||||
|
* sysctl - restore kernel parameters using `sysctl --system`. See `sysctl(8)`
|
||||||
|
for a list of possible locations that the parameters are read from.
|
||||||
|
|
||||||
|
|
||||||
|
The following services are enabled by default and configured to run *after*
|
||||||
|
the `sysinit` target and *before* the `network` target:
|
||||||
|
|
||||||
|
* ifcfg - static network configuration
|
||||||
|
Does the static network configuration outlined in [network.md](network.md)
|
||||||
|
|
||||||
|
|
||||||
|
## Default Shutdown and Reboot Services
|
||||||
|
|
||||||
|
For the shutdown and reboot targets, the following services are executed:
|
||||||
|
|
||||||
|
* sigterm - send the SIGTERM signal to all processes and wait for 5 seconds
|
||||||
|
* sigkill - send the SIGKILL signal to all remaining processes
|
||||||
|
* ifdown - bring all network interfaces down
|
||||||
|
* sync - run the sync command
|
||||||
|
|
||||||
|
|
||||||
|
## Additional Services not Enabled by Default
|
||||||
|
|
||||||
|
* agetty - A parameterizeable, respawn type `agetty` service. The first
|
||||||
|
parameter is the terminal device that the getty should run on.
|
||||||
|
* dhcpcdmaster - If one or more network interfaces should be configured using
|
||||||
|
dhcpcd, this service starts a central `dhcpcd` master instance.
|
||||||
|
* dhcpcd - A parameterizeable single shot service that signals the `dhcpcd`
|
||||||
|
master that it should configure a specific interface. The first parameter
|
||||||
|
is the interface that should be configured by `dhcpcd`.
|
||||||
|
* dnsmasq - A respawn type service for the `dnsmasq` DNS and DHCP server.
|
||||||
|
* hostapd - If the system should operate a WIFI access point, this respawn
|
||||||
|
type service can be enabled to manage an instace of the `hostapd` program.
|
||||||
|
* unbound - A respawn type service that manages an instance of the `unbound`
|
||||||
|
name resolver.
|
||||||
|
* usyslogd - A respawn type service that manages an instance of the `usyslogd`
|
||||||
|
syslogd implementation that is part of this package.
|
||||||
|
* hwclock - If the system has a hardware clock, this service can restore the
|
||||||
|
kernels clock from the hardware at bootup, between the `vfs` and `sysinit`
|
||||||
|
targets.
|
||||||
|
* nft - If enabled, restores net filter table rules during boot.
|
||||||
|
* swclock - For systems that don't have a hardware clock, this service
|
||||||
|
restores a somewhat usable time from a file during boot.
|
||||||
|
* swclocksave - For systems that don't have a hardware clock, this service
|
||||||
|
saves the current time to a file during shutdown or reboot.
|
71
docs/init.md
Normal file
71
docs/init.md
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
# The Init Daemon
|
||||||
|
|
||||||
|
## Initial Ram Disk to Rootfs transition
|
||||||
|
|
||||||
|
After mounting the root filesystem, either the kernel or the initial ram disk
|
||||||
|
startup process is expected to exec the init program from the root filesystem.
|
||||||
|
|
||||||
|
At the current time, there is no support for re-scanning the service files
|
||||||
|
*yet*, so when init is started, the final configuration in `/etc/init.d` has to
|
||||||
|
be present. As a result, we currently cannot perform mounting of `/etc/` or
|
||||||
|
packing init into the initial ram disk and doing the rootfs transition.
|
||||||
|
|
||||||
|
Also, as a result of this, changing the service configuration requires a system
|
||||||
|
reboot to be effective.
|
||||||
|
|
||||||
|
This _will_ change in the future.
|
||||||
|
|
||||||
|
|
||||||
|
## Service Types and Targets
|
||||||
|
|
||||||
|
A service file has a *type*, specifying whether the service should be run once
|
||||||
|
or restarted when it terminates and a *target*, specifying when the service
|
||||||
|
should be run.
|
||||||
|
|
||||||
|
The *target* is similar to a runlevel in System V init. The init daemon
|
||||||
|
currently knows about the following targets:
|
||||||
|
|
||||||
|
* boot
|
||||||
|
* reboot
|
||||||
|
* shutdown
|
||||||
|
|
||||||
|
When `init` is run, it starts all the services for the `boot` target. From the
|
||||||
|
`boot` target it can transition to any other target and execute the services
|
||||||
|
for the specified target.
|
||||||
|
|
||||||
|
The `reboot` and `shutdown` targets cannot transition to any other target and
|
||||||
|
when invoked, cause initd to drop everything else it intended to do.
|
||||||
|
|
||||||
|
For the `reboot` and `shutdown` targets, respawn type processes are no longer
|
||||||
|
restarted when they terminate and once all services have been executed, the
|
||||||
|
`init` program performs a hard system reboot or power off.
|
||||||
|
|
||||||
|
The init program tries to capture the `CTRL+ALT+DELETE` key sequence (or its
|
||||||
|
local equivalent) and transitions to the reboot target if pressed.
|
||||||
|
|
||||||
|
|
||||||
|
## Service Configuration Rescan
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
|
|
||||||
|
## Control Socket and Signals
|
||||||
|
|
||||||
|
The `init` program catches the following signals:
|
||||||
|
|
||||||
|
* `SIGCHLD`
|
||||||
|
* `SIGINT`
|
||||||
|
* `SIGTERM`
|
||||||
|
|
||||||
|
The `SIGCHLD` handler implements standard process reaping. If a terminated
|
||||||
|
process belongs to one of the supervised services, the configured action is
|
||||||
|
taken (e.g. restarting it).
|
||||||
|
|
||||||
|
When `SIGINT` is caugth, `init` transitions to the `reboot` target. Similarly,
|
||||||
|
`SIGTERM` causes `init` to transition to the `shutdown` target.
|
||||||
|
|
||||||
|
|
||||||
|
For more complex tasks, `init` creates a control socket that the command line
|
||||||
|
tools included in this package can use. For the time being, the control socket
|
||||||
|
can only tell the init daemon to transition to the `reboot` or `shutdown`
|
||||||
|
target.
|
83
docs/network.md
Normal file
83
docs/network.md
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
# Static Network Configuration
|
||||||
|
|
||||||
|
The default configuration provides multiple services that perform network
|
||||||
|
initialization and static configuration using helper scripts that require
|
||||||
|
programs from the `iproute2` package.
|
||||||
|
|
||||||
|
Configuration files are typically stored in `/etc/netcfg/` (depending on
|
||||||
|
configure options).
|
||||||
|
|
||||||
|
Please note that the loopback device is treated specially and not included in
|
||||||
|
any of the network configuration outlined below. The loopback device is brought
|
||||||
|
up and configured by a dedicated service long before the network configuration
|
||||||
|
is done.
|
||||||
|
|
||||||
|
|
||||||
|
## Interface Renaming
|
||||||
|
|
||||||
|
If the `ifrename` service is enabled (it is disabled by default), network
|
||||||
|
interfaces are renamed based on a rule set stored in the file `ifrename`.
|
||||||
|
The file contains comma separated shell globing patterns for the current
|
||||||
|
interface name, MAC address and a prefix for the new interface name.
|
||||||
|
|
||||||
|
For each network interface, rules are processed top to bottom. If the first two
|
||||||
|
globing patterns apply, the interface is renamed. Interfaces with the same
|
||||||
|
prefix are sorted by mac address and a running index is appended to the prefix.
|
||||||
|
|
||||||
|
If none of the rules apply, the interface name is left unchanged.
|
||||||
|
|
||||||
|
|
||||||
|
The intent is, to provide a way to configure persistent, deterministic names for
|
||||||
|
at least all network interfaces that are permanently installed on a board.
|
||||||
|
|
||||||
|
Extension cards or external network adapters should be given a different prefix
|
||||||
|
to avoid changes in the order as they come and go.
|
||||||
|
|
||||||
|
|
||||||
|
## Interface Configuration
|
||||||
|
|
||||||
|
After interface renaming, for each network interface, the configuration path is
|
||||||
|
scanned for files with the same name as the interface.
|
||||||
|
|
||||||
|
Each successfully found configuration file is processed line by line, top to
|
||||||
|
bottom. Each line may contain a keyword, followed by multiple arguments.
|
||||||
|
|
||||||
|
The following keywords can be used to add IPv4 or IPv6 network addresses to
|
||||||
|
an interface:
|
||||||
|
|
||||||
|
* address
|
||||||
|
* addr
|
||||||
|
* ip
|
||||||
|
* ip6
|
||||||
|
* ipv6
|
||||||
|
|
||||||
|
Those commands are expected to be followed by an IPv4 or IPv6 address and
|
||||||
|
network mask.
|
||||||
|
|
||||||
|
|
||||||
|
Furthermore, the following commands can be used for configuring interface
|
||||||
|
parameters:
|
||||||
|
|
||||||
|
* `arp {on|off}`
|
||||||
|
* `multicast {on|off}`
|
||||||
|
* `mtu <value>`
|
||||||
|
* `offload [rx {on|off}] [tx {on|off}] [sg {on|off}] [tso {on|off}]`
|
||||||
|
* `offload [gso {on|off}] [gro {on|off}] [lro {on|off}] [rxvlan {on|off}]`
|
||||||
|
* `offload [txvlan {on|off}] [ntuple {on|off}] [rxhash {on|off}]`
|
||||||
|
* `offload [ufo {on|off}]`
|
||||||
|
|
||||||
|
|
||||||
|
## Route Configuration
|
||||||
|
|
||||||
|
After interface configuration is done, routes and rules are restored from a
|
||||||
|
file named `routes` in the same configuration path.
|
||||||
|
|
||||||
|
The file may contain lines starting with `route` or `rule`. Everything that
|
||||||
|
follows is passed on to `ip route add` or `ip rule add` respectively.
|
||||||
|
|
||||||
|
|
||||||
|
## Net Filter Tables
|
||||||
|
|
||||||
|
|
||||||
|
An additional service is provided that restores the nft rule set from
|
||||||
|
`/etc/nftables.rules`.
|
193
docs/services.md
193
docs/services.md
|
@ -1,84 +1,31 @@
|
||||||
# Service Files
|
# Service Files
|
||||||
|
|
||||||
Services that can be started and managed by init are described by service
|
The init process reads service descriptions from `/etc/init.d` which usually
|
||||||
description files stored in `/usr/share/init`.
|
contains symlinks to the actual service files which can be conveniently removed
|
||||||
|
or added to disable or enable services.
|
||||||
|
|
||||||
The init process actually reads from `/etc/init.d` which contains symlinks to
|
Default services provided by this package are installed in `/usr/share/init`,
|
||||||
the actual service files.
|
i.e. this is where the symlinks point to.
|
||||||
|
|
||||||
|
|
||||||
|
Note that the actual locations may be different, depending on the configure
|
||||||
|
flags used.
|
||||||
|
|
||||||
Enabling a service means adding a symlink, disabling means removing a symlink.
|
|
||||||
|
|
||||||
Service descriptions can be parameterized. The arguments are extracted from the
|
Service descriptions can be parameterized. The arguments are extracted from the
|
||||||
name of the symlink. Currently only 1 parameter is supported. The argument
|
name of the symlink. Currently only 1 parameter is supported. The argument
|
||||||
value is separated from the service name by an '@' character in the symlink
|
value is separated from the service name by an '@' character in the symlink
|
||||||
name.
|
name.
|
||||||
|
|
||||||
|
The file name of the sysmlink, excluding any parameters, is accepted as the
|
||||||
|
canonical name of a service and used when referring to it via command line
|
||||||
|
utilities or when injecting dependencies from a service file.
|
||||||
|
|
||||||
|
|
||||||
Below is an annotated example for a simple, service description for a
|
## Syntax
|
||||||
generic, parameterized agetty service:
|
|
||||||
|
|
||||||
#
|
Each line in a service description is made up of a keyword, followed by one
|
||||||
# The text that init should print out when the status of the
|
or more arguments and terminated by a line break.
|
||||||
# service changes.
|
|
||||||
#
|
|
||||||
# The '%0' is replaced with the first argument extracted from the
|
|
||||||
# symlink name.
|
|
||||||
#
|
|
||||||
description "agetty on %0"
|
|
||||||
|
|
||||||
#
|
|
||||||
# How to run the service. 'respawn' means restart the service when it
|
|
||||||
# terminates, 'once' means run it only once and continue with other
|
|
||||||
# services in the mean while, 'wait' means run it once, but block until
|
|
||||||
# it exits.
|
|
||||||
#
|
|
||||||
type respawn
|
|
||||||
|
|
||||||
#
|
|
||||||
# When to start the service. 'boot' means when booting the system. Other
|
|
||||||
# options are 'reboot', 'shutdown' and 'ctrlaltdel'. The system always
|
|
||||||
# starts into the 'boot' target and then later transitions to one of the
|
|
||||||
# others.
|
|
||||||
#
|
|
||||||
target boot
|
|
||||||
|
|
||||||
#
|
|
||||||
# A list of service names that must be started before this service can
|
|
||||||
# be run, i.e. this services needs to be started after those.
|
|
||||||
#
|
|
||||||
# This can only refer to generic names, not specific instances. For
|
|
||||||
# instance, you can say "after getty" to make sure a service comes up after
|
|
||||||
# all gettys are started, but you cannot specify "after agetty@tty1".
|
|
||||||
#
|
|
||||||
# Similar to 'after', there is also a 'before' keyword for specifying
|
|
||||||
# dependencies.
|
|
||||||
#
|
|
||||||
after sysinit
|
|
||||||
|
|
||||||
#
|
|
||||||
# The 'tty' directive specifies a file to which all I/O of the process is
|
|
||||||
# redirected. The specified device file is used as a controlling tty for
|
|
||||||
# the process and a new session is created with the service process as
|
|
||||||
# session leader.
|
|
||||||
#
|
|
||||||
# In this example, we derive the controlling tty from the service
|
|
||||||
# description argument.
|
|
||||||
#
|
|
||||||
tty "/dev/%0"
|
|
||||||
|
|
||||||
#
|
|
||||||
# The 'exec' directive specifies the command to execute in order to start
|
|
||||||
# the service. See in the example below on how to run multiple commands.
|
|
||||||
#
|
|
||||||
# Again we use the argument to specify what terminal our getty
|
|
||||||
# should run on.
|
|
||||||
#
|
|
||||||
exec agetty %0 linux
|
|
||||||
|
|
||||||
As can be seen in this simple example, each line in a service description is
|
|
||||||
made up of a keyword, followed by one or more arguments and terminated by a
|
|
||||||
line break.
|
|
||||||
|
|
||||||
Blank lines are ignored and shell-style comments can be used.
|
Blank lines are ignored and shell-style comments can be used.
|
||||||
|
|
||||||
|
@ -92,6 +39,115 @@ done using a '%' sign, followed by the argument index. A '%' sign can be
|
||||||
escaped by writing '%%'.
|
escaped by writing '%%'.
|
||||||
|
|
||||||
|
|
||||||
|
## Targets and Types
|
||||||
|
|
||||||
|
Service files specify a *target* which is basically like a SystemV runlevel
|
||||||
|
and can be one of the following:
|
||||||
|
|
||||||
|
* boot
|
||||||
|
* reboot
|
||||||
|
* shutdown
|
||||||
|
|
||||||
|
After parsing the configuration files, the init process starts running the
|
||||||
|
services for the `boot` target in a topological order as determined by their
|
||||||
|
dependencies.
|
||||||
|
|
||||||
|
Services can be of one of the following *types*:
|
||||||
|
|
||||||
|
* wait
|
||||||
|
* once
|
||||||
|
* respawn
|
||||||
|
|
||||||
|
Services of type `wait` are started exactly once and the init process waits
|
||||||
|
until they terminate before continuing with other services.
|
||||||
|
|
||||||
|
The type `once` also only runs services once, but immediately continues
|
||||||
|
starting other services in the mean time without waiting. The init process
|
||||||
|
only waits for `once` types when transitioning to another target.
|
||||||
|
|
||||||
|
Services of type `respawn` also don't stall the init process and are re-started
|
||||||
|
whenever they terminate.
|
||||||
|
|
||||||
|
The keyword `limit` can be used a after `respawn` to specify how often a service
|
||||||
|
may be restarted before giving up.
|
||||||
|
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
A service description file can specify dependencies using the keywords `after`
|
||||||
|
and `before`, each followed by a space separated list of service names.
|
||||||
|
|
||||||
|
The init program executes a service after all the services specified by the
|
||||||
|
`after` keyword have been started (type once or respawn) or have been completed
|
||||||
|
(type wait).
|
||||||
|
|
||||||
|
The `before` keyword injects dependencies in reverse, i.e. all services
|
||||||
|
specified after the `before` keyword are only executed after the service in
|
||||||
|
question has been started.
|
||||||
|
|
||||||
|
If a service specified by `after` or `before` does not exist, it is simply
|
||||||
|
ignored. This can occur for instance if the specified service is not enabled
|
||||||
|
at all in the current configuration.
|
||||||
|
|
||||||
|
|
||||||
|
## Running Services
|
||||||
|
|
||||||
|
If a service contains an `exec` line, the init process attempts to run it
|
||||||
|
using the `runsvc` helper program that sets up the environment, attempts to
|
||||||
|
execute the specified command line and passes the exit status back to the init
|
||||||
|
process.
|
||||||
|
|
||||||
|
If multiple exec lines are specified, `runsvc` executes them sequentially and
|
||||||
|
stops if any one returns a non-zero exit status.
|
||||||
|
|
||||||
|
The environment variables visible to the service processes are read
|
||||||
|
from `/etc/initd.env`.
|
||||||
|
|
||||||
|
If the service description contains a `tty` field, the specified device file
|
||||||
|
is opened by runsvc and standard I/O is redirected to it and a new session
|
||||||
|
is created. The keyword `truncate` can be used to make `runsvc` truncate the
|
||||||
|
file to zero size first.
|
||||||
|
|
||||||
|
For convenience, multiple exec lines can be wrapped into braces, as can be
|
||||||
|
seen in one of the examples below.
|
||||||
|
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Below is an annotated example for a simple, service description for a
|
||||||
|
generic, parameterized getty service:
|
||||||
|
|
||||||
|
#
|
||||||
|
# The text that init should print out when the status of the
|
||||||
|
# service changes.
|
||||||
|
#
|
||||||
|
# The '%0' is replaced with the first argument extracted from the
|
||||||
|
# symlink name.
|
||||||
|
#
|
||||||
|
description "agetty on %0"
|
||||||
|
|
||||||
|
# Restart the getty when it terminates.
|
||||||
|
type respawn
|
||||||
|
|
||||||
|
# We want to spawn gettys when booting the system
|
||||||
|
target boot
|
||||||
|
|
||||||
|
# Only run this service after the 'sysinit' service is done
|
||||||
|
after sysinit
|
||||||
|
|
||||||
|
#
|
||||||
|
# Redirect all I/O of the process to this file. The specified device file
|
||||||
|
# is used as a controlling tty for the process and a new session is created
|
||||||
|
# with the service process as session leader.
|
||||||
|
#
|
||||||
|
# In this example, we derive the controlling tty from the service
|
||||||
|
# description argument.
|
||||||
|
#
|
||||||
|
tty "/dev/%0"
|
||||||
|
|
||||||
|
# In order to run the service, simply fire up the agetty program
|
||||||
|
exec agetty %0 linux
|
||||||
|
|
||||||
If a service should sequentially run multiple commands, they can be grouped
|
If a service should sequentially run multiple commands, they can be grouped
|
||||||
inside braces as can be seen in the following, abbreviated example:
|
inside braces as can be seen in the following, abbreviated example:
|
||||||
|
|
||||||
|
@ -107,4 +163,3 @@ inside braces as can be seen in the following, abbreviated example:
|
||||||
mkdir /var/tmp -m 0755
|
mkdir /var/tmp -m 0755
|
||||||
mount --bind /cfg/preserve/var_lib /var/lib
|
mount --bind /cfg/preserve/var_lib /var/lib
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
94
docs/usyslogd.md
Normal file
94
docs/usyslogd.md
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
# Syslogd Implementation
|
||||||
|
|
||||||
|
A tiny syslogd implementation `usyslogd` is provided as part of this package.
|
||||||
|
|
||||||
|
It opens a socket in `/dev/log`, processes syslog messages and forwards the
|
||||||
|
parsed message to a modular backend interface.
|
||||||
|
|
||||||
|
Currently, there is only one implementation of the backend interface that dumps
|
||||||
|
the log messages into files in the processes working directory (by default
|
||||||
|
`/var/log`).
|
||||||
|
|
||||||
|
A simple log rotation scheme has been implemented.
|
||||||
|
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
By default, the daemon switches its working directory to `/var/log`. The
|
||||||
|
directory is created if it doesn't exist and the daemon always tries to
|
||||||
|
change its mode to one that doesn't allow other users (except group members)
|
||||||
|
to access the directory.
|
||||||
|
|
||||||
|
If told to so on the command line, the daemon chroots to the log directory.
|
||||||
|
|
||||||
|
By default, the daemon then tries to drop privileges by switching to user and
|
||||||
|
group named `syslogd` if they exist (any other user or group can be specified
|
||||||
|
on the command line; doing so causes syslogd to fail if they don't exist).
|
||||||
|
|
||||||
|
|
||||||
|
On a system that hosts accounts for multiple users that may be more or less
|
||||||
|
trusted, one may consider only giving system services access to the syslog
|
||||||
|
socket and not allowing regular users. Otherwise, a user may flood the syslog
|
||||||
|
daemon with messages, possibly leading to resource starvation, or (in the case
|
||||||
|
of size limited log rotation outlined below) to the loss of otherwise critical
|
||||||
|
log messages. Since this is not the primary target of the Pygos system, such
|
||||||
|
a mechanism is not yet implemented.
|
||||||
|
|
||||||
|
In case of a system where only daemons are running, the above mentioned
|
||||||
|
security measure is useless. If a remote attacker manages to get regular user
|
||||||
|
privileges, you already have a different, much greater problem. Also, a remote
|
||||||
|
attacker would have to compromise a local daemon that already has special
|
||||||
|
access to the syslog socket, which is again your least concern in this
|
||||||
|
scenario.
|
||||||
|
|
||||||
|
|
||||||
|
## Logrotation
|
||||||
|
|
||||||
|
The backend can be configured to do log rotation in a continuous fashion (i.e.
|
||||||
|
in a way that log messages aren't lost), or in a way where it drops old
|
||||||
|
messages. Furthermore, the backend can be configured to automatically do a log
|
||||||
|
rotation if a certain size threshold is hit.
|
||||||
|
|
||||||
|
If the `usyslogd` receives a `SIGHUP`, it tells the backend to do log rotation.
|
||||||
|
|
||||||
|
In the case of the size threshold, the backend is expected to do the rotation
|
||||||
|
on its own if the predetermined limit is hit.
|
||||||
|
|
||||||
|
|
||||||
|
## File Based Backend
|
||||||
|
|
||||||
|
The file based backend writes log messages to files in the current working
|
||||||
|
directory (by default `/var/log`), named either after the ident string (if
|
||||||
|
specified) or the facility name.
|
||||||
|
|
||||||
|
Log messages are prefixed with an ISO 8601 time stamp, optionally the facility
|
||||||
|
name (unless part of the file name), the log level and the senders PID. Each
|
||||||
|
of those fields is enclosed in brackets.
|
||||||
|
|
||||||
|
Log rotation in a continuous fashion means renaming the existing log file to
|
||||||
|
one suffixed with the current time stamp. Overwriting old messages renaming
|
||||||
|
the log file by appending a constant `.1` suffix.
|
||||||
|
|
||||||
|
|
||||||
|
## Default Configuration
|
||||||
|
|
||||||
|
The default service configuration limits the log file size to 8 KiB and
|
||||||
|
configures the daemon to overwrite old messages when rotating log files,
|
||||||
|
effectively limiting the amount of log data to 16 KiB per source or facility.
|
||||||
|
|
||||||
|
The intended use case in the Pygos system is logging to a ramdisk without
|
||||||
|
exhausting available memory.
|
||||||
|
|
||||||
|
|
||||||
|
## Possible Future Directions
|
||||||
|
|
||||||
|
In the near term future, the daemon probably requires more fine grained control
|
||||||
|
over logging such as setting a minimum log level or a way to configure limits
|
||||||
|
per facility or service.
|
||||||
|
|
||||||
|
In the medium term future, extended resource control using c-groups might be
|
||||||
|
a possibility.
|
||||||
|
|
||||||
|
Future directions may include adding other backends, such as forwarding the
|
||||||
|
log messages to a central server, for instance using syslog over UDP/TCP or
|
||||||
|
using the front end of some time series database.
|
Loading…
Reference in a new issue