diff options
author | Daniel Zheng <zhengdaniel@google.com> | 2024-02-29 05:20:48 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2024-02-29 05:20:48 +0000 |
commit | 4b7655d03d895592748c477d4da7b25603cff0dc (patch) | |
tree | 6e1e23963a7c799d78a1ec56aa13b636adc2abf8 | |
parent | f9ad892e9fca24c56f21152cb35c0f341f2c041d (diff) | |
parent | 5a6e32b3b8f52541ee3ccd96158ea0ebfe4338e8 (diff) | |
download | update_engine-4b7655d03d895592748c477d4da7b25603cff0dc.tar.gz |
update_engine: factor out source_copy method am: 5a6e32b3b8
Original change: https://android-review.googlesource.com/c/platform/system/update_engine/+/2976857
Change-Id: I10daddd806fa9437ed1d53feb9feea8f98a073b0
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | payload_consumer/vabc_partition_writer.cc | 140 | ||||
-rw-r--r-- | payload_consumer/vabc_partition_writer.h | 8 |
2 files changed, 86 insertions, 62 deletions
diff --git a/payload_consumer/vabc_partition_writer.cc b/payload_consumer/vabc_partition_writer.cc index 97de934f..c879375d 100644 --- a/payload_consumer/vabc_partition_writer.cc +++ b/payload_consumer/vabc_partition_writer.cc @@ -97,6 +97,78 @@ VABCPartitionWriter::VABCPartitionWriter( << copy_blocks_.blocks() << " copy blocks"; } +bool VABCPartitionWriter::ProcessSourceCopyOperation( + const InstallOperation& operation, + const size_t block_size, + const ExtentRanges& copy_blocks, + const FileDescriptorPtr& source_fd, + android::snapshot::ICowWriter* cow_writer, + bool sequence_op_supported) { + // COPY ops are already handled during Init(), no need to do actual work, but + // we still want to verify that all blocks contain expected data. + TEST_AND_RETURN_FALSE(source_fd != nullptr); + std::vector<CowOperation> converted; + + const auto& src_extents = operation.src_extents(); + const auto& dst_extents = operation.dst_extents(); + BlockIterator it1{src_extents}; + BlockIterator it2{dst_extents}; + const bool userSnapshots = android::base::GetBoolProperty( + "ro.virtual_ab.userspace.snapshots.enabled", false); + // For devices not supporting XOR, sequence op is not supported, so all COPY + // operations are written up front in strict merge order. + while (!it1.is_end() && !it2.is_end()) { + const auto src_block = *it1; + const auto dst_block = *it2; + ++it1; + ++it2; + if (src_block == dst_block) { + continue; + } + if (copy_blocks.ContainsBlock(dst_block)) { + if (sequence_op_supported) { + push_back(&converted, {CowOperation::CowCopy, src_block, dst_block, 1}); + } + } else { + push_back(&converted, + {CowOperation::CowReplace, src_block, dst_block, 1}); + } + } + std::vector<uint8_t> buffer; + for (const auto& cow_op : converted) { + if (cow_op.op == CowOperation::CowCopy) { + if (userSnapshots) { + cow_writer->AddCopy( + cow_op.dst_block, cow_op.src_block, cow_op.block_count); + } else { + // Add blocks in reverse order, because snapused specifically prefers + // this ordering. Since we already eliminated all self-overlapping + // SOURCE_COPY during delta generation, this should be safe to do. + for (size_t i = cow_op.block_count; i > 0; i--) { + TEST_AND_RETURN_FALSE(cow_writer->AddCopy(cow_op.dst_block + i - 1, + cow_op.src_block + i - 1)); + } + } + continue; + } + buffer.resize(block_size * cow_op.block_count); + ssize_t bytes_read = 0; + TEST_AND_RETURN_FALSE(utils::ReadAll(source_fd, + buffer.data(), + block_size * cow_op.block_count, + cow_op.src_block * block_size, + &bytes_read)); + if (bytes_read <= 0 || static_cast<size_t>(bytes_read) != buffer.size()) { + LOG(ERROR) << "source_fd->Read failed: " << bytes_read + << "\ncow op: " << cow_op.op; + return false; + } + TEST_AND_RETURN_FALSE(cow_writer->AddRawBlocks( + cow_op.dst_block, buffer.data(), buffer.size())); + } + return true; +} + bool VABCPartitionWriter::DoesDeviceSupportsXor() { return dynamic_control_->GetVirtualAbCompressionXorFeatureFlag().IsEnabled(); } @@ -272,70 +344,14 @@ std::unique_ptr<ExtentWriter> VABCPartitionWriter::CreateBaseExtentWriter() { [[nodiscard]] bool VABCPartitionWriter::PerformSourceCopyOperation( const InstallOperation& operation, ErrorCode* error) { - // COPY ops are already handled during Init(), no need to do actual work, but - // we still want to verify that all blocks contain expected data. auto source_fd = verified_source_fd_.ChooseSourceFD(operation, error); - TEST_AND_RETURN_FALSE(source_fd != nullptr); - std::vector<CowOperation> converted; - const auto& src_extents = operation.src_extents(); - const auto& dst_extents = operation.dst_extents(); - BlockIterator it1{src_extents}; - BlockIterator it2{dst_extents}; - const bool userSnapshots = android::base::GetBoolProperty( - "ro.virtual_ab.userspace.snapshots.enabled", false); - // For devices not supporting XOR, sequence op is not supported, so all COPY - // operations are written up front in strict merge order. - const auto sequence_op_supported = DoesDeviceSupportsXor(); - while (!it1.is_end() && !it2.is_end()) { - const auto src_block = *it1; - const auto dst_block = *it2; - ++it1; - ++it2; - if (src_block == dst_block) { - continue; - } - if (copy_blocks_.ContainsBlock(dst_block)) { - if (sequence_op_supported) { - push_back(&converted, {CowOperation::CowCopy, src_block, dst_block, 1}); - } - } else { - push_back(&converted, - {CowOperation::CowReplace, src_block, dst_block, 1}); - } - } - std::vector<uint8_t> buffer; - for (const auto& cow_op : converted) { - if (cow_op.op == CowOperation::CowCopy) { - if (userSnapshots) { - cow_writer_->AddCopy( - cow_op.dst_block, cow_op.src_block, cow_op.block_count); - } else { - // Add blocks in reverse order, because snapused specifically prefers - // this ordering. Since we already eliminated all self-overlapping - // SOURCE_COPY during delta generation, this should be safe to do. - for (size_t i = cow_op.block_count; i > 0; i--) { - TEST_AND_RETURN_FALSE(cow_writer_->AddCopy(cow_op.dst_block + i - 1, - cow_op.src_block + i - 1)); - } - } - continue; - } - buffer.resize(block_size_ * cow_op.block_count); - ssize_t bytes_read = 0; - TEST_AND_RETURN_FALSE(utils::ReadAll(source_fd, - buffer.data(), - block_size_ * cow_op.block_count, - cow_op.src_block * block_size_, - &bytes_read)); - if (bytes_read <= 0 || static_cast<size_t>(bytes_read) != buffer.size()) { - LOG(ERROR) << "source_fd->Read failed: " << bytes_read; - return false; - } - TEST_AND_RETURN_FALSE(cow_writer_->AddRawBlocks( - cow_op.dst_block, buffer.data(), buffer.size())); - } - return true; + return ProcessSourceCopyOperation(operation, + block_size_, + copy_blocks_, + source_fd, + cow_writer_.get(), + DoesDeviceSupportsXor()); } bool VABCPartitionWriter::PerformReplaceOperation(const InstallOperation& op, diff --git a/payload_consumer/vabc_partition_writer.h b/payload_consumer/vabc_partition_writer.h index 977fbe5d..bd3db79e 100644 --- a/payload_consumer/vabc_partition_writer.h +++ b/payload_consumer/vabc_partition_writer.h @@ -34,6 +34,14 @@ namespace chromeos_update_engine { class VABCPartitionWriter final : public PartitionWriterInterface { public: + static bool ProcessSourceCopyOperation( + const InstallOperation& operation, + const size_t block_size, + const ExtentRanges& copy_blocks, + const FileDescriptorPtr& source_fd, + android::snapshot::ICowWriter* cow_writer, + bool sequence_op_supported); + VABCPartitionWriter(const PartitionUpdate& partition_update, const InstallPlan::Partition& install_part, DynamicPartitionControlInterface* dynamic_control, |