Do not skip copying in place block if source corrupted
In VAB(both plain and VABC), we will skip copying some blocks if the
source and target extents are exactly the same. However, if these source
blocks are corrupted then we would miss the oppoturnity to correct them
using FEC.
To address this issue, attempt to FEC correct the corrupted blocks and
write these blocks back to source partition.
Test: th
Bug: 276846805
Change-Id: Ic1e0276a310cff0be3695ef5f3a2c99437c29159
diff --git a/payload_consumer/partition_writer.cc b/payload_consumer/partition_writer.cc
index d7d8bea..2ec05f5 100644
--- a/payload_consumer/partition_writer.cc
+++ b/payload_consumer/partition_writer.cc
@@ -32,18 +32,14 @@
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
-#include "update_engine/common/terminator.h"
+#include "update_engine/common/error_code.h"
#include "update_engine/common/utils.h"
-#include "update_engine/payload_consumer/bzip_extent_writer.h"
#include "update_engine/payload_consumer/cached_file_descriptor.h"
-#include "update_engine/payload_consumer/extent_reader.h"
#include "update_engine/payload_consumer/extent_writer.h"
#include "update_engine/payload_consumer/file_descriptor_utils.h"
#include "update_engine/payload_consumer/install_operation_executor.h"
#include "update_engine/payload_consumer/install_plan.h"
#include "update_engine/payload_consumer/mount_history.h"
-#include "update_engine/payload_consumer/payload_constants.h"
-#include "update_engine/payload_consumer/xz_extent_writer.h"
#include "update_engine/payload_generator/extent_utils.h"
namespace chromeos_update_engine {
@@ -232,22 +228,23 @@
// decide it the operation should be skipped.
const PartitionUpdate& partition = partition_update_;
- InstallOperation buf;
- const bool should_optimize = dynamic_control_->OptimizeOperation(
- partition.partition_name(), operation, &buf);
- const InstallOperation& optimized = should_optimize ? buf : operation;
-
// Invoke ChooseSourceFD with original operation, so that it can properly
// verify source hashes. Optimized operation might contain a smaller set of
// extents, or completely empty.
auto source_fd = ChooseSourceFD(operation, error);
- if (source_fd == nullptr) {
- LOG(ERROR) << "Unrecoverable source hash mismatch found on partition "
- << partition.partition_name()
- << " extents: " << ExtentsToString(operation.src_extents());
+ if (*error != ErrorCode::kSuccess || source_fd == nullptr) {
+ LOG(WARNING) << "Source hash mismatch detected for extents "
+ << operation.src_extents() << " on partition "
+ << partition.partition_name() << " @ " << source_path_;
+
return false;
}
+ InstallOperation buf;
+ const bool should_optimize = dynamic_control_->OptimizeOperation(
+ partition.partition_name(), operation, &buf);
+ const InstallOperation& optimized = should_optimize ? buf : operation;
+
auto writer = CreateBaseExtentWriter();
return install_op_executor_.ExecuteSourceCopyOperation(
optimized, std::move(writer), source_fd);
@@ -340,8 +337,9 @@
// Log remount history if this device is an ext4 partition.
LogMountHistory(source_fd);
-
- *error = ErrorCode::kDownloadStateInitializationError;
+ if (error) {
+ *error = ErrorCode::kDownloadStateInitializationError;
+ }
return false;
}
return true;