On 1/26/22 7:11 AM, Bruce Ashfield wrote:
On Wed, Jan 26, 2022 at 2:22 AM Alejandro Hernandez Samaniego
<[email protected]> wrote:
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.
Alejandro,

What's the higher level use case for this ? It would be worth capturing
it in the commit log.  Is this filling a gap in existing functionality ? Is it
for spinning up initramfs only configurations ? A security thing ?

Hi Bruce, thanks for reviewing this and pointing out what I missed, I'll be 
sending a v2 later today.

There may be several reasons why we'd want to have the possibility of keeping 
the original
rootfs unmodified, and keeping user customizations on a separate device, for 
example it
would make it easier to perform a factory reset on a device.

Signed-off-by: Alejandro Enedino Hernandez Samaniego <[email protected]>
---
  .../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
+
The new script should have a copyright and SPDX identifier .. Don't
take this as great wisdom, it is something thatI always forget to to
as well!

On that note, is this completely from scratch or is it the assembly of
other bits and pieces found elsewhere ? It would be good to document
that as well.

Oops! completely forgot!, I'll add it.

This is loosely based on the overlay-etc.bbclass the difference is that
the class only works for overlaying /etc and it doesnt require an
initramfs, but, while its possible to tinker it in such a way that it
overlays /, its not possible to access the original (RO) / after booting the
system, this is the reason  why this has to be done from initramfs and why
this doesnt patch the overlay-etc.bbclass instead.

I believe Ubuntu has this feature, coming from the cloud-initramfs
package, functionally it should be similar although no code was borrowed
from there.

I'll add a note about the overlay-etc class though.

+# 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
For maintenance reasons, it would be a good idea to expand on (in
words) what the tweak is, what the old value is, and the new.

Actually that comment (along with the next couple of lines) is coming
from the rootfs-postcommands.bbclass to mount the root filesystem RO.


+    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"
What's the boot flow in the end ? The r/w overlay is setup, and the rest of the
initrams -> full boot happens as normal ?

Bruce

In the initramfs-framework flow, this  would be the last module that is run, and 
"replaces" the finish module,
so the rest of the initramfs-modules that were installed should have been run 
already keeping the same boot
flow, although, instead of the finish module executing switch_root to the now 
mounted real root, this chroots
into the now mounted real RW root overlay.

This patch does not install (or create any rdepends to) the 
initramfs-module-overlayroot package on purpose,
the original flow using initramfs-framework is kept, it would only change to 
the above flow when a user manually
installs this module on their initramfs image.

Alejandro


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





--
- Thou shalt not follow the NULL pointer, for chaos and madness await
thee at its end
- "Use the force Harry" - Gandalf, Star Trek II
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#160990): 
https://lists.openembedded.org/g/openembedded-core/message/160990
Mute This Topic: https://lists.openembedded.org/mt/88691930/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to