From 2cd8cf450d64137144cd920dd02137111f2e8a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C4=8Cerm=C3=A1k?= Date: Thu, 11 Jun 2026 16:33:30 +0200 Subject: [PATCH] Shrink data partition for leaner disk images and faster flashing (#4764) Borrow shrinking used in home-assistant/operating-system-full-images for reducing the data partition size to only fit its contents. Currently the data partition is intentionally overprovisioned to comfortably fit all docker images in the hassio build. This results in unnecessarily large image which takes longer to flash, as all the zeroes at the end of the filesystem need to be written to the SD card. For OVA and aarch64 VM formats, the image is resized before creating the VM images - this also makes all generic-aarch64 images sized to 32GB, unlike 6GB which inherently needed resizing before use. Some juggling extra juggling is needed in the aarch64 post-image step, as we want to preserve the raw image (e.g. for generic aarch64 boards) but it's desirable to keep it minimal as well, as it's meant to be flashed to real hardware storage. --- .../board/arm-uefi/generic-aarch64/haos-hook.sh | 10 ++++++++++ .../board/arm-uefi/generic-aarch64/meta | 1 - buildroot-external/board/pc/generic-x86-64/meta | 1 - buildroot-external/board/pc/ova/haos-hook.sh | 2 ++ buildroot-external/board/pc/ova/meta | 1 - buildroot-external/genimage/genimage.cfg | 2 -- buildroot-external/genimage/partitions-os-gpt.cfg | 1 - buildroot-external/genimage/partitions-os-mbr.cfg | 1 - .../package/hassio/create-data-partition.sh | 14 ++++++++++++++ buildroot-external/scripts/hdd-image.sh | 11 +++++++++-- 10 files changed, 35 insertions(+), 9 deletions(-) diff --git a/buildroot-external/board/arm-uefi/generic-aarch64/haos-hook.sh b/buildroot-external/board/arm-uefi/generic-aarch64/haos-hook.sh index 6114be2c1..ca7518f9d 100755 --- a/buildroot-external/board/arm-uefi/generic-aarch64/haos-hook.sh +++ b/buildroot-external/board/arm-uefi/generic-aarch64/haos-hook.sh @@ -19,6 +19,14 @@ function haos_pre_image() { function haos_post_image() { + local hdd_img="$(haos_image_name img)" + local hdd_img_orig="$(haos_image_name img.orig)" + + # Resize for VM images, preserving original + cp "$hdd_img" "$hdd_img_orig" + resize_disk_image_virtual 32G + + # Create VM archives convert_disk_image_virtual vmdk convert_disk_image_virtual vdi convert_disk_image_virtual qcow2 @@ -27,5 +35,7 @@ function haos_post_image() { convert_disk_image_zip vdi convert_disk_image_xz qcow2 + # Use unresized image for .img.xz + mv "$hdd_img_orig" "$hdd_img" convert_disk_image_xz } diff --git a/buildroot-external/board/arm-uefi/generic-aarch64/meta b/buildroot-external/board/arm-uefi/generic-aarch64/meta index a7c53f40b..9507dfa9d 100644 --- a/buildroot-external/board/arm-uefi/generic-aarch64/meta +++ b/buildroot-external/board/arm-uefi/generic-aarch64/meta @@ -6,6 +6,5 @@ KERNEL_FILE=Image PARTITION_TABLE_TYPE=gpt BOOT_SIZE=32M BOOT_SPL=false -DISK_SIZE=6G SUPERVISOR_MACHINE=qemuarm-64 SUPERVISOR_ARCH=aarch64 diff --git a/buildroot-external/board/pc/generic-x86-64/meta b/buildroot-external/board/pc/generic-x86-64/meta index 6672e3a3e..6b9578d4e 100644 --- a/buildroot-external/board/pc/generic-x86-64/meta +++ b/buildroot-external/board/pc/generic-x86-64/meta @@ -6,6 +6,5 @@ KERNEL_FILE=bzImage PARTITION_TABLE_TYPE=gpt BOOT_SIZE=32M BOOT_SPL=false -DISK_SIZE=6G SUPERVISOR_MACHINE=generic-x86-64 SUPERVISOR_ARCH=amd64 diff --git a/buildroot-external/board/pc/ova/haos-hook.sh b/buildroot-external/board/pc/ova/haos-hook.sh index 3c6b7ccb9..6d6b4c1e7 100755 --- a/buildroot-external/board/pc/ova/haos-hook.sh +++ b/buildroot-external/board/pc/ova/haos-hook.sh @@ -22,6 +22,8 @@ function haos_post_image() { local hdd_img="$(haos_image_name img)" # Virtual Disk images + resize_disk_image_virtual 32G + convert_disk_image_virtual vmdk convert_disk_image_virtual vhdx convert_disk_image_virtual vdi diff --git a/buildroot-external/board/pc/ova/meta b/buildroot-external/board/pc/ova/meta index 0250513b8..5a812b6e7 100644 --- a/buildroot-external/board/pc/ova/meta +++ b/buildroot-external/board/pc/ova/meta @@ -6,6 +6,5 @@ KERNEL_FILE=bzImage PARTITION_TABLE_TYPE=gpt BOOT_SIZE=32M BOOT_SPL=false -DISK_SIZE=32G SUPERVISOR_MACHINE=qemux86-64 SUPERVISOR_ARCH=amd64 diff --git a/buildroot-external/genimage/genimage.cfg b/buildroot-external/genimage/genimage.cfg index fcd29a773..2e1c21d14 100644 --- a/buildroot-external/genimage/genimage.cfg +++ b/buildroot-external/genimage/genimage.cfg @@ -1,8 +1,6 @@ include("images-os.cfg") image "${IMAGE_NAME}.img" { - size = "${DISK_SIZE:-2G}" - include("hdimage-${PARTITION_TABLE_TYPE}.cfg") include("partition-spl-${BOOT_SPL_TYPE}.cfg") diff --git a/buildroot-external/genimage/partitions-os-gpt.cfg b/buildroot-external/genimage/partitions-os-gpt.cfg index 83028a8d7..814e7a3e1 100644 --- a/buildroot-external/genimage/partitions-os-gpt.cfg +++ b/buildroot-external/genimage/partitions-os-gpt.cfg @@ -42,6 +42,5 @@ partition hassos-overlay { partition hassos-data { partition-type-uuid = "linux" partition-uuid = "a52a4597-fa3a-4851-aefd-2fbe9f849079" - size = ${DATA_SIZE} image = ${DATA_IMAGE} } diff --git a/buildroot-external/genimage/partitions-os-mbr.cfg b/buildroot-external/genimage/partitions-os-mbr.cfg index ba9cc06c5..c40892b94 100644 --- a/buildroot-external/genimage/partitions-os-mbr.cfg +++ b/buildroot-external/genimage/partitions-os-mbr.cfg @@ -41,7 +41,6 @@ partition hassos-overlay { partition hassos-data { partition-type = 0x83 - size = ${DATA_SIZE} image = ${DATA_IMAGE} forced-primary = "yes" } diff --git a/buildroot-external/package/hassio/create-data-partition.sh b/buildroot-external/package/hassio/create-data-partition.sh index 7dbfb43dc..bc717c178 100755 --- a/buildroot-external/package/hassio/create-data-partition.sh +++ b/buildroot-external/package/hassio/create-data-partition.sh @@ -42,3 +42,17 @@ curl -fsL -o "${data_dir}/supervisor/apparmor/hassio-supervisor" "${APPARMOR_URL # Persist build-time updater channel jq -n --arg channel "${channel}" '{"channel": \$channel}' > "${data_dir}/supervisor/updater.json" EOF + +# Tear down docker and unmount the data partition before shrinking +docker rm -f "${container}" > /dev/null +sudo umount "${data_dir}" +trap - ERR EXIT + +# Shrink the filesystem to its minimum size +e2fsck -f -y "${data_img}" +resize2fs -M "${data_img}" + +# Truncate image file to match the filesystem size +block_count=$(dumpe2fs -h "${data_img}" 2>/dev/null | awk '/^Block count:/{print $3}') +block_size=$(dumpe2fs -h "${data_img}" 2>/dev/null | awk '/^Block size:/{print $3}') +truncate --size="$((block_count * block_size))" "${data_img}" diff --git a/buildroot-external/scripts/hdd-image.sh b/buildroot-external/scripts/hdd-image.sh index d179eba81..0506c73a6 100755 --- a/buildroot-external/scripts/hdd-image.sh +++ b/buildroot-external/scripts/hdd-image.sh @@ -4,7 +4,6 @@ BOOTSTATE_SIZE=8M SYSTEM_SIZE=256M KERNEL_SIZE=24M OVERLAY_SIZE=96M -DATA_SIZE=1280M function create_disk_image() { if [ -f "${BOARD_DIR}/genimage.cfg" ]; then @@ -24,7 +23,7 @@ function create_disk_image() { ota_version="$(haos_version)" export ota_compatible ota_version # variables used in genimage configs - export BOOTSTATE_SIZE SYSTEM_SIZE KERNEL_SIZE OVERLAY_SIZE DATA_SIZE + export BOOTSTATE_SIZE SYSTEM_SIZE KERNEL_SIZE OVERLAY_SIZE RAUC_MANIFEST=$(tempio -template "${BR2_EXTERNAL_HAOS_PATH}/ota/manifest.raucm.gtpl") IMAGE_NAME="$(haos_image_basename)" BOOT_SPL_TYPE=$(test "$BOOT_SPL" == "true" && echo "spl" || echo "nospl") @@ -52,6 +51,14 @@ function create_disk_image() { --includepath "${BOARD_DIR}:${BR2_EXTERNAL_HAOS_PATH}/genimage" } +function resize_disk_image_virtual() { + local size="${1}" + local hdd_img + hdd_img="$(haos_image_name img)" + + qemu-img resize -q -f raw "${hdd_img}" "${size}" +} + function convert_disk_image_virtual() { local hdd_ext="${1}" local hdd_img