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 |