When installed, this module mounts a read-write (RW) overlay on top of a root filesystem, which is kept read-only (RO).
It needs to be executed after the initramfs-module-rootfs since it relies on it to mount the filesystem at initramfs startup but before the finish module which normally switches root. It requires rootrw=<foo> to be passed as a kernel parameter to specify the device/partition to be used as RW by the overlay and has a dependency on overlayfs support being present in the running kernel. It does not require the read-only IMAGE_FEATURE to be enabled. Signed-off-by: Alejandro Enedino Hernandez Samaniego <a...@linux.microsoft.com> --- .../initramfs-framework/overlayroot | 93 +++++++++++++++++++ .../initrdscripts/initramfs-framework_1.0.bb | 9 ++ 2 files changed, 102 insertions(+) create mode 100644 meta/recipes-core/initrdscripts/initramfs-framework/overlayroot diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/overlayroot b/meta/recipes-core/initrdscripts/initramfs-framework/overlayroot new file mode 100644 index 0000000000..ec5700e8fc --- /dev/null +++ b/meta/recipes-core/initrdscripts/initramfs-framework/overlayroot @@ -0,0 +1,93 @@ +#!/bin/sh + +# Simple initramfs module intended to mount a read-write (RW) +# overlayfs on top of /, keeping the original root filesystem +# as read-only (RO). +# +# NOTE: The read-only IMAGE_FEATURE is not required for this to work +# +# It relies on the initramfs-module-rootfs to mount the original +# root filesystem, and requires 'rootrw=<foo>' to be passed as a +# kernel parameter, specifying the device/partition intended to +# use as RW. +# +# It also has a dependency on overlayfs being enabled in the +# running kernel via KERNEL_FEATURES (kmeta) or any other means. +# +# The RO root filesystem remains accessible by the system, mounted +# at /rofs + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +# We get OLDROOT from the rootfs module +OLDROOT="/rootfs" + +NEWROOT="${RWMOUNT}/root" +RWMOUNT="/overlay" +ROMOUNT="${RWMOUNT}/rofs" +UPPER_DIR="${RWMOUNT}/upper" +WORK_DIR="${RWMOUNT}/work" + +MODULES_DIR=/init.d + +exit_gracefully() { + echo $1 >/dev/console + echo >/dev/console + echo "OverlayRoot mounting failed, starting system as read-only" >/dev/console + echo >/dev/console + + # Make sure / is mounted as read only anyway. + # Borrowed from rootfs-postcommands.bbclass + # Tweak the mount option and fs_passno for rootfs in fstab + if [ -f ${OLDROOT}/etc/fstab ]; then + sed -i -e '/^[#[:space:]]*\/dev\/root/{s/defaults/ro/;s/\([[:space:]]*[[:digit:]]\)\([[:space:]]*\)[[:digit:]]$/\1\20/}' ${OLDROOT}/etc/fstab + fi + + # Tweak the "mount -o remount,rw /" command in busybox-inittab inittab + if [ -f ${OLDROOT}/etc/inittab ]; then + sed -i 's|/bin/mount -o remount,rw /|/bin/mount -o remount,ro /|' ${OLDROOT}/etc/inittab + fi + + # Continue as if the overlayroot module didn't exist + . $MODULES_DIR/99-finish + eval "finish_run" +} + + +if [ -z "$bootparam_rootrw" ]; then + exit_gracefully "rootrw= kernel parameter doesn't exist and its required to mount the overlayfs" +fi + +mkdir -p ${RWMOUNT} + +# Mount RW device +if mount -n -t ${bootparam_rootfstype:-ext4} -o ${bootparam_rootflags:-defaults} ${bootparam_rootrw} ${RWMOUNT} +then + # Set up overlay directories + mkdir -p ${UPPER_DIR} + mkdir -p ${WORK_DIR} + mkdir -p ${NEWROOT} + mkdir -p ${ROMOUNT} + + # Remount OLDROOT as read-only + mount -o bind ${OLDROOT} ${ROMOUNT} + mount -o remount,ro ${ROMOUNT} + + # Mount RW overlay + mount -t overlay overlay -o lowerdir=${ROMOUNT},upperdir=${UPPER_DIR},workdir=${WORK_DIR} ${NEWROOT} || exit_gracefully "initramfs-overlayroot: Mounting overlay failed" +else + exit_gracefully "initramfs-overlayroot: Mounting RW device failed" +fi + +# Set up filesystems on overlay +mkdir -p ${NEWROOT}/proc +mkdir -p ${NEWROOT}/dev +mkdir -p ${NEWROOT}/sys +mkdir -p ${NEWROOT}/rofs + +mount -n --move ${ROMOUNT} ${NEWROOT}/rofs +mount -n --move /proc ${NEWROOT}/proc +mount -n --move /sys ${NEWROOT}/sys +mount -n --move /dev ${NEWROOT}/dev + +exec chroot ${NEWROOT}/ ${bootparam_init:-/sbin/init} || exit_gracefully "Couldn't chroot into overlay" diff --git a/meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb b/meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb index 9e8c1dc3ab..4e76e20026 100644 --- a/meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb +++ b/meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb @@ -18,6 +18,7 @@ SRC_URI = "file://init \ file://e2fs \ file://debug \ file://lvm \ + file://overlayroot \ " S = "${WORKDIR}" @@ -49,6 +50,9 @@ do_install() { # lvm install -m 0755 ${WORKDIR}/lvm ${D}/init.d/09-lvm + # overlayroot needs to run after rootfs module but before finish + install -m 0755 ${WORKDIR}/overlayroot ${D}/init.d/91-overlayroot + # Create device nodes expected by some kernels in initramfs # before even executing /init. install -d ${D}/dev @@ -64,6 +68,7 @@ PACKAGES = "${PN}-base \ initramfs-module-rootfs \ initramfs-module-debug \ initramfs-module-lvm \ + initramfs-module-overlayroot \ " FILES:${PN}-base = "/init /init.d/99-finish /dev" @@ -107,3 +112,7 @@ FILES:initramfs-module-debug = "/init.d/00-debug" SUMMARY:initramfs-module-lvm = "initramfs lvm rootfs support" RDEPENDS:initramfs-module-lvm = "${PN}-base" FILES:initramfs-module-lvm = "/init.d/09-lvm" + +SUMMARY:initramfs-module-overlayroot = "initramfs support for mounting a RW overlay on top of a RO root filesystem" +RDEPENDS:initramfs-module-overlayroot = "${PN}-base initramfs-module-rootfs" +FILES:initramfs-module-overlayroot = "/init.d/91-overlayroot" -- 2.25.1
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#160961): https://lists.openembedded.org/g/openembedded-core/message/160961 Mute This Topic: https://lists.openembedded.org/mt/88691930/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-