| 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_diff_generator.h" | 5 #include "update_engine/delta_diff_generator.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <inttypes.h> | 9 #include <inttypes.h> |
| 10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 #include "update_engine/bzip.h" | 24 #include "update_engine/bzip.h" |
| 25 #include "update_engine/cycle_breaker.h" | 25 #include "update_engine/cycle_breaker.h" |
| 26 #include "update_engine/extent_mapper.h" | 26 #include "update_engine/extent_mapper.h" |
| 27 #include "update_engine/extent_ranges.h" | 27 #include "update_engine/extent_ranges.h" |
| 28 #include "update_engine/file_writer.h" | 28 #include "update_engine/file_writer.h" |
| 29 #include "update_engine/filesystem_iterator.h" | 29 #include "update_engine/filesystem_iterator.h" |
| 30 #include "update_engine/full_update_generator.h" | 30 #include "update_engine/full_update_generator.h" |
| 31 #include "update_engine/graph_types.h" | 31 #include "update_engine/graph_types.h" |
| 32 #include "update_engine/graph_utils.h" | 32 #include "update_engine/graph_utils.h" |
| 33 #include "update_engine/metadata.h" |
| 33 #include "update_engine/omaha_hash_calculator.h" | 34 #include "update_engine/omaha_hash_calculator.h" |
| 34 #include "update_engine/payload_signer.h" | 35 #include "update_engine/payload_signer.h" |
| 35 #include "update_engine/subprocess.h" | 36 #include "update_engine/subprocess.h" |
| 36 #include "update_engine/topological_sort.h" | 37 #include "update_engine/topological_sort.h" |
| 37 #include "update_engine/update_metadata.pb.h" | 38 #include "update_engine/update_metadata.pb.h" |
| 38 #include "update_engine/utils.h" | 39 #include "update_engine/utils.h" |
| 39 | 40 |
| 40 using std::make_pair; | 41 using std::make_pair; |
| 41 using std::map; | 42 using std::map; |
| 42 using std::max; | 43 using std::max; |
| 43 using std::min; | 44 using std::min; |
| 44 using std::pair; | 45 using std::pair; |
| 45 using std::set; | 46 using std::set; |
| 46 using std::string; | 47 using std::string; |
| 47 using std::vector; | 48 using std::vector; |
| 48 | 49 |
| 49 namespace chromeos_update_engine { | 50 namespace chromeos_update_engine { |
| 50 | 51 |
| 51 typedef DeltaDiffGenerator::Block Block; | 52 typedef DeltaDiffGenerator::Block Block; |
| 52 typedef map<const DeltaArchiveManifest_InstallOperation*, | 53 typedef map<const DeltaArchiveManifest_InstallOperation*, |
| 53 const string*> OperationNameMap; | 54 const string*> OperationNameMap; |
| 54 | 55 |
| 55 namespace { | |
| 56 const size_t kBlockSize = 4096; // bytes | |
| 57 | |
| 58 // TODO(adlr): switch from 1GiB to 2GiB when we no longer care about old | |
| 59 // clients: | |
| 60 const size_t kRootFSPartitionSize = 1 * 1024 * 1024 * 1024; // bytes | |
| 61 const uint64_t kVersionNumber = 1; | |
| 62 const uint64_t kFullUpdateChunkSize = 1024 * 1024; // bytes | |
| 63 | |
| 64 static const char* kInstallOperationTypes[] = { | |
| 65 "REPLACE", | |
| 66 "REPLACE_BZ", | |
| 67 "MOVE", | |
| 68 "BSDIFF" | |
| 69 }; | |
| 70 | |
| 71 // Stores all Extents for a file into 'out'. Returns true on success. | |
| 72 bool GatherExtents(const string& path, | |
| 73 google::protobuf::RepeatedPtrField<Extent>* out) { | |
| 74 vector<Extent> extents; | |
| 75 TEST_AND_RETURN_FALSE(extent_mapper::ExtentsForFileFibmap(path, &extents)); | |
| 76 DeltaDiffGenerator::StoreExtents(extents, out); | |
| 77 return true; | |
| 78 } | |
| 79 | |
| 80 // Runs the bsdiff tool on two files and returns the resulting delta in | 56 // Runs the bsdiff tool on two files and returns the resulting delta in |
| 81 // 'out'. Returns true on success. | 57 // 'out'. Returns true on success. |
| 82 bool BsdiffFiles(const string& old_file, | 58 bool BsdiffFiles(const string& old_file, |
| 83 const string& new_file, | 59 const string& new_file, |
| 84 vector<char>* out) { | 60 vector<char>* out) { |
| 85 const string kPatchFile = "/tmp/delta.patchXXXXXX"; | 61 const string kPatchFile = "/tmp/delta.patchXXXXXX"; |
| 86 string patch_file_path; | 62 string patch_file_path; |
| 87 | 63 |
| 88 TEST_AND_RETURN_FALSE( | 64 TEST_AND_RETURN_FALSE( |
| 89 utils::MakeTempFile(kPatchFile, &patch_file_path, NULL)); | 65 utils::MakeTempFile(kPatchFile, &patch_file_path, NULL)); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 << ") and also " << vertex << "(" | 121 << ") and also " << vertex << "(" |
| 146 << graph[vertex].file_name << ")"; | 122 << graph[vertex].file_name << ")"; |
| 147 } | 123 } |
| 148 (*blocks)[block].*access_type = vertex; | 124 (*blocks)[block].*access_type = vertex; |
| 149 } | 125 } |
| 150 } | 126 } |
| 151 } | 127 } |
| 152 return true; | 128 return true; |
| 153 } | 129 } |
| 154 | 130 |
| 131 namespace { |
| 132 const size_t kBlockSize = 4096; // bytes |
| 133 |
| 134 // TODO(adlr): switch from 1GiB to 2GiB when we no longer care about old |
| 135 // clients: |
| 136 const size_t kRootFSPartitionSize = 1 * 1024 * 1024 * 1024; // bytes |
| 137 const uint64_t kVersionNumber = 1; |
| 138 const uint64_t kFullUpdateChunkSize = 1024 * 1024; // bytes |
| 139 |
| 140 static const char* kInstallOperationTypes[] = { |
| 141 "REPLACE", |
| 142 "REPLACE_BZ", |
| 143 "MOVE", |
| 144 "BSDIFF" |
| 145 }; |
| 146 |
| 147 // Stores all Extents for a file into 'out'. Returns true on success. |
| 148 bool GatherExtents(const string& path, |
| 149 google::protobuf::RepeatedPtrField<Extent>* out) { |
| 150 vector<Extent> extents; |
| 151 TEST_AND_RETURN_FALSE(extent_mapper::ExtentsForFileFibmap(path, &extents)); |
| 152 DeltaDiffGenerator::StoreExtents(extents, out); |
| 153 return true; |
| 154 } |
| 155 |
| 155 // For a given regular file which must exist at new_root + path, and | 156 // For a given regular file which must exist at new_root + path, and |
| 156 // may exist at old_root + path, creates a new InstallOperation and | 157 // may exist at old_root + path, creates a new InstallOperation and |
| 157 // adds it to the graph. Also, populates the |blocks| array as | 158 // adds it to the graph. Also, populates the |blocks| array as |
| 158 // necessary, if |blocks| is non-NULL. Also, writes the data | 159 // necessary, if |blocks| is non-NULL. Also, writes the data |
| 159 // necessary to send the file down to the client into data_fd, which | 160 // necessary to send the file down to the client into data_fd, which |
| 160 // has length *data_file_size. *data_file_size is updated | 161 // has length *data_file_size. *data_file_size is updated |
| 161 // appropriately. If |existing_vertex| is no kInvalidIndex, use that | 162 // appropriately. If |existing_vertex| is no kInvalidIndex, use that |
| 162 // rather than allocating a new vertex. Returns true on success. | 163 // rather than allocating a new vertex. Returns true on success. |
| 163 bool DeltaReadFile(Graph* graph, | 164 bool DeltaReadFile(Graph* graph, |
| 164 Vertex::Index existing_vertex, | 165 Vertex::Index existing_vertex, |
| (...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 | 1384 |
| 1384 TEST_AND_RETURN_FALSE(DeltaReadFiles(&graph, | 1385 TEST_AND_RETURN_FALSE(DeltaReadFiles(&graph, |
| 1385 &blocks, | 1386 &blocks, |
| 1386 old_root, | 1387 old_root, |
| 1387 new_root, | 1388 new_root, |
| 1388 fd, | 1389 fd, |
| 1389 &data_file_size)); | 1390 &data_file_size)); |
| 1390 LOG(INFO) << "done reading normal files"; | 1391 LOG(INFO) << "done reading normal files"; |
| 1391 CheckGraph(graph); | 1392 CheckGraph(graph); |
| 1392 | 1393 |
| 1394 LOG(INFO) << "Starting metadata processing"; |
| 1395 TEST_AND_RETURN_FALSE(DeltaReadMetadata(&graph, |
| 1396 &blocks, |
| 1397 old_image, |
| 1398 new_image, |
| 1399 fd, |
| 1400 &data_file_size)); |
| 1401 LOG(INFO) << "Done metadata processing"; |
| 1402 CheckGraph(graph); |
| 1403 |
| 1393 graph.resize(graph.size() + 1); | 1404 graph.resize(graph.size() + 1); |
| 1394 TEST_AND_RETURN_FALSE(ReadUnwrittenBlocks(blocks, | 1405 TEST_AND_RETURN_FALSE(ReadUnwrittenBlocks(blocks, |
| 1395 fd, | 1406 fd, |
| 1396 &data_file_size, | 1407 &data_file_size, |
| 1397 new_image, | 1408 new_image, |
| 1398 &graph.back())); | 1409 &graph.back())); |
| 1399 | 1410 |
| 1400 // Final scratch block (if there's space) | 1411 // Final scratch block (if there's space) |
| 1401 if (blocks.size() < (kRootFSPartitionSize / kBlockSize)) { | 1412 if (blocks.size() < (kRootFSPartitionSize / kBlockSize)) { |
| 1402 scratch_vertex = graph.size(); | 1413 scratch_vertex = graph.size(); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1583 | 1594 |
| 1584 LOG(INFO) << "All done. Successfully created delta file."; | 1595 LOG(INFO) << "All done. Successfully created delta file."; |
| 1585 return true; | 1596 return true; |
| 1586 } | 1597 } |
| 1587 | 1598 |
| 1588 const char* const kBsdiffPath = "bsdiff"; | 1599 const char* const kBsdiffPath = "bsdiff"; |
| 1589 const char* const kBspatchPath = "bspatch"; | 1600 const char* const kBspatchPath = "bspatch"; |
| 1590 const char* const kDeltaMagic = "CrAU"; | 1601 const char* const kDeltaMagic = "CrAU"; |
| 1591 | 1602 |
| 1592 }; // namespace chromeos_update_engine | 1603 }; // namespace chromeos_update_engine |
| OLD | NEW |