| Index: delta_performer.cc
|
| diff --git a/delta_performer.cc b/delta_performer.cc
|
| index 10031eb8f8d5225ee4719d6a3ad648cf275676d6..0eccb09782b7d93db1acaa19743536eff80f0030 100644
|
| --- a/delta_performer.cc
|
| +++ b/delta_performer.cc
|
| @@ -198,7 +198,10 @@ ssize_t DeltaPerformer::Write(const void* bytes, size_t count) {
|
| manifest_metadata_size_))
|
| << "Unable to save the manifest metadata size.";
|
| manifest_valid_ = true;
|
| - block_size_ = manifest_.block_size();
|
| + if (!PrimeUpdateState()) {
|
| + LOG(ERROR) << "Unable to prime the update state.";
|
| + return -EINVAL;
|
| + }
|
| }
|
| ssize_t total_operations = manifest_.install_operations_size() +
|
| manifest_.kernel_install_operations_size();
|
| @@ -225,7 +228,7 @@ ssize_t DeltaPerformer::Write(const void* bytes, size_t count) {
|
| // update.
|
| if (!IsIdempotentOperation(op)) {
|
| Terminator::set_exit_blocked(true);
|
| - ResetUpdateProgress(prefs_);
|
| + ResetUpdateProgress(prefs_, true);
|
| }
|
| if (op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE ||
|
| op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ) {
|
| @@ -281,8 +284,8 @@ bool DeltaPerformer::PerformReplaceOperation(
|
|
|
| // 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.
|
| - CHECK_EQ(buffer_offset_, operation.data_offset());
|
| - CHECK_GE(buffer_.size(), operation.data_length());
|
| + TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
|
| + TEST_AND_RETURN_FALSE(buffer_.size() >= operation.data_length());
|
|
|
| // Extract the signature message if it's in this operation.
|
| ExtractSignatureMessage(operation);
|
| @@ -405,8 +408,8 @@ bool DeltaPerformer::PerformBsdiffOperation(
|
| bool is_kernel_partition) {
|
| // 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.
|
| - CHECK_EQ(buffer_offset_, operation.data_offset());
|
| - CHECK_GE(buffer_.size(), operation.data_length());
|
| + TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
|
| + TEST_AND_RETURN_FALSE(buffer_.size() >= operation.data_length());
|
|
|
| string input_positions;
|
| TEST_AND_RETURN_FALSE(ExtentsToBsdiffPositionsString(operation.src_extents(),
|
| @@ -571,9 +574,16 @@ bool DeltaPerformer::CanResumeUpdate(PrefsInterface* prefs,
|
| return true;
|
| }
|
|
|
| -bool DeltaPerformer::ResetUpdateProgress(PrefsInterface* prefs) {
|
| +bool DeltaPerformer::ResetUpdateProgress(PrefsInterface* prefs, bool quick) {
|
| TEST_AND_RETURN_FALSE(prefs->SetInt64(kPrefsUpdateStateNextOperation,
|
| kUpdateStateOperationInvalid));
|
| + if (!quick) {
|
| + prefs->SetString(kPrefsUpdateCheckResponseHash, "");
|
| + prefs->SetInt64(kPrefsUpdateStateNextDataOffset, -1);
|
| + prefs->SetString(kPrefsUpdateStateSHA256Context, "");
|
| + prefs->SetString(kPrefsUpdateStateSignedSHA256Context, "");
|
| + prefs->SetInt64(kPrefsManifestMetadataSize, -1);
|
| + }
|
| return true;
|
| }
|
|
|
| @@ -581,7 +591,7 @@ bool DeltaPerformer::CheckpointUpdateProgress() {
|
| Terminator::set_exit_blocked(true);
|
| if (last_updated_buffer_offset_ != buffer_offset_) {
|
| // Resets the progress in case we die in the middle of the state update.
|
| - ResetUpdateProgress(prefs_);
|
| + ResetUpdateProgress(prefs_, true);
|
| TEST_AND_RETURN_FALSE(
|
| prefs_->SetString(kPrefsUpdateStateSHA256Context,
|
| hash_calculator_.GetContext()));
|
| @@ -594,4 +604,43 @@ bool DeltaPerformer::CheckpointUpdateProgress() {
|
| return true;
|
| }
|
|
|
| +bool DeltaPerformer::PrimeUpdateState() {
|
| + CHECK(manifest_valid_);
|
| + block_size_ = manifest_.block_size();
|
| +
|
| + int64_t next_operation = kUpdateStateOperationInvalid;
|
| + if (!prefs_->GetInt64(kPrefsUpdateStateNextOperation, &next_operation) ||
|
| + next_operation == kUpdateStateOperationInvalid ||
|
| + next_operation <= 0) {
|
| + // Initiating a new update, no more state needs to be initialized.
|
| + return true;
|
| + }
|
| + next_operation_num_ = next_operation;
|
| +
|
| + // Resuming an update -- load the rest of the update state.
|
| + int64_t next_data_offset = -1;
|
| + TEST_AND_RETURN_FALSE(prefs_->GetInt64(kPrefsUpdateStateNextDataOffset,
|
| + &next_data_offset) &&
|
| + next_data_offset >= 0);
|
| + buffer_offset_ = next_data_offset;
|
| +
|
| + // The signed hash context may be empty if the interrupted update didn't reach
|
| + // the signature blob.
|
| + prefs_->GetString(kPrefsUpdateStateSignedSHA256Context,
|
| + &signed_hash_context_);
|
| +
|
| + string hash_context;
|
| + TEST_AND_RETURN_FALSE(prefs_->GetString(kPrefsUpdateStateSHA256Context,
|
| + &hash_context) &&
|
| + hash_calculator_.SetContext(hash_context));
|
| +
|
| + int64_t manifest_metadata_size = 0;
|
| + TEST_AND_RETURN_FALSE(prefs_->GetInt64(kPrefsManifestMetadataSize,
|
| + &manifest_metadata_size) &&
|
| + manifest_metadata_size > 0);
|
| + manifest_metadata_size_ = manifest_metadata_size;
|
| +
|
| + return true;
|
| +}
|
| +
|
| } // namespace chromeos_update_engine
|
|
|