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 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 TEST_AND_RETURN_FALSE( | 584 TEST_AND_RETURN_FALSE( |
585 GatherExtents(new_filename, operation.mutable_dst_extents())); | 585 GatherExtents(new_filename, operation.mutable_dst_extents())); |
586 operation.set_dst_length(new_data.size()); | 586 operation.set_dst_length(new_data.size()); |
587 | 587 |
588 out_data->swap(data); | 588 out_data->swap(data); |
589 *out_op = operation; | 589 *out_op = operation; |
590 | 590 |
591 return true; | 591 return true; |
592 } | 592 } |
593 | 593 |
594 bool InitializePartitionInfo(const string& partition, PartitionInfo* info) { | 594 bool InitializePartitionInfo(bool is_kernel, |
595 const off_t size = utils::FileSize(partition); | 595 const string& partition, |
596 TEST_AND_RETURN_FALSE(size >= 0); | 596 PartitionInfo* info) { |
| 597 int64_t size = 0; |
| 598 if (is_kernel) { |
| 599 size = utils::FileSize(partition); |
| 600 } else { |
| 601 int block_count = 0, block_size = 0; |
| 602 TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(partition, |
| 603 &block_count, |
| 604 &block_size)); |
| 605 size = static_cast<int64_t>(block_count) * block_size; |
| 606 } |
| 607 TEST_AND_RETURN_FALSE(size > 0); |
597 info->set_size(size); | 608 info->set_size(size); |
598 OmahaHashCalculator hasher; | 609 OmahaHashCalculator hasher; |
599 TEST_AND_RETURN_FALSE(hasher.UpdateFile(partition, -1) == size); | 610 TEST_AND_RETURN_FALSE(hasher.UpdateFile(partition, size) == size); |
600 TEST_AND_RETURN_FALSE(hasher.Finalize()); | 611 TEST_AND_RETURN_FALSE(hasher.Finalize()); |
601 const vector<char>& hash = hasher.raw_hash(); | 612 const vector<char>& hash = hasher.raw_hash(); |
602 info->set_hash(hash.data(), hash.size()); | 613 info->set_hash(hash.data(), hash.size()); |
603 return true; | 614 return true; |
604 } | 615 } |
605 | 616 |
606 bool InitializePartitionInfos(const string& old_kernel, | 617 bool InitializePartitionInfos(const string& old_kernel, |
607 const string& new_kernel, | 618 const string& new_kernel, |
608 const string& old_rootfs, | 619 const string& old_rootfs, |
609 const string& new_rootfs, | 620 const string& new_rootfs, |
610 DeltaArchiveManifest* manifest) { | 621 DeltaArchiveManifest* manifest) { |
611 if (!old_kernel.empty()) { | 622 if (!old_kernel.empty()) { |
612 TEST_AND_RETURN_FALSE( | 623 TEST_AND_RETURN_FALSE( |
613 InitializePartitionInfo(old_kernel, | 624 InitializePartitionInfo(true, |
| 625 old_kernel, |
614 manifest->mutable_old_kernel_info())); | 626 manifest->mutable_old_kernel_info())); |
615 } | 627 } |
616 TEST_AND_RETURN_FALSE( | 628 TEST_AND_RETURN_FALSE( |
617 InitializePartitionInfo(new_kernel, manifest->mutable_new_kernel_info())); | 629 InitializePartitionInfo(true, |
| 630 new_kernel, |
| 631 manifest->mutable_new_kernel_info())); |
618 if (!old_rootfs.empty()) { | 632 if (!old_rootfs.empty()) { |
619 TEST_AND_RETURN_FALSE( | 633 TEST_AND_RETURN_FALSE( |
620 InitializePartitionInfo(old_rootfs, | 634 InitializePartitionInfo(false, |
| 635 old_rootfs, |
621 manifest->mutable_old_rootfs_info())); | 636 manifest->mutable_old_rootfs_info())); |
622 } | 637 } |
623 TEST_AND_RETURN_FALSE( | 638 TEST_AND_RETURN_FALSE( |
624 InitializePartitionInfo(new_rootfs, manifest->mutable_new_rootfs_info())); | 639 InitializePartitionInfo(false, |
| 640 new_rootfs, |
| 641 manifest->mutable_new_rootfs_info())); |
625 return true; | 642 return true; |
626 } | 643 } |
627 | 644 |
628 namespace { | 645 namespace { |
629 | 646 |
630 // Takes a collection (vector or RepeatedPtrField) of Extent and | 647 // Takes a collection (vector or RepeatedPtrField) of Extent and |
631 // returns a vector of the blocks referenced, in order. | 648 // returns a vector of the blocks referenced, in order. |
632 template<typename T> | 649 template<typename T> |
633 vector<uint64_t> ExpandExtents(const T& extents) { | 650 vector<uint64_t> ExpandExtents(const T& extents) { |
634 vector<uint64_t> ret; | 651 vector<uint64_t> ret; |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 graph_utils::DumpGraph(*graph); | 1174 graph_utils::DumpGraph(*graph); |
1158 CHECK(NoTempBlocksRemain(*graph)); | 1175 CHECK(NoTempBlocksRemain(*graph)); |
1159 LOG(INFO) << "done making sure all temp blocks are allocated"; | 1176 LOG(INFO) << "done making sure all temp blocks are allocated"; |
1160 return true; | 1177 return true; |
1161 } | 1178 } |
1162 | 1179 |
1163 bool DeltaDiffGenerator::ReadFullUpdateFromDisk( | 1180 bool DeltaDiffGenerator::ReadFullUpdateFromDisk( |
1164 Graph* graph, | 1181 Graph* graph, |
1165 const std::string& new_kernel_part, | 1182 const std::string& new_kernel_part, |
1166 const std::string& new_image, | 1183 const std::string& new_image, |
| 1184 off_t image_size, |
1167 int fd, | 1185 int fd, |
1168 off_t* data_file_size, | 1186 off_t* data_file_size, |
1169 off_t chunk_size, | 1187 off_t chunk_size, |
1170 vector<DeltaArchiveManifest_InstallOperation>* kernel_ops, | 1188 vector<DeltaArchiveManifest_InstallOperation>* kernel_ops, |
1171 std::vector<Vertex::Index>* final_order) { | 1189 std::vector<Vertex::Index>* final_order) { |
1172 TEST_AND_RETURN_FALSE(chunk_size > 0); | 1190 TEST_AND_RETURN_FALSE(chunk_size > 0); |
1173 TEST_AND_RETURN_FALSE((chunk_size % kBlockSize) == 0); | 1191 TEST_AND_RETURN_FALSE((chunk_size % kBlockSize) == 0); |
1174 | 1192 |
1175 // Get the sizes early in the function, so we can fail fast if the user | 1193 // Get the sizes early in the function, so we can fail fast if the user |
1176 // passed us bad paths. | 1194 // passed us bad paths. |
1177 const off_t image_size = utils::FileSize(new_image); | 1195 TEST_AND_RETURN_FALSE(image_size >= 0 && |
1178 TEST_AND_RETURN_FALSE(image_size >= 0); | 1196 image_size <= utils::FileSize(new_image)); |
1179 const off_t kernel_size = utils::FileSize(new_kernel_part); | 1197 const off_t kernel_size = utils::FileSize(new_kernel_part); |
1180 TEST_AND_RETURN_FALSE(kernel_size >= 0); | 1198 TEST_AND_RETURN_FALSE(kernel_size >= 0); |
1181 | 1199 |
1182 off_t part_sizes[] = { image_size, kernel_size }; | 1200 off_t part_sizes[] = { image_size, kernel_size }; |
1183 string paths[] = { new_image, new_kernel_part }; | 1201 string paths[] = { new_image, new_kernel_part }; |
1184 | 1202 |
1185 for (int partition = 0; partition < 2; ++partition) { | 1203 for (int partition = 0; partition < 2; ++partition) { |
1186 const string& path = paths[partition]; | 1204 const string& path = paths[partition]; |
1187 LOG(INFO) << "compressing " << path; | 1205 LOG(INFO) << "compressing " << path; |
1188 | 1206 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 | 1257 |
1240 bool DeltaDiffGenerator::GenerateDeltaUpdateFile( | 1258 bool DeltaDiffGenerator::GenerateDeltaUpdateFile( |
1241 const string& old_root, | 1259 const string& old_root, |
1242 const string& old_image, | 1260 const string& old_image, |
1243 const string& new_root, | 1261 const string& new_root, |
1244 const string& new_image, | 1262 const string& new_image, |
1245 const string& old_kernel_part, | 1263 const string& old_kernel_part, |
1246 const string& new_kernel_part, | 1264 const string& new_kernel_part, |
1247 const string& output_path, | 1265 const string& output_path, |
1248 const string& private_key_path) { | 1266 const string& private_key_path) { |
1249 struct stat old_image_stbuf; | 1267 int old_image_block_count = 0, old_image_block_size = 0; |
1250 struct stat new_image_stbuf; | 1268 int new_image_block_count = 0, new_image_block_size = 0; |
1251 TEST_AND_RETURN_FALSE_ERRNO(stat(new_image.c_str(), &new_image_stbuf) == 0); | 1269 TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(new_image, |
| 1270 &new_image_block_count, |
| 1271 &new_image_block_size)); |
1252 if (!old_image.empty()) { | 1272 if (!old_image.empty()) { |
1253 TEST_AND_RETURN_FALSE_ERRNO(stat(old_image.c_str(), &old_image_stbuf) == 0); | 1273 TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(old_image, |
1254 LOG_IF(WARNING, new_image_stbuf.st_size != old_image_stbuf.st_size) | 1274 &old_image_block_count, |
1255 << "Old and new images are different sizes."; | 1275 &old_image_block_size)); |
1256 LOG_IF(FATAL, old_image_stbuf.st_size % kBlockSize) | 1276 TEST_AND_RETURN_FALSE(old_image_block_size == new_image_block_size); |
1257 << "Old image not a multiple of block size " << kBlockSize; | 1277 LOG_IF(WARNING, old_image_block_count != new_image_block_count) |
| 1278 << "Old and new images have different block counts."; |
1258 // Sanity check kernel partition arg | 1279 // Sanity check kernel partition arg |
1259 TEST_AND_RETURN_FALSE(utils::FileSize(old_kernel_part) >= 0); | 1280 TEST_AND_RETURN_FALSE(utils::FileSize(old_kernel_part) >= 0); |
1260 } else { | |
1261 old_image_stbuf.st_size = 0; | |
1262 } | 1281 } |
1263 LOG_IF(FATAL, new_image_stbuf.st_size % kBlockSize) | |
1264 << "New image not a multiple of block size " << kBlockSize; | |
1265 | |
1266 // Sanity check kernel partition arg | 1282 // Sanity check kernel partition arg |
1267 TEST_AND_RETURN_FALSE(utils::FileSize(new_kernel_part) >= 0); | 1283 TEST_AND_RETURN_FALSE(utils::FileSize(new_kernel_part) >= 0); |
1268 | 1284 |
1269 vector<Block> blocks(max(old_image_stbuf.st_size / kBlockSize, | 1285 vector<Block> blocks(max(old_image_block_count, new_image_block_count)); |
1270 new_image_stbuf.st_size / kBlockSize)); | 1286 LOG(INFO) << "Invalid block index: " << Vertex::kInvalidIndex; |
1271 LOG(INFO) << "invalid: " << Vertex::kInvalidIndex; | 1287 LOG(INFO) << "Block count: " << blocks.size(); |
1272 LOG(INFO) << "len: " << blocks.size(); | |
1273 for (vector<Block>::size_type i = 0; i < blocks.size(); i++) { | 1288 for (vector<Block>::size_type i = 0; i < blocks.size(); i++) { |
1274 CHECK(blocks[i].reader == Vertex::kInvalidIndex); | 1289 CHECK(blocks[i].reader == Vertex::kInvalidIndex); |
1275 CHECK(blocks[i].writer == Vertex::kInvalidIndex); | 1290 CHECK(blocks[i].writer == Vertex::kInvalidIndex); |
1276 } | 1291 } |
1277 Graph graph; | 1292 Graph graph; |
1278 CheckGraph(graph); | 1293 CheckGraph(graph); |
1279 | 1294 |
1280 const string kTempFileTemplate("/tmp/CrAU_temp_data.XXXXXX"); | 1295 const string kTempFileTemplate("/tmp/CrAU_temp_data.XXXXXX"); |
1281 string temp_file_path; | 1296 string temp_file_path; |
1282 off_t data_file_size = 0; | 1297 off_t data_file_size = 0; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 LOG(INFO) << "Done creating edges"; | 1341 LOG(INFO) << "Done creating edges"; |
1327 CheckGraph(graph); | 1342 CheckGraph(graph); |
1328 | 1343 |
1329 TEST_AND_RETURN_FALSE(ConvertGraphToDag(&graph, | 1344 TEST_AND_RETURN_FALSE(ConvertGraphToDag(&graph, |
1330 new_root, | 1345 new_root, |
1331 fd, | 1346 fd, |
1332 &data_file_size, | 1347 &data_file_size, |
1333 &final_order)); | 1348 &final_order)); |
1334 } else { | 1349 } else { |
1335 // Full update | 1350 // Full update |
| 1351 off_t new_image_size = |
| 1352 static_cast<off_t>(new_image_block_count) * new_image_block_size; |
1336 TEST_AND_RETURN_FALSE(ReadFullUpdateFromDisk(&graph, | 1353 TEST_AND_RETURN_FALSE(ReadFullUpdateFromDisk(&graph, |
1337 new_kernel_part, | 1354 new_kernel_part, |
1338 new_image, | 1355 new_image, |
| 1356 new_image_size, |
1339 fd, | 1357 fd, |
1340 &data_file_size, | 1358 &data_file_size, |
1341 kFullUpdateChunkSize, | 1359 kFullUpdateChunkSize, |
1342 &kernel_ops, | 1360 &kernel_ops, |
1343 &final_order)); | 1361 &final_order)); |
1344 } | 1362 } |
1345 } | 1363 } |
1346 | 1364 |
1347 // Convert to protobuf Manifest object | 1365 // Convert to protobuf Manifest object |
1348 DeltaArchiveManifest manifest; | 1366 DeltaArchiveManifest manifest; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1494 | 1512 |
1495 LOG(INFO) << "All done. Successfully created delta file."; | 1513 LOG(INFO) << "All done. Successfully created delta file."; |
1496 return true; | 1514 return true; |
1497 } | 1515 } |
1498 | 1516 |
1499 const char* const kBsdiffPath = "/usr/bin/bsdiff"; | 1517 const char* const kBsdiffPath = "/usr/bin/bsdiff"; |
1500 const char* const kBspatchPath = "/usr/bin/bspatch"; | 1518 const char* const kBspatchPath = "/usr/bin/bspatch"; |
1501 const char* const kDeltaMagic = "CrAU"; | 1519 const char* const kDeltaMagic = "CrAU"; |
1502 | 1520 |
1503 }; // namespace chromeos_update_engine | 1521 }; // namespace chromeos_update_engine |
OLD | NEW |