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 11 matching lines...) Expand all Loading... |
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/graph_types.h" | 30 #include "update_engine/graph_types.h" |
31 #include "update_engine/graph_utils.h" | 31 #include "update_engine/graph_utils.h" |
| 32 #include "update_engine/omaha_hash_calculator.h" |
32 #include "update_engine/payload_signer.h" | 33 #include "update_engine/payload_signer.h" |
33 #include "update_engine/subprocess.h" | 34 #include "update_engine/subprocess.h" |
34 #include "update_engine/topological_sort.h" | 35 #include "update_engine/topological_sort.h" |
35 #include "update_engine/update_metadata.pb.h" | 36 #include "update_engine/update_metadata.pb.h" |
36 #include "update_engine/utils.h" | 37 #include "update_engine/utils.h" |
37 | 38 |
38 using std::make_pair; | 39 using std::make_pair; |
39 using std::map; | 40 using std::map; |
40 using std::max; | 41 using std::max; |
41 using std::min; | 42 using std::min; |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 TEST_AND_RETURN_FALSE( | 580 TEST_AND_RETURN_FALSE( |
580 GatherExtents(new_filename, operation.mutable_dst_extents())); | 581 GatherExtents(new_filename, operation.mutable_dst_extents())); |
581 operation.set_dst_length(new_data.size()); | 582 operation.set_dst_length(new_data.size()); |
582 | 583 |
583 out_data->swap(data); | 584 out_data->swap(data); |
584 *out_op = operation; | 585 *out_op = operation; |
585 | 586 |
586 return true; | 587 return true; |
587 } | 588 } |
588 | 589 |
| 590 bool InitializePartitionInfo(const string& partition, PartitionInfo* info) { |
| 591 const off_t size = utils::FileSize(partition); |
| 592 TEST_AND_RETURN_FALSE(size >= 0); |
| 593 info->set_size(size); |
| 594 OmahaHashCalculator hasher; |
| 595 TEST_AND_RETURN_FALSE(hasher.UpdateFile(partition, -1) == size); |
| 596 TEST_AND_RETURN_FALSE(hasher.Finalize()); |
| 597 const vector<char>& hash = hasher.raw_hash(); |
| 598 info->set_hash(string(&hash[0], hash.size())); |
| 599 return true; |
| 600 } |
| 601 |
| 602 bool InitializePartitionInfos(const string& old_kernel, |
| 603 const string& new_kernel, |
| 604 const string& old_rootfs, |
| 605 const string& new_rootfs, |
| 606 DeltaArchiveManifest* manifest) { |
| 607 if (!old_kernel.empty()) { |
| 608 TEST_AND_RETURN_FALSE( |
| 609 InitializePartitionInfo(old_kernel, |
| 610 manifest->mutable_old_kernel_info())); |
| 611 } |
| 612 TEST_AND_RETURN_FALSE( |
| 613 InitializePartitionInfo(new_kernel, manifest->mutable_new_kernel_info())); |
| 614 if (!old_rootfs.empty()) { |
| 615 TEST_AND_RETURN_FALSE( |
| 616 InitializePartitionInfo(old_rootfs, |
| 617 manifest->mutable_old_rootfs_info())); |
| 618 } |
| 619 TEST_AND_RETURN_FALSE( |
| 620 InitializePartitionInfo(new_rootfs, manifest->mutable_new_rootfs_info())); |
| 621 return true; |
| 622 } |
| 623 |
589 namespace { | 624 namespace { |
590 | 625 |
591 // Takes a collection (vector or RepeatedPtrField) of Extent and | 626 // Takes a collection (vector or RepeatedPtrField) of Extent and |
592 // returns a vector of the blocks referenced, in order. | 627 // returns a vector of the blocks referenced, in order. |
593 template<typename T> | 628 template<typename T> |
594 vector<uint64_t> ExpandExtents(const T& extents) { | 629 vector<uint64_t> ExpandExtents(const T& extents) { |
595 vector<uint64_t> ret; | 630 vector<uint64_t> ret; |
596 for (size_t i = 0, e = static_cast<size_t>(extents.size()); i != e; ++i) { | 631 for (size_t i = 0, e = static_cast<size_t>(extents.size()); i != e; ++i) { |
597 const Extent extent = graph_utils::GetElement(extents, i); | 632 const Extent extent = graph_utils::GetElement(extents, i); |
598 if (extent.start_block() == kSparseHole) { | 633 if (extent.start_block() == kSparseHole) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 LOG(INFO) << "using " << graph_utils::EdgeWeight(*graph, *it) | 707 LOG(INFO) << "using " << graph_utils::EdgeWeight(*graph, *it) |
673 << " scratch blocks (" | 708 << " scratch blocks (" |
674 << scratch_blocks_used << ")"; | 709 << scratch_blocks_used << ")"; |
675 cuts.back().tmp_extents = | 710 cuts.back().tmp_extents = |
676 scratch_allocator.Allocate(graph_utils::EdgeWeight(*graph, *it)); | 711 scratch_allocator.Allocate(graph_utils::EdgeWeight(*graph, *it)); |
677 // create vertex to copy original->scratch | 712 // create vertex to copy original->scratch |
678 cuts.back().new_vertex = graph->size(); | 713 cuts.back().new_vertex = graph->size(); |
679 graph->resize(graph->size() + 1); | 714 graph->resize(graph->size() + 1); |
680 cuts.back().old_src = it->first; | 715 cuts.back().old_src = it->first; |
681 cuts.back().old_dst = it->second; | 716 cuts.back().old_dst = it->second; |
682 | 717 |
683 EdgeProperties& cut_edge_properties = | 718 EdgeProperties& cut_edge_properties = |
684 (*graph)[it->first].out_edges.find(it->second)->second; | 719 (*graph)[it->first].out_edges.find(it->second)->second; |
685 | 720 |
686 // This should never happen, as we should only be cutting edges between | 721 // This should never happen, as we should only be cutting edges between |
687 // real file nodes, and write-before relationships are created from | 722 // real file nodes, and write-before relationships are created from |
688 // a real file node to a temp copy node: | 723 // a real file node to a temp copy node: |
689 CHECK(cut_edge_properties.write_extents.empty()) | 724 CHECK(cut_edge_properties.write_extents.empty()) |
690 << "Can't cut edge that has write-before relationship."; | 725 << "Can't cut edge that has write-before relationship."; |
691 | 726 |
692 // make node depend on the copy operation | 727 // make node depend on the copy operation |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 kTempBlockStart, kSparseHole - kTempBlockStart)); | 931 kTempBlockStart, kSparseHole - kTempBlockStart)); |
897 ranges.SubtractRepeatedExtents((*graph)[test_node].op.src_extents()); | 932 ranges.SubtractRepeatedExtents((*graph)[test_node].op.src_extents()); |
898 // For now, for simplicity, subtract out all blocks in read-before | 933 // For now, for simplicity, subtract out all blocks in read-before |
899 // dependencies. | 934 // dependencies. |
900 for (Vertex::EdgeMap::const_iterator edge_i = | 935 for (Vertex::EdgeMap::const_iterator edge_i = |
901 (*graph)[test_node].out_edges.begin(), | 936 (*graph)[test_node].out_edges.begin(), |
902 edge_e = (*graph)[test_node].out_edges.end(); | 937 edge_e = (*graph)[test_node].out_edges.end(); |
903 edge_i != edge_e; ++edge_i) { | 938 edge_i != edge_e; ++edge_i) { |
904 ranges.SubtractExtents(edge_i->second.extents); | 939 ranges.SubtractExtents(edge_i->second.extents); |
905 } | 940 } |
906 | 941 |
907 uint64_t blocks_found = ranges.blocks(); | 942 uint64_t blocks_found = ranges.blocks(); |
908 if (blocks_found < blocks_needed) { | 943 if (blocks_found < blocks_needed) { |
909 if (blocks_found > 0) | 944 if (blocks_found > 0) |
910 LOG(INFO) << "insufficient blocks found in topo node " << j | 945 LOG(INFO) << "insufficient blocks found in topo node " << j |
911 << " (node " << (*op_indexes)[j] << "). Found only " | 946 << " (node " << (*op_indexes)[j] << "). Found only " |
912 << blocks_found; | 947 << blocks_found; |
913 continue; | 948 continue; |
914 } | 949 } |
915 found_node = true; | 950 found_node = true; |
916 LOG(INFO) << "Found sufficient blocks in topo node " << j | 951 LOG(INFO) << "Found sufficient blocks in topo node " << j |
917 << " (node " << (*op_indexes)[j] << ")"; | 952 << " (node " << (*op_indexes)[j] << ")"; |
918 // Sub in the blocks, and make the node supplying the blocks | 953 // Sub in the blocks, and make the node supplying the blocks |
919 // depend on old_dst. | 954 // depend on old_dst. |
920 vector<Extent> real_extents = | 955 vector<Extent> real_extents = |
921 ranges.GetExtentsForBlockCount(blocks_needed); | 956 ranges.GetExtentsForBlockCount(blocks_needed); |
922 | 957 |
923 // Fix the old dest node w/ the real blocks | 958 // Fix the old dest node w/ the real blocks |
924 SubstituteBlocks(&(*graph)[node], | 959 SubstituteBlocks(&(*graph)[node], |
925 cuts[i].tmp_extents, | 960 cuts[i].tmp_extents, |
926 real_extents); | 961 real_extents); |
927 | 962 |
928 // Fix the new node w/ the real blocks. Since the new node is just a | 963 // Fix the new node w/ the real blocks. Since the new node is just a |
929 // copy operation, we can replace all the dest extents w/ the real | 964 // copy operation, we can replace all the dest extents w/ the real |
930 // blocks. | 965 // blocks. |
931 DeltaArchiveManifest_InstallOperation *op = | 966 DeltaArchiveManifest_InstallOperation *op = |
932 &(*graph)[cuts[i].new_vertex].op; | 967 &(*graph)[cuts[i].new_vertex].op; |
933 op->clear_dst_extents(); | 968 op->clear_dst_extents(); |
934 StoreExtents(real_extents, op->mutable_dst_extents()); | 969 StoreExtents(real_extents, op->mutable_dst_extents()); |
935 | 970 |
936 // Add an edge from the real-block supplier to the old dest block. | 971 // Add an edge from the real-block supplier to the old dest block. |
937 graph_utils::AddReadBeforeDepExtents(&(*graph)[test_node], | 972 graph_utils::AddReadBeforeDepExtents(&(*graph)[test_node], |
938 node, | 973 node, |
939 real_extents); | 974 real_extents); |
940 break; | 975 break; |
941 } | 976 } |
942 if (!found_node) { | 977 if (!found_node) { |
943 // convert to full op | 978 // convert to full op |
944 LOG(WARNING) << "Failed to find enough temp blocks for cut " << i | 979 LOG(WARNING) << "Failed to find enough temp blocks for cut " << i |
945 << " with old dest (graph node " << node | 980 << " with old dest (graph node " << node |
946 << "). Converting to a full op, at the expense of a " | 981 << "). Converting to a full op, at the expense of a " |
947 << "good compression ratio."; | 982 << "good compression ratio."; |
948 TEST_AND_RETURN_FALSE(ConvertCutToFullOp(graph, | 983 TEST_AND_RETURN_FALSE(ConvertCutToFullOp(graph, |
949 cuts[i], | 984 cuts[i], |
950 new_root, | 985 new_root, |
951 data_fd, | 986 data_fd, |
952 data_file_size)); | 987 data_file_size)); |
953 // move the full op to the back | 988 // move the full op to the back |
954 vector<Vertex::Index> new_op_indexes; | 989 vector<Vertex::Index> new_op_indexes; |
955 for (vector<Vertex::Index>::const_iterator iter_i = op_indexes->begin(), | 990 for (vector<Vertex::Index>::const_iterator iter_i = op_indexes->begin(), |
956 iter_e = op_indexes->end(); iter_i != iter_e; ++iter_i) { | 991 iter_e = op_indexes->end(); iter_i != iter_e; ++iter_i) { |
957 if ((*iter_i == cuts[i].old_dst) || (*iter_i == cuts[i].new_vertex)) | 992 if ((*iter_i == cuts[i].old_dst) || (*iter_i == cuts[i].new_vertex)) |
958 continue; | 993 continue; |
959 new_op_indexes.push_back(*iter_i); | 994 new_op_indexes.push_back(*iter_i); |
960 } | 995 } |
961 new_op_indexes.push_back(cuts[i].old_dst); | 996 new_op_indexes.push_back(cuts[i].old_dst); |
962 op_indexes->swap(new_op_indexes); | 997 op_indexes->swap(new_op_indexes); |
963 | 998 |
964 GenerateReverseTopoOrderMap(*op_indexes, reverse_op_indexes); | 999 GenerateReverseTopoOrderMap(*op_indexes, reverse_op_indexes); |
965 } | 1000 } |
966 if (i == e) { | 1001 if (i == e) { |
967 // break out of for() loop | 1002 // break out of for() loop |
968 break; | 1003 break; |
969 } | 1004 } |
970 } | 1005 } |
971 return true; | 1006 return true; |
972 } | 1007 } |
973 | 1008 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 } | 1073 } |
1039 return true; | 1074 return true; |
1040 } | 1075 } |
1041 | 1076 |
1042 bool DeltaDiffGenerator::ConvertCutToFullOp(Graph* graph, | 1077 bool DeltaDiffGenerator::ConvertCutToFullOp(Graph* graph, |
1043 const CutEdgeVertexes& cut, | 1078 const CutEdgeVertexes& cut, |
1044 const string& new_root, | 1079 const string& new_root, |
1045 int data_fd, | 1080 int data_fd, |
1046 off_t* data_file_size) { | 1081 off_t* data_file_size) { |
1047 // Drop all incoming edges, keep all outgoing edges | 1082 // Drop all incoming edges, keep all outgoing edges |
1048 | 1083 |
1049 // Keep all outgoing edges | 1084 // Keep all outgoing edges |
1050 Vertex::EdgeMap out_edges = (*graph)[cut.old_dst].out_edges; | 1085 Vertex::EdgeMap out_edges = (*graph)[cut.old_dst].out_edges; |
1051 graph_utils::DropWriteBeforeDeps(&out_edges); | 1086 graph_utils::DropWriteBeforeDeps(&out_edges); |
1052 | 1087 |
1053 TEST_AND_RETURN_FALSE(DeltaReadFile(graph, | 1088 TEST_AND_RETURN_FALSE(DeltaReadFile(graph, |
1054 cut.old_dst, | 1089 cut.old_dst, |
1055 NULL, | 1090 NULL, |
1056 "/-!@:&*nonexistent_path", | 1091 "/-!@:&*nonexistent_path", |
1057 new_root, | 1092 new_root, |
1058 (*graph)[cut.old_dst].file_name, | 1093 (*graph)[cut.old_dst].file_name, |
1059 data_fd, | 1094 data_fd, |
1060 data_file_size)); | 1095 data_file_size)); |
1061 | 1096 |
1062 (*graph)[cut.old_dst].out_edges = out_edges; | 1097 (*graph)[cut.old_dst].out_edges = out_edges; |
1063 | 1098 |
1064 // Right now we don't have doubly-linked edges, so we have to scan | 1099 // Right now we don't have doubly-linked edges, so we have to scan |
1065 // the whole graph. | 1100 // the whole graph. |
1066 graph_utils::DropIncomingEdgesTo(graph, cut.old_dst); | 1101 graph_utils::DropIncomingEdgesTo(graph, cut.old_dst); |
1067 | 1102 |
1068 // Delete temp node | 1103 // Delete temp node |
1069 (*graph)[cut.old_src].out_edges.erase(cut.new_vertex); | 1104 (*graph)[cut.old_src].out_edges.erase(cut.new_vertex); |
1070 CHECK((*graph)[cut.old_dst].out_edges.find(cut.new_vertex) == | 1105 CHECK((*graph)[cut.old_dst].out_edges.find(cut.new_vertex) == |
1071 (*graph)[cut.old_dst].out_edges.end()); | 1106 (*graph)[cut.old_dst].out_edges.end()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 Graph* graph, | 1160 Graph* graph, |
1126 const std::string& new_kernel_part, | 1161 const std::string& new_kernel_part, |
1127 const std::string& new_image, | 1162 const std::string& new_image, |
1128 int fd, | 1163 int fd, |
1129 off_t* data_file_size, | 1164 off_t* data_file_size, |
1130 off_t chunk_size, | 1165 off_t chunk_size, |
1131 vector<DeltaArchiveManifest_InstallOperation>* kernel_ops, | 1166 vector<DeltaArchiveManifest_InstallOperation>* kernel_ops, |
1132 std::vector<Vertex::Index>* final_order) { | 1167 std::vector<Vertex::Index>* final_order) { |
1133 TEST_AND_RETURN_FALSE(chunk_size > 0); | 1168 TEST_AND_RETURN_FALSE(chunk_size > 0); |
1134 TEST_AND_RETURN_FALSE((chunk_size % kBlockSize) == 0); | 1169 TEST_AND_RETURN_FALSE((chunk_size % kBlockSize) == 0); |
1135 | 1170 |
1136 // Get the sizes early in the function, so we can fail fast if the user | 1171 // Get the sizes early in the function, so we can fail fast if the user |
1137 // passed us bad paths. | 1172 // passed us bad paths. |
1138 const off_t image_size = utils::FileSize(new_image); | 1173 const off_t image_size = utils::FileSize(new_image); |
1139 TEST_AND_RETURN_FALSE(image_size >= 0); | 1174 TEST_AND_RETURN_FALSE(image_size >= 0); |
1140 const off_t kernel_size = utils::FileSize(new_kernel_part); | 1175 const off_t kernel_size = utils::FileSize(new_kernel_part); |
1141 TEST_AND_RETURN_FALSE(kernel_size >= 0); | 1176 TEST_AND_RETURN_FALSE(kernel_size >= 0); |
1142 | 1177 |
1143 off_t part_sizes[] = { image_size, kernel_size }; | 1178 off_t part_sizes[] = { image_size, kernel_size }; |
1144 string paths[] = { new_image, new_kernel_part }; | 1179 string paths[] = { new_image, new_kernel_part }; |
1145 | 1180 |
(...skipping 13 matching lines...) Expand all Loading... |
1159 if (partition == 0) { | 1194 if (partition == 0) { |
1160 graph->resize(graph->size() + 1); | 1195 graph->resize(graph->size() + 1); |
1161 graph->back().file_name = path + StringPrintf("-%" PRIi64, counter); | 1196 graph->back().file_name = path + StringPrintf("-%" PRIi64, counter); |
1162 op = &graph->back().op; | 1197 op = &graph->back().op; |
1163 final_order->push_back(graph->size() - 1); | 1198 final_order->push_back(graph->size() - 1); |
1164 } else { | 1199 } else { |
1165 kernel_ops->resize(kernel_ops->size() + 1); | 1200 kernel_ops->resize(kernel_ops->size() + 1); |
1166 op = &kernel_ops->back(); | 1201 op = &kernel_ops->back(); |
1167 } | 1202 } |
1168 LOG(INFO) << "have an op"; | 1203 LOG(INFO) << "have an op"; |
1169 | 1204 |
1170 vector<char> buf(min(bytes_left, chunk_size)); | 1205 vector<char> buf(min(bytes_left, chunk_size)); |
1171 LOG(INFO) << "buf size: " << buf.size(); | 1206 LOG(INFO) << "buf size: " << buf.size(); |
1172 ssize_t bytes_read = -1; | 1207 ssize_t bytes_read = -1; |
1173 | 1208 |
1174 TEST_AND_RETURN_FALSE(utils::PReadAll( | 1209 TEST_AND_RETURN_FALSE(utils::PReadAll( |
1175 in_fd, &buf[0], buf.size(), offset, &bytes_read)); | 1210 in_fd, &buf[0], buf.size(), offset, &bytes_read)); |
1176 TEST_AND_RETURN_FALSE(bytes_read == static_cast<ssize_t>(buf.size())); | 1211 TEST_AND_RETURN_FALSE(bytes_read == static_cast<ssize_t>(buf.size())); |
1177 | 1212 |
1178 vector<char> buf_compressed; | 1213 vector<char> buf_compressed; |
1179 | 1214 |
1180 TEST_AND_RETURN_FALSE(BzipCompress(buf, &buf_compressed)); | 1215 TEST_AND_RETURN_FALSE(BzipCompress(buf, &buf_compressed)); |
1181 const bool compress = buf_compressed.size() < buf.size(); | 1216 const bool compress = buf_compressed.size() < buf.size(); |
1182 const vector<char>& use_buf = compress ? buf_compressed : buf; | 1217 const vector<char>& use_buf = compress ? buf_compressed : buf; |
1183 if (compress) { | 1218 if (compress) { |
1184 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ); | 1219 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ); |
1185 } else { | 1220 } else { |
1186 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE); | 1221 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE); |
1187 } | 1222 } |
1188 op->set_data_offset(*data_file_size); | 1223 op->set_data_offset(*data_file_size); |
1189 *data_file_size += use_buf.size(); | 1224 *data_file_size += use_buf.size(); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 &signature_blob_length)); | 1409 &signature_blob_length)); |
1375 dummy_op->set_data_length(signature_blob_length); | 1410 dummy_op->set_data_length(signature_blob_length); |
1376 manifest.set_signatures_size(signature_blob_length); | 1411 manifest.set_signatures_size(signature_blob_length); |
1377 Extent* dummy_extent = dummy_op->add_dst_extents(); | 1412 Extent* dummy_extent = dummy_op->add_dst_extents(); |
1378 // Tell the dummy op to write this data to a big sparse hole | 1413 // Tell the dummy op to write this data to a big sparse hole |
1379 dummy_extent->set_start_block(kSparseHole); | 1414 dummy_extent->set_start_block(kSparseHole); |
1380 dummy_extent->set_num_blocks((signature_blob_length + kBlockSize - 1) / | 1415 dummy_extent->set_num_blocks((signature_blob_length + kBlockSize - 1) / |
1381 kBlockSize); | 1416 kBlockSize); |
1382 } | 1417 } |
1383 | 1418 |
| 1419 TEST_AND_RETURN_FALSE(InitializePartitionInfos(old_kernel_part, |
| 1420 new_kernel_part, |
| 1421 old_image, |
| 1422 new_image, |
| 1423 &manifest)); |
| 1424 |
1384 // Serialize protobuf | 1425 // Serialize protobuf |
1385 string serialized_manifest; | 1426 string serialized_manifest; |
1386 | 1427 |
1387 CheckGraph(graph); | 1428 CheckGraph(graph); |
1388 TEST_AND_RETURN_FALSE(manifest.AppendToString(&serialized_manifest)); | 1429 TEST_AND_RETURN_FALSE(manifest.AppendToString(&serialized_manifest)); |
1389 CheckGraph(graph); | 1430 CheckGraph(graph); |
1390 | 1431 |
1391 LOG(INFO) << "Writing final delta file header..."; | 1432 LOG(INFO) << "Writing final delta file header..."; |
1392 DirectFileWriter writer; | 1433 DirectFileWriter writer; |
1393 TEST_AND_RETURN_FALSE_ERRNO(writer.Open(output_path.c_str(), | 1434 TEST_AND_RETURN_FALSE_ERRNO(writer.Open(output_path.c_str(), |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 | 1486 |
1446 LOG(INFO) << "All done. Successfully created delta file."; | 1487 LOG(INFO) << "All done. Successfully created delta file."; |
1447 return true; | 1488 return true; |
1448 } | 1489 } |
1449 | 1490 |
1450 const char* const kBsdiffPath = "/usr/bin/bsdiff"; | 1491 const char* const kBsdiffPath = "/usr/bin/bsdiff"; |
1451 const char* const kBspatchPath = "/usr/bin/bspatch"; | 1492 const char* const kBspatchPath = "/usr/bin/bspatch"; |
1452 const char* const kDeltaMagic = "CrAU"; | 1493 const char* const kDeltaMagic = "CrAU"; |
1453 | 1494 |
1454 }; // namespace chromeos_update_engine | 1495 }; // namespace chromeos_update_engine |
OLD | NEW |