summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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"