Skip to content

Init

Init is PID 1 - the first process started by the Kernel on server startup. Originally, "init" would merely load a file to get the , and would display a progress bar that means absolutely nothing, before spawning /bin/sh. Easy-peasy.

However, at some point, I decided for no good reason to have the init process spawn various "services" with automatic start-order calculation and basic service supervision, all from a declarative service file. Why would I do that? ...

Anyways, the file at /etc/init/services.toml describes all the services, and their dependencies. The init process will constantly poll all the services that it knows about (started or not) asking if they want to start, and if so, are they "ready"? (Ready is a simple boolean flag on each service, and that flag will get set to true based on conditions described in the services file.) If all services that want to start are currently ready, cool! Else, we select all services with "ready" dependencies and start them in parallel. Repeat that until the startup is complete.

HACKS

If init ever gets to a point where some services still want to start, but they all have non-ready dependencies, that means there is a cycle inside the service file. Hooray! Init gracefully handles that situation by crashing.

The Service Lifecycle

In a nutshell, the Service lifecycle is:

Service lifecycle

All services start as "STOPPED", but if the services.toml file has boot=true, then we'll automatically bump the service to "WAITING". (Else, it'd take a command from the user to bump that service into that state.) One the service is "WAITING", it will wait for all of its dependencies to get their "ready" flags set. Once that happens, the service's binary file is spawned, and the Service is now "RUNNING".

The Service continues along like this until the binary exits. The process then enters the "EXIT" state, and is immediately filed into one of 3 states:

  • "DONE" if the service was supposed to exit (once=true) and then exited with a 0 exit code.
  • "ERROR" if the service was supposed to exit (once=true) but then exited with a non-zero exit code.
  • "RUNNING" if the service was NOT supposed to exit (once=false).

User Command

Services can be started and stopped on a whim using the service command's --up and --down arguments. Behind the scenes, it sends messages to the init process using the /var/run/init/cmd.pipe FIFO pipe, and the init process will attempt to wrangle the service into that state. You can also introspect the service status using this tool as well!

txt
/home/raydog$ service --info session
Name    session
PID     4
State   RUNNING
Start # 1

HACKS

It is really easy to get the OS into a fairly broken state with this command. Have fun!

The Apollo 11 Service

Toast OS has one service that does not start by default during server startup called apollo11. It will replay the entirety of the Apollo 11 moon mission in realtime to /var/log/apollo11.log.

txt
/home/raydog$ service --up apollo11
service: 'up apollo11' command sent to init

/home/raydog$ tail -f /var/log/apollo11.log
CDR: Roger. Clock.
CDR: Roger. We got a roll program.
CMP: Roger. Roll.
CDR: Roll's complete and the pitch is programed.
CDR: One Bravo.

TODO

I should probably bundle the Apollo11 file separately from the rest of the OS, and only bring the file into the FS if the service gets started. That one file alone increases the size of the JS bundle from 318.2 KiB to 786.4 KiB!