Skip to content

Commit 3172cf1

Browse files
committed
test: initrd in /usr
Signed-off-by: Kai Lueke <[email protected]>
1 parent 31ba296 commit 3172cf1

File tree

5 files changed

+185
-1
lines changed

5 files changed

+185
-1
lines changed

dracut/03flatcar-network/parse-ip-for-networkd.service

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Description=Write systemd-networkd units from cmdline
33
DefaultDependencies=false
44

5-
After=afterburn-network-kargs.service
5+
After=afterburn-network-kargs.service dracut-cmdline.service
66
PartOf=systemd-networkd.service
77
Before=systemd-networkd.service initrd-switch-root.target
88
# Switching the root filesystem terminates all running services with binaries from the initramfs, we need to finish before that happens

dracut/10diskless-generator/diskless-generator

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
33
# ex: ts=8 sw=4 sts=4 et filetype=sh
44

5+
# NOTE: The /usr.squashfs mounting for /sysusr is done in /minimal-init
6+
# (making the mount unit here a no-op) but the /sysroot mounting is
7+
# and must still be done here, same for the rootfs RAM setup
8+
59
set -e
610

711
UNIT_DIR="${1:-/tmp}"

dracut/10usr-generator/usr-generator

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
# by systemd-fstab-generator. This module is only needed for old
1111
# bootloaders that pass usr=.
1212

13+
# NOTE: Now done in /minimal-init but since the "mount.usr" generator also runs,
14+
# it seems ok to also keep the "usr" generator even though the mount units are
15+
# a no-op
1316
set -e
1417

1518
UNIT_DIR="${1:-/tmp}"

dracut/10verity-generator/verity-generator

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
# This script generates a service that manages a dm-verity device for the chosen USR partition
66

7+
# NOTE: The verity setup is now done in /minimal-init and this logic not used:
8+
exit 0
9+
710
set -e
811

912
UNIT_DIR="${1:-/tmp}"

minimal-init

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#!/bin/sh
2+
set -u
3+
busybox mount -n -t proc proc /proc
4+
busybox mount -n -t devtmpfs devtmpfs /dev
5+
busybox mount -n -t sysfs sysfs /sys
6+
busybox --install -s
7+
if [ ! -x "/dev/pts" ]; then mkdir /dev/pts; fi
8+
if [ ! -x "/dev/shm" ]; then mkdir /dev/shm; fi
9+
busybox mount -n -t devpts devpts /dev/pts -o gid=5,mode=620,ptmxmode=000
10+
11+
cmdline_arg() {
12+
local name="$1"
13+
local value="${2-}"
14+
for arg in $(cat /proc/cmdline); do
15+
if [[ "${arg%%=*}" == "${name}" ]]; then
16+
value="${arg#*=}"
17+
fi
18+
done
19+
echo "${value}"
20+
}
21+
22+
emergency() {
23+
echo "ERROR: The early initrd has failed. To active debug shell breakpoints, boot with rd.earlyshell in the kernel cmdline, and to active tracing, boot with rd.earlytrace" >&2
24+
if read -s -p "Press Enter for emergency shell or wait 60 seconds for reboot." -t 60; then
25+
echo >&2; echo "Entering emergency mode. Exit the shell to retry /init (you might need to clean up mounts first) or reboot with 'reboot -f'." >&2
26+
busybox sh || true
27+
exec /init
28+
else
29+
echo >&2; echo "INFO: Rebooting" >&2
30+
exec reboot -f
31+
fi
32+
}
33+
trap 'emergency' ERR
34+
35+
# Custom debug breakpoint
36+
debug_sh() {
37+
if [ "$(cmdline_arg rd.earlyshell)" != "" ]; then
38+
echo "INFO: Entering debug shell breakpoint ($*), exit to continue booting (reboot with 'reboot -f')">&2
39+
busybox sh || true
40+
fi
41+
}
42+
debug_sh 1/4: before mdev
43+
if [ "$(cmdline_arg rd.earlytrace)" != "" ]; then
44+
set -x
45+
fi
46+
47+
mdev -d
48+
mdev -s
49+
# Coldplugging but with using /sbin/modprobe (which is kmod) instead of busybox's modprobe
50+
# because busybox doesn't properly support the globs in modules.alias
51+
find /sys/ -name modalias -print0 | xargs -0 sort -u | tr '\n' '\0' | xargs -0 /sbin/modprobe -abq || true
52+
# Required to access disks, but not autoloaded:
53+
modprobe sd_mod
54+
55+
debug_sh 2/4: before verity
56+
57+
find_drive() {
58+
local search="$1"
59+
local ueventline=
60+
local blkidmatch=
61+
local drive=
62+
local waitingmsg=
63+
case "${search}" in
64+
LABEL=*)
65+
blkidmatch="${search#LABEL=}"
66+
# Needs " around the value
67+
blkidmatch="LABEL=\"${blkidmatch}\""
68+
;;
69+
UUID=*)
70+
blkidmatch="${search#UUID=}"
71+
# Needs " around the value
72+
blkidmatch="UUID=\"$(echo "${blkidmatch}" | tr "[:upper:]" "[:lower:]")\""
73+
;;
74+
PARTUUID=*)
75+
ueventline="${search#PARTUUID=}"
76+
ueventline="PARTUUID=$(echo "${ueventline}" | tr "[:upper:]" "[:lower:]")"
77+
;;
78+
PARTLABEL=*)
79+
ueventline="PARTNAME=${search#PARTLABEL=}"
80+
;;
81+
*)
82+
echo "${search}"
83+
return
84+
;;
85+
esac
86+
while [ "${drive}" = "" ]; do
87+
if [ "${ueventline}" != "" ]; then
88+
drive="$({ grep -s -l -m 1 -r "${ueventline}" /sys/class/block/*/uevent || true; } | cut -d / -f 5)"
89+
else
90+
drive="$(blkid | { grep -m 1 "${blkidmatch}" || true ; } | cut -d : -f 1 | cut -d / -f 3-)"
91+
fi
92+
if [ "${drive}" = "" ] && [ "${waitingmsg}" = "" ]; then
93+
echo "Waiting for drive..." >&2
94+
waitingmsg=1
95+
fi
96+
done
97+
drive="/dev/${drive}"
98+
echo "${drive}"
99+
}
100+
101+
# Ported code from the generators
102+
verityusr=$(cmdline_arg verity.usr)
103+
usrhash=$(cmdline_arg verity.usrhash)
104+
105+
verityusr=$(find_drive "${verityusr}")
106+
107+
# Only proceed if the source is a path and we have sufficient parameters.
108+
if echo "${verityusr}" | grep -q "^/" && [ "${usrhash}" != "" ]; then
109+
# Hardcoded expected value from the image GPT layout
110+
veritysetup --panic-on-corruption --hash-offset=1065345024 open "${verityusr}" usr "${verityusr}" "${usrhash}"
111+
# If there's a hash mismatch during table initialization,
112+
# veritysetup reports it on stderr but still exits 0.
113+
# Manually check the target status and fail if invalid.
114+
status=$(dmsetup status usr | cut -d " " -f 4)
115+
if [ "${status}" != V ]; then
116+
echo "Verity setup failed" >&2
117+
exit 1
118+
fi
119+
fi
120+
121+
usr=$(cmdline_arg mount.usr $(cmdline_arg usr))
122+
usrfstype=$(cmdline_arg mount.usrfstype $(cmdline_arg usrfstype auto))
123+
usrflags=$(cmdline_arg mount.usrflags $(cmdline_arg usrflags ro))
124+
125+
usr=$(find_drive "${usr}")
126+
127+
if [ "${usr}" = "" ] && [ -f /usr.squashfs ]; then
128+
usr=/usr.squashfs
129+
usrfstype=squashfs
130+
elif [ "${usrfstype}" = btrfs ] || [ "${usrfstype}" = auto ]; then
131+
if [ "$(echo ",${usrflags}," | grep -v -F ',ro,')" != "" ]; then
132+
true # Don't set "norecovery" when mounting rw
133+
else
134+
usrflags="${usrflags},rescue=nologreplay"
135+
fi
136+
fi
137+
# Only proceed if the source is a path.
138+
if echo "${usr}" | grep -v -q "^/"; then
139+
echo "No mountable /usr partition given (usr='${usr}')" >&2
140+
exit 1
141+
fi
142+
143+
debug_sh 3/4: before /sysusr mount
144+
145+
echo "Mounting /usr from ${usr}"
146+
# mount -t auto only works if btrfs is already loaded
147+
modprobe btrfs
148+
mount -t "${usrfstype}" -o "${usrflags}" "${usr}" /sysusr/usr
149+
150+
# Busybox doesn't load this for us
151+
modprobe loop
152+
losetup -r -f /sysusr/usr/lib/flatcar/bootengine.img
153+
mkdir /underlay /work
154+
mount -t tmpfs tmpfs /work
155+
mkdir /work/realinit /work/work
156+
mount -t squashfs /dev/loop0 /underlay
157+
mount -t overlay -o rw,lowerdir=/underlay,upperdir=/work/realinit,workdir=/work/work overlay /realinit
158+
mkdir -p /realinit/sysusr/usr
159+
mount -o move /sysusr/usr /realinit/sysusr/usr
160+
if [ "${usr}" = /usr.squashfs ]; then
161+
mkdir -p /oem
162+
mkdir -p /realinit/oem
163+
mount -o bind /oem /realinit/oem
164+
touch /realinit/usr.squashfs
165+
mount -o bind /usr.squashfs /realinit/usr.squashfs
166+
fi
167+
debug_sh 4/4: before switch_root to /realinit
168+
killall mdev || true
169+
umount /proc
170+
umount /sys
171+
umount /dev/pts
172+
# Lazy unmount because /dev/console is held by the current process
173+
umount -l /dev
174+
exec switch_root /realinit /init

0 commit comments

Comments
 (0)