Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Unified Diff: delta_performer.cc

Issue 3620013: AU: Resume interrupted update attempts. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/update_engine.git
Patch Set: fix setup download Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « delta_performer.h ('k') | delta_performer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « delta_performer.h ('k') | delta_performer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698