summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlejandro Hernandez Samaniego <alhe@linux.microsoft.com>2022-01-29 12:48:39 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-03-01 23:44:59 +0000
commited323de4dcb600dd71d544f5994f52307b6db564 (patch)
tree581575b6fa10b8f987dedff95ecc7f0e1f7716f9
parent31bca6db85302e4b178c274b026fe0f42cbfa10f (diff)
downloadpoky-ed323de4dcb600dd71d544f5994f52307b6db564.tar.gz
initramfs-framework: Add overlayroot module
When installed, this module mounts a read-write (RW) overlay on top of a root filesystem, which is kept read-only (RO), free from modifications by the user, this might prove to be useful if we want to access or restore the original unmodified rootfs. The existing overlay-etc.bbclass does something similar, it mounts an overlay on top of the /etc directory, however doing the same for root causes the original root to be inaccessible once the system is booted, hence why this module is added to the initramfs boot flow, allowing us to mount the RW overlay, while keeping the original rootfs mounted at /rofs once the system finishes booting. This script is loosely based on that class. This module 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. The module 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. After overlayroot is executed the usual boot flow continues from the real init process. If something goes wrong while running this module, the rootfs is still mounted RO (with no overlay) and the finish module is executed to continue booting normally. Its worth noting that, on purpose, this isnt installed by default on any images that use initramfs-framework to keep the boot flow unmodified, only when a user manually requests to install it, then it becomes functional. (From OE-Core rev: 4f876982a856c54a8074c85346632e33caa7ef53) Signed-off-by: Alejandro Enedino Hernandez Samaniego <alhe@linux.microsoft.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-core/initrdscripts/initramfs-framework/overlayroot112
-rw-r--r--meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb9
2 files changed, 121 insertions, 0 deletions
diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/overlayroot b/meta/recipes-core/initrdscripts/initramfs-framework/overlayroot
new file mode 100644
index 0000000000..d40342dc59
--- /dev/null
+++ b/meta/recipes-core/initrdscripts/initramfs-framework/overlayroot
@@ -0,0 +1,112 @@
1#!/bin/sh
2
3# SPDX-License-Identifier: MIT
4#
5# Copyright 2022 (C), Microsoft Corporation
6
7# Simple initramfs module intended to mount a read-write (RW)
8# overlayfs on top of /, keeping the original root filesystem
9# as read-only (RO), free from modifications by the user.
10#
11# NOTE: The read-only IMAGE_FEATURE is not required for this to work
12#
13# This script is based on the overlay-etc.bbclass, which sets up
14# an overlay on top of the /etc directory, but in this case allows
15# accessing the original, unmodified rootfs at /rofs after boot.
16#
17# It relies on the initramfs-module-rootfs to mount the original
18# root filesystem, and requires 'rootrw=<foo>' to be passed as a
19# kernel parameter, specifying the device/partition intended to
20# use as RW.
21#
22# This module needs to be executed after the initramfs-module-rootfs
23# since it relies on it to mount the filesystem at initramfs startup
24# but before the finish module which normally switches root.
25# After overlayroot is executed the usual boot flow continues from
26# the real init process.
27#
28# If something goes wrong while running this module, the rootfs
29# is still mounted RO (with no overlay) and the finish module is
30# executed to continue booting normally.
31#
32# It also has a dependency on overlayfs being enabled in the
33# running kernel via KERNEL_FEATURES (kmeta) or any other means.
34
35
36PATH=/sbin:/bin:/usr/sbin:/usr/bin
37
38# We get OLDROOT from the rootfs module
39OLDROOT="/rootfs"
40
41NEWROOT="${RWMOUNT}/root"
42RWMOUNT="/overlay"
43ROMOUNT="${RWMOUNT}/rofs"
44UPPER_DIR="${RWMOUNT}/upper"
45WORK_DIR="${RWMOUNT}/work"
46
47MODULES_DIR=/init.d
48
49# Something went wrong, make sure / is mounted as read only anyway.
50exit_gracefully() {
51 echo $1 >/dev/console
52 echo >/dev/console
53 echo "OverlayRoot mounting failed, starting system as read-only" >/dev/console
54 echo >/dev/console
55
56 # The following is borrowed from rootfs-postcommands.bbclass
57 # This basically looks at the real rootfs mounting options and
58 # replaces them with "ro"
59
60 # Tweak the mount option and fs_passno for rootfs in fstab
61 if [ -f ${OLDROOT}/etc/fstab ]; then
62 sed -i -e '/^[#[:space:]]*\/dev\/root/{s/defaults/ro/;s/\([[:space:]]*[[:digit:]]\)\([[:space:]]*\)[[:digit:]]$/\1\20/}' ${OLDROOT}/etc/fstab
63 fi
64
65 # Tweak the "mount -o remount,rw /" command in busybox-inittab inittab
66 if [ -f ${OLDROOT}/etc/inittab ]; then
67 sed -i 's|/bin/mount -o remount,rw /|/bin/mount -o remount,ro /|' ${OLDROOT}/etc/inittab
68 fi
69
70 # Continue as if the overlayroot module didn't exist to continue booting
71 . $MODULES_DIR/99-finish
72 eval "finish_run"
73}
74
75
76if [ -z "$bootparam_rootrw" ]; then
77 exit_gracefully "rootrw= kernel parameter doesn't exist and its required to mount the overlayfs"
78fi
79
80mkdir -p ${RWMOUNT}
81
82# Mount RW device
83if mount -n -t ${bootparam_rootfstype:-ext4} -o ${bootparam_rootflags:-defaults} ${bootparam_rootrw} ${RWMOUNT}
84then
85 # Set up overlay directories
86 mkdir -p ${UPPER_DIR}
87 mkdir -p ${WORK_DIR}
88 mkdir -p ${NEWROOT}
89 mkdir -p ${ROMOUNT}
90
91 # Remount OLDROOT as read-only
92 mount -o bind ${OLDROOT} ${ROMOUNT}
93 mount -o remount,ro ${ROMOUNT}
94
95 # Mount RW overlay
96 mount -t overlay overlay -o lowerdir=${ROMOUNT},upperdir=${UPPER_DIR},workdir=${WORK_DIR} ${NEWROOT} || exit_gracefully "initramfs-overlayroot: Mounting overlay failed"
97else
98 exit_gracefully "initramfs-overlayroot: Mounting RW device failed"
99fi
100
101# Set up filesystems on overlay
102mkdir -p ${NEWROOT}/proc
103mkdir -p ${NEWROOT}/dev
104mkdir -p ${NEWROOT}/sys
105mkdir -p ${NEWROOT}/rofs
106
107mount -n --move ${ROMOUNT} ${NEWROOT}/rofs
108mount -n --move /proc ${NEWROOT}/proc
109mount -n --move /sys ${NEWROOT}/sys
110mount -n --move /dev ${NEWROOT}/dev
111
112exec 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 \
18 file://e2fs \ 18 file://e2fs \
19 file://debug \ 19 file://debug \
20 file://lvm \ 20 file://lvm \
21 file://overlayroot \
21 " 22 "
22 23
23S = "${WORKDIR}" 24S = "${WORKDIR}"
@@ -49,6 +50,9 @@ do_install() {
49 # lvm 50 # lvm
50 install -m 0755 ${WORKDIR}/lvm ${D}/init.d/09-lvm 51 install -m 0755 ${WORKDIR}/lvm ${D}/init.d/09-lvm
51 52
53 # overlayroot needs to run after rootfs module but before finish
54 install -m 0755 ${WORKDIR}/overlayroot ${D}/init.d/91-overlayroot
55
52 # Create device nodes expected by some kernels in initramfs 56 # Create device nodes expected by some kernels in initramfs
53 # before even executing /init. 57 # before even executing /init.
54 install -d ${D}/dev 58 install -d ${D}/dev
@@ -64,6 +68,7 @@ PACKAGES = "${PN}-base \
64 initramfs-module-rootfs \ 68 initramfs-module-rootfs \
65 initramfs-module-debug \ 69 initramfs-module-debug \
66 initramfs-module-lvm \ 70 initramfs-module-lvm \
71 initramfs-module-overlayroot \
67 " 72 "
68 73
69FILES:${PN}-base = "/init /init.d/99-finish /dev" 74FILES:${PN}-base = "/init /init.d/99-finish /dev"
@@ -107,3 +112,7 @@ FILES:initramfs-module-debug = "/init.d/00-debug"
107SUMMARY:initramfs-module-lvm = "initramfs lvm rootfs support" 112SUMMARY:initramfs-module-lvm = "initramfs lvm rootfs support"
108RDEPENDS:initramfs-module-lvm = "${PN}-base" 113RDEPENDS:initramfs-module-lvm = "${PN}-base"
109FILES:initramfs-module-lvm = "/init.d/09-lvm" 114FILES:initramfs-module-lvm = "/init.d/09-lvm"
115
116SUMMARY:initramfs-module-overlayroot = "initramfs support for mounting a RW overlay on top of a RO root filesystem"
117RDEPENDS:initramfs-module-overlayroot = "${PN}-base initramfs-module-rootfs"
118FILES:initramfs-module-overlayroot = "/init.d/91-overlayroot"