synit/notes/init.md

3.5 KiB

init procedure

Summary of stages
-----------------

detect stage -> stage1 or stage2

stage1 (initramfs)
 - mount various `tmpfs` and other kernel file systems
 - get udev-like running? maybe not needed til stage2?
 - mount rootfs
 - move the `tmpfs`s etc over to the new mount
 - pivot root

stage2 (real root)
 - we don't need to mount the `tmpfs`s again
 - the udev-like will be started by the supervision system
 - so will all the other mounts
 - we really just need to get to the point where the broker is
   running and reacting to saved/configured system state
 - we might be able to just `switch_root` straight into the broker??

If the same /init script is to be used for initramfs and "stage two", then there needs to be a mechanism for distinguishing the two instances of /init. The experimental sketch I made uses presence of /proc/mounts as a signal we're in stage two.

Filesystems on /dev; in Debian bookworm:

udev on /dev type devtmpfs (rw,nosuid,relatime,size=8088328k,nr_inodes=2022082,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M)

In my /init sketch:

mount -t devtmpfs none /dev
mkdir /dev/pts
mkdir /dev/shm
mount -t devpts none /dev/pts

Note the differences in mount flags for the Debian case; e.g. /dev/shm has nodev set on it.

In my sketch, I have a weak attempt at parallelism, modprobeing btrfs at the same time as running udhcpc.

To mount the root filesystem, we need all the necessary kernel modules. Maybe a udev-like "mount server" process could handle mount requests and modprobe as necessary?

In my sketch, network interfaces have to be up before we try to mount the rootfs because it formats (!) the rootfs if it can't mount it (!!) and then installs Alpine on it.

To swap over from initramfs to stage two: after the root is mounted, move the existing mounts (/dev, /proc, /sys, /run), kill all other processes, and switch_root.

broker and supervisor startup

Now we're in "stage two", with no processes except the broker running.

Let's use a rabbit-boot-like setup where we have a little logic-program-a-like determining process startup order. One difference will be the "supergoals" which will be configured in a couple of ways: a static "supergoal" of something which can get config from the file system and start other things, plus dynamic ones from user requests to start/stop stuff.

Service classes & service instances: classes will be registered with the system and declare reverse dependencies. Forward dependencies are included with instances since they can be dynamic (? do we want this?) and each service is aware of what it needs at the moment it starts.

Services: are Syndicate programs that speak the protocol on stdio. To run other things, a supervisor program will listen to Syndicate and run a subprocess in an ad-hoc way.

pid-1 concerns

PID-1 concerns: