| 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 | 
|---|