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, modprobe
ing
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:
- sessions https://man7.org/linux/man-pages/man2/setsid.2.html
- handling of SIGINT and SIGTERM is special
- (and how should SIGSTOP / SIGTSTP/SIGTTIN/SIGTTOU work?? there's some detail here https://github.com/Yelp/dumb-init I don't understand)
- the container case is different from the host case
- "pivoting" to shutdown mode
- reaping of orphaned processes