aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README68
-rw-r--r--README.md90
-rw-r--r--docs/bootup.md71
-rw-r--r--docs/services.md110
4 files changed, 271 insertions, 68 deletions
diff --git a/README b/README
deleted file mode 100644
index b9b9528..0000000
--- a/README
+++ /dev/null
@@ -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.
-
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a944831
--- /dev/null
+++ b/README.md
@@ -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.
+
diff --git a/docs/bootup.md b/docs/bootup.md
new file mode 100644
index 0000000..1f107bd
--- /dev/null
+++ b/docs/bootup.md
@@ -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.
+
diff --git a/docs/services.md b/docs/services.md
new file mode 100644
index 0000000..223cfb5
--- /dev/null
+++ b/docs/services.md
@@ -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
+ }
+