summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/initrdscripts/initramfs-framework
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/initrdscripts/initramfs-framework')
-rwxr-xr-xmeta/recipes-core/initrdscripts/initramfs-framework/finish21
-rw-r--r--meta/recipes-core/initrdscripts/initramfs-framework/overlayroot118
-rw-r--r--meta/recipes-core/initrdscripts/initramfs-framework/rootfs19
-rw-r--r--meta/recipes-core/initrdscripts/initramfs-framework/setup-live2
4 files changed, 144 insertions, 16 deletions
diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/finish b/meta/recipes-core/initrdscripts/initramfs-framework/finish
index 717383ebac..ac0de9f996 100755
--- a/meta/recipes-core/initrdscripts/initramfs-framework/finish
+++ b/meta/recipes-core/initrdscripts/initramfs-framework/finish
@@ -12,8 +12,29 @@ finish_run() {
12 fatal "ERROR: There's no '/dev' on rootfs." 12 fatal "ERROR: There's no '/dev' on rootfs."
13 fi 13 fi
14 14
15 # Unmount anything that was automounted by busybox via mdev-mount.sh.
16 # We're about to switch_root, and leaving anything mounted will prevent
17 # the next rootfs from modifying the block device. Ignore ROOT_DISK,
18 # if it was set by setup-live, because it'll be mounted over loopback
19 # to ROOTFS_DIR.
20 local dev
21 for dev in /run/media/*; do
22 if mountpoint -q "${dev}" && [ "${dev##*/}" != "${ROOT_DISK}" ]; then
23 umount -f "${dev}" || debug "Failed to unmount ${dev}"
24 fi
25 done
26
15 info "Switching root to '$ROOTFS_DIR'..." 27 info "Switching root to '$ROOTFS_DIR'..."
16 28
29 debug "Moving basic mounts onto rootfs"
30 for dir in `awk '/\/dev.* \/run\/media/{print $2}' /proc/mounts`; do
31 # Parse any OCT or HEX encoded chars such as spaces
32 # in the mount points to actual ASCII chars
33 dir=`printf $dir`
34 mkdir -p "${ROOTFS_DIR}/media/${dir##*/}"
35 mount -n --move "$dir" "${ROOTFS_DIR}/media/${dir##*/}"
36 done
37
17 debug "Moving /dev, /proc and /sys onto rootfs..." 38 debug "Moving /dev, /proc and /sys onto rootfs..."
18 mount --move /dev $ROOTFS_DIR/dev 39 mount --move /dev $ROOTFS_DIR/dev
19 mount --move /proc $ROOTFS_DIR/proc 40 mount --move /proc $ROOTFS_DIR/proc
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"
diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/rootfs b/meta/recipes-core/initrdscripts/initramfs-framework/rootfs
index ee24e82af3..e0efbe6ebe 100644
--- a/meta/recipes-core/initrdscripts/initramfs-framework/rootfs
+++ b/meta/recipes-core/initrdscripts/initramfs-framework/rootfs
@@ -24,24 +24,13 @@ rootfs_run() {
24 if [ "`echo ${bootparam_root} | cut -c1-5`" = "UUID=" ]; then 24 if [ "`echo ${bootparam_root} | cut -c1-5`" = "UUID=" ]; then
25 root_uuid=`echo $bootparam_root | cut -c6-` 25 root_uuid=`echo $bootparam_root | cut -c6-`
26 bootparam_root="/dev/disk/by-uuid/$root_uuid" 26 bootparam_root="/dev/disk/by-uuid/$root_uuid"
27 fi 27 elif [ "`echo ${bootparam_root} | cut -c1-9`" = "PARTUUID=" ]; then
28
29 if [ "`echo ${bootparam_root} | cut -c1-9`" = "PARTUUID=" ]; then
30 root_partuuid=`echo $bootparam_root | cut -c10-` 28 root_partuuid=`echo $bootparam_root | cut -c10-`
31 bootparam_root="/dev/disk/by-partuuid/$root_partuuid" 29 bootparam_root="/dev/disk/by-partuuid/$root_partuuid"
32 fi 30 elif [ "`echo ${bootparam_root} | cut -c1-10`" = "PARTLABEL=" ]; then
33
34 if [ "`echo ${bootparam_root} | cut -c1-10`" = "PARTLABEL=" ]; then
35 root_partlabel=`echo $bootparam_root | cut -c11-`
36 bootparam_root="/dev/disk/by-partlabel/$root_partlabel"
37 fi
38
39 if [ "`echo ${bootparam_root} | cut -c1-10`" = "PARTLABEL=" ]; then
40 root_partlabel=`echo $bootparam_root | cut -c11-` 31 root_partlabel=`echo $bootparam_root | cut -c11-`
41 bootparam_root="/dev/disk/by-partlabel/$root_partlabel" 32 bootparam_root="/dev/disk/by-partlabel/$root_partlabel"
42 fi 33 elif [ "`echo ${bootparam_root} | cut -c1-6`" = "LABEL=" ]; then
43
44 if [ "`echo ${bootparam_root} | cut -c1-6`" = "LABEL=" ]; then
45 root_label=`echo $bootparam_root | cut -c7-` 34 root_label=`echo $bootparam_root | cut -c7-`
46 bootparam_root="/dev/disk/by-label/$root_label" 35 bootparam_root="/dev/disk/by-label/$root_label"
47 fi 36 fi
@@ -67,8 +56,8 @@ rootfs_run() {
67 # It is unlikely to change, but keep trying anyway. 56 # It is unlikely to change, but keep trying anyway.
68 # Perhaps we pick a different device next time. 57 # Perhaps we pick a different device next time.
69 umount $ROOTFS_DIR 58 umount $ROOTFS_DIR
70 fi
71 fi 59 fi
60 fi
72 fi 61 fi
73 debug "Sleeping for $delay second(s) to wait root to settle..." 62 debug "Sleeping for $delay second(s) to wait root to settle..."
74 sleep $delay 63 sleep $delay
diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/setup-live b/meta/recipes-core/initrdscripts/initramfs-framework/setup-live
index 4c79f41285..7e92f93322 100644
--- a/meta/recipes-core/initrdscripts/initramfs-framework/setup-live
+++ b/meta/recipes-core/initrdscripts/initramfs-framework/setup-live
@@ -1,4 +1,4 @@
1#/bin/sh 1#!/bin/sh
2# Copyright (C) 2011 O.S. Systems Software LTDA. 2# Copyright (C) 2011 O.S. Systems Software LTDA.
3# Licensed on MIT 3# Licensed on MIT
4 4