Skip to content

Commit 5f1944b

Browse files
pothoschewi
andcommitted
Use a minimal initrd to switch to the full initrd stored in /usr
The growth of binaries over time and the inclusion of new features filled the available boot partition space, so that the kernel+initrd almost couldn't fit twice anymore as required for updates. We employed workarounds such as wrapper scripts for ignition, afterburn and other binaries so that they are loaded from /usr. However, this was still not enough and we would have to do the same for (network) kernel modules and firmware. To avoid making this ever more complex we can use a dedicated initrd focused on loading the full initrd from /usr and then this full initrd can use dracut as before and even drop all the workarounds we accumulated. Generate a minimal initrd to use instead of the full bootengine initrd. The bootengine initrd gets stored as squashfs on /usr. The minimal initrd still includes the early_cpio for amd64 microcode updates. We have a fixed list of modules or module directories to include, only focused on loading /usr and any emergency console interaction. This requires also checking for module dependencies to copy over. The busybox, veritysetup, and kmod binaries are needed and get their required libraries resolved and copied over. They are not static and use shared libraries which should be ok for now. The resulting vmlinuz file is 27 MB for amd64, down from ~60 MB, so we have enough room to include more kernel modules and so on for the next years while we also grow the boot partition and wait for users to redeploy until we can rely on a larger boot partition and eventually drop the minimal initrd again. Pulls in flatcar/bootengine#110 for the minimal initrd script and flatcar/seismograph#12 for making the device mapper discovery for the "rootdev" command more reliable. This also requied a backport of a kernel patch from 2017 that exposes the PARTUUID in the /sys uevent file. Co-authored-by: James Le Cuirot <[email protected]> Signed-off-by: Kai Lueke <[email protected]>
1 parent 1ff7c42 commit 5f1944b

File tree

9 files changed

+128
-3
lines changed

9 files changed

+128
-3
lines changed

build_library/build_image_util.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,8 @@ finish_image() {
582582
local image_initrd_contents="${11}"
583583
local image_initrd_contents_wtd="${12}"
584584
local image_disk_space_usage="${13}"
585+
local image_realinitrd_contents="${14}"
586+
local image_realinitrd_contents_wtd="${15}"
585587

586588
local install_grub=0
587589
local disk_img="${BUILD_DIR}/${image_name}"
@@ -877,6 +879,20 @@ EOF
877879
rm -rf "${BUILD_DIR}/tmp_initrd_contents"
878880
fi
879881

882+
if [[ -n ${image_realinitrd_contents} || -n ${image_realinitrd_contents_wtd} ]]; then
883+
mkdir -p "${BUILD_DIR}/tmp_initrd_contents"
884+
sudo mount "${root_fs_dir}/usr/lib/flatcar/bootengine.img" "${BUILD_DIR}/tmp_initrd_contents"
885+
if [[ -n ${image_realinitrd_contents} ]]; then
886+
write_contents "${BUILD_DIR}/tmp_initrd_contents" "${BUILD_DIR}/${image_realinitrd_contents}"
887+
fi
888+
889+
if [[ -n ${image_realinitrd_contents_wtd} ]]; then
890+
write_contents_with_technical_details "${BUILD_DIR}/tmp_initrd_contents" "${BUILD_DIR}/${image_realinitrd_contents_wtd}"
891+
fi
892+
sudo umount "${BUILD_DIR}/tmp_initrd_contents"
893+
rm -rf "${BUILD_DIR}/tmp_initrd_contents"
894+
fi
895+
880896
if [[ -n "${image_disk_space_usage}" ]]; then
881897
write_disk_space_usage "${root_fs_dir}" "${BUILD_DIR}/${image_disk_space_usage}"
882898
fi

build_library/prod_image_util.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ create_prod_image() {
8383
local image_initrd_contents="${image_name%.bin}_initrd_contents.txt"
8484
local image_initrd_contents_wtd="${image_name%.bin}_initrd_contents_wtd.txt"
8585
local image_disk_usage="${image_name%.bin}_disk_usage.txt"
86+
local image_realinitrd_contents="${image_name%.bin}_realinitrd_contents.txt"
87+
local image_realinitrd_contents_wtd="${image_name%.bin}_realinitrd_contents_wtd.txt"
8688
local image_sysext_base="${image_name%.bin}_sysext.squashfs"
8789

8890
start_image "${image_name}" "${disk_layout}" "${root_fs_dir}" "${update_group}"
@@ -180,7 +182,9 @@ EOF
180182
"${image_kconfig}" \
181183
"${image_initrd_contents}" \
182184
"${image_initrd_contents_wtd}" \
183-
"${image_disk_usage}"
185+
"${image_disk_usage}" \
186+
"${image_realinitrd_contents}" \
187+
"${image_realinitrd_contents_wtd}"
184188

185189
# Official builds will sign and upload these files later, so remove them to
186190
# prevent them from being uploaded now.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Reduced the kernel+initrd size on `/boot` by half. Flatcar now uses a minimal first stage initrd just to access the `/usr` partition and then switches to the full initrd that does the full system preparation as before. Since this means that the set of kernel modules available in the first initrd is reduced, please report any impact.

ci-automation/image_changes.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,15 @@ function print_image_reports() {
729729
echo "Note that vmlinuz-a also contains the kernel code, which might have changed too, so the reported difference does not accurately describe the change in initrd."
730730
echo
731731

732+
yell "Real/full init ramdisk (bootengine.img) differences compared to ${previous_version_description}"
733+
underline "Real/full init ramdisk (bootengine.img) file changes, compared to ${previous_version_description}:"
734+
env \
735+
"${package_diff_env[@]}" FILE=flatcar_production_image_realinitrd_contents.txt FILESONLY=1 CUTKERNEL=1 \
736+
"${flatcar_build_scripts_repo}/package-diff" "${package_diff_params[@]}" 2>&1 || true
737+
738+
underline "Real/full init ramdisk (bootengine.img) file size changes, compared to ${previous_version_description}:"
739+
"${size_changes_invocation[@]}" "${size_change_report_params[@]/%/:realinitrd-wtd}" 2>&1 || true
740+
732741
local base_sysext
733742
for base_sysext in "${base_sysexts[@]}"; do
734743
yell "Base sysext ${base_sysext} changes compared to ${previous_version_description}"

sdk_container/src/third_party/coreos-overlay/sys-apps/seismograph/seismograph-9999.ebuild

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ EGIT_REPO_URI="https://github.com/flatcar/seismograph.git"
77
if [[ "${PV}" == 9999 ]]; then
88
KEYWORDS="~amd64 ~arm ~arm64 ~x86"
99
else
10-
EGIT_COMMIT="e32ac4d13ca44333dc77e5872dbf23f964b6f1e2" # main
10+
EGIT_COMMIT="231f8b31c576133f75151d34cb90890bfaf15ebe" # main
1111
KEYWORDS="amd64 arm arm64 x86"
1212
fi
1313

sdk_container/src/third_party/coreos-overlay/sys-kernel/bootengine/bootengine-9999.ebuild

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ EGIT_REPO_URI="https://github.com/flatcar/bootengine.git"
77
if [[ "${PV}" == 9999 ]]; then
88
KEYWORDS="~amd64 ~arm ~arm64 ~x86"
99
else
10-
EGIT_COMMIT="daf43bf9c1ca45bf1a43566c3a6f96ec0cb44a36" # flatcar-master
10+
EGIT_COMMIT="0b9d52e647289fe7793839265617afc5178d5f00" # flatcar-master
1111
KEYWORDS="amd64 arm arm64 x86"
1212
fi
1313

@@ -23,6 +23,7 @@ src_install() {
2323
insinto /usr/lib/dracut/modules.d/
2424
doins -r dracut/.
2525
dosbin update-bootengine
26+
dosbin minimal-init
2627

2728
# must be executable since dracut's install scripts just
2829
# re-use existing filesystem permissions during initrd creation.

sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-kernel/coreos-kernel-6.12.51.ebuild

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ DEPEND="
2626
coreos-base/coreos-init:=
2727
sys-apps/azure-vm-utils[dracut]
2828
sys-apps/baselayout
29+
sys-apps/busybox
2930
sys-apps/coreutils
3031
sys-apps/findutils
3132
sys-apps/grep
@@ -89,6 +90,59 @@ src_compile() {
8990

9091
tc-export PKG_CONFIG
9192
"${ESYSROOT}"/usr/bin/update-bootengine -k "${KV_FULL}" -o "${S}"/build/bootengine.cpio "${BE_ARGS[@]}" || die
93+
# Copy full initrd over to /usr as filesystem image
94+
mkdir "${S}"/build/bootengine || die
95+
pushd "${S}"/build/bootengine || die
96+
lsinitrd --kver SILENCEERROR --unpack "${S}"/build/bootengine.cpio || die
97+
mksquashfs . "${S}"/build/bootengine.img -noappend -xattrs-exclude ^btrfs. || die
98+
popd || die
99+
# Create minimal initrd
100+
if use amd64; then
101+
mkdir "${S}"/build/early-cpio || die
102+
pushd "${S}"/build/early-cpio || die
103+
lsinitrd --kver SILENCEERROR --unpackearly "${S}"/build/bootengine.cpio || die
104+
# Recreate to only contain the early cpio for microcode
105+
find . -print0 | cpio --null --create --verbose --format=newc > "${S}"/build/bootengine.cpio || die
106+
# Debug: List contents after recreation
107+
cpio -t < "${S}"/build/bootengine.cpio
108+
popd || die
109+
else
110+
# No early cpio, drop full initrd
111+
> "${S}"/build/bootengine.cpio
112+
fi
113+
mkdir "${S}"/build/minimal || die
114+
pushd "${S}"/build/minimal || die
115+
mkdir -p {etc,dev,proc,sys,dev,usr/bin,usr/lib64,realinit,sysusr/usr} || die
116+
ln -s usr/bin bin || die
117+
ln -s usr/bin sbin || die
118+
ln -s bin usr/sbin || die
119+
ln -s usr/lib64 lib || die
120+
ln -s usr/lib64 lib64 || die
121+
ln -s lib64 usr/lib || die
122+
mkdir -p lib/modules/"${KV_FULL}"/ || die
123+
# Instead from ESYSROOT we can also copy kernel modules from the dracut pre-selection
124+
cp "${S}"/build/bootengine/usr/lib/modules/"${KV_FULL}"/modules.* lib/modules/"${KV_FULL}"/ || die
125+
mkdir -p lib/modprobe.d/ || die
126+
cp "${S}"/build/bootengine/lib/modprobe.d/* lib/modprobe.d/ || die
127+
# Only include modules related to mounting /usr and for interacting with the emergency console
128+
pushd "${S}/build/bootengine/usr/lib/modules/${KV_FULL}" || die
129+
find kernel/drivers/{ata,block,hid,hv,input/serio,mmc,nvme,pci,scsi,usb} kernel/fs/{btrfs,overlayfs,squashfs} kernel/security/keys -name "*.ko.*" -printf "%f\0" | DRACUT_NO_XATTR=1 xargs --null "${BROOT}"/usr/lib/dracut/dracut-install --destrootdir "${S}"/build/minimal --kerneldir . --sysrootdir "${S}"/build/bootengine/ --firmwaredirs "${S}"/build/bootengine/usr/lib/firmware --module dm-verity dm-mod virtio_console || die
130+
popd || die
131+
echo '$MODALIAS=.* 0:0 660 @/sbin/modprobe "$MODALIAS"' > ./etc/mdev.conf || die
132+
# We can't use busybox's modprobe because it doesn't support the globs in module.alias, breaking module loading
133+
DRACUT_NO_XATTR=1 "${BROOT}"/usr/lib/dracut/dracut-install --destrootdir . --sysrootdir "${ESYSROOT}" --ldd /bin/veritysetup /bin/dmsetup /bin/busybox /sbin/modprobe || die
134+
cp -a "${ESYSROOT}"/usr/bin/minimal-init ./init || die
135+
# Make it easier to debug by not relying too much on the first commands
136+
ln -s busybox ./bin/sh || die
137+
mknod ./dev/console c 5 1 || die
138+
mknod ./dev/null c 1 3 || die
139+
mknod ./dev/tty c 5 0 || die
140+
mknod ./dev/urandom c 1 9 || die
141+
mknod ./dev/random c 1 8 || die
142+
mknod ./dev/zero c 1 5 || die
143+
# No compression because CONFIG_INITRAMFS_COMPRESSION_XZ should take care of it
144+
find . -print0 | cpio --null --create --verbose --format=newc >> "${S}"/build/bootengine.cpio || die
145+
popd || die
92146
kmake "$(kernel_target)"
93147

94148
# sanity check :)
@@ -111,4 +165,7 @@ src_install() {
111165
# For easy access to vdso debug symbols in gdb:
112166
# set debug-file-directory /usr/lib/debug/usr/lib/modules/${KV_FULL}/vdso/
113167
kmake INSTALL_MOD_PATH="${ED}/usr/lib/debug/usr" vdso_install
168+
169+
insinto "/usr/lib/flatcar"
170+
doins build/bootengine.img
114171
}

sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/coreos-sources-6.12.51.ebuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ UNIPATCH_LIST="
4343
${PATCH_DIR}/z0006-mtd-disable-slram-and-phram-when-locked-down.patch \
4444
${PATCH_DIR}/z0007-arm64-add-kernel-config-option-to-lock-down-when.patch \
4545
${PATCH_DIR}/z0008-tools-hv-fix-cross-compilation-for-ARM64.patch \
46+
${PATCH_DIR}/z0009-block-add-partition-uuid-into-uevent.patch \
4647
"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
From 758737d86f8a2d74c0fa9f8b2523fa7fd1e0d0aa Mon Sep 17 00:00:00 2001
2+
From: Konstantin Khlebnikov <[email protected]>
3+
Date: Fri, 4 Oct 2024 17:13:43 -0700
4+
Subject: [PATCH] block: add partition uuid into uevent as "PARTUUID"
5+
6+
Both most common formats have uuid in addition to partition name:
7+
GPT: standard uuid xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
8+
DOS: 4 byte disk signature and 1 byte partition xxxxxxxx-xx
9+
10+
Tools from util-linux use the same notation for them.
11+
12+
Signed-off-by: Konstantin Khlebnikov <[email protected]>
13+
Reviewed-by: Kyle Fortin <[email protected]>
14+
[dianders: rebased to modern kernels]
15+
Signed-off-by: Douglas Anderson <[email protected]>
16+
Signed-off-by: Douglas Anderson <[email protected]>
17+
Reviewed-by: Christoph Hellwig <[email protected]>
18+
Link: https://lore.kernel.org/r/20241004171340.v2.1.I938c91d10e454e841fdf5d64499a8ae8514dc004@changeid
19+
Signed-off-by: Jens Axboe <[email protected]>
20+
---
21+
block/partitions/core.c | 2 ++
22+
1 file changed, 2 insertions(+)
23+
24+
diff --git a/block/partitions/core.c b/block/partitions/core.c
25+
index cdad05f9764768..815ed33caa1b86 100644
26+
--- a/block/partitions/core.c
27+
+++ b/block/partitions/core.c
28+
@@ -256,6 +256,8 @@ static int part_uevent(const struct device *dev, struct kobj_uevent_env *env)
29+
add_uevent_var(env, "PARTN=%u", bdev_partno(part));
30+
if (part->bd_meta_info && part->bd_meta_info->volname[0])
31+
add_uevent_var(env, "PARTNAME=%s", part->bd_meta_info->volname);
32+
+ if (part->bd_meta_info && part->bd_meta_info->uuid[0])
33+
+ add_uevent_var(env, "PARTUUID=%s", part->bd_meta_info->uuid);
34+
return 0;
35+
}
36+

0 commit comments

Comments
 (0)