summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/initrdscripts/initramfs-framework/overlayroot
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/initrdscripts/initramfs-framework/overlayroot')
-rw-r--r--meta/recipes-core/initrdscripts/initramfs-framework/overlayroot118
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
38PATH=/sbin:/bin:/usr/sbin:/usr/bin
39
40# We get OLDROOT from the rootfs module
41OLDROOT="/rootfs"
42
43NEWROOT="${RWMOUNT}/root"
44RWMOUNT="/overlay"
45ROMOUNT="${RWMOUNT}/rofs"
46UPPER_DIR="${RWMOUNT}/upper"
47WORK_DIR="${RWMOUNT}/work"
48
49MODULES_DIR=/init.d
50
51# Something went wrong, make sure / is mounted as read only anyway.
52exit_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
78if [ ! -z "$bootparam_rootrw" ]; then
79 bootparam_overlayrootrwdev="$bootparam_rootrw"
80fi
81
82if [ -z "$bootparam_overlayrootrwdev" ]; then
83 exit_gracefully "overlayrootrwdev= kernel parameter doesn't exist and its required to mount the overlayfs"
84fi
85
86mkdir -p ${RWMOUNT}
87
88# Mount RW device
89if mount -n -t ${bootparam_overlayrootfstype:-ext4} -o ${bootparam_overlayrootfsflags:-defaults} ${bootparam_overlayrootrwdev} ${RWMOUNT}
90then
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"
103else
104 exit_gracefully "initramfs-overlayroot: Mounting RW device failed"
105fi
106
107# Set up filesystems on overlay
108mkdir -p ${NEWROOT}/proc
109mkdir -p ${NEWROOT}/dev
110mkdir -p ${NEWROOT}/sys
111mkdir -p ${NEWROOT}/rofs
112
113mount -n --move ${ROMOUNT} ${NEWROOT}/rofs
114mount -n --move /proc ${NEWROOT}/proc
115mount -n --move /sys ${NEWROOT}/sys
116mount -n --move /dev ${NEWROOT}/dev
117
118exec chroot ${NEWROOT}/ ${bootparam_init:-/sbin/init} || exit_gracefully "Couldn't chroot into overlay"