Rick Winscot
2021-04-30 14:39:23 UTC
We have an embedded product that uses a minimal Linux distribution
generated via Buildroot.
Early in the project it was decided to make the rootfs read-only... in an
effort to improve durability in environments where power fluctuations might
cause problems on the eMMC. At the same time, making logging (e.g. /var)
persistent for debugging was added to requirements. Persistent storage
would be achieved by mounting /var to a separate partition that is
read-write.
Several-hundred hours later... with many systemd-analyze reports and
various configurations tested, we have determined that managing the /var
mount with stadard services is not going to work due to tightly coupled and
precisely timed dependencies. Attempts with /etc/fstab and the systemd
generator are also unstable.
Getting /var mounted in proximity to the initialization of
systemd-journald.service seemed illusive.
Several days ago I found a post on Stackoverflow that tied into udev
triggers that seemed promising; resulting in the method outlined below.
Initial testing shows proper timing with all dependencies satisfied.
However, the solution feels... hackey.
My question for anyone on the list, is the method outlined below a
reasonable solution to mounting /var early in the start-up cycle?
Or... is there a better way? Some trimming
Step One: Create a systemd service that mounts /var to the specified
partition
Service: /etc/systemd/system/var.service
[Unit]
Description=service for mounting /var
DefaultDependencies=no
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/mount /dev/mmcblk0p6
Step Two: Add a nofail mount
fstab: /etc/fstab
/dev/root / auto rw 0 1
/dev/mmcblk0p6 /var ext4 rw,nofail 0 0
Step Three: Add a wants dependency on the mount in udev triggers (some
lines deleted for brevity)
Service: /usr/lib/systemd/system/systemd-udev-trigger.service
[Unit]
...
Wants=systemd-udevd.service var.service
[Service]
...
ExecStart=udevadm trigger --type=subsystems --action=add ; /usr/bin/udevadm
trigger
Finally, systemd-analyze plot shows that the mount works as desired.
systemd-udev-trigger.service
var.service
dev-mmcblk0p6.device
var.mount
....
systemd-remount-fs.service
systemd-journal-flush.service
local-fs-pre.target
....
generated via Buildroot.
Early in the project it was decided to make the rootfs read-only... in an
effort to improve durability in environments where power fluctuations might
cause problems on the eMMC. At the same time, making logging (e.g. /var)
persistent for debugging was added to requirements. Persistent storage
would be achieved by mounting /var to a separate partition that is
read-write.
Several-hundred hours later... with many systemd-analyze reports and
various configurations tested, we have determined that managing the /var
mount with stadard services is not going to work due to tightly coupled and
precisely timed dependencies. Attempts with /etc/fstab and the systemd
generator are also unstable.
Getting /var mounted in proximity to the initialization of
systemd-journald.service seemed illusive.
Several days ago I found a post on Stackoverflow that tied into udev
triggers that seemed promising; resulting in the method outlined below.
Initial testing shows proper timing with all dependencies satisfied.
However, the solution feels... hackey.
My question for anyone on the list, is the method outlined below a
reasonable solution to mounting /var early in the start-up cycle?
Or... is there a better way? Some trimming
Step One: Create a systemd service that mounts /var to the specified
partition
Service: /etc/systemd/system/var.service
[Unit]
Description=service for mounting /var
DefaultDependencies=no
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/mount /dev/mmcblk0p6
Step Two: Add a nofail mount
fstab: /etc/fstab
/dev/root / auto rw 0 1
/dev/mmcblk0p6 /var ext4 rw,nofail 0 0
Step Three: Add a wants dependency on the mount in udev triggers (some
lines deleted for brevity)
Service: /usr/lib/systemd/system/systemd-udev-trigger.service
[Unit]
...
Wants=systemd-udevd.service var.service
[Service]
...
ExecStart=udevadm trigger --type=subsystems --action=add ; /usr/bin/udevadm
trigger
Finally, systemd-analyze plot shows that the mount works as desired.
systemd-udev-trigger.service
var.service
dev-mmcblk0p6.device
var.mount
....
systemd-remount-fs.service
systemd-journal-flush.service
local-fs-pre.target
....