diff options
-rw-r--r-- | meta/recipes-core/initrdscripts/initramfs-framework/overlayroot | 112 | ||||
-rw-r--r-- | meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb | 9 |
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 | |||
36 | PATH=/sbin:/bin:/usr/sbin:/usr/bin | ||
37 | |||
38 | # We get OLDROOT from the rootfs module | ||
39 | OLDROOT="/rootfs" | ||
40 | |||
41 | NEWROOT="${RWMOUNT}/root" | ||
42 | RWMOUNT="/overlay" | ||
43 | ROMOUNT="${RWMOUNT}/rofs" | ||
44 | UPPER_DIR="${RWMOUNT}/upper" | ||
45 | WORK_DIR="${RWMOUNT}/work" | ||
46 | |||
47 | MODULES_DIR=/init.d | ||
48 | |||
49 | # Something went wrong, make sure / is mounted as read only anyway. | ||
50 | exit_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 | |||
76 | if [ -z "$bootparam_rootrw" ]; then | ||
77 | exit_gracefully "rootrw= kernel parameter doesn't exist and its required to mount the overlayfs" | ||
78 | fi | ||
79 | |||
80 | mkdir -p ${RWMOUNT} | ||
81 | |||
82 | # Mount RW device | ||
83 | if mount -n -t ${bootparam_rootfstype:-ext4} -o ${bootparam_rootflags:-defaults} ${bootparam_rootrw} ${RWMOUNT} | ||
84 | then | ||
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" | ||
97 | else | ||
98 | exit_gracefully "initramfs-overlayroot: Mounting RW device failed" | ||
99 | fi | ||
100 | |||
101 | # Set up filesystems on overlay | ||
102 | mkdir -p ${NEWROOT}/proc | ||
103 | mkdir -p ${NEWROOT}/dev | ||
104 | mkdir -p ${NEWROOT}/sys | ||
105 | mkdir -p ${NEWROOT}/rofs | ||
106 | |||
107 | mount -n --move ${ROMOUNT} ${NEWROOT}/rofs | ||
108 | mount -n --move /proc ${NEWROOT}/proc | ||
109 | mount -n --move /sys ${NEWROOT}/sys | ||
110 | mount -n --move /dev ${NEWROOT}/dev | ||
111 | |||
112 | 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 \ | |||
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 | ||
23 | S = "${WORKDIR}" | 24 | S = "${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 | ||
69 | FILES:${PN}-base = "/init /init.d/99-finish /dev" | 74 | FILES:${PN}-base = "/init /init.d/99-finish /dev" |
@@ -107,3 +112,7 @@ FILES:initramfs-module-debug = "/init.d/00-debug" | |||
107 | SUMMARY:initramfs-module-lvm = "initramfs lvm rootfs support" | 112 | SUMMARY:initramfs-module-lvm = "initramfs lvm rootfs support" |
108 | RDEPENDS:initramfs-module-lvm = "${PN}-base" | 113 | RDEPENDS:initramfs-module-lvm = "${PN}-base" |
109 | FILES:initramfs-module-lvm = "/init.d/09-lvm" | 114 | FILES:initramfs-module-lvm = "/init.d/09-lvm" |
115 | |||
116 | SUMMARY:initramfs-module-overlayroot = "initramfs support for mounting a RW overlay on top of a RO root filesystem" | ||
117 | RDEPENDS:initramfs-module-overlayroot = "${PN}-base initramfs-module-rootfs" | ||
118 | FILES:initramfs-module-overlayroot = "/init.d/91-overlayroot" | ||