diff options
Diffstat (limited to 'meta/recipes-core/initrdscripts/initramfs-framework/overlayroot')
-rw-r--r-- | meta/recipes-core/initrdscripts/initramfs-framework/overlayroot | 118 |
1 files changed, 118 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..0d41432878 --- /dev/null +++ b/meta/recipes-core/initrdscripts/initramfs-framework/overlayroot | |||
@@ -0,0 +1,118 @@ | |||
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 'overlayrootrwdev=<foo>' to be passed as a | ||
19 | # kernel parameter, specifying the device/partition intended to | ||
20 | # use as RW. | ||
21 | # Mount options of the RW device can be tweaked with 'overlayrootfstype=' | ||
22 | # (defaults to 'ext4') and 'overlayrootfsflags=' ('defaults'). | ||
23 | # | ||
24 | # This module needs to be executed after the initramfs-module-rootfs | ||
25 | # since it relies on it to mount the filesystem at initramfs startup | ||
26 | # but before the finish module which normally switches root. | ||
27 | # After overlayroot is executed the usual boot flow continues from | ||
28 | # the real init process. | ||
29 | # | ||
30 | # If something goes wrong while running this module, the rootfs | ||
31 | # is still mounted RO (with no overlay) and the finish module is | ||
32 | # executed to continue booting normally. | ||
33 | # | ||
34 | # It also has a dependency on overlayfs being enabled in the | ||
35 | # running kernel via KERNEL_FEATURES (kmeta) or any other means. | ||
36 | |||
37 | |||
38 | PATH=/sbin:/bin:/usr/sbin:/usr/bin | ||
39 | |||
40 | # We get OLDROOT from the rootfs module | ||
41 | OLDROOT="/rootfs" | ||
42 | |||
43 | NEWROOT="${RWMOUNT}/root" | ||
44 | RWMOUNT="/overlay" | ||
45 | ROMOUNT="${RWMOUNT}/rofs" | ||
46 | UPPER_DIR="${RWMOUNT}/upper" | ||
47 | WORK_DIR="${RWMOUNT}/work" | ||
48 | |||
49 | MODULES_DIR=/init.d | ||
50 | |||
51 | # Something went wrong, make sure / is mounted as read only anyway. | ||
52 | exit_gracefully() { | ||
53 | echo $1 >/dev/console | ||
54 | echo >/dev/console | ||
55 | echo "OverlayRoot mounting failed, starting system as read-only" >/dev/console | ||
56 | echo >/dev/console | ||
57 | |||
58 | # The following is borrowed from rootfs-postcommands.bbclass | ||
59 | # This basically looks at the real rootfs mounting options and | ||
60 | # replaces them with "ro" | ||
61 | |||
62 | # Tweak the mount option and fs_passno for rootfs in fstab | ||
63 | if [ -f ${OLDROOT}/etc/fstab ]; then | ||
64 | sed -i -e '/^[#[:space:]]*\/dev\/root/{s/defaults/ro/;s/\([[:space:]]*[[:digit:]]\)\([[:space:]]*\)[[:digit:]]$/\1\20/}' ${OLDROOT}/etc/fstab | ||
65 | fi | ||
66 | |||
67 | # Tweak the "mount -o remount,rw /" command in busybox-inittab inittab | ||
68 | if [ -f ${OLDROOT}/etc/inittab ]; then | ||
69 | sed -i 's|/bin/mount -o remount,rw /|/bin/mount -o remount,ro /|' ${OLDROOT}/etc/inittab | ||
70 | fi | ||
71 | |||
72 | # Continue as if the overlayroot module didn't exist to continue booting | ||
73 | . $MODULES_DIR/99-finish | ||
74 | eval "finish_run" | ||
75 | } | ||
76 | |||
77 | # migrate legacy parameter | ||
78 | if [ ! -z "$bootparam_rootrw" ]; then | ||
79 | bootparam_overlayrootrwdev="$bootparam_rootrw" | ||
80 | fi | ||
81 | |||
82 | if [ -z "$bootparam_overlayrootrwdev" ]; then | ||
83 | exit_gracefully "overlayrootrwdev= kernel parameter doesn't exist and its required to mount the overlayfs" | ||
84 | fi | ||
85 | |||
86 | mkdir -p ${RWMOUNT} | ||
87 | |||
88 | # Mount RW device | ||
89 | if mount -n -t ${bootparam_overlayrootfstype:-ext4} -o ${bootparam_overlayrootfsflags:-defaults} ${bootparam_overlayrootrwdev} ${RWMOUNT} | ||
90 | then | ||
91 | # Set up overlay directories | ||
92 | mkdir -p ${UPPER_DIR} | ||
93 | mkdir -p ${WORK_DIR} | ||
94 | mkdir -p ${NEWROOT} | ||
95 | mkdir -p ${ROMOUNT} | ||
96 | |||
97 | # Remount OLDROOT as read-only | ||
98 | mount -o bind ${OLDROOT} ${ROMOUNT} | ||
99 | mount -o remount,ro ${ROMOUNT} | ||
100 | |||
101 | # Mount RW overlay | ||
102 | mount -t overlay overlay -o lowerdir=${ROMOUNT},upperdir=${UPPER_DIR},workdir=${WORK_DIR} ${NEWROOT} || exit_gracefully "initramfs-overlayroot: Mounting overlay failed" | ||
103 | else | ||
104 | exit_gracefully "initramfs-overlayroot: Mounting RW device failed" | ||
105 | fi | ||
106 | |||
107 | # Set up filesystems on overlay | ||
108 | mkdir -p ${NEWROOT}/proc | ||
109 | mkdir -p ${NEWROOT}/dev | ||
110 | mkdir -p ${NEWROOT}/sys | ||
111 | mkdir -p ${NEWROOT}/rofs | ||
112 | |||
113 | mount -n --move ${ROMOUNT} ${NEWROOT}/rofs | ||
114 | mount -n --move /proc ${NEWROOT}/proc | ||
115 | mount -n --move /sys ${NEWROOT}/sys | ||
116 | mount -n --move /dev ${NEWROOT}/dev | ||
117 | |||
118 | exec chroot ${NEWROOT}/ ${bootparam_init:-/sbin/init} || exit_gracefully "Couldn't chroot into overlay" | ||