| 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> |
| 11 #include <sys/types.h> | 11 #include <sys/types.h> |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <map> | 14 #include <map> |
| 15 #include <set> | 15 #include <set> |
| 16 #include <string> | 16 #include <string> |
| 17 #include <utility> | 17 #include <utility> |
| 18 #include <vector> | 18 #include <vector> |
| 19 | 19 |
| 20 #include <base/logging.h> | 20 #include <base/logging.h> |
| 21 #include <base/string_util.h> | 21 #include <base/string_util.h> |
| 22 #include <bzlib.h> | 22 #include <bzlib.h> |
| 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/graph_types.h" | 31 #include "update_engine/graph_types.h" |
| 31 #include "update_engine/graph_utils.h" | 32 #include "update_engine/graph_utils.h" |
| 32 #include "update_engine/omaha_hash_calculator.h" | 33 #include "update_engine/omaha_hash_calculator.h" |
| 33 #include "update_engine/payload_signer.h" | 34 #include "update_engine/payload_signer.h" |
| 34 #include "update_engine/subprocess.h" | 35 #include "update_engine/subprocess.h" |
| 35 #include "update_engine/topological_sort.h" | 36 #include "update_engine/topological_sort.h" |
| 36 #include "update_engine/update_metadata.pb.h" | 37 #include "update_engine/update_metadata.pb.h" |
| 37 #include "update_engine/utils.h" | 38 #include "update_engine/utils.h" |
| 38 | 39 |
| 39 using std::make_pair; | 40 using std::make_pair; |
| (...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1301 &inverse_final_order, | 1302 &inverse_final_order, |
| 1302 cuts)); | 1303 cuts)); |
| 1303 LOG(INFO) << "Making sure all temp blocks have been allocated"; | 1304 LOG(INFO) << "Making sure all temp blocks have been allocated"; |
| 1304 | 1305 |
| 1305 graph_utils::DumpGraph(*graph); | 1306 graph_utils::DumpGraph(*graph); |
| 1306 CHECK(NoTempBlocksRemain(*graph)); | 1307 CHECK(NoTempBlocksRemain(*graph)); |
| 1307 LOG(INFO) << "done making sure all temp blocks are allocated"; | 1308 LOG(INFO) << "done making sure all temp blocks are allocated"; |
| 1308 return true; | 1309 return true; |
| 1309 } | 1310 } |
| 1310 | 1311 |
| 1311 bool DeltaDiffGenerator::ReadFullUpdateFromDisk( | |
| 1312 Graph* graph, | |
| 1313 const std::string& new_kernel_part, | |
| 1314 const std::string& new_image, | |
| 1315 off_t image_size, | |
| 1316 int fd, | |
| 1317 off_t* data_file_size, | |
| 1318 off_t chunk_size, | |
| 1319 vector<DeltaArchiveManifest_InstallOperation>* kernel_ops, | |
| 1320 std::vector<Vertex::Index>* final_order) { | |
| 1321 TEST_AND_RETURN_FALSE(chunk_size > 0); | |
| 1322 TEST_AND_RETURN_FALSE((chunk_size % kBlockSize) == 0); | |
| 1323 | |
| 1324 // Get the sizes early in the function, so we can fail fast if the user | |
| 1325 // passed us bad paths. | |
| 1326 TEST_AND_RETURN_FALSE(image_size >= 0 && | |
| 1327 image_size <= utils::FileSize(new_image)); | |
| 1328 const off_t kernel_size = utils::FileSize(new_kernel_part); | |
| 1329 TEST_AND_RETURN_FALSE(kernel_size >= 0); | |
| 1330 | |
| 1331 off_t part_sizes[] = { image_size, kernel_size }; | |
| 1332 string paths[] = { new_image, new_kernel_part }; | |
| 1333 | |
| 1334 for (int partition = 0; partition < 2; ++partition) { | |
| 1335 const string& path = paths[partition]; | |
| 1336 LOG(INFO) << "compressing " << path; | |
| 1337 | |
| 1338 int in_fd = open(path.c_str(), O_RDONLY, 0); | |
| 1339 TEST_AND_RETURN_FALSE(in_fd >= 0); | |
| 1340 ScopedFdCloser in_fd_closer(&in_fd); | |
| 1341 | |
| 1342 for (off_t bytes_left = part_sizes[partition], counter = 0, offset = 0; | |
| 1343 bytes_left > 0; | |
| 1344 bytes_left -= chunk_size, ++counter, offset += chunk_size) { | |
| 1345 DeltaArchiveManifest_InstallOperation* op = NULL; | |
| 1346 if (partition == 0) { | |
| 1347 graph->resize(graph->size() + 1); | |
| 1348 graph->back().file_name = path + StringPrintf("-%" PRIi64, counter); | |
| 1349 op = &graph->back().op; | |
| 1350 final_order->push_back(graph->size() - 1); | |
| 1351 } else { | |
| 1352 kernel_ops->resize(kernel_ops->size() + 1); | |
| 1353 op = &kernel_ops->back(); | |
| 1354 } | |
| 1355 | |
| 1356 vector<char> buf(min(bytes_left, chunk_size)); | |
| 1357 ssize_t bytes_read = -1; | |
| 1358 | |
| 1359 TEST_AND_RETURN_FALSE(utils::PReadAll( | |
| 1360 in_fd, &buf[0], buf.size(), offset, &bytes_read)); | |
| 1361 TEST_AND_RETURN_FALSE(bytes_read == static_cast<ssize_t>(buf.size())); | |
| 1362 | |
| 1363 vector<char> buf_compressed; | |
| 1364 | |
| 1365 TEST_AND_RETURN_FALSE(BzipCompress(buf, &buf_compressed)); | |
| 1366 const bool compress = buf_compressed.size() < buf.size(); | |
| 1367 const vector<char>& use_buf = compress ? buf_compressed : buf; | |
| 1368 if (compress) { | |
| 1369 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ); | |
| 1370 } else { | |
| 1371 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE); | |
| 1372 } | |
| 1373 op->set_data_offset(*data_file_size); | |
| 1374 TEST_AND_RETURN_FALSE(utils::WriteAll(fd, &use_buf[0], use_buf.size())); | |
| 1375 *data_file_size += use_buf.size(); | |
| 1376 op->set_data_length(use_buf.size()); | |
| 1377 Extent* dst_extent = op->add_dst_extents(); | |
| 1378 dst_extent->set_start_block(offset / kBlockSize); | |
| 1379 dst_extent->set_num_blocks(chunk_size / kBlockSize); | |
| 1380 | |
| 1381 LOG(INFO) << StringPrintf("%.1f", offset * 100.0 / part_sizes[partition]) | |
| 1382 << "% complete (offset: " << offset << ", buf size: " | |
| 1383 << buf.size() << ")"; | |
| 1384 } | |
| 1385 } | |
| 1386 | |
| 1387 return true; | |
| 1388 } | |
| 1389 | |
| 1390 bool DeltaDiffGenerator::GenerateDeltaUpdateFile( | 1312 bool DeltaDiffGenerator::GenerateDeltaUpdateFile( |
| 1391 const string& old_root, | 1313 const string& old_root, |
| 1392 const string& old_image, | 1314 const string& old_image, |
| 1393 const string& new_root, | 1315 const string& new_root, |
| 1394 const string& new_image, | 1316 const string& new_image, |
| 1395 const string& old_kernel_part, | 1317 const string& old_kernel_part, |
| 1396 const string& new_kernel_part, | 1318 const string& new_kernel_part, |
| 1397 const string& output_path, | 1319 const string& output_path, |
| 1398 const string& private_key_path) { | 1320 const string& private_key_path) { |
| 1399 int old_image_block_count = 0, old_image_block_size = 0; | 1321 int old_image_block_count = 0, old_image_block_size = 0; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1473 | 1395 |
| 1474 TEST_AND_RETURN_FALSE(ConvertGraphToDag(&graph, | 1396 TEST_AND_RETURN_FALSE(ConvertGraphToDag(&graph, |
| 1475 new_root, | 1397 new_root, |
| 1476 fd, | 1398 fd, |
| 1477 &data_file_size, | 1399 &data_file_size, |
| 1478 &final_order)); | 1400 &final_order)); |
| 1479 } else { | 1401 } else { |
| 1480 // Full update | 1402 // Full update |
| 1481 off_t new_image_size = | 1403 off_t new_image_size = |
| 1482 static_cast<off_t>(new_image_block_count) * new_image_block_size; | 1404 static_cast<off_t>(new_image_block_count) * new_image_block_size; |
| 1483 TEST_AND_RETURN_FALSE(ReadFullUpdateFromDisk(&graph, | 1405 TEST_AND_RETURN_FALSE(FullUpdateGenerator::Run(&graph, |
| 1484 new_kernel_part, | 1406 new_kernel_part, |
| 1485 new_image, | 1407 new_image, |
| 1486 new_image_size, | 1408 new_image_size, |
| 1487 fd, | 1409 fd, |
| 1488 &data_file_size, | 1410 &data_file_size, |
| 1489 kFullUpdateChunkSize, | 1411 kFullUpdateChunkSize, |
| 1490 &kernel_ops, | 1412 kBlockSize, |
| 1491 &final_order)); | 1413 &kernel_ops, |
| 1414 &final_order)); |
| 1492 } | 1415 } |
| 1493 } | 1416 } |
| 1494 | 1417 |
| 1495 // Convert to protobuf Manifest object | 1418 // Convert to protobuf Manifest object |
| 1496 DeltaArchiveManifest manifest; | 1419 DeltaArchiveManifest manifest; |
| 1497 OperationNameMap op_name_map; | 1420 OperationNameMap op_name_map; |
| 1498 CheckGraph(graph); | 1421 CheckGraph(graph); |
| 1499 InstallOperationsToManifest(graph, | 1422 InstallOperationsToManifest(graph, |
| 1500 final_order, | 1423 final_order, |
| 1501 kernel_ops, | 1424 kernel_ops, |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1631 | 1554 |
| 1632 LOG(INFO) << "All done. Successfully created delta file."; | 1555 LOG(INFO) << "All done. Successfully created delta file."; |
| 1633 return true; | 1556 return true; |
| 1634 } | 1557 } |
| 1635 | 1558 |
| 1636 const char* const kBsdiffPath = "bsdiff"; | 1559 const char* const kBsdiffPath = "bsdiff"; |
| 1637 const char* const kBspatchPath = "bspatch"; | 1560 const char* const kBspatchPath = "bspatch"; |
| 1638 const char* const kDeltaMagic = "CrAU"; | 1561 const char* const kDeltaMagic = "CrAU"; |
| 1639 | 1562 |
| 1640 }; // namespace chromeos_update_engine | 1563 }; // namespace chromeos_update_engine |
| OLD | NEW |