Skip to content

Commit 16591e9

Browse files
committed
40ignition-ostree: copy ESP contents as independent filesystems
If the firmware writes to an individual replica, the RAID will desynchronize. Linux md will return reads from either replica, and then any dependent writes could corrupt the filesystem. To prevent this, fcct will no longer put the ESP on a RAID; instead we create multiple independent filesystems and copy the contents to each. This is okay because bootupd and fwupd should be the only things that care about the contents of the ESP. Don't worry too much about backward compatibility because we're making this change soon after the functionality landed, and before it was documented. For the record, old configs will fail on new systems (because the partitions will be RAID members) but new configs will skip copying /boot on old systems (because there's no filesystem labeled "EFI-SYSTEM").
1 parent dd848b8 commit 16591e9

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
set -euo pipefail
33

44
boot_sector_size=440
5+
esp_typeguid=c12a7328-f81f-11d2-ba4b-00a0c93ec93b
56
bios_typeguid=21686148-6449-6e6f-744e-656564454649
67
prep_typeguid=9e1a2d38-c612-4316-aa26-8b49521e5a8b
78

@@ -84,18 +85,19 @@ case "${1:-}" in
8485
# Mounts are not in a private namespace so we can mount ${saved_data}
8586
wipes_root=$(jq "$(query_fslabel root) | length" "${ignition_cfg}")
8687
wipes_boot=$(jq "$(query_fslabel boot) | length" "${ignition_cfg}")
87-
wipes_esp=$(jq "$(query_fslabel EFI-SYSTEM) | length" "${ignition_cfg}")
88+
creates_esp=$(jq "$(query_parttype ${esp_typeguid}) | length" "${ignition_cfg}")
8889
creates_bios=$(jq "$(query_parttype ${bios_typeguid}) | length" "${ignition_cfg}")
8990
creates_prep=$(jq "$(query_parttype ${prep_typeguid}) | length" "${ignition_cfg}")
90-
if [ "${wipes_root}${wipes_boot}${wipes_esp}${creates_bios}${creates_prep}" = "00000" ]; then
91+
if [ "${wipes_root}${wipes_boot}${creates_esp}${creates_bios}${creates_prep}" = "00000" ]; then
9192
exit 0
9293
fi
9394
echo "Detected partition replacement in fetched Ignition config: /run/ignition.json"
94-
# verify all BIOS and PReP partitions have non-null unique labels
95+
# verify all ESP, BIOS, and PReP partitions have non-null unique labels
96+
unique_esp=$(jq -r "$(query_parttype ${esp_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}")
9597
unique_bios=$(jq -r "$(query_parttype ${bios_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}")
9698
unique_prep=$(jq -r "$(query_parttype ${prep_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}")
97-
if [ "${creates_bios}" != "${unique_bios}" -o "${creates_prep}" != "${unique_prep}" ]; then
98-
echo "Found duplicate or missing BIOS-BOOT or PReP labels in config" >&2
99+
if [ "${creates_esp}" != "${unique_esp}" -o "${creates_bios}" != "${unique_bios}" -o "${creates_prep}" != "${unique_prep}" ]; then
100+
echo "Found duplicate or missing ESP, BIOS-BOOT, or PReP labels in config" >&2
99101
exit 1
100102
fi
101103
modprobe zram num_devices=0
@@ -118,7 +120,7 @@ case "${1:-}" in
118120
if [ "${wipes_boot}" != "0" ]; then
119121
mkdir "${saved_boot}"
120122
fi
121-
if [ "${wipes_esp}" != "0" ]; then
123+
if [ "${creates_esp}" != "0" ]; then
122124
mkdir "${saved_esp}"
123125
fi
124126
if [ "${creates_bios}" != "0" ]; then
@@ -180,7 +182,17 @@ case "${1:-}" in
180182
fi
181183
if [ -d "${saved_esp}" ]; then
182184
echo "Restoring EFI System Partition from RAM..."
183-
mount_and_restore_filesystem_by_label EFI-SYSTEM /sysroot/boot/efi "${saved_esp}"
185+
get_partlabels_for_parttype "${esp_typeguid}" | while read label; do
186+
# Don't use mount_and_restore_filesystem_by_label because:
187+
# 1. We're mounting by partlabel, not FS label
188+
# 2. We need to copy the contents to each partition, not move
189+
# them once
190+
# 3. We don't need the by-label symlink to be correct and
191+
# nothing later in boot will be mounting the filesystem
192+
mountpoint="/mnt/esp-${label}"
193+
mount_verbose "/dev/disk/by-partlabel/${label}" "${mountpoint}"
194+
find "${saved_esp}" -mindepth 1 -maxdepth 1 -exec cp -a {} "${mountpoint}" \;
195+
done
184196
fi
185197
if [ -d "${saved_bios}" ]; then
186198
echo "Restoring BIOS Boot partition and boot sector from RAM..."

0 commit comments

Comments
 (0)