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

Unified Diff: delta_performer.cc

Issue 3521016: AU: Start checkpointing update progress. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/update_engine.git
Patch Set: address review comments 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 2436797210fa895738ee43d28d8f9fd7d4180c25..6143ec5ae6556f405144ef91a135fc9fb9a6a47c 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -21,6 +21,7 @@
#include "update_engine/extent_writer.h"
#include "update_engine/graph_types.h"
#include "update_engine/payload_signer.h"
+#include "update_engine/prefs_interface.h"
#include "update_engine/subprocess.h"
using std::min;
@@ -36,6 +37,18 @@ const int kDeltaVersionLength = 8;
const int kDeltaProtobufLengthLength = 8;
const char kUpdatePayloadPublicKeyPath[] =
"/usr/share/update_engine/update-payload-key.pub.pem";
+const int kUpdateStateOperationInvalid = -1;
+
+// Returns true if |op| is idempotent -- i.e., if we can interrupt it and repeat
+// it safely. Returns false otherwise.
+bool IsIdempotentOperation(const DeltaArchiveManifest_InstallOperation& op) {
+ if (op.src_extents_size() == 0) {
+ return true;
+ }
+ // TODO(petkov): Cover the case where the source and target extents don't
+ // intersect.
+ return false;
+}
// Converts extents to a human-readable string, for use by DumpUpdateProto().
string ExtentsToString(const RepeatedPtrField<Extent>& extents) {
@@ -177,10 +190,13 @@ ssize_t DeltaPerformer::Write(const void* bytes, size_t count) {
}
// Remove protobuf and header info from buffer_, so buffer_ contains
// just data blobs
- DiscardBufferHeadBytes(strlen(kDeltaMagic) +
- kDeltaVersionLength +
- kDeltaProtobufLengthLength + protobuf_length,
+ size_t metadata_size = strlen(kDeltaMagic) + kDeltaVersionLength +
+ kDeltaProtobufLengthLength + protobuf_length;
+ DiscardBufferHeadBytes(metadata_size,
true); // do_hash
+ LOG_IF(WARNING, !prefs_->SetInt64(kPrefsManifestMetadataSize,
+ metadata_size))
+ << "Unable to save the manifest metadata size.";
manifest_valid_ = true;
block_size_ = manifest_.block_size();
}
@@ -202,6 +218,12 @@ ssize_t DeltaPerformer::Write(const void* bytes, size_t count) {
}
bool is_kernel_partition =
(next_operation_num_ >= manifest_.install_operations_size());
+ // If about to start a non-idempotent operation, clear the update state so
+ // that if the operation gets interrupted, we don't try to resume the
+ // update.
+ if (!IsIdempotentOperation(op)) {
+ ResetUpdateProgress();
+ }
if (op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE ||
op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ) {
if (!PerformReplaceOperation(op, is_kernel_partition)) {
@@ -223,6 +245,7 @@ ssize_t DeltaPerformer::Write(const void* bytes, size_t count) {
}
}
next_operation_num_++;
+ CheckpointUpdateProgress();
}
return count;
}
@@ -489,4 +512,22 @@ void DeltaPerformer::DiscardBufferHeadBytes(size_t count, bool do_hash) {
buffer_.erase(buffer_.begin(), buffer_.begin() + count);
}
+bool DeltaPerformer::ResetUpdateProgress() {
+ TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextOperation,
+ kUpdateStateOperationInvalid));
+ return true;
+}
+
+bool DeltaPerformer::CheckpointUpdateProgress() {
+ // First reset the progress in case we die in the middle of the state update.
+ ResetUpdateProgress();
+ TEST_AND_RETURN_FALSE(prefs_->SetString(kPrefsUpdateStateSignedSHA256Context,
+ hash_calculator_.GetContext()));
+ TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextDataOffset,
+ buffer_offset_));
+ TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextOperation,
+ next_operation_num_));
+ 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