Loading fs_mgr/liblp/images.cpp +26 −24 Original line number Diff line number Diff line Loading @@ -98,11 +98,12 @@ bool WriteToImageFile(const char* file, const LpMetadata& input) { return WriteToImageFile(fd, input); } SparseBuilder::SparseBuilder(const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images) ImageBuilder::ImageBuilder(const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify) : metadata_(metadata), geometry_(metadata.geometry), block_size_(block_size), sparsify_(sparsify), images_(images) { uint64_t total_size = GetTotalSuperPartitionSize(metadata); if (block_size % LP_SECTOR_SIZE != 0) { Loading Loading @@ -144,11 +145,11 @@ SparseBuilder::SparseBuilder(const LpMetadata& metadata, uint32_t block_size, } } bool SparseBuilder::IsValid() const { bool ImageBuilder::IsValid() const { return device_images_.size() == metadata_.block_devices.size(); } bool SparseBuilder::Export(const char* file) { bool ImageBuilder::Export(const char* file) { unique_fd fd(open(file, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC, 0644)); if (fd < 0) { PERROR << "open failed: " << file; Loading @@ -158,8 +159,8 @@ bool SparseBuilder::Export(const char* file) { LERROR << "Cannot export to a single image on retrofit builds."; return false; } // No gzip compression; sparseify; no checksum. int ret = sparse_file_write(device_images_[0].get(), fd, false, true, false); // No gzip compression; no checksum. int ret = sparse_file_write(device_images_[0].get(), fd, false, sparsify_, false); if (ret != 0) { LERROR << "sparse_file_write failed (error code " << ret << ")"; return false; Loading @@ -167,7 +168,7 @@ bool SparseBuilder::Export(const char* file) { return true; } bool SparseBuilder::ExportFiles(const std::string& output_dir) { bool ImageBuilder::ExportFiles(const std::string& output_dir) { for (size_t i = 0; i < device_images_.size(); i++) { std::string name = GetBlockDevicePartitionName(metadata_.block_devices[i]); std::string file_name = "super_" + name + ".img"; Loading @@ -179,8 +180,8 @@ bool SparseBuilder::ExportFiles(const std::string& output_dir) { PERROR << "open failed: " << file_path; return false; } // No gzip compression; sparseify; no checksum. int ret = sparse_file_write(device_images_[i].get(), fd, false, true, false); // No gzip compression; no checksum. int ret = sparse_file_write(device_images_[i].get(), fd, false, sparsify_, false); if (ret != 0) { LERROR << "sparse_file_write failed (error code " << ret << ")"; return false; Loading @@ -189,7 +190,7 @@ bool SparseBuilder::ExportFiles(const std::string& output_dir) { return true; } bool SparseBuilder::AddData(sparse_file* file, const std::string& blob, uint64_t sector) { bool ImageBuilder::AddData(sparse_file* file, const std::string& blob, uint64_t sector) { uint32_t block; if (!SectorToBlock(sector, &block)) { return false; Loading @@ -203,7 +204,7 @@ bool SparseBuilder::AddData(sparse_file* file, const std::string& blob, uint64_t return true; } bool SparseBuilder::SectorToBlock(uint64_t sector, uint32_t* block) { bool ImageBuilder::SectorToBlock(uint64_t sector, uint32_t* block) { // The caller must ensure that the metadata has an alignment that is a // multiple of the block size. liblp will take care of the rest, ensuring // that all partitions are on an aligned boundary. Therefore all writes Loading @@ -218,11 +219,11 @@ bool SparseBuilder::SectorToBlock(uint64_t sector, uint32_t* block) { return true; } uint64_t SparseBuilder::BlockToSector(uint64_t block) const { uint64_t ImageBuilder::BlockToSector(uint64_t block) const { return (block * block_size_) / LP_SECTOR_SIZE; } bool SparseBuilder::Build() { bool ImageBuilder::Build() { if (sparse_file_add_fill(device_images_[0].get(), 0, LP_PARTITION_RESERVED_BYTES, 0) < 0) { LERROR << "Could not add initial sparse block for reserved zeroes"; return false; Loading Loading @@ -275,7 +276,7 @@ static inline bool HasFillValue(uint32_t* buffer, size_t count) { return true; } bool SparseBuilder::AddPartitionImage(const LpMetadataPartition& partition, bool ImageBuilder::AddPartitionImage(const LpMetadataPartition& partition, const std::string& file) { // Track which extent we're processing. uint32_t extent_index = partition.first_extent_index; Loading Loading @@ -371,7 +372,7 @@ bool SparseBuilder::AddPartitionImage(const LpMetadataPartition& partition, return true; } uint64_t SparseBuilder::ComputePartitionSize(const LpMetadataPartition& partition) const { uint64_t ImageBuilder::ComputePartitionSize(const LpMetadataPartition& partition) const { uint64_t sectors = 0; for (size_t i = 0; i < partition.num_extents; i++) { sectors += metadata_.extents[partition.first_extent_index + i].num_sectors; Loading @@ -386,7 +387,7 @@ uint64_t SparseBuilder::ComputePartitionSize(const LpMetadataPartition& partitio // // Without this, it would be more difficult to find the appropriate extent for // an output block. With this guarantee it is a linear walk. bool SparseBuilder::CheckExtentOrdering() { bool ImageBuilder::CheckExtentOrdering() { std::vector<uint64_t> last_sectors(metadata_.block_devices.size()); for (const auto& extent : metadata_.extents) { Loading @@ -407,7 +408,7 @@ bool SparseBuilder::CheckExtentOrdering() { return true; } int SparseBuilder::OpenImageFile(const std::string& file) { int ImageBuilder::OpenImageFile(const std::string& file) { android::base::unique_fd source_fd = GetControlFileOrOpen(file.c_str(), O_RDONLY | O_CLOEXEC); if (source_fd < 0) { PERROR << "open image file failed: " << file; Loading Loading @@ -437,15 +438,16 @@ int SparseBuilder::OpenImageFile(const std::string& file) { return temp_fds_.back().get(); } bool WriteToSparseFile(const char* file, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images) { SparseBuilder builder(metadata, block_size, images); bool WriteToImageFile(const char* file, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify) { ImageBuilder builder(metadata, block_size, images, sparsify); return builder.IsValid() && builder.Build() && builder.Export(file); } bool WriteSplitSparseFiles(const std::string& output_dir, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images) { SparseBuilder builder(metadata, block_size, images); bool WriteSplitImageFiles(const std::string& output_dir, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify) { ImageBuilder builder(metadata, block_size, images, sparsify); return builder.IsValid() && builder.Build() && builder.ExportFiles(output_dir); } Loading fs_mgr/liblp/images.h +5 −4 Original line number Diff line number Diff line Loading @@ -32,13 +32,13 @@ std::unique_ptr<LpMetadata> ReadFromImageFile(int fd); bool WriteToImageFile(const char* file, const LpMetadata& metadata); bool WriteToImageFile(int fd, const LpMetadata& metadata); // We use an object to build the sparse file since it requires that data // We use an object to build the image file since it requires that data // pointers be held alive until the sparse file is destroyed. It's easier // to do this when the data pointers are all in one place. class SparseBuilder { class ImageBuilder { public: SparseBuilder(const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images); ImageBuilder(const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify); bool Build(); bool Export(const char* file); Loading @@ -60,6 +60,7 @@ class SparseBuilder { const LpMetadata& metadata_; const LpMetadataGeometry& geometry_; uint32_t block_size_; bool sparsify_; std::vector<SparsePtr> device_images_; std::string all_metadata_; Loading fs_mgr/liblp/include/liblp/liblp.h +5 −4 Original line number Diff line number Diff line Loading @@ -72,8 +72,8 @@ std::unique_ptr<LpMetadata> ReadMetadata(const std::string& super_partition, uin // Read/Write logical partition metadata to an image file, for diagnostics or // flashing. bool WriteToSparseFile(const char* file, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images); bool WriteToImageFile(const char* file, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify); bool WriteToImageFile(const char* file, const LpMetadata& metadata); std::unique_ptr<LpMetadata> ReadFromImageFile(const std::string& image_file); std::unique_ptr<LpMetadata> ReadFromImageBlob(const void* data, size_t bytes); Loading @@ -83,8 +83,9 @@ std::unique_ptr<LpMetadata> ReadFromImageBlob(const void* data, size_t bytes); // is intended for retrofit devices, and will generate one sparse file per // block device (each named super_<name>.img) and placed in the specified // output folder. bool WriteSplitSparseFiles(const std::string& output_dir, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images); bool WriteSplitImageFiles(const std::string& output_dir, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify); // Helper to extract safe C++ strings from partition info. std::string GetPartitionName(const LpMetadataPartition& partition); Loading fs_mgr/liblp/io_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -598,7 +598,7 @@ TEST(liblp, FlashSparseImage) { ASSERT_NE(exported, nullptr); // Build the sparse file. SparseBuilder sparse(*exported.get(), 512, {}); ImageBuilder sparse(*exported.get(), 512, {}, true /* sparsify */); ASSERT_TRUE(sparse.IsValid()); ASSERT_TRUE(sparse.Build()); Loading Loading
fs_mgr/liblp/images.cpp +26 −24 Original line number Diff line number Diff line Loading @@ -98,11 +98,12 @@ bool WriteToImageFile(const char* file, const LpMetadata& input) { return WriteToImageFile(fd, input); } SparseBuilder::SparseBuilder(const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images) ImageBuilder::ImageBuilder(const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify) : metadata_(metadata), geometry_(metadata.geometry), block_size_(block_size), sparsify_(sparsify), images_(images) { uint64_t total_size = GetTotalSuperPartitionSize(metadata); if (block_size % LP_SECTOR_SIZE != 0) { Loading Loading @@ -144,11 +145,11 @@ SparseBuilder::SparseBuilder(const LpMetadata& metadata, uint32_t block_size, } } bool SparseBuilder::IsValid() const { bool ImageBuilder::IsValid() const { return device_images_.size() == metadata_.block_devices.size(); } bool SparseBuilder::Export(const char* file) { bool ImageBuilder::Export(const char* file) { unique_fd fd(open(file, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC, 0644)); if (fd < 0) { PERROR << "open failed: " << file; Loading @@ -158,8 +159,8 @@ bool SparseBuilder::Export(const char* file) { LERROR << "Cannot export to a single image on retrofit builds."; return false; } // No gzip compression; sparseify; no checksum. int ret = sparse_file_write(device_images_[0].get(), fd, false, true, false); // No gzip compression; no checksum. int ret = sparse_file_write(device_images_[0].get(), fd, false, sparsify_, false); if (ret != 0) { LERROR << "sparse_file_write failed (error code " << ret << ")"; return false; Loading @@ -167,7 +168,7 @@ bool SparseBuilder::Export(const char* file) { return true; } bool SparseBuilder::ExportFiles(const std::string& output_dir) { bool ImageBuilder::ExportFiles(const std::string& output_dir) { for (size_t i = 0; i < device_images_.size(); i++) { std::string name = GetBlockDevicePartitionName(metadata_.block_devices[i]); std::string file_name = "super_" + name + ".img"; Loading @@ -179,8 +180,8 @@ bool SparseBuilder::ExportFiles(const std::string& output_dir) { PERROR << "open failed: " << file_path; return false; } // No gzip compression; sparseify; no checksum. int ret = sparse_file_write(device_images_[i].get(), fd, false, true, false); // No gzip compression; no checksum. int ret = sparse_file_write(device_images_[i].get(), fd, false, sparsify_, false); if (ret != 0) { LERROR << "sparse_file_write failed (error code " << ret << ")"; return false; Loading @@ -189,7 +190,7 @@ bool SparseBuilder::ExportFiles(const std::string& output_dir) { return true; } bool SparseBuilder::AddData(sparse_file* file, const std::string& blob, uint64_t sector) { bool ImageBuilder::AddData(sparse_file* file, const std::string& blob, uint64_t sector) { uint32_t block; if (!SectorToBlock(sector, &block)) { return false; Loading @@ -203,7 +204,7 @@ bool SparseBuilder::AddData(sparse_file* file, const std::string& blob, uint64_t return true; } bool SparseBuilder::SectorToBlock(uint64_t sector, uint32_t* block) { bool ImageBuilder::SectorToBlock(uint64_t sector, uint32_t* block) { // The caller must ensure that the metadata has an alignment that is a // multiple of the block size. liblp will take care of the rest, ensuring // that all partitions are on an aligned boundary. Therefore all writes Loading @@ -218,11 +219,11 @@ bool SparseBuilder::SectorToBlock(uint64_t sector, uint32_t* block) { return true; } uint64_t SparseBuilder::BlockToSector(uint64_t block) const { uint64_t ImageBuilder::BlockToSector(uint64_t block) const { return (block * block_size_) / LP_SECTOR_SIZE; } bool SparseBuilder::Build() { bool ImageBuilder::Build() { if (sparse_file_add_fill(device_images_[0].get(), 0, LP_PARTITION_RESERVED_BYTES, 0) < 0) { LERROR << "Could not add initial sparse block for reserved zeroes"; return false; Loading Loading @@ -275,7 +276,7 @@ static inline bool HasFillValue(uint32_t* buffer, size_t count) { return true; } bool SparseBuilder::AddPartitionImage(const LpMetadataPartition& partition, bool ImageBuilder::AddPartitionImage(const LpMetadataPartition& partition, const std::string& file) { // Track which extent we're processing. uint32_t extent_index = partition.first_extent_index; Loading Loading @@ -371,7 +372,7 @@ bool SparseBuilder::AddPartitionImage(const LpMetadataPartition& partition, return true; } uint64_t SparseBuilder::ComputePartitionSize(const LpMetadataPartition& partition) const { uint64_t ImageBuilder::ComputePartitionSize(const LpMetadataPartition& partition) const { uint64_t sectors = 0; for (size_t i = 0; i < partition.num_extents; i++) { sectors += metadata_.extents[partition.first_extent_index + i].num_sectors; Loading @@ -386,7 +387,7 @@ uint64_t SparseBuilder::ComputePartitionSize(const LpMetadataPartition& partitio // // Without this, it would be more difficult to find the appropriate extent for // an output block. With this guarantee it is a linear walk. bool SparseBuilder::CheckExtentOrdering() { bool ImageBuilder::CheckExtentOrdering() { std::vector<uint64_t> last_sectors(metadata_.block_devices.size()); for (const auto& extent : metadata_.extents) { Loading @@ -407,7 +408,7 @@ bool SparseBuilder::CheckExtentOrdering() { return true; } int SparseBuilder::OpenImageFile(const std::string& file) { int ImageBuilder::OpenImageFile(const std::string& file) { android::base::unique_fd source_fd = GetControlFileOrOpen(file.c_str(), O_RDONLY | O_CLOEXEC); if (source_fd < 0) { PERROR << "open image file failed: " << file; Loading Loading @@ -437,15 +438,16 @@ int SparseBuilder::OpenImageFile(const std::string& file) { return temp_fds_.back().get(); } bool WriteToSparseFile(const char* file, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images) { SparseBuilder builder(metadata, block_size, images); bool WriteToImageFile(const char* file, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify) { ImageBuilder builder(metadata, block_size, images, sparsify); return builder.IsValid() && builder.Build() && builder.Export(file); } bool WriteSplitSparseFiles(const std::string& output_dir, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images) { SparseBuilder builder(metadata, block_size, images); bool WriteSplitImageFiles(const std::string& output_dir, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify) { ImageBuilder builder(metadata, block_size, images, sparsify); return builder.IsValid() && builder.Build() && builder.ExportFiles(output_dir); } Loading
fs_mgr/liblp/images.h +5 −4 Original line number Diff line number Diff line Loading @@ -32,13 +32,13 @@ std::unique_ptr<LpMetadata> ReadFromImageFile(int fd); bool WriteToImageFile(const char* file, const LpMetadata& metadata); bool WriteToImageFile(int fd, const LpMetadata& metadata); // We use an object to build the sparse file since it requires that data // We use an object to build the image file since it requires that data // pointers be held alive until the sparse file is destroyed. It's easier // to do this when the data pointers are all in one place. class SparseBuilder { class ImageBuilder { public: SparseBuilder(const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images); ImageBuilder(const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify); bool Build(); bool Export(const char* file); Loading @@ -60,6 +60,7 @@ class SparseBuilder { const LpMetadata& metadata_; const LpMetadataGeometry& geometry_; uint32_t block_size_; bool sparsify_; std::vector<SparsePtr> device_images_; std::string all_metadata_; Loading
fs_mgr/liblp/include/liblp/liblp.h +5 −4 Original line number Diff line number Diff line Loading @@ -72,8 +72,8 @@ std::unique_ptr<LpMetadata> ReadMetadata(const std::string& super_partition, uin // Read/Write logical partition metadata to an image file, for diagnostics or // flashing. bool WriteToSparseFile(const char* file, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images); bool WriteToImageFile(const char* file, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify); bool WriteToImageFile(const char* file, const LpMetadata& metadata); std::unique_ptr<LpMetadata> ReadFromImageFile(const std::string& image_file); std::unique_ptr<LpMetadata> ReadFromImageBlob(const void* data, size_t bytes); Loading @@ -83,8 +83,9 @@ std::unique_ptr<LpMetadata> ReadFromImageBlob(const void* data, size_t bytes); // is intended for retrofit devices, and will generate one sparse file per // block device (each named super_<name>.img) and placed in the specified // output folder. bool WriteSplitSparseFiles(const std::string& output_dir, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images); bool WriteSplitImageFiles(const std::string& output_dir, const LpMetadata& metadata, uint32_t block_size, const std::map<std::string, std::string>& images, bool sparsify); // Helper to extract safe C++ strings from partition info. std::string GetPartitionName(const LpMetadataPartition& partition); Loading
fs_mgr/liblp/io_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -598,7 +598,7 @@ TEST(liblp, FlashSparseImage) { ASSERT_NE(exported, nullptr); // Build the sparse file. SparseBuilder sparse(*exported.get(), 512, {}); ImageBuilder sparse(*exported.get(), 512, {}, true /* sparsify */); ASSERT_TRUE(sparse.IsValid()); ASSERT_TRUE(sparse.Build()); Loading