From f35661fac220fc1dcb25ee68f4132dfc98464fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Fri, 8 May 2026 22:57:40 +0200 Subject: [PATCH] image-builder: add erofs dm-verity support and lz4hc compression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add full dm-verity and measured rootfs support to create_erofs_rootfs_image(), bringing it to parity with the ext4 path. Unlike ext4, which is a read-write filesystem mounted read-only by convention, erofs is structurally read-only -- no journal, no write metadata, no superblock write path. This is a natural fit for dm-verity: erofs never attempts writes, so verity never has to reject anything. With ext4, the kernel must skip journal replay on verity-protected devices, which is a fragile assumption. Signed-off-by: Fabiano Fidêncio --- tools/osbuilder/image-builder/Dockerfile | 1 + .../osbuilder/image-builder/image_builder.sh | 34 ++++++++++++++----- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/tools/osbuilder/image-builder/Dockerfile b/tools/osbuilder/image-builder/Dockerfile index 77c319e32d..11dd3bfbd4 100644 --- a/tools/osbuilder/image-builder/Dockerfile +++ b/tools/osbuilder/image-builder/Dockerfile @@ -9,6 +9,7 @@ RUN ([ -n "$http_proxy" ] && \ sed -i '$ a proxy='$http_proxy /etc/dnf/dnf.conf ; true) && \ dnf install -y \ e2fsprogs \ + erofs-utils \ findutils \ gcc \ gdisk \ diff --git a/tools/osbuilder/image-builder/image_builder.sh b/tools/osbuilder/image-builder/image_builder.sh index 91a97c4eef..fddb9326d6 100755 --- a/tools/osbuilder/image-builder/image_builder.sh +++ b/tools/osbuilder/image-builder/image_builder.sh @@ -574,10 +574,6 @@ create_erofs_rootfs_image() { die "Invalid block size for erofs" fi - if ! device="$(setup_loop_device "${image}")"; then - die "Could not setup loop device" - fi - local mount_dir mount_dir=$(mktemp -p "${TMPDIR:-/tmp}" -d osbuilder-mount-dir.XXXX) @@ -594,18 +590,32 @@ create_erofs_rootfs_image() { setup_systemd "${mount_dir}" local -r fsimage="$(mktemp)" - mkfs.erofs -Enoinline_data "${fsimage}" "${mount_dir}" + mkfs.erofs -zlz4hc -Enoinline_data "${fsimage}" "${mount_dir}" local -r img_size="$(stat -c"%s" "${fsimage}")" - local -r img_size_mb="$(((("${img_size}" + 1048576) / 1048576) + 1 + "${rootfs_start}"))" + local img_size_mb="$(((("${img_size}" + 1048576) / 1048576) + 1 + "${rootfs_start}"))" + + if [[ "${MEASURED_ROOTFS}" == "yes" ]]; then + # create_disk places the hash partition at 99% of the disk, + # so p1 only gets 99% of img_size_mb. Scale up so the erofs + # data still fits: img_size_mb / 0.99 ≈ img_size_mb * 100 / 99 + 1 + img_size_mb=$(( (img_size_mb * 100 / 99) + 1 )) + fi create_disk "${image}" "${img_size_mb}" "ext4" "${rootfs_start}" + if ! device="$(setup_loop_device "${image}")"; then + die "Could not setup loop device" + fi + dd if="${fsimage}" of="${device}p1" + rm -f "${fsimage}" + + setup_verity "${device}" "${image}" losetup -d "${device}" rm -rf "${mount_dir}" - return "${img_size_mb}" + erofs_img_size_mb="${img_size_mb}" } set_dax_header() { @@ -620,7 +630,13 @@ set_dax_header() { local dax_image="${image}.dax" rm -f "${dax_image}" "${header_image}" - create_disk "${header_image}" "${img_size}" "${fs_type}" "${rootfs_offset}" + # parted doesn't recognize erofs as a partition type, use ext4 as the + # partition label -- it's just metadata and doesn't affect the contents. + local parted_fs_type="${fs_type}" + if [[ "${fs_type}" == "erofs" ]]; then + parted_fs_type="ext4" + fi + create_disk "${header_image}" "${img_size}" "${parted_fs_type}" "${rootfs_offset}" dax_header_bytes=$((dax_header_sz * 1024 * 1024)) dax_alignment_bytes=$((dax_alignment * 1024 * 1024)) @@ -701,7 +717,7 @@ main() { # rather than some device, so no need to guess the device dest size first. create_erofs_rootfs_image "${rootfs}" "${image}" \ "${block_size}" "${agent_bin}" - rootfs_img_size=$? + rootfs_img_size="${erofs_img_size_mb}" img_size=$((rootfs_img_size + dax_header_sz)) else img_size=$(calculate_img_size "${rootfs}" "${root_free_space}" \