At start, systemd reads and loads all unit files before executing any of them, including mount units. This means that all unit files must reside on partitions that were mounted before systemd start, normally just the root partition mounted by the kernel itself.
This is a problem for us, since some of the unit files reside (indirectly as symlinks) on the /data partition. These are used to implement some for user-defined config that must persist across OTA rootfs updates.
There are a couple of approaches to handle this.
First is to mount /data before systemd starts. This is the preferred approach. I'll discuss these options below.
Second is to add a systemd service file that triggers a reload of the unit files after the mounts, but before the services are run. I don't like this approach. It is very brittle and requires complex ordering configuration.
Mounting /data before systemd
First some background on the Linux boot process. The kernel mounts the initial rootfs given to it by the kernel command line arguments, and then executes /sbin/init as PID 1. On older sysv systems, this is a script that enumerates and executes init files l. On newer systemd systems, it is a symlink to the systemd binary.
Sometimes the kernel cannot directly load the real rootfs (maybe it is encrypted, or needs to be mounted over a network). In this case, temporary rootfs is passed to the kernel to be loaded in RAM (ramdisk, initramfs or initrd). This is contains enough to mount the real rootfs, switch_root to the new rootfs, and exec the new /sbin/init.
Proposed approach
Configuring a separate initramfs just to mount /data before systemd starts is complex, particularly with buildroot. Instead, we can just replace /sbin/init (via the overlay rootfs) with an executable script that mounts /data and then execs systemd. Something like
$!/bin/sh
mount /dev/mmc???????? /data
exec /usr/lib/systemd/systemd
At start, systemd reads and loads all unit files before executing any of them, including mount units. This means that all unit files must reside on partitions that were mounted before systemd start, normally just the root partition mounted by the kernel itself.
This is a problem for us, since some of the unit files reside (indirectly as symlinks) on the /data partition. These are used to implement some for user-defined config that must persist across OTA rootfs updates.
There are a couple of approaches to handle this.
First is to mount /data before systemd starts. This is the preferred approach. I'll discuss these options below.
Second is to add a systemd service file that triggers a reload of the unit files after the mounts, but before the services are run. I don't like this approach. It is very brittle and requires complex ordering configuration.
Mounting /data before systemd
First some background on the Linux boot process. The kernel mounts the initial rootfs given to it by the kernel command line arguments, and then executes /sbin/init as PID 1. On older sysv systems, this is a script that enumerates and executes init files l. On newer systemd systems, it is a symlink to the systemd binary.
Sometimes the kernel cannot directly load the real rootfs (maybe it is encrypted, or needs to be mounted over a network). In this case, temporary rootfs is passed to the kernel to be loaded in RAM (ramdisk, initramfs or initrd). This is contains enough to mount the real rootfs, switch_root to the new rootfs, and exec the new /sbin/init.
Proposed approach
Configuring a separate initramfs just to mount /data before systemd starts is complex, particularly with buildroot. Instead, we can just replace /sbin/init (via the overlay rootfs) with an executable script that mounts /data and then execs systemd. Something like