mirror of
https://github.com/pygos/init.git
synced 2024-12-22 23:30:50 +01:00
Add basic documentation stub
Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
This commit is contained in:
parent
0b3f53cd9f
commit
cd946f0b9c
4 changed files with 271 additions and 68 deletions
68
README
68
README
|
@ -1,68 +0,0 @@
|
|||
|
||||
This directory contains the source code for a tiny init devised for
|
||||
the Pygos system.
|
||||
|
||||
The main goal of this project is to create a simple framework for:
|
||||
- system boot up and initialization
|
||||
- service supervision
|
||||
|
||||
With the additional aims of having something that:
|
||||
- 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
|
||||
Linux specific features (e.g. signalfd), but if sufficient interest exists,
|
||||
it should still be possible to make it run on some BSDs or whatever else.
|
||||
|
||||
The init system tries to mimic the concept of unit files from systemd as
|
||||
those were considered to be a good design choice.
|
||||
|
||||
Right now, the system is in a "basically works" proof of concept stage and
|
||||
needs some more work to become usable.
|
||||
|
||||
There are plans for *maybe* *eventually* adding support for Linux name
|
||||
spaces, seccomp filters and cgroups as needed in the medium future.
|
||||
|
||||
|
||||
There are already a bunch of similar projects out there that have been
|
||||
considered for use in the Pygos system. The reason for starting a new
|
||||
one was mainly dissatisfaction with the existing ones. Other Projects
|
||||
that have been considered include:
|
||||
|
||||
- systemd
|
||||
Contains a lot of good ideas, but it is HUGE. It has tons of
|
||||
dependencies. It implements tons of things that it simply shouldn't.
|
||||
It has a horrid, "modern", python based, hipster build system.
|
||||
It's simply too damn large and complex.
|
||||
|
||||
- SystemV init
|
||||
A bad combination of unnecessary complexity where it isn't needed and a
|
||||
complete lack of abstraction where it would be needed. Shell script
|
||||
copy and paste madness. There are reasons people started developing
|
||||
alternatives (other than "hurr-durr-parallel-boots").
|
||||
|
||||
- upstart
|
||||
Seems nice overall, but needlessly big and complex for the intended
|
||||
use case in Pygos. Would have needlessly added D-Bus to the system.
|
||||
|
||||
- OpenRC
|
||||
Was already integrated into Pygos. Things turned out to be broken.
|
||||
Upstream developers did not accept fixes (after ignoring them for weeks
|
||||
and preferring typo fixes instead). Complaints from other people who
|
||||
tried to contribute fixes were observed on Github. Complaints from
|
||||
package maintainers about deteriorating code quality were observed
|
||||
on the official IRC channel. Documentation is non-existent.
|
||||
|
||||
- daemontools and similar (runnit, s6, minit, ...)
|
||||
The sixties are over. And even code from that era is more readable. The
|
||||
source code for those projects should better be tossed out the window and
|
||||
rewritten from scratch. If you are a first semester CS student and you
|
||||
hand something like this in as a homework, the best you might get is a
|
||||
well deserved slap on the back of your head.
|
||||
|
||||
- busybox init
|
||||
Nice and simple. Probably the best fit if the rest of your user space is
|
||||
busybox as well.
|
||||
|
90
README.md
Normal file
90
README.md
Normal file
|
@ -0,0 +1,90 @@
|
|||
# About
|
||||
|
||||
This directory contains the source code for a tiny init devised for
|
||||
the Pygos system.
|
||||
|
||||
The main goal of this project is to create a simple framework for:
|
||||
|
||||
- system boot up and initialization
|
||||
- service supervision
|
||||
|
||||
With the additional aims of having something that:
|
||||
|
||||
- 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
|
||||
Linux specific features (e.g. signalfd), but if sufficient interest exists,
|
||||
it should still be possible to make it run on some BSDs or whatever else.
|
||||
|
||||
The init system tries to mimic the concept of unit files from systemd as those
|
||||
were considered to be a good design choice.
|
||||
|
||||
Those parameterizeable service description files are stored in `/usr/share/init`
|
||||
by default. Services are enabled by creating a symlink in `/etc/init.d`. This
|
||||
can be done 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
|
||||
daemon does during system boot.
|
||||
|
||||
|
||||
Right now, the system is in a "basically works" proof of concept stage and
|
||||
needs some more work to become usable.
|
||||
|
||||
There are plans for *maybe* *eventually* adding support for Linux name
|
||||
spaces, seccomp filters and cgroups as needed in the medium future.
|
||||
|
||||
|
||||
## Why
|
||||
|
||||
There are already a bunch of similar projects out there that have been
|
||||
considered for use in the Pygos system. The reason for starting a new
|
||||
one was mainly dissatisfaction with the existing ones. Other Projects
|
||||
that have been considered include:
|
||||
|
||||
- systemd
|
||||
|
||||
Contains a lot of good ideas, but it is HUGE. It has tons of
|
||||
dependencies. It implements tons of things that it simply shouldn't.
|
||||
It has a horrid, "modern", python based, hipster build system.
|
||||
It's simply too damn large and complex.
|
||||
|
||||
- SystemV init
|
||||
|
||||
A bad combination of unnecessary complexity where it isn't needed and a
|
||||
complete lack of abstraction where it would be needed. Shell script
|
||||
copy and paste madness. There are reasons people started developing
|
||||
alternatives (other than "hurr-durr-parallel-boots").
|
||||
|
||||
- upstart
|
||||
|
||||
Seems nice overall, but needlessly big and complex for the intended
|
||||
use case in Pygos. Would have needlessly added D-Bus to the system.
|
||||
|
||||
- OpenRC
|
||||
|
||||
Was already integrated into Pygos. Things turned out to be broken.
|
||||
Upstream developers did not accept fixes (after ignoring them for weeks
|
||||
and preferring typo fixes instead). Complaints from other people who
|
||||
tried to contribute fixes were observed on GitHub. Complaints from
|
||||
package maintainers about deteriorating code quality were observed
|
||||
on the official IRC channel. Documentation is non-existent.
|
||||
|
||||
- daemon tools and similar (runnit, s6, minit, ...)
|
||||
|
||||
The sixties are over. And even code from that era is more readable. The
|
||||
source code for those projects should better be tossed out the window and
|
||||
rewritten from scratch. If you are a first semester CS student and you
|
||||
hand something like this in as a homework, the best you might get is a
|
||||
well deserved slap on the back of your head.
|
||||
|
||||
- busybox init
|
||||
|
||||
Nice and simple. Probably the best fit if the rest of your user space is
|
||||
busybox as well.
|
||||
|
71
docs/bootup.md
Normal file
71
docs/bootup.md
Normal file
|
@ -0,0 +1,71 @@
|
|||
# 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.
|
||||
|
110
docs/services.md
Normal file
110
docs/services.md
Normal file
|
@ -0,0 +1,110 @@
|
|||
# Service Files
|
||||
|
||||
Services that can be started and managed by init are described by service
|
||||
description files stored in `/usr/share/init`.
|
||||
|
||||
The init process actually reads from `/etc/init.d` which contains symlinks to
|
||||
the actual service files.
|
||||
|
||||
Enabling a service means adding a symlink, disabling means removing a symlink.
|
||||
|
||||
Service descriptions can be parameterized. The arguments are extracted from the
|
||||
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
|
||||
name.
|
||||
|
||||
|
||||
|
||||
Below is an annotated example for a simple, service description for a
|
||||
generic, parameterized agetty 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"
|
||||
|
||||
#
|
||||
# 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.
|
||||
|
||||
Arguments are separated by space. Quotation marks can be used to treat
|
||||
something containing spaces or comment character as a single argument.
|
||||
|
||||
In between quotation marks, C-style escape sequences can be used.
|
||||
|
||||
Argument substitution (arguments derived from the symlink name) can be
|
||||
done using a '%' sign, followed by the argument index. A '%' sign can be
|
||||
escaped by writing '%%'.
|
||||
|
||||
|
||||
If a service should sequentially run multiple commands, they can be grouped
|
||||
inside braces as can be seen in the following, abbreviated example:
|
||||
|
||||
description "mount /var"
|
||||
type wait
|
||||
target boot
|
||||
before vfs
|
||||
exec {
|
||||
mount -t tmpfs none /var
|
||||
mkdir /var/log -m 0755
|
||||
mkdir /var/spool -m 0755
|
||||
mkdir /var/lib -m 0755
|
||||
mkdir /var/tmp -m 0755
|
||||
mount --bind /cfg/preserve/var_lib /var/lib
|
||||
}
|
||||
|
Loading…
Reference in a new issue