After some experiments I found that one target-service pair is enough to boot into. Copied from
Description=shell.service: Console and Login
ExecStartPost=/usr/bin/openvt -f -c 16 agetty tty16
ExecStartPost=/usr/bin/openvt -f -c 17 -- agetty -p tty17
ExecStartPost=/usr/bin/openvt -f -c 18 -- agetty -p -a USER tty18
For testing: renaming the distro's unit dir to
/lib/systemd/systemDEACT is a simple but radical way to reduce the number of units/unit-files from 200 to 10; there are still some false ones:
UNIT LOAD ACTIVE SUB DESCRIPTION
dev-sda3.device loaded activating tentative /dev/sda3
-.mount loaded active mounted Root Mount
tmp.mount loaded active mounted /tmp
init.scope loaded active running System and Service Manager
io.service loaded inactive dead io: usbhid kmod for keyboard
remount.service loaded inactive dead remount: rw for / and tmpfs for /tmp
shell.service loaded active running shell.service: Console and Login
-.slice loaded active active Root Slice
system.slice loaded active active System Slice
* systemd-journald.socket not-found inactive dead systemd-journald.socket
* local-fs-pre.target not-found inactive dead local-fs-pre.target
* local-fs.target not-found inactive dead local-fs.target
mini.target loaded active active "mini": Minimal Boot and Shell
* swap.target not-found inactive dead swap.target
* umount.target not-found inactive dead umount.target
shell.service (see top) I made a
modprobe usbhid is crucial for my (any?) USB keyboard. The remount service needs a sync with the fsck in arch's initrd script for the remount and with tmp.mount for
/tmp. I also have to find out where to place that
rw correctly on the KCL...in the meantime I get a couple of green
[OK] at bootup from two oneshot and one idle services.
The dependency tree is:
remount redundant/conflicting with KCL and
io just doing
modprobe usbhid (which can be done with a
shell.service also), this is just one target/service pair. Plus the
default.target link if you don't add
systemd.unit=mini.target on the kernel CL.
I spent hours chasing the tentative
dev-sdaX.device (the only, root partition); now I think this is halfways normal.
init.scope are internal and make sense.
tmp.mount I think is generated in
not-found journald, local-fs, swap and umount units don't seem to hurt systemd; with
--state loaded they are not shown. They probably should be created as first additional units. But how define
local-fs when root partition comes already checked from initrd? Can a boot with initrd be minimal?
systemctl status is also minimal. There is a slice, but only one (no user-X slices):
Jobs: 0 queued
Failed: 0 units
Since: Fri 2021-10-01 15:24:16 UTC; 3min 2s ago
| `-1 /sbin/init arch\x5cvmlinuz-linux
|-220 agetty tty16
|-222 agetty -p tty17
|-225 agetty -p -a USER tty18
`-238 systemctl status
KillMode you can control what happens to the processes inside shell.service. The corresponding
ps axf is:
1 ? Ss 0:00 /sbin/init arch\vmlinuz-linux
215 tty1 Ss 0:00 /usr/lib/systemd/systemd-sulogin-shell
219 tty1 S 0:00 \_ bash
245 tty1 R+ 0:00 \_ ps axf
246 tty1 S+ 0:00 \_ tail -8
220 tty16 Ss+ 0:00 agetty tty16
222 tty17 Ss+ 0:00 agetty -p tty17
225 tty18 Ss+ 0:00 agetty -p -a USER tty18
agettys have no parent - thanks to
openvt ? - but still PID1/init/systemd keeps track of the pids. I was able to restart
shell.service with different
exit on that sulogin-shell is not recommended...
And how can I stop all this?
After that radical dir-rename the
reboot command "can not talk to init daemon" or so. A (copy of)
reboot.service with action
reboot-force (not reboot, not reboot-immediate) is the most direct way out, and sufficient for this test bootup (no journald running etc.). Sysvinit shutdown is not really elegant either, nor fast.
systemctl start reboot then does the PID signalling and killing and a
sync (I guess), but no otherwise ordered shutdown. That would be with a "final" or "shutdown" target, from where you can go to CPU
halt. With or w/o shutdown-initramfs.
systemd can start and run (and stop!) without journald, udevd and dbus and all these unit files, and
--user instances. But it is hard to "supermask" (i.e. make go away) the 200 distro-units, and then there still are some traces of built-in units and built-in logic.