From fb7a98271e40f3ec3ed1e541c9a670ff043eefed Mon Sep 17 00:00:00 2001 From: Kun Lai Date: Wed, 21 Jan 2026 18:20:13 +0800 Subject: [PATCH 1/2] fix(convert): avoid "No space left on device" during UKI patching The `objcopy` operation was failing with "No space left on device" when patching the UKI file directly on a small EFI partition (/boot/efi). Key changes: 1. Move dracut UKI generation and `objcopy` patching to `/tmp` to avoid partition size constraints. 2. Clean up existing EFI entries and `NvVars` earlier to release space. 3. Copy the finalized UKI image to the destination after patching is complete. Signed-off-by: Kun Lai --- cryptpilot-convert.sh | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/cryptpilot-convert.sh b/cryptpilot-convert.sh index 7876bb5..659c4a0 100755 --- a/cryptpilot-convert.sh +++ b/cryptpilot-convert.sh @@ -931,7 +931,12 @@ if [[ -f /tmp/cryptpilot/global.toml ]]; then dracut_common_args+=(--include /tmp/cryptpilot/global.toml /etc/cryptpilot/global.toml) fi -if [ "${uki:-false}" = true ]; then +if [ "${uki:-false}" = true ]; then + # Remove all existing EFI entries + find /boot/efi/EFI -mindepth 1 -maxdepth 1 -exec rm -rf {} + + # Remove NvVars file + rm -f /boot/efi/NvVars + # Generate UKI with dracut echo "Generating UKI image" dracut_args=("${dracut_common_args[@]}" --uefi --hostonly-cmdline) @@ -939,23 +944,22 @@ if [ "${uki:-false}" = true ]; then cmdline=$(echo "${cmdline} ${uki_append_cmdline}" | xargs) dracut_args=("${dracut_args[@]}" --kernel-cmdline "$cmdline") - UKI_FILE="/boot/efi/EFI/BOOT/BOOTX64.EFI" - dracut "${dracut_args[@]}" "$UKI_FILE" + FINAL_UKI_FILE="/boot/efi/EFI/BOOT/BOOTX64.EFI" + TMP_UKI_FILE="/tmp/BOOTX64.EFI" + dracut "${dracut_args[@]}" "$TMP_UKI_FILE" echo "Patching cmdline in UKI" # The generated cmdline will have a leading space, remove it - objcopy --dump-section .cmdline="/tmp/cmdline_full.bin" "$UKI_FILE" + objcopy --dump-section .cmdline="/tmp/cmdline_full.bin" "$TMP_UKI_FILE" /dev/null cat "/tmp/cmdline_full.bin" | xargs echo -n 2>/dev/null >"/tmp/cmdline_stripped.bin" echo -ne "\x00" >>"/tmp/cmdline_stripped.bin" - objcopy --update-section .cmdline="/tmp/cmdline_stripped.bin" "$UKI_FILE" + objcopy --update-section .cmdline="/tmp/cmdline_stripped.bin" "$TMP_UKI_FILE" + mkdir -p $(dirname "$FINAL_UKI_FILE") + cp "$TMP_UKI_FILE" "$FINAL_UKI_FILE" + + echo "UKI successfully created at $FINAL_UKI_FILE, the default boot entry is now overwrited" - echo "UKI successfully created at $UKI_FILE, the default boot entry is now overwrited" - # Remove all other EFI entries - find /boot/efi/EFI -mindepth 1 -maxdepth 1 ! -name BOOT -exec rm -rf {} + - find /boot/efi/EFI/BOOT -mindepth 1 -maxdepth 1 ! -name BOOTX64.EFI -exec rm -rf {} + - # Remove NvVars file - rm -f /boot/efi/NvVars else echo "Generating new initrd image" dracut "${dracut_common_args[@]}" From 4daceeb9fc037520e13ab31cf799fe14f3af726a Mon Sep 17 00:00:00 2001 From: Kun Lai Date: Wed, 21 Jan 2026 20:10:23 +0800 Subject: [PATCH 2/2] feat(cryptpilot-convert): mark rootfs as read-only - Mark the rootfs partition as read-only using `tune2fs -O read-only`. - Automatically add `ro` and `noload` flags to the root partition in `/etc/fstab`. - Ensure the fstab modification is idempotent and handles various formatting styles. Signed-off-by: Kun Lai --- cryptpilot-convert.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/cryptpilot-convert.sh b/cryptpilot-convert.sh index 659c4a0..ca22564 100755 --- a/cryptpilot-convert.sh +++ b/cryptpilot-convert.sh @@ -752,6 +752,9 @@ step:update_rootfs() { fi log::info "Updating /etc/fstab" + # add ro,noload flag / if it is an ext4 partition + sed -i '/^[[:space:]]*[^#].*[[:space:]]\+\/[[:space:]]\+ext4[[:space:]]\+/ { /[,[:space:]]ro\([,[:space:]]\|$\)/! s/\([[:space:]]ext4[[:space:]]\+\)\([^[:space:]]\+\)/\1\2,ro/ ; /[,[:space:]]noload\([,[:space:]]\|$\)/! s/\([[:space:]]ext4[[:space:]]\+\)\([^[:space:]]\+\)/\1\2,noload/ }' "${rootfs_mount_point}/etc/fstab" + # Prevent duplicate mounting of efi partitions sed -i '/[[:space:]]\/boot\/efi[[:space:]]/ s/defaults,/defaults,auto,nofail,/' "${rootfs_mount_point}/etc/fstab" @@ -944,13 +947,14 @@ if [ "${uki:-false}" = true ]; then cmdline=$(echo "${cmdline} ${uki_append_cmdline}" | xargs) dracut_args=("${dracut_args[@]}" --kernel-cmdline "$cmdline") - FINAL_UKI_FILE="/boot/efi/EFI/BOOT/BOOTX64.EFI" + # Put UKI to /tmp/ instead of /boot directory since objcopy will create a temporary file in the same directory, which may cause no space left error TMP_UKI_FILE="/tmp/BOOTX64.EFI" + FINAL_UKI_FILE="/boot/efi/EFI/BOOT/BOOTX64.EFI" dracut "${dracut_args[@]}" "$TMP_UKI_FILE" echo "Patching cmdline in UKI" # The generated cmdline will have a leading space, remove it - objcopy --dump-section .cmdline="/tmp/cmdline_full.bin" "$TMP_UKI_FILE" /dev/null + objcopy --dump-section .cmdline="/tmp/cmdline_full.bin" "$TMP_UKI_FILE" cat "/tmp/cmdline_full.bin" | xargs echo -n 2>/dev/null >"/tmp/cmdline_stripped.bin" echo -ne "\x00" >>"/tmp/cmdline_stripped.bin" objcopy --update-section .cmdline="/tmp/cmdline_stripped.bin" "$TMP_UKI_FILE" @@ -970,17 +974,22 @@ EOF } - # Note that the rootfs.img will not be used any more so mount it without 'ro' flag will not change the hash of rootfs. + # Remove read-only flag from rootfs.img + tune2fs -O ^read-only "${rootfs_file_path}" + + # Note that the rootfs.img will not be used any more so mount it without '-o ro' flag will not change the hash of rootfs. run_in_chroot_mounts "$rootfs_file_path" "$efi_part" "$boot_file_path" update_initrd_inner "$uki" "$uki_append_cmdline" } step::shrink_and_extract_rootfs_part() { local rootfs_orig_part=$1 + # Mark the rootfs partition as read-only + tune2fs -O read-only "${rootfs_orig_part}" + + # Adjust file system content, all move to front local before_shrink_size_in_bytes before_shrink_size_in_bytes=$(blockdev --getsize64 "${rootfs_orig_part}") - - # Adjust file system content, all move to front log::info "Checking and shrinking rootfs filesystem" if e2fsck -y -f "${rootfs_orig_part}"; then