diff options
author | Scott Lobdell <slobdell@google.com> | 2022-04-22 23:23:52 +0000 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2022-04-22 23:38:03 +0000 |
commit | 8fbaeebe74b774e14f1f46e14c4abaf5d5924b74 (patch) | |
tree | e13b5159a7992ed86c1b34408556504949ecfbdf | |
parent | dd4b721fc3372fedd1728035a56affa93eec5929 (diff) | |
parent | 715b57b9999920bf2448e8a705b530dad32b1485 (diff) |
Merge TP1A.220414.003
Change-Id: I65bc5b848e85ac1d9ca7f9f6e8087539ba8c23ca
-rw-r--r-- | aosp/dynamic_partition_control_android.cc | 9 | ||||
-rw-r--r-- | aosp/dynamic_partition_control_android.h | 2 | ||||
-rw-r--r-- | aosp/mock_dynamic_partition_control_android.h | 4 | ||||
-rw-r--r-- | aosp/ota_extractor.cc | 115 | ||||
-rw-r--r-- | common/dynamic_partition_control_interface.h | 2 | ||||
-rw-r--r-- | common/dynamic_partition_control_stub.cc | 4 | ||||
-rw-r--r-- | common/dynamic_partition_control_stub.h | 3 | ||||
-rw-r--r-- | common/mock_dynamic_partition_control.h | 4 | ||||
-rw-r--r-- | payload_consumer/install_operation_executor.cc | 1 | ||||
-rw-r--r-- | payload_consumer/install_plan.cc | 79 | ||||
-rw-r--r-- | payload_consumer/install_plan.h | 2 | ||||
-rw-r--r-- | payload_consumer/vabc_partition_writer.cc | 12 | ||||
-rw-r--r-- | payload_consumer/vabc_partition_writer_unittest.cc | 14 | ||||
-rw-r--r-- | payload_consumer/verity_writer_android.cc | 5 | ||||
-rw-r--r-- | update_metadata.proto | 35 |
15 files changed, 205 insertions, 86 deletions
diff --git a/aosp/dynamic_partition_control_android.cc b/aosp/dynamic_partition_control_android.cc index e39e7bc7..27d1d541 100644 --- a/aosp/dynamic_partition_control_android.cc +++ b/aosp/dynamic_partition_control_android.cc @@ -82,6 +82,8 @@ constexpr char kVirtualAbEnabled[] = "ro.virtual_ab.enabled"; constexpr char kVirtualAbRetrofit[] = "ro.virtual_ab.retrofit"; constexpr char kVirtualAbCompressionEnabled[] = "ro.virtual_ab.compression.enabled"; +constexpr auto&& kVirtualAbCompressionXorEnabled = + "ro.virtual_ab.compression.xor.enabled"; // Currently, android doesn't have a retrofit prop for VAB Compression. However, // struct FeatureFlag forces us to determine if a feature is 'retrofit'. So this @@ -126,6 +128,8 @@ DynamicPartitionControlAndroid::DynamicPartitionControlAndroid( virtual_ab_(GetFeatureFlag(kVirtualAbEnabled, kVirtualAbRetrofit)), virtual_ab_compression_(GetFeatureFlag(kVirtualAbCompressionEnabled, kVirtualAbCompressionRetrofit)), + virtual_ab_compression_xor_( + GetFeatureFlag(kVirtualAbCompressionXorEnabled, "")), source_slot_(source_slot) { if (GetVirtualAbFeatureFlag().IsEnabled()) { snapshot_ = SnapshotManager::New(); @@ -152,6 +156,11 @@ DynamicPartitionControlAndroid::GetVirtualAbCompressionFeatureFlag() { return virtual_ab_compression_; } +FeatureFlag +DynamicPartitionControlAndroid::GetVirtualAbCompressionXorFeatureFlag() { + return virtual_ab_compression_xor_; +} + bool DynamicPartitionControlAndroid::OptimizeOperation( const std::string& partition_name, const InstallOperation& operation, diff --git a/aosp/dynamic_partition_control_android.h b/aosp/dynamic_partition_control_android.h index 457ef182..92761d22 100644 --- a/aosp/dynamic_partition_control_android.h +++ b/aosp/dynamic_partition_control_android.h @@ -44,6 +44,7 @@ class DynamicPartitionControlAndroid : public DynamicPartitionControlInterface { FeatureFlag GetDynamicPartitionsFeatureFlag() override; FeatureFlag GetVirtualAbFeatureFlag() override; FeatureFlag GetVirtualAbCompressionFeatureFlag() override; + FeatureFlag GetVirtualAbCompressionXorFeatureFlag() override; bool OptimizeOperation(const std::string& partition_name, const InstallOperation& operation, InstallOperation* optimized) override; @@ -339,6 +340,7 @@ class DynamicPartitionControlAndroid : public DynamicPartitionControlInterface { const FeatureFlag dynamic_partitions_; const FeatureFlag virtual_ab_; const FeatureFlag virtual_ab_compression_; + const FeatureFlag virtual_ab_compression_xor_; std::unique_ptr<android::snapshot::ISnapshotManager> snapshot_; std::unique_ptr<android::snapshot::AutoDevice> metadata_device_; bool target_supports_snapshot_ = false; diff --git a/aosp/mock_dynamic_partition_control_android.h b/aosp/mock_dynamic_partition_control_android.h index 33ef39c8..f55cdf78 100644 --- a/aosp/mock_dynamic_partition_control_android.h +++ b/aosp/mock_dynamic_partition_control_android.h @@ -73,6 +73,10 @@ class MockDynamicPartitionControlAndroid MOCK_METHOD(std::string, GetSuperPartitionName, (uint32_t), (override)); MOCK_METHOD(FeatureFlag, GetVirtualAbFeatureFlag, (), (override)); MOCK_METHOD(FeatureFlag, GetVirtualAbCompressionFeatureFlag, (), (override)); + MOCK_METHOD(FeatureFlag, + GetVirtualAbCompressionXorFeatureFlag, + (), + (override)); MOCK_METHOD(bool, FinishUpdate, (bool), (override)); MOCK_METHOD(bool, GetSystemOtherPath, diff --git a/aosp/ota_extractor.cc b/aosp/ota_extractor.cc index 80bb74bf..7492bc5a 100644 --- a/aosp/ota_extractor.cc +++ b/aosp/ota_extractor.cc @@ -14,13 +14,13 @@ // limitations under the License. // -#include <fcntl.h> - +#include <array> #include <cstdint> #include <cstdio> #include <iterator> #include <memory> +#include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> @@ -28,16 +28,22 @@ #include <base/files/file_path.h> #include <gflags/gflags.h> #include <unistd.h> +#include <xz.h> #include "update_engine/common/utils.h" #include "update_engine/common/hash_calculator.h" #include "update_engine/payload_consumer/file_descriptor.h" +#include "update_engine/payload_consumer/file_descriptor_utils.h" #include "update_engine/payload_consumer/install_operation_executor.h" #include "update_engine/payload_consumer/payload_metadata.h" +#include "update_engine/payload_consumer/verity_writer_android.h" #include "update_engine/update_metadata.pb.h" -#include "xz.h" DEFINE_string(payload, "", "Path to payload.bin"); +DEFINE_string( + input_dir, + "", + "Directory to read input images. Only required for incremental OTAs"); DEFINE_string(output_dir, "", "Directory to put output images"); DEFINE_int64(payload_offset, 0, @@ -53,18 +59,55 @@ using chromeos_update_engine::PayloadMetadata; namespace chromeos_update_engine { +void WriteVerity(const PartitionUpdate& partition, + FileDescriptorPtr fd, + const size_t block_size) { + // 512KB buffer, arbitrary value. Larger buffers may improve performance. + static constexpr size_t BUFFER_SIZE = 1024 * 512; + if (partition.hash_tree_extent().num_blocks() == 0 && + partition.fec_extent().num_blocks() == 0) { + return; + } + InstallPlan::Partition install_part; + install_part.block_size = block_size; + CHECK(install_part.ParseVerityConfig(partition)); + VerityWriterAndroid writer; + CHECK(writer.Init(install_part)); + std::array<uint8_t, BUFFER_SIZE> buffer; + const auto data_size = + install_part.hash_tree_data_offset + install_part.hash_tree_data_size; + size_t offset = 0; + while (offset < data_size) { + const auto bytes_to_read = + static_cast<ssize_t>(std::min(BUFFER_SIZE, data_size - offset)); + ssize_t bytes_read; + CHECK( + utils::ReadAll(fd, buffer.data(), bytes_to_read, offset, &bytes_read)); + CHECK_EQ(bytes_read, bytes_to_read) + << " Failed to read at offset " << offset << " " + << android::base::ErrnoNumberAsString(errno); + writer.Update(offset, buffer.data(), bytes_read); + offset += bytes_read; + } + CHECK(writer.Finalize(fd.get(), fd.get())); + return; +} + bool ExtractImagesFromOTA(const DeltaArchiveManifest& manifest, const PayloadMetadata& metadata, int payload_fd, size_t payload_offset, + std::string_view input_dir, std::string_view output_dir, const std::set<std::string>& partitions) { InstallOperationExecutor executor(manifest.block_size()); const size_t data_begin = metadata.GetMetadataSize() + metadata.GetMetadataSignatureSize() + payload_offset; - const base::FilePath path( + const base::FilePath output_dir_path( base::StringPiece(output_dir.data(), output_dir.size())); + const base::FilePath input_dir_path( + base::StringPiece(input_dir.data(), input_dir.size())); std::vector<unsigned char> blob; for (const auto& partition : manifest.partitions()) { if (!partitions.empty() && @@ -74,18 +117,39 @@ bool ExtractImagesFromOTA(const DeltaArchiveManifest& manifest, LOG(INFO) << "Extracting partition " << partition.partition_name() << " size: " << partition.new_partition_info().size(); const auto output_path = - path.Append(partition.partition_name() + ".img").value(); - auto fd = + output_dir_path.Append(partition.partition_name() + ".img").value(); + const auto input_path = + input_dir_path.Append(partition.partition_name() + ".img").value(); + auto out_fd = std::make_shared<chromeos_update_engine::EintrSafeFileDescriptor>(); TEST_AND_RETURN_FALSE_ERRNO( - fd->Open(output_path.c_str(), O_RDWR | O_CREAT, 0644)); + out_fd->Open(output_path.c_str(), O_RDWR | O_CREAT, 0644)); + auto in_fd = + std::make_shared<chromeos_update_engine::EintrSafeFileDescriptor>(); + TEST_AND_RETURN_FALSE_ERRNO(in_fd->Open(input_path.c_str(), O_RDONLY)); + for (const auto& op : partition.operations()) { + if (op.has_src_sha256_hash()) { + brillo::Blob actual_hash; + TEST_AND_RETURN_FALSE(fd_utils::ReadAndHashExtents( + in_fd, op.src_extents(), manifest.block_size(), &actual_hash)); + CHECK_EQ(HexEncode(ToStringView(actual_hash)), + HexEncode(op.src_sha256_hash())); + } + blob.resize(op.data_length()); const auto op_data_offset = data_begin + op.data_offset(); ssize_t bytes_read = 0; TEST_AND_RETURN_FALSE(utils::PReadAll( payload_fd, blob.data(), blob.size(), op_data_offset, &bytes_read)); - auto direct_writer = std::make_unique<DirectExtentWriter>(fd); + if (op.has_data_sha256_hash()) { + brillo::Blob actual_hash; + TEST_AND_RETURN_FALSE( + HashCalculator::RawHashOfData(blob, &actual_hash)); + CHECK_EQ(HexEncode(ToStringView(actual_hash)), + HexEncode(op.data_sha256_hash())); + } + auto direct_writer = std::make_unique<DirectExtentWriter>(out_fd); if (op.type() == InstallOperation::ZERO) { TEST_AND_RETURN_FALSE(executor.ExecuteZeroOrDiscardOperation( op, std::move(direct_writer))); @@ -94,12 +158,15 @@ bool ExtractImagesFromOTA(const DeltaArchiveManifest& manifest, op.type() == InstallOperation::REPLACE_XZ) { TEST_AND_RETURN_FALSE(executor.ExecuteReplaceOperation( op, std::move(direct_writer), blob.data(), blob.size())); + } else if (op.type() == InstallOperation::SOURCE_COPY) { + TEST_AND_RETURN_FALSE(executor.ExecuteSourceCopyOperation( + op, std::move(direct_writer), in_fd)); } else { - LOG(ERROR) << "Unsupported operation type: " << op.type() << ", " - << InstallOperation::Type_Name(op.type()); - return false; + TEST_AND_RETURN_FALSE(executor.ExecuteDiffOperation( + op, std::move(direct_writer), in_fd, blob.data(), blob.size())); } } + WriteVerity(partition, out_fd, manifest.block_size()); int err = truncate64(output_path.c_str(), partition.new_partition_info().size()); if (err) { @@ -110,14 +177,32 @@ bool ExtractImagesFromOTA(const DeltaArchiveManifest& manifest, TEST_AND_RETURN_FALSE( HashCalculator::RawHashOfFile(output_path, &actual_hash)); CHECK_EQ(HexEncode(ToStringView(actual_hash)), - HexEncode(partition.new_partition_info().hash())); + HexEncode(partition.new_partition_info().hash())) + << " Partition " << partition.partition_name() + << " hash mismatches. Either the source image or OTA package is " + "corrupted."; } return true; } } // namespace chromeos_update_engine +namespace { + +bool IsIncrementalOTA(const DeltaArchiveManifest& manifest) { + for (const auto& part : manifest.partitions()) { + if (part.has_old_partition_info()) { + return true; + } + } + return false; +} + +} // namespace + int main(int argc, char* argv[]) { + gflags::SetUsageMessage( + "A tool to extract device images from Android OTA packages"); gflags::ParseCommandLineFlags(&argc, &argv, true); xz_crc32_init(); auto tokens = android::base::Tokenize(FLAGS_partitions, ","); @@ -172,10 +257,16 @@ int main(int argc, char* argv[]) { LOG(ERROR) << "Failed to parse manifest!"; return 1; } + if (IsIncrementalOTA(manifest) && FLAGS_input_dir.empty()) { + LOG(ERROR) << FLAGS_payload + << " is an incremental OTA, --input_dir parameter is required."; + return 1; + } return !ExtractImagesFromOTA(manifest, payload_metadata, payload_fd, FLAGS_payload_offset, + FLAGS_input_dir, FLAGS_output_dir, partitions); } diff --git a/common/dynamic_partition_control_interface.h b/common/dynamic_partition_control_interface.h index e6ebe6a1..2c01b1a9 100644 --- a/common/dynamic_partition_control_interface.h +++ b/common/dynamic_partition_control_interface.h @@ -73,6 +73,8 @@ class DynamicPartitionControlInterface { // DOES NOT tell you if VABC is used for current OTA update. For that, use // UpdateUsesSnapshotCompression. virtual FeatureFlag GetVirtualAbCompressionFeatureFlag() = 0; + // Return the feature flag for Virtual AB Compression XOR + virtual FeatureFlag GetVirtualAbCompressionXorFeatureFlag() = 0; // Attempt to optimize |operation|. // If successful, |optimized| contains an operation with extents that diff --git a/common/dynamic_partition_control_stub.cc b/common/dynamic_partition_control_stub.cc index dd30a8b6..6283b1db 100644 --- a/common/dynamic_partition_control_stub.cc +++ b/common/dynamic_partition_control_stub.cc @@ -38,6 +38,10 @@ FeatureFlag DynamicPartitionControlStub::GetVirtualAbCompressionFeatureFlag() { return FeatureFlag(FeatureFlag::Value::NONE); } +FeatureFlag DynamicPartitionControlStub::GetVirtualAbCompressionXorFeatureFlag() { + return FeatureFlag(FeatureFlag::Value::NONE); +} + bool DynamicPartitionControlStub::OptimizeOperation( const std::string& partition_name, const InstallOperation& operation, diff --git a/common/dynamic_partition_control_stub.h b/common/dynamic_partition_control_stub.h index 5aa43367..15137d2c 100644 --- a/common/dynamic_partition_control_stub.h +++ b/common/dynamic_partition_control_stub.h @@ -27,11 +27,12 @@ namespace chromeos_update_engine { -class DynamicPartitionControlStub : public DynamicPartitionControlInterface { +class DynamicPartitionControlStub final : public DynamicPartitionControlInterface { public: FeatureFlag GetDynamicPartitionsFeatureFlag() override; FeatureFlag GetVirtualAbFeatureFlag() override; FeatureFlag GetVirtualAbCompressionFeatureFlag() override; + FeatureFlag GetVirtualAbCompressionXorFeatureFlag() override; bool OptimizeOperation(const std::string& partition_name, const InstallOperation& operation, InstallOperation* optimized) override; diff --git a/common/mock_dynamic_partition_control.h b/common/mock_dynamic_partition_control.h index f3a446af..fd0a5a98 100644 --- a/common/mock_dynamic_partition_control.h +++ b/common/mock_dynamic_partition_control.h @@ -34,6 +34,10 @@ class MockDynamicPartitionControl : public DynamicPartitionControlInterface { MOCK_METHOD(bool, GetDeviceDir, (std::string*), (override)); MOCK_METHOD(FeatureFlag, GetDynamicPartitionsFeatureFlag, (), (override)); MOCK_METHOD(FeatureFlag, GetVirtualAbCompressionFeatureFlag, (), (override)); + MOCK_METHOD(FeatureFlag, + GetVirtualAbCompressionXorFeatureFlag, + (), + (override)); MOCK_METHOD(FeatureFlag, GetVirtualAbFeatureFlag, (), (override)); MOCK_METHOD(bool, FinishUpdate, (bool), (override)); MOCK_METHOD(std::unique_ptr<FileDescriptor>, diff --git a/payload_consumer/install_operation_executor.cc b/payload_consumer/install_operation_executor.cc index 69ef9c19..cd6546f4 100644 --- a/payload_consumer/install_operation_executor.cc +++ b/payload_consumer/install_operation_executor.cc @@ -255,6 +255,7 @@ bool InstallOperationExecutor::ExecuteDiffOperation( operation, std::move(writer), source_fd, data, count); default: LOG(ERROR) << "Unexpected operation type when executing diff ops " + << operation.type() << " " << operation.Type_Name(operation.type()); return false; } diff --git a/payload_consumer/install_plan.cc b/payload_consumer/install_plan.cc index db0af4e2..91eb53b3 100644 --- a/payload_consumer/install_plan.cc +++ b/payload_consumer/install_plan.cc @@ -187,6 +187,44 @@ bool InstallPlan::Partition::operator==( postinstall_optional == that.postinstall_optional); } +bool InstallPlan::Partition::ParseVerityConfig( + const PartitionUpdate& partition) { + if (partition.has_hash_tree_extent()) { + Extent extent = partition.hash_tree_data_extent(); + hash_tree_data_offset = extent.start_block() * block_size; + hash_tree_data_size = extent.num_blocks() * block_size; + extent = partition.hash_tree_extent(); + hash_tree_offset = extent.start_block() * block_size; + hash_tree_size = extent.num_blocks() * block_size; + uint64_t hash_tree_data_end = hash_tree_data_offset + hash_tree_data_size; + if (hash_tree_offset < hash_tree_data_end) { + LOG(ERROR) << "Invalid hash tree extents, hash tree data ends at " + << hash_tree_data_end << ", but hash tree starts at " + << hash_tree_offset; + return false; + } + hash_tree_algorithm = partition.hash_tree_algorithm(); + hash_tree_salt.assign(partition.hash_tree_salt().begin(), + partition.hash_tree_salt().end()); + } + if (partition.has_fec_extent()) { + Extent extent = partition.fec_data_extent(); + fec_data_offset = extent.start_block() * block_size; + fec_data_size = extent.num_blocks() * block_size; + extent = partition.fec_extent(); + fec_offset = extent.start_block() * block_size; + fec_size = extent.num_blocks() * block_size; + uint64_t fec_data_end = fec_data_offset + fec_data_size; + if (fec_offset < fec_data_end) { + LOG(ERROR) << "Invalid fec extents, fec data ends at " << fec_data_end + << ", but fec starts at " << fec_offset; + return false; + } + fec_roots = partition.fec_roots(); + } + return true; +} + template <typename PartitinoUpdateArray> bool InstallPlan::ParseManifestToInstallPlan( const PartitinoUpdateArray& partitions, @@ -226,42 +264,11 @@ bool InstallPlan::ParseManifestToInstallPlan( install_part.target_hash.assign(info.hash().begin(), info.hash().end()); install_part.block_size = block_size; - if (partition.has_hash_tree_extent()) { - Extent extent = partition.hash_tree_data_extent(); - install_part.hash_tree_data_offset = extent.start_block() * block_size; - install_part.hash_tree_data_size = extent.num_blocks() * block_size; - extent = partition.hash_tree_extent(); - install_part.hash_tree_offset = extent.start_block() * block_size; - install_part.hash_tree_size = extent.num_blocks() * block_size; - uint64_t hash_tree_data_end = - install_part.hash_tree_data_offset + install_part.hash_tree_data_size; - if (install_part.hash_tree_offset < hash_tree_data_end) { - LOG(ERROR) << "Invalid hash tree extents, hash tree data ends at " - << hash_tree_data_end << ", but hash tree starts at " - << install_part.hash_tree_offset; - *error = ErrorCode::kDownloadNewPartitionInfoError; - return false; - } - install_part.hash_tree_algorithm = partition.hash_tree_algorithm(); - install_part.hash_tree_salt.assign(partition.hash_tree_salt().begin(), - partition.hash_tree_salt().end()); - } - if (partition.has_fec_extent()) { - Extent extent = partition.fec_data_extent(); - install_part.fec_data_offset = extent.start_block() * block_size; - install_part.fec_data_size = extent.num_blocks() * block_size; - extent = partition.fec_extent(); - install_part.fec_offset = extent.start_block() * block_size; - install_part.fec_size = extent.num_blocks() * block_size; - uint64_t fec_data_end = - install_part.fec_data_offset + install_part.fec_data_size; - if (install_part.fec_offset < fec_data_end) { - LOG(ERROR) << "Invalid fec extents, fec data ends at " << fec_data_end - << ", but fec starts at " << install_part.fec_offset; - *error = ErrorCode::kDownloadNewPartitionInfoError; - return false; - } - install_part.fec_roots = partition.fec_roots(); + if (!install_part.ParseVerityConfig(partition)) { + *error = ErrorCode::kDownloadNewPartitionInfoError; + LOG(INFO) << "Failed to parse partition `" << partition.partition_name() + << "` verity configs"; + return false; } install_plan->partitions.push_back(install_part); diff --git a/payload_consumer/install_plan.h b/payload_consumer/install_plan.h index 0278ea51..883aa60c 100644 --- a/payload_consumer/install_plan.h +++ b/payload_consumer/install_plan.h @@ -156,6 +156,8 @@ struct InstallPlan { uint64_t fec_offset{0}; uint64_t fec_size{0}; uint32_t fec_roots{0}; + + bool ParseVerityConfig(const PartitionUpdate&); }; std::vector<Partition> partitions; diff --git a/payload_consumer/vabc_partition_writer.cc b/payload_consumer/vabc_partition_writer.cc index 54aea860..8ae0b51f 100644 --- a/payload_consumer/vabc_partition_writer.cc +++ b/payload_consumer/vabc_partition_writer.cc @@ -97,7 +97,17 @@ VABCPartitionWriter::VABCPartitionWriter( bool VABCPartitionWriter::Init(const InstallPlan* install_plan, bool source_may_exist, size_t next_op_index) { - xor_map_ = ComputeXorMap(partition_update_.merge_operations()); + if (dynamic_control_->GetVirtualAbCompressionXorFeatureFlag().IsEnabled()) { + xor_map_ = ComputeXorMap(partition_update_.merge_operations()); + if (xor_map_.size() > 0) { + LOG(INFO) << "Virtual AB Compression with XOR is enabled"; + } else { + LOG(INFO) << "Device supports Virtual AB compression with XOR, but OTA " + "package does not."; + } + } else { + LOG(INFO) << "Virtual AB Compression with XOR is disabled."; + } TEST_AND_RETURN_FALSE(install_plan != nullptr); if (source_may_exist && install_part_.source_size > 0) { TEST_AND_RETURN_FALSE(!install_part_.source_path.empty()); diff --git a/payload_consumer/vabc_partition_writer_unittest.cc b/payload_consumer/vabc_partition_writer_unittest.cc index f331091d..20aa75f8 100644 --- a/payload_consumer/vabc_partition_writer_unittest.cc +++ b/payload_consumer/vabc_partition_writer_unittest.cc @@ -48,7 +48,11 @@ static constexpr auto& fake_part_name = "fake_part"; static constexpr size_t FAKE_PART_SIZE = 4096 * 50; class VABCPartitionWriterTest : public ::testing::Test { public: - void SetUp() override { ftruncate(source_part_.fd, FAKE_PART_SIZE); } + void SetUp() override { + ftruncate(source_part_.fd, FAKE_PART_SIZE); + ON_CALL(dynamic_control_, GetVirtualAbCompressionXorFeatureFlag()) + .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::NONE))); + } protected: CowMergeOperation* AddMergeOp(PartitionUpdate* partition, @@ -102,6 +106,8 @@ TEST_F(VABCPartitionWriterTest, MergeSequenceWriteTest) { ON_CALL(*cow_writer, EmitLabel(_)).WillByDefault(Return(true)); return cow_writer; })); + EXPECT_CALL(dynamic_control_, GetVirtualAbCompressionXorFeatureFlag()) + .WillRepeatedly(Return(FeatureFlag(FeatureFlag::Value::LAUNCH))); ASSERT_TRUE(writer_.Init(&install_plan_, true, 0)); } @@ -125,6 +131,8 @@ TEST_F(VABCPartitionWriterTest, MergeSequenceXorSameBlock) { ON_CALL(*cow_writer, EmitLabel(_)).WillByDefault(Return(true)); return cow_writer; })); + EXPECT_CALL(dynamic_control_, GetVirtualAbCompressionXorFeatureFlag()) + .WillRepeatedly(Return(FeatureFlag(FeatureFlag::Value::LAUNCH))); ASSERT_TRUE(writer_.Init(&install_plan_, true, 0)); } @@ -224,10 +232,12 @@ TEST_F(VABCPartitionWriterTest, StreamXORBlockTest) { .WillOnce(Return(true)); return cow_writer; })); + EXPECT_CALL(dynamic_control_, GetVirtualAbCompressionXorFeatureFlag()) + .WillRepeatedly(Return(FeatureFlag(FeatureFlag::Value::LAUNCH))); VABCPartitionWriter writer_{ partition_update_, install_part_, &dynamic_control_, kBlockSize}; ASSERT_TRUE(writer_.Init(&install_plan_, true, 0)); - auto patch_data = GetNoopBSDIFF(kBlockSize * 5); + const auto patch_data = GetNoopBSDIFF(kBlockSize * 5); ASSERT_GT(patch_data.size(), 0UL); ASSERT_TRUE(writer_.PerformDiffOperation( *install_op, nullptr, patch_data.data(), patch_data.size())); diff --git a/payload_consumer/verity_writer_android.cc b/payload_consumer/verity_writer_android.cc index ffa29446..91efa3e2 100644 --- a/payload_consumer/verity_writer_android.cc +++ b/payload_consumer/verity_writer_android.cc @@ -116,7 +116,8 @@ bool VerityWriterAndroid::Finalize(FileDescriptor* read_fd, return false; } // All hash tree data blocks has been hashed, write hash tree to disk. - LOG(INFO) << "Writing verity hash tree to " << partition_->target_path; + LOG(INFO) << "Writing verity hash tree to " + << partition_->readonly_target_path; if (hash_tree_builder_) { TEST_AND_RETURN_FALSE(hash_tree_builder_->BuildHashTree()); TEST_AND_RETURN_FALSE_ERRNO( @@ -130,7 +131,7 @@ bool VerityWriterAndroid::Finalize(FileDescriptor* read_fd, hash_tree_builder_.reset(); } if (partition_->fec_size != 0) { - LOG(INFO) << "Writing verity FEC to " << partition_->target_path; + LOG(INFO) << "Writing verity FEC to " << partition_->readonly_target_path; TEST_AND_RETURN_FALSE(EncodeFEC(read_fd, write_fd, partition_->fec_data_offset, diff --git a/update_metadata.proto b/update_metadata.proto index d318a629..3f454add 100644 --- a/update_metadata.proto +++ b/update_metadata.proto @@ -146,25 +146,6 @@ message PartitionInfo { optional bytes hash = 2; } -// Describe an image we are based on in a human friendly way. -// Examples: -// dev-channel, x86-alex, 1.2.3, mp-v3 -// nplusone-channel, x86-alex, 1.2.4, mp-v3, dev-channel, 1.2.3 -// -// All fields will be set, if this message is present. -message ImageInfo { - optional string board = 1 [deprecated = true]; - optional string key = 2 [deprecated = true]; - optional string channel = 3 [deprecated = true]; - optional string version = 4 [deprecated = true]; - - // If these values aren't present, they should be assumed to match - // the equivalent value above. They are normally only different for - // special image types such as nplusone images. - optional string build_channel = 5 [deprecated = true]; - optional string build_version = 6 [deprecated = true]; -} - message InstallOperation { enum Type { REPLACE = 0; // Replace destination extents w/ attached data. @@ -401,8 +382,7 @@ message DeltaArchiveManifest { // Only present in major version = 1. List of install operations for the // kernel and rootfs partitions. For major version = 2 see the |partitions| // field. - repeated InstallOperation install_operations = 1 [deprecated = true]; - repeated InstallOperation kernel_install_operations = 2 [deprecated = true]; + reserved 1, 2; // (At time of writing) usually 4096 optional uint32 block_size = 3 [default = 4096]; @@ -415,17 +395,8 @@ message DeltaArchiveManifest { optional uint64 signatures_offset = 4; optional uint64 signatures_size = 5; - // Only present in major version = 1. Partition metadata used to validate the - // update. For major version = 2 see the |partitions| field. - optional PartitionInfo old_kernel_info = 6 [deprecated = true]; - optional PartitionInfo new_kernel_info = 7 [deprecated = true]; - optional PartitionInfo old_rootfs_info = 8 [deprecated = true]; - optional PartitionInfo new_rootfs_info = 9 [deprecated = true]; - - // old_image_info will only be present for delta images. - optional ImageInfo old_image_info = 10 [deprecated = true]; - - optional ImageInfo new_image_info = 11 [deprecated = true]; + // Fields deprecated in major version 2. + reserved 6,7,8,9,10,11; // The minor version, also referred as "delta version", of the payload. // Minor version 0 is full payload, everything else is delta payload. |