Hi all. I have openwrt running nicely on an embedded device with an NVME as root filesystem. I understand that during normal boot on a flash-based system /rom is where the read-only root ends up with the remaining flash space as overlay under /overlay.
What I would like is to assign a partition on my NVME as read-only root with a second partition as the overlay. How might I do this?
That's not easily possible, in some ways not at all (very deep procd changes necessary - and everything in OpenWrt expects a writable /, to the extent that procd will mount a tmpfs based overlay should everything else fail). While nothing is impossible, this would require quite a few changes.
I am using the imagebuilder to compile my images, so I can use FILES= to override the critical part of the preinit state - at least that is my idea.
The role of /lib/preinit/80_mount_root is to set up the root. It will mount rootfs_data as the overlay unless there is an extroot, in which case that is used. This works however only on devices recognized by mount_root part of fstools. It seems to me I can do this with a script.
I have a solution. The script below I added as /lib/preinit/82_mount_root_nvme using the FILES= option in the image builder. It will mount an nvme partition rootfs_data as the overlay partition.
# Copyright (C) 2024 Signalytic
#
# This assumes blkid is installed.
# We will only attempt if there is no overlay already and there is a rootfs_data
# partition on /dev/nvme0n1.
no_overlay_and_nvme_root() {
if [ -b /dev/nvme0n1 ] && [ $(block info|grep "\/overlay"|wc -l) = "0" ]; then
ROOTFSDATADEV=$(blkid -L rootfs_data /dev/nvme0n1)
if [ -n "$ROOTFSDATADEV" ]; then
echo "0"
fi
fi
echo "1"
}
# Check again for presence of overlay, because init script sequencing and
# running are separate.
# This will create the rootfs_data partition if it does not already exist
do_mount_root_nvme() {
if [ $(block info|grep "\/overlay"|wc -l) = "0" ]; then
DATADEV=$(blkid -L rootfs_data)
if [ -z "$DATADEV" ]; then
echo "ERROR: unable to create rootfs_data partition"
exit 1
fi
mkdir -p /nvme
mount / /nvme
mount -o remount,ro /nvme
mkdir -p /overlay
mount ${DATADEV} /overlay
mkdir -p /overlay/work
mkdir -p /overlay/upper
fopivot /overlay/upper /overlay/work /nvme 1
fi
}
[ "$INITRAMFS" = "1" ] || [ "$(no_overlay_and_nvme_root)" = "1" ] || boot_hook_add preinit_main do_mount_root_nvme