From 9659cd07d91cc1d02dff78085323df098e102c54 Mon Sep 17 00:00:00 2001 From: Kelvin Zhang Date: Fri, 9 Oct 2026 22:04:24 -0700 Subject: [PATCH] assemble_cvd: update sparse super images in raw form When repacking DLKM partitions, convert a sparse build super image directly into the per-instance raw image first. Both lpadd operations can then update that image in place instead of repeatedly converting the full super image between sparse and raw formats. --- .../commands/assemble_cvd/disk/BUILD.bazel | 2 ++ .../disk/kernel_ramdisk_repacker.cpp | 14 +++++++++++--- .../libs/image_aggregator/sparse_image.cc | 19 ++++++++++++------- .../host/libs/image_aggregator/sparse_image.h | 2 ++ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/disk/BUILD.bazel b/base/cvd/cuttlefish/host/commands/assemble_cvd/disk/BUILD.bazel index aaa8aadae39..d3cf54b03b0 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/disk/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/disk/BUILD.bazel @@ -240,6 +240,8 @@ cf_cc_library( "//cuttlefish/host/commands/assemble_cvd/disk:image_file", "//cuttlefish/host/commands/assemble_cvd/flags:boot_image", "//cuttlefish/host/libs/config:cuttlefish_config", + "//cuttlefish/host/libs/image_aggregator:sparse_image", + "//cuttlefish/posix:rename", "//cuttlefish/posix:strerror", "//cuttlefish/result:expect", "//cuttlefish/result:result_type", diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/disk/kernel_ramdisk_repacker.cpp b/base/cvd/cuttlefish/host/commands/assemble_cvd/disk/kernel_ramdisk_repacker.cpp index 267fc346684..a3414505429 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/disk/kernel_ramdisk_repacker.cpp +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/disk/kernel_ramdisk_repacker.cpp @@ -29,6 +29,8 @@ #include "cuttlefish/host/commands/assemble_cvd/flags/boot_image.h" #include "cuttlefish/host/commands/assemble_cvd/vendor_dlkm_utils.h" #include "cuttlefish/host/libs/config/cuttlefish_config.h" +#include "cuttlefish/host/libs/image_aggregator/sparse_image.h" +#include "cuttlefish/posix/rename.h" #include "cuttlefish/posix/strerror.h" #include "cuttlefish/result/expect.h" #include "cuttlefish/result/result_type.h" @@ -83,9 +85,15 @@ Result RepackSuperAndVbmeta( const auto new_super_img = instance.new_super_image(); // This file may have already been created by super_image_mixer.cc if (!FileExists(new_super_img)) { - CF_EXPECTF(Copy(instance.super_image(), new_super_img), - "Failed to copy super image '{}' to '{}': '{}'", - instance.super_image(), new_super_img, StrError(errno)); + if (CF_EXPECT(IsSparseImage(instance.super_image()))) { + const auto tmp_super_img = new_super_img + ".tmp"; + CF_EXPECT(ConvertSparseImageToRaw(instance.super_image(), tmp_super_img)); + CF_EXPECT(Rename(tmp_super_img, new_super_img)); + } else { + CF_EXPECTF(Copy(instance.super_image(), new_super_img), + "Failed to copy super image '{}' to '{}': '{}'", + instance.super_image(), new_super_img, StrError(errno)); + } } CF_EXPECT(RepackSuperWithPartition(new_super_img, new_vendor_dlkm_img, diff --git a/base/cvd/cuttlefish/host/libs/image_aggregator/sparse_image.cc b/base/cvd/cuttlefish/host/libs/image_aggregator/sparse_image.cc index e351f63c8a6..fedc339d1d5 100644 --- a/base/cvd/cuttlefish/host/libs/image_aggregator/sparse_image.cc +++ b/base/cvd/cuttlefish/host/libs/image_aggregator/sparse_image.cc @@ -68,6 +68,17 @@ Result IsSparseImage(const std::string& image_path) { return buffer == kAndroidSparseImageMagic; } +Result ConvertSparseImageToRaw(const std::string& source_path, + const std::string& destination_path) { + CF_EXPECT(IsSparseImage(source_path), + "Source image is not an Android sparse image"); + int status = Execute({Simg2ImgBinary(), source_path, destination_path}); + CF_EXPECT_EQ(status, 0, "Unable to convert Android sparse image '" + << source_path << "' to raw image '" + << destination_path << "': " << status); + return {}; +} + Result ForceRawImage(const std::string& image_path) { if (!CF_EXPECT(IsSparseImage(image_path))) { return {}; @@ -78,13 +89,7 @@ Result ForceRawImage(const std::string& image_path) { } std::string tmp_raw_image_path = image_path + ".raw"; - // Use simg2img to convert sparse image to raw images. - int simg2img_status = - Execute({Simg2ImgBinary(), image_path, tmp_raw_image_path}); - - CF_EXPECT_EQ(simg2img_status, 0, - "Unable to convert Android sparse image '" - << image_path << "' to raw image: " << simg2img_status); + CF_EXPECT(ConvertSparseImageToRaw(image_path, tmp_raw_image_path)); // Replace the original sparse image with the raw image. // `rename` can fail if these are on different mounts, but they are files diff --git a/base/cvd/cuttlefish/host/libs/image_aggregator/sparse_image.h b/base/cvd/cuttlefish/host/libs/image_aggregator/sparse_image.h index dd157f7faf7..a46199ea129 100644 --- a/base/cvd/cuttlefish/host/libs/image_aggregator/sparse_image.h +++ b/base/cvd/cuttlefish/host/libs/image_aggregator/sparse_image.h @@ -28,6 +28,8 @@ namespace cuttlefish { Result ForceRawImage(const std::string& image_path); Result IsSparseImage(const std::string& image_path); +Result ConvertSparseImageToRaw(const std::string& source_path, + const std::string& destination_path); /** Image file format comprised of a list of chunks of "raw data" and "fill * data" that is a repeated byte string. */