DeltaPerformer uses ShouldSkipOperation()
Enable DeltaPerformer request DynamicPartitionControl if a SOURCE_COPY
operation can be skip.
A SOURCE_COPY operation can still fail if its hash does not correspond
to the partition's.
Bug: 141207436
Test: manual OTA application
Change-Id: Ib3d8c9343acb4d3655781150a4cca57985f20387
Signed-off-by: Alessio Balsini <balsini@google.com>
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index f9244a9..3d38c5b 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -1154,7 +1154,14 @@
TEST_AND_RETURN_FALSE(source_fd_ != nullptr);
+ // The device may optimize the SOURCE_COPY operation.
+ // Being this a device-specific optimization let DynamicPartitionController
+ // decide it the operation should be skipped.
+ const auto& partition_control = boot_control_->GetDynamicPartitionControl();
+ bool should_skip = partition_control->ShouldSkipOperation(operation);
+
if (operation.has_src_sha256_hash()) {
+ bool read_ok;
brillo::Blob source_hash;
brillo::Blob expected_source_hash(operation.src_sha256_hash().begin(),
operation.src_sha256_hash().end());
@@ -1163,12 +1170,17 @@
// device doesn't match or there was an error reading the source partition.
// Note that this code will also fall back if writing the target partition
// fails.
- bool read_ok = fd_utils::CopyAndHashExtents(source_fd_,
- operation.src_extents(),
- target_fd_,
- operation.dst_extents(),
- block_size_,
- &source_hash);
+ if (should_skip) {
+ read_ok = fd_utils::ReadAndHashExtents(
+ source_fd_, operation.src_extents(), block_size_, &source_hash);
+ } else {
+ read_ok = fd_utils::CopyAndHashExtents(source_fd_,
+ operation.src_extents(),
+ target_fd_,
+ operation.dst_extents(),
+ block_size_,
+ &source_hash);
+ }
if (read_ok && expected_source_hash == source_hash)
return true;
@@ -1185,12 +1197,18 @@
<< base::HexEncode(expected_source_hash.data(),
expected_source_hash.size());
- TEST_AND_RETURN_FALSE(fd_utils::CopyAndHashExtents(source_ecc_fd_,
- operation.src_extents(),
- target_fd_,
- operation.dst_extents(),
- block_size_,
- &source_hash));
+ if (should_skip) {
+ TEST_AND_RETURN_FALSE(fd_utils::ReadAndHashExtents(
+ source_ecc_fd_, operation.src_extents(), block_size_, &source_hash));
+ } else {
+ TEST_AND_RETURN_FALSE(
+ fd_utils::CopyAndHashExtents(source_ecc_fd_,
+ operation.src_extents(),
+ target_fd_,
+ operation.dst_extents(),
+ block_size_,
+ &source_hash));
+ }
TEST_AND_RETURN_FALSE(
ValidateSourceHash(source_hash, operation, source_ecc_fd_, error));
// At this point reading from the the error corrected device worked, but
@@ -1202,6 +1220,10 @@
// corrected device first since we can't verify the block in the raw device
// at this point, but we fall back to the raw device since the error
// corrected device can be shorter or not available.
+
+ if (should_skip)
+ return true;
+
if (OpenCurrentECCPartition() &&
fd_utils::CopyAndHashExtents(source_ecc_fd_,
operation.src_extents(),