Skip to content

Instantly share code, notes, and snippets.

@groundwater
Last active December 23, 2015 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save groundwater/6643177 to your computer and use it in GitHub Desktop.
Save groundwater/6643177 to your computer and use it in GitHub Desktop.

NodeOS Init

History

Init is the first process launched on boot that is not in kernel space. Init runs as the root user, but it is still a user land process. Init has a process-id, it can be sent signals, and uses standard syscalls to interact with the kernel.

What makes init special is that it is essentially in charge of booting the operating system. During the boot process and after the kernel has fully loaded, control of the system is passed to init from the kernel. At boot time, control of the system passes through several programs, each one passing control onto the next. By passing control up the chain, each system can remain focused on its individual task.

Init is responsible for starting the window manager, for starting the network, for starting the command prompt, and just about every other service you interact with on the system. If you wish a service to start automatically, init needs to know.

Traditional init systems like system.d and upstart let you place configuration files into /etc/rcX.d/, /etc/init/, and /etc/init.d. When init starts, it consults these directories to determine what processes to boot, and how to boot them. An upstart file, for example, will specify the command to execute, the working directory, speical environment variables and so on.

Under these systems, init not only handles starting and stopping these processes, it determines which processes to start.

The New Init

NodeOS init re-invents the old idea of passing the baton forward. After the kernel hands control of the system to init, init simply starts a job-control server and then passes control to another process called the first runner. The first runners job is to decide what to boot.

Init itself is dumb, it is only a job-control server. Through an HTTP interface you can start and stop jobs through init. Init handles all the difficulties around daemonizing and monitoring jobs, so the first runner can focus on just deciding what jobs to start.

Typically the first runner will use the HTTP inteface provided by init to start a series of system daemons like sshd, getty, and any http servers.

Init on LXC-Containers

LXC containers are like chroot on sterroids. Containers let you run one or more processes in complete isolation from the rest of the system. Sometimes containers are used to isolate dependencies, such as ensuring an executable can always find a specific version of a library. Other times containers are used to run entire linux systems inside the outer system.

Init is useful in both contexts, and plays well with containers. Start a one-off console by changing the first runner to a shell like bash.

BOOT=0 lxc-start -n$NAME init bash

This starts init, but with the first-runner set to bash. The first runner and init share the same console, so you will immediately be dropped into an interactive bash console. The benefit of doing it this way is that the init daemon is running and can be interacted with.

By setting the environment variable BOOT=0 init knows to exit after the first runner exists. Normally init remains running long after the first-runner has done its job. However for these more ephemeral linux containers, we may only want init running while we are interacting with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment