Merge changes from topic 'nyc-mr1-ue_sideload_recovery' into nyc-mr1-dev
* changes:
Setup a temporary directory for update_engine_sideload.
DO NOT MERGE: Make update_engine compile in the branch.
New setting to mark postinstall as optional.
Report the progress of the update when sideloading.
Compile update_engine_sideload as a static recovery program.
Remove libcurl support from update_engine_sideload.
Build update_engine_sideload.
Implement a memory-based Prefs class.
Remove unused libbrillo-http dependency.
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index ae59034..a156132 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -28,6 +28,7 @@
#include <base/files/file_util.h>
#include <base/format_macros.h>
+#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/data_encoding.h>
@@ -277,9 +278,15 @@
if (op_result)
return true;
+ size_t partition_first_op_num =
+ current_partition_ ? acc_num_operations_[current_partition_ - 1] : 0;
LOG(ERROR) << "Failed to perform " << op_type_name << " operation "
- << next_operation_num_;
- *error = ErrorCode::kDownloadOperationExecutionError;
+ << next_operation_num_ << ", which is the operation "
+ << next_operation_num_ - partition_first_op_num
+ << " in partition \""
+ << partitions_[current_partition_].partition_name() << "\"";
+ if (*error == ErrorCode::kSuccess)
+ *error = ErrorCode::kDownloadOperationExecutionError;
return false;
}
@@ -714,10 +721,10 @@
op_result = PerformBsdiffOperation(op);
break;
case InstallOperation::SOURCE_COPY:
- op_result = PerformSourceCopyOperation(op);
+ op_result = PerformSourceCopyOperation(op, error);
break;
case InstallOperation::SOURCE_BSDIFF:
- op_result = PerformSourceBsdiffOperation(op);
+ op_result = PerformSourceBsdiffOperation(op, error);
break;
default:
op_result = false;
@@ -1043,16 +1050,34 @@
}
// Compare |calculated_hash| with source hash in |operation|, return false and
-// dump hash if don't match.
+// dump hash and set |error| if don't match.
bool ValidateSourceHash(const brillo::Blob& calculated_hash,
- const InstallOperation& operation) {
+ const InstallOperation& operation,
+ ErrorCode* error) {
brillo::Blob expected_source_hash(operation.src_sha256_hash().begin(),
operation.src_sha256_hash().end());
if (calculated_hash != expected_source_hash) {
- LOG(ERROR) << "Hash verification failed. Expected hash = ";
- utils::HexDumpVector(expected_source_hash);
- LOG(ERROR) << "Calculated hash = ";
- utils::HexDumpVector(calculated_hash);
+ LOG(ERROR) << "The hash of the source data on disk for this operation "
+ << "doesn't match the expected value. This could mean that the "
+ << "delta update payload was targeted for another version, or "
+ << "that the source partition was modified after it was "
+ << "installed, for example, by mounting a filesystem.";
+ LOG(ERROR) << "Expected: sha256|hex = "
+ << base::HexEncode(expected_source_hash.data(),
+ expected_source_hash.size());
+ LOG(ERROR) << "Calculated: sha256|hex = "
+ << base::HexEncode(calculated_hash.data(),
+ calculated_hash.size());
+
+ vector<string> source_extents;
+ for (const Extent& ext : operation.src_extents()) {
+ source_extents.push_back(base::StringPrintf(
+ "%" PRIu64 ":%" PRIu64, ext.start_block(), ext.num_blocks()));
+ }
+ LOG(ERROR) << "Operation source (offset:size) in blocks: "
+ << base::JoinString(source_extents, ",");
+
+ *error = ErrorCode::kDownloadStateInitializationError;
return false;
}
return true;
@@ -1061,7 +1086,7 @@
} // namespace
bool DeltaPerformer::PerformSourceCopyOperation(
- const InstallOperation& operation) {
+ const InstallOperation& operation, ErrorCode* error) {
if (operation.has_src_length())
TEST_AND_RETURN_FALSE(operation.src_length() % block_size_ == 0);
if (operation.has_dst_length())
@@ -1114,7 +1139,7 @@
if (operation.has_src_sha256_hash()) {
TEST_AND_RETURN_FALSE(source_hasher.Finalize());
TEST_AND_RETURN_FALSE(
- ValidateSourceHash(source_hasher.raw_hash(), operation));
+ ValidateSourceHash(source_hasher.raw_hash(), operation, error));
}
DCHECK_EQ(bytes_read, static_cast<ssize_t>(blocks_to_read * block_size_));
@@ -1202,7 +1227,7 @@
}
bool DeltaPerformer::PerformSourceBsdiffOperation(
- const InstallOperation& operation) {
+ const InstallOperation& operation, ErrorCode* error) {
// Since we delete data off the beginning of the buffer as we use it,
// the data we need should be exactly at the beginning of the buffer.
TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
@@ -1232,7 +1257,7 @@
}
TEST_AND_RETURN_FALSE(source_hasher.Finalize());
TEST_AND_RETURN_FALSE(
- ValidateSourceHash(source_hasher.raw_hash(), operation));
+ ValidateSourceHash(source_hasher.raw_hash(), operation, error));
}
string input_positions;
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index 0a60020..fdfcb5b 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -250,12 +250,16 @@
bool PerformInstallOperation(const InstallOperation& operation);
// These perform a specific type of operation and return true on success.
+ // |error| will be set if source hash mismatch, otherwise |error| might not be
+ // set even if it fails.
bool PerformReplaceOperation(const InstallOperation& operation);
bool PerformZeroOrDiscardOperation(const InstallOperation& operation);
bool PerformMoveOperation(const InstallOperation& operation);
bool PerformBsdiffOperation(const InstallOperation& operation);
- bool PerformSourceCopyOperation(const InstallOperation& operation);
- bool PerformSourceBsdiffOperation(const InstallOperation& operation);
+ bool PerformSourceCopyOperation(const InstallOperation& operation,
+ ErrorCode* error);
+ bool PerformSourceBsdiffOperation(const InstallOperation& operation,
+ ErrorCode* error);
// Extracts the payload signature message from the blob on the |operation| if
// the offset matches the one specified by the manifest. Returns whether the