OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "update_engine/delta_performer.h" | 5 #include "update_engine/delta_performer.h" |
6 | 6 |
7 #include <endian.h> | 7 #include <endian.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <cstring> | 11 #include <cstring> |
12 #include <string> | 12 #include <string> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include <base/scoped_ptr.h> | 15 #include <base/scoped_ptr.h> |
16 #include <base/string_util.h> | 16 #include <base/string_util.h> |
17 #include <google/protobuf/repeated_field.h> | 17 #include <google/protobuf/repeated_field.h> |
18 | 18 |
19 #include "update_engine/bzip_extent_writer.h" | 19 #include "update_engine/bzip_extent_writer.h" |
20 #include "update_engine/delta_diff_generator.h" | 20 #include "update_engine/delta_diff_generator.h" |
| 21 #include "update_engine/extent_ranges.h" |
21 #include "update_engine/extent_writer.h" | 22 #include "update_engine/extent_writer.h" |
22 #include "update_engine/graph_types.h" | 23 #include "update_engine/graph_types.h" |
23 #include "update_engine/payload_signer.h" | 24 #include "update_engine/payload_signer.h" |
24 #include "update_engine/prefs_interface.h" | 25 #include "update_engine/prefs_interface.h" |
25 #include "update_engine/subprocess.h" | 26 #include "update_engine/subprocess.h" |
26 #include "update_engine/terminator.h" | 27 #include "update_engine/terminator.h" |
27 | 28 |
28 using std::min; | 29 using std::min; |
29 using std::string; | 30 using std::string; |
30 using std::vector; | 31 using std::vector; |
31 using google::protobuf::RepeatedPtrField; | 32 using google::protobuf::RepeatedPtrField; |
32 | 33 |
33 namespace chromeos_update_engine { | 34 namespace chromeos_update_engine { |
34 | 35 |
35 namespace { | 36 namespace { |
36 | 37 |
37 const int kDeltaVersionLength = 8; | 38 const int kDeltaVersionLength = 8; |
38 const int kDeltaProtobufLengthLength = 8; | 39 const int kDeltaProtobufLengthLength = 8; |
39 const char kUpdatePayloadPublicKeyPath[] = | 40 const char kUpdatePayloadPublicKeyPath[] = |
40 "/usr/share/update_engine/update-payload-key.pub.pem"; | 41 "/usr/share/update_engine/update-payload-key.pub.pem"; |
41 const int kUpdateStateOperationInvalid = -1; | 42 const int kUpdateStateOperationInvalid = -1; |
42 | 43 |
43 // Returns true if |op| is idempotent -- i.e., if we can interrupt it and repeat | |
44 // it safely. Returns false otherwise. | |
45 bool IsIdempotentOperation(const DeltaArchiveManifest_InstallOperation& op) { | |
46 if (op.src_extents_size() == 0) { | |
47 return true; | |
48 } | |
49 // TODO(petkov): Cover the case where the source and target extents don't | |
50 // intersect. | |
51 return false; | |
52 } | |
53 | |
54 // Converts extents to a human-readable string, for use by DumpUpdateProto(). | 44 // Converts extents to a human-readable string, for use by DumpUpdateProto(). |
55 string ExtentsToString(const RepeatedPtrField<Extent>& extents) { | 45 string ExtentsToString(const RepeatedPtrField<Extent>& extents) { |
56 string ret; | 46 string ret; |
57 for (int i = 0; i < extents.size(); i++) { | 47 for (int i = 0; i < extents.size(); i++) { |
58 const Extent& extent = extents.Get(i); | 48 const Extent& extent = extents.Get(i); |
59 if (extent.start_block() == kSparseHole) { | 49 if (extent.start_block() == kSparseHole) { |
60 ret += StringPrintf("{kSparseHole, %" PRIu64 "}, ", extent.num_blocks()); | 50 ret += StringPrintf("{kSparseHole, %" PRIu64 "}, ", extent.num_blocks()); |
61 } else { | 51 } else { |
62 ret += StringPrintf("{%" PRIu64 ", %" PRIu64 "}, ", | 52 ret += StringPrintf("{%" PRIu64 ", %" PRIu64 "}, ", |
63 extent.start_block(), extent.num_blocks()); | 53 extent.start_block(), extent.num_blocks()); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 *err = errno; | 104 *err = errno; |
115 PLOG(ERROR) << "Unable to open file " << path; | 105 PLOG(ERROR) << "Unable to open file " << path; |
116 return false; | 106 return false; |
117 } | 107 } |
118 *err = 0; | 108 *err = 0; |
119 return true; | 109 return true; |
120 } | 110 } |
121 | 111 |
122 } // namespace {} | 112 } // namespace {} |
123 | 113 |
| 114 // Returns true if |op| is idempotent -- i.e., if we can interrupt it and repeat |
| 115 // it safely. Returns false otherwise. |
| 116 bool DeltaPerformer::IsIdempotentOperation( |
| 117 const DeltaArchiveManifest_InstallOperation& op) { |
| 118 if (op.src_extents_size() == 0) { |
| 119 return true; |
| 120 } |
| 121 // TODO(adlr): detect other types of idempotent operations. For example, |
| 122 // a MOVE may move a block onto itself. |
| 123 |
| 124 // When in doubt, it's safe to declare an op non-idempotent. |
| 125 ExtentRanges src_ranges; |
| 126 src_ranges.AddRepeatedExtents(op.src_extents()); |
| 127 const uint64_t block_count = src_ranges.blocks(); |
| 128 src_ranges.SubtractRepeatedExtents(op.dst_extents()); |
| 129 return block_count == src_ranges.blocks(); |
| 130 } |
| 131 |
124 int DeltaPerformer::Open(const char* path, int flags, mode_t mode) { | 132 int DeltaPerformer::Open(const char* path, int flags, mode_t mode) { |
125 int err; | 133 int err; |
126 if (OpenFile(path, &fd_, &err)) | 134 if (OpenFile(path, &fd_, &err)) |
127 path_ = path; | 135 path_ = path; |
128 return -err; | 136 return -err; |
129 } | 137 } |
130 | 138 |
131 bool DeltaPerformer::OpenKernel(const char* kernel_path) { | 139 bool DeltaPerformer::OpenKernel(const char* kernel_path) { |
132 int err; | 140 int err; |
133 bool success = OpenFile(kernel_path, &kernel_fd_, &err); | 141 bool success = OpenFile(kernel_path, &kernel_fd_, &err); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextDataOffset, | 596 TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextDataOffset, |
589 buffer_offset_)); | 597 buffer_offset_)); |
590 last_updated_buffer_offset_ = buffer_offset_; | 598 last_updated_buffer_offset_ = buffer_offset_; |
591 } | 599 } |
592 TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextOperation, | 600 TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextOperation, |
593 next_operation_num_)); | 601 next_operation_num_)); |
594 return true; | 602 return true; |
595 } | 603 } |
596 | 604 |
597 } // namespace chromeos_update_engine | 605 } // namespace chromeos_update_engine |
OLD | NEW |