From a54dcaf86e16a0d71faf2e3cc4077bf367c07419 Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Thu, 13 May 2021 21:57:02 +0900 Subject: [PATCH] microdroid: each partition in payload has size in it When creating the composite disk image for payload, add fillers with size of the backing files so that microdroid can read block devices easily with its original size. filler with size makes each partition well aligned with 4k boundary and the last 4byte conveys the size(BE). Bug: 187783952 Test: MicrodroidHostTestCases Change-Id: I072873779df4737448112e262fc1b051c0229ea8 --- microdroid/signature/mk_payload.cc | 47 +++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/microdroid/signature/mk_payload.cc b/microdroid/signature/mk_payload.cc index 8046b5ea..0ea4d2cf 100644 --- a/microdroid/signature/mk_payload.cc +++ b/microdroid/signature/mk_payload.cc @@ -36,6 +36,7 @@ using android::base::Dirname; using android::base::ErrnoError; using android::base::Error; using android::base::Result; +using android::base::unique_fd; using android::microdroid::ApexSignature; using android::microdroid::MicrodroidSignature; using android::microdroid::WriteMicrodroidSignature; @@ -43,9 +44,10 @@ using android::microdroid::WriteMicrodroidSignature; using com::android::apex::ApexInfoList; using com::android::apex::readApexInfoList; +using cuttlefish::AlignToPartitionSize; using cuttlefish::CreateCompositeDisk; -using cuttlefish::ImagePartition; using cuttlefish::kLinuxFilesystem; +using cuttlefish::MultipleImagePartition; Result GetFileSize(const std::string& path) { struct stat st; @@ -211,24 +213,53 @@ Result MakeSignature(const Config& config, const std::string& filename) { return WriteMicrodroidSignature(signature, out); } +Result GenerateFiller(const std::string& file_path, const std::string& filler_path) { + auto file_size = GetFileSize(file_path); + if (!file_size.ok()) { + return file_size.error(); + } + auto disk_size = AlignToPartitionSize(*file_size + sizeof(uint32_t)); + + unique_fd fd(TEMP_FAILURE_RETRY(open(filler_path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0600))); + if (fd.get() == -1) { + return ErrnoError() << "open(" << filler_path << ") failed."; + } + uint32_t size = htobe32(static_cast(*file_size)); + if (ftruncate(fd.get(), disk_size - *file_size) == -1) { + return ErrnoError() << "ftruncate(" << filler_path << ") failed."; + } + if (lseek(fd.get(), -sizeof(size), SEEK_END) == -1) { + return ErrnoError() << "lseek(" << filler_path << ") failed."; + } + if (write(fd.get(), &size, sizeof(size)) <= 0) { + return ErrnoError() << "write(" << filler_path << ") failed."; + } + return {}; +} + Result MakePayload(const Config& config, const std::string& signature_file, const std::string& output_file) { - std::vector partitions; + std::vector partitions; // put signature at the first partition - partitions.push_back(ImagePartition{ + partitions.push_back(MultipleImagePartition{ .label = "signature", - .image_file_path = signature_file, + .image_file_paths = {signature_file}, .type = kLinuxFilesystem, .read_only = true, }); - // put apexes at the subsequent partitions + // put apexes at the subsequent partitions with "size" filler for (size_t i = 0; i < config.apexes.size(); i++) { const auto& apex_config = config.apexes[i]; - partitions.push_back(ImagePartition{ - .label = "payload_apex_" + std::to_string(i), - .image_file_path = apex_config.path, + std::string apex_path = ToAbsolute(apex_config.path, config.dirname); + std::string filler_path = output_file + "." + std::to_string(i); + if (auto ret = GenerateFiller(apex_path, filler_path); !ret.ok()) { + return ret.error(); + } + partitions.push_back(MultipleImagePartition{ + .label = "microdroid-apex-" + std::to_string(i), + .image_file_paths = {apex_path, filler_path}, .type = kLinuxFilesystem, .read_only = true, });