diff options
Diffstat (limited to 'meta/recipes-core/initrdscripts/initramfs-framework')
6 files changed, 166 insertions, 32 deletions
diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/finish b/meta/recipes-core/initrdscripts/initramfs-framework/finish index 717383ebac..716c2f44af 100755 --- a/meta/recipes-core/initrdscripts/initramfs-framework/finish +++ b/meta/recipes-core/initrdscripts/initramfs-framework/finish | |||
@@ -12,15 +12,36 @@ 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 |
20 | mount --move /sys $ROOTFS_DIR/sys | 41 | mount --move /sys $ROOTFS_DIR/sys |
21 | 42 | ||
22 | cd $ROOTFS_DIR | 43 | cd $ROOTFS_DIR |
23 | exec switch_root -c /dev/console $ROOTFS_DIR ${bootparam_init:-/sbin/init} | 44 | exec switch_root $ROOTFS_DIR ${bootparam_init:-/sbin/init} |
24 | else | 45 | else |
25 | debug "No rootfs has been set" | 46 | debug "No rootfs has been set" |
26 | fi | 47 | fi |
diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/init b/meta/recipes-core/initrdscripts/initramfs-framework/init index 567694aff7..a48b77e95e 100755 --- a/meta/recipes-core/initrdscripts/initramfs-framework/init +++ b/meta/recipes-core/initrdscripts/initramfs-framework/init | |||
@@ -54,20 +54,23 @@ debug() { | |||
54 | } | 54 | } |
55 | 55 | ||
56 | # Prints a message and start a endless loop | 56 | # Prints a message and start a endless loop |
57 | # Force reboot if init_fatal_reboot bootparam is set | ||
57 | fatal() { | 58 | fatal() { |
58 | echo $1 >/dev/console | 59 | echo $1 >/dev/console |
59 | echo >/dev/console | 60 | echo >/dev/console |
60 | 61 | ||
61 | if [ -n "$bootparam_init_fatal_sh" ]; then | 62 | if [ -n "$bootparam_init_fatal_reboot" ]; then |
62 | sh | 63 | reboot -f |
63 | else | 64 | elif [ -n "$bootparam_init_fatal_sh" ]; then |
64 | while [ "true" ]; do | 65 | sh |
65 | sleep 3600 | 66 | else |
66 | done | 67 | while [ "true" ]; do |
67 | fi | 68 | sleep 3600 |
69 | done | ||
70 | fi | ||
68 | } | 71 | } |
69 | 72 | ||
70 | # Variables shared amoung modules | 73 | # Variables shared among modules |
71 | ROOTFS_DIR="/rootfs" # where to do the switch root | 74 | ROOTFS_DIR="/rootfs" # where to do the switch root |
72 | MODULE_PRE_HOOKS="" # functions to call before running each module | 75 | MODULE_PRE_HOOKS="" # functions to call before running each module |
73 | MODULE_POST_HOOKS="" # functions to call after running each module | 76 | MODULE_POST_HOOKS="" # functions to call after running each module |
@@ -117,7 +120,7 @@ if grep -q devtmpfs /proc/filesystems; then | |||
117 | mount -t devtmpfs devtmpfs /dev | 120 | mount -t devtmpfs devtmpfs /dev |
118 | else | 121 | else |
119 | if [ ! -d /dev ]; then | 122 | if [ ! -d /dev ]; then |
120 | fatal "ERROR: /dev doesn't exist and kernel doesn't has devtmpfs enabled." | 123 | fatal "ERROR: /dev doesn't exist and kernel doesn't have devtmpfs enabled." |
121 | fi | 124 | fi |
122 | fi | 125 | fi |
123 | 126 | ||
diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/nfsrootfs b/meta/recipes-core/initrdscripts/initramfs-framework/nfsrootfs index e67ee4c25d..30555aef55 100644 --- a/meta/recipes-core/initrdscripts/initramfs-framework/nfsrootfs +++ b/meta/recipes-core/initrdscripts/initramfs-framework/nfsrootfs | |||
@@ -1,7 +1,7 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | nfsrootfs_enabled() { | 3 | nfsrootfs_enabled() { |
4 | if [ ${bootparam_root} != "/dev/nfs" ] || [ -z ${bootparam_nfsroot} ]; then | 4 | if [ "${bootparam_root}" != "/dev/nfs" ] || [ -z ${bootparam_nfsroot} ]; then |
5 | return 1 | 5 | return 1 |
6 | fi | 6 | fi |
7 | return 0 | 7 | return 0 |
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" | ||
diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/rootfs b/meta/recipes-core/initrdscripts/initramfs-framework/rootfs index ee24e82af3..df0cbfb091 100644 --- a/meta/recipes-core/initrdscripts/initramfs-framework/rootfs +++ b/meta/recipes-core/initrdscripts/initramfs-framework/rootfs | |||
@@ -24,29 +24,20 @@ 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" |
36 | elif echo "${bootparam_root}" | grep -q '^ubi[0-9]\+:'; then | ||
37 | bootparam_rootfstype="ubifs" | ||
47 | fi | 38 | fi |
48 | 39 | ||
49 | if [ -e "$bootparam_root" ]; then | 40 | if [ -e "$bootparam_root" ] || [ -n "$bootparam_rootfstype" ]; then |
50 | flags="" | 41 | flags="" |
51 | if [ -n "$bootparam_ro" ] && ! echo "$bootparam_rootflags" | grep -w -q "ro"; then | 42 | if [ -n "$bootparam_ro" ] && ! echo "$bootparam_rootflags" | grep -w -q "ro"; then |
52 | if [ -n "$bootparam_rootflags" ]; then | 43 | if [ -n "$bootparam_rootflags" ]; then |
@@ -60,6 +51,7 @@ rootfs_run() { | |||
60 | if [ -n "$bootparam_rootfstype" ]; then | 51 | if [ -n "$bootparam_rootfstype" ]; then |
61 | flags="$flags -t$bootparam_rootfstype" | 52 | flags="$flags -t$bootparam_rootfstype" |
62 | fi | 53 | fi |
54 | debug "mount $flags $bootparam_root $ROOTFS_DIR" | ||
63 | mount $flags $bootparam_root $ROOTFS_DIR | 55 | mount $flags $bootparam_root $ROOTFS_DIR |
64 | if mountpoint -q $ROOTFS_DIR; then | 56 | if mountpoint -q $ROOTFS_DIR; then |
65 | break | 57 | break |
@@ -67,10 +59,10 @@ rootfs_run() { | |||
67 | # It is unlikely to change, but keep trying anyway. | 59 | # It is unlikely to change, but keep trying anyway. |
68 | # Perhaps we pick a different device next time. | 60 | # Perhaps we pick a different device next time. |
69 | umount $ROOTFS_DIR | 61 | umount $ROOTFS_DIR |
70 | fi | ||
71 | fi | 62 | fi |
63 | fi | ||
72 | fi | 64 | fi |
73 | debug "Sleeping for $delay second(s) to wait root to settle..." | 65 | debug "Sleeping for $delay second(s) to wait for root to settle..." |
74 | sleep $delay | 66 | sleep $delay |
75 | C=$(( $C + 1 )) | 67 | C=$(( $C + 1 )) |
76 | done | 68 | done |
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 | ||