Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: delta_diff_generator.cc

Issue 3997007: AU: fix delta generation when running out of scratch. (Closed) Base URL: http://git.chromium.org/git/update_engine.git
Patch Set: Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « delta_diff_generator.h ('k') | delta_diff_generator_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 22 matching lines...) Expand all
33 #include "update_engine/payload_signer.h" 33 #include "update_engine/payload_signer.h"
34 #include "update_engine/subprocess.h" 34 #include "update_engine/subprocess.h"
35 #include "update_engine/topological_sort.h" 35 #include "update_engine/topological_sort.h"
36 #include "update_engine/update_metadata.pb.h" 36 #include "update_engine/update_metadata.pb.h"
37 #include "update_engine/utils.h" 37 #include "update_engine/utils.h"
38 38
39 using std::make_pair; 39 using std::make_pair;
40 using std::map; 40 using std::map;
41 using std::max; 41 using std::max;
42 using std::min; 42 using std::min;
43 using std::pair;
43 using std::set; 44 using std::set;
44 using std::string; 45 using std::string;
45 using std::vector; 46 using std::vector;
46 47
47 namespace chromeos_update_engine { 48 namespace chromeos_update_engine {
48 49
49 typedef DeltaDiffGenerator::Block Block; 50 typedef DeltaDiffGenerator::Block Block;
50 typedef map<const DeltaArchiveManifest_InstallOperation*, 51 typedef map<const DeltaArchiveManifest_InstallOperation*,
51 const string*> OperationNameMap; 52 const string*> OperationNameMap;
52 53
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 LOG(ERROR) << "kTempBlockStart: " << kTempBlockStart; 917 LOG(ERROR) << "kTempBlockStart: " << kTempBlockStart;
917 LOG(ERROR) << "returning true"; 918 LOG(ERROR) << "returning true";
918 return true; 919 return true;
919 } 920 }
920 // check for wrap-around, which would be a bug: 921 // check for wrap-around, which would be a bug:
921 CHECK(start <= (start + num)); 922 CHECK(start <= (start + num));
922 } 923 }
923 return false; 924 return false;
924 } 925 }
925 926
927 bool ConvertCutsToFull(
petkov 2010/10/23 04:52:52 Might be useful to add a docstring.
928 Graph* graph,
929 const string& new_root,
930 int data_fd,
931 off_t* data_file_size,
932 vector<Vertex::Index>* op_indexes,
933 vector<vector<Vertex::Index>::size_type>* reverse_op_indexes,
934 const vector<CutEdgeVertexes>& cuts) {
935 CHECK(!cuts.empty());
936 set<Vertex::Index> deleted_nodes;
937 for (vector<CutEdgeVertexes>::const_iterator it = cuts.begin(),
938 e = cuts.end(); it != e; ++it) {
939 TEST_AND_RETURN_FALSE(DeltaDiffGenerator::ConvertCutToFullOp(
940 graph,
941 *it,
942 new_root,
943 data_fd,
944 data_file_size));
945 deleted_nodes.insert(it->new_vertex);
946 }
947 deleted_nodes.insert(cuts[0].old_dst);
948
949 vector<Vertex::Index> new_op_indexes;
950 new_op_indexes.reserve(op_indexes->size());
951 for (vector<Vertex::Index>::iterator it = op_indexes->begin(),
952 e = op_indexes->end(); it != e; ++it) {
953 if (utils::SetContainsKey(deleted_nodes, *it))
954 continue;
955 new_op_indexes.push_back(*it);
956 }
957 new_op_indexes.push_back(cuts[0].old_dst);
958 op_indexes->swap(new_op_indexes);
959 DeltaDiffGenerator::GenerateReverseTopoOrderMap(*op_indexes,
960 reverse_op_indexes);
961 return true;
962 }
963
964 // All cuts must have the same old_dst.
965 bool AssignBlockForAdjoiningCuts(
petkov 2010/10/23 04:52:52 A docstring might be useful. Also, it might make s
966 Graph* graph,
967 const string& new_root,
968 int data_fd,
969 off_t* data_file_size,
970 vector<Vertex::Index>* op_indexes,
971 vector<vector<Vertex::Index>::size_type>* reverse_op_indexes,
972 const vector<CutEdgeVertexes>& cuts) {
973 CHECK(!cuts.empty());
974 const Vertex::Index old_dst = cuts[0].old_dst;
975 // Calculate # of blocks needed
976 uint64_t blocks_needed = 0;
977 map<const CutEdgeVertexes*, uint64_t> cuts_blocks_needed;
978 for (vector<CutEdgeVertexes>::const_iterator it = cuts.begin(),
979 e = cuts.end(); it != e; ++it) {
980 uint64_t cut_blocks_needed = 0;
981 for (vector<Extent>::const_iterator jt = it->tmp_extents.begin(),
982 je = it->tmp_extents.end(); jt != je; ++jt) {
983 cut_blocks_needed += jt->num_blocks();
984 }
985 blocks_needed += cut_blocks_needed;
986 cuts_blocks_needed[&*it] = cut_blocks_needed;
987 }
988 LOG(INFO) << "Need to find " << blocks_needed << " blocks for "
989 << cuts.size() << " cuts";
990
991 // Find enough blocks
992 ExtentRanges scratch_ranges;
993 // Each block that's supplying temp blocks and the corresponding blocks:
994 typedef vector<pair<Vertex::Index, ExtentRanges> > SupplierVector;
995 SupplierVector block_suppliers;
996 uint64_t scratch_blocks_found = 0;
997 LOG(INFO) << "scan from " << (*reverse_op_indexes)[old_dst] + 1
998 << " to " << op_indexes->size();
999 for (vector<Vertex::Index>::size_type i = (*reverse_op_indexes)[old_dst] + 1,
1000 e = op_indexes->size(); i < e; ++i) {
1001 Vertex::Index test_node = (*op_indexes)[i];
1002 if (!(*graph)[test_node].valid)
1003 continue;
1004 // See if this node has sufficient blocks
1005 ExtentRanges ranges;
1006 ranges.AddRepeatedExtents((*graph)[test_node].op.dst_extents());
1007 ranges.SubtractExtent(ExtentForRange(
1008 kTempBlockStart, kSparseHole - kTempBlockStart));
1009 ranges.SubtractRepeatedExtents((*graph)[test_node].op.src_extents());
1010 // For now, for simplicity, subtract out all blocks in read-before
1011 // dependencies.
1012 for (Vertex::EdgeMap::const_iterator edge_i =
1013 (*graph)[test_node].out_edges.begin(),
1014 edge_e = (*graph)[test_node].out_edges.end();
1015 edge_i != edge_e; ++edge_i) {
1016 ranges.SubtractExtents(edge_i->second.extents);
1017 }
1018 if (ranges.blocks() == 0)
1019 continue;
1020
1021 if (ranges.blocks() + scratch_blocks_found > blocks_needed) {
1022 // trim down ranges
1023 vector<Extent> new_ranges = ranges.GetExtentsForBlockCount(
1024 blocks_needed - scratch_blocks_found);
1025 ranges = ExtentRanges();
1026 ranges.AddExtents(new_ranges);
1027 }
1028 scratch_ranges.AddRanges(ranges);
1029 block_suppliers.push_back(make_pair(test_node, ranges));
1030 scratch_blocks_found += ranges.blocks();
1031 LOG(INFO) << "Adding " << ranges.blocks() << " blocks. Now have "
1032 << scratch_ranges.blocks();
1033 if (scratch_ranges.blocks() >= blocks_needed)
1034 break;
1035 }
1036 if (scratch_ranges.blocks() < blocks_needed) {
1037 LOG(INFO) << "Unable to find sufficient scratch";
1038 TEST_AND_RETURN_FALSE(ConvertCutsToFull(graph,
1039 new_root,
1040 data_fd,
1041 data_file_size,
1042 op_indexes,
1043 reverse_op_indexes,
1044 cuts));
1045 return true;
1046 }
1047 // Use the scratch we found
1048 TEST_AND_RETURN_FALSE(scratch_ranges.blocks() == scratch_blocks_found);
1049
1050 // Make all the suppliers depend on this node
1051 for (SupplierVector::iterator it = block_suppliers.begin(),
1052 e = block_suppliers.end(); it != e; ++it) {
1053 graph_utils::AddReadBeforeDepExtents(
1054 &(*graph)[it->first],
1055 old_dst,
1056 it->second.GetExtentsForBlockCount(it->second.blocks()));
1057 }
1058
1059 // Replace temp blocks in each cut
1060 for (vector<CutEdgeVertexes>::const_iterator it = cuts.begin(),
1061 e = cuts.end(); it != e; ++it) {
1062 vector<Extent> real_extents =
1063 scratch_ranges.GetExtentsForBlockCount(cuts_blocks_needed[&*it]);
1064 scratch_ranges.SubtractExtents(real_extents);
1065
1066 // Fix the old dest node w/ the real blocks
1067 DeltaDiffGenerator::SubstituteBlocks(&(*graph)[old_dst],
1068 it->tmp_extents,
1069 real_extents);
1070
1071 // Fix the new node w/ the real blocks. Since the new node is just a
1072 // copy operation, we can replace all the dest extents w/ the real
1073 // blocks.
1074 DeltaArchiveManifest_InstallOperation *op =
1075 &(*graph)[it->new_vertex].op;
1076 op->clear_dst_extents();
1077 DeltaDiffGenerator::StoreExtents(real_extents, op->mutable_dst_extents());
1078 }
1079 LOG(INFO) << "Done subbing in for cut set";
1080 return true;
1081 }
1082
926 } // namespace {} 1083 } // namespace {}
927 1084
928 // Returns true if |op| is a no-op operation that doesn't do any useful work 1085 // Returns true if |op| is a no-op operation that doesn't do any useful work
929 // (e.g., a move operation that copies blocks onto themselves). 1086 // (e.g., a move operation that copies blocks onto themselves).
930 bool DeltaDiffGenerator::IsNoopOperation( 1087 bool DeltaDiffGenerator::IsNoopOperation(
931 const DeltaArchiveManifest_InstallOperation& op) { 1088 const DeltaArchiveManifest_InstallOperation& op) {
932 return (op.type() == DeltaArchiveManifest_InstallOperation_Type_MOVE && 1089 return (op.type() == DeltaArchiveManifest_InstallOperation_Type_MOVE &&
933 ExpandExtents(op.src_extents()) == ExpandExtents(op.dst_extents())); 1090 ExpandExtents(op.src_extents()) == ExpandExtents(op.dst_extents()));
934 } 1091 }
935 1092
936 bool DeltaDiffGenerator::AssignTempBlocks( 1093 bool DeltaDiffGenerator::AssignTempBlocks(
937 Graph* graph, 1094 Graph* graph,
938 const string& new_root, 1095 const string& new_root,
939 int data_fd, 1096 int data_fd,
940 off_t* data_file_size, 1097 off_t* data_file_size,
941 vector<Vertex::Index>* op_indexes, 1098 vector<Vertex::Index>* op_indexes,
942 vector<vector<Vertex::Index>::size_type>* reverse_op_indexes, 1099 vector<vector<Vertex::Index>::size_type>* reverse_op_indexes,
943 vector<CutEdgeVertexes>& cuts) { 1100 const vector<CutEdgeVertexes>& cuts) {
944 CHECK(!cuts.empty()); 1101 CHECK(!cuts.empty());
1102
1103 // group of cuts w/ the same old_dst:
1104 vector<CutEdgeVertexes> cuts_group;
1105
945 for (vector<CutEdgeVertexes>::size_type i = cuts.size() - 1, e = 0; 1106 for (vector<CutEdgeVertexes>::size_type i = cuts.size() - 1, e = 0;
946 true ; --i) { 1107 true ; --i) {
947 LOG(INFO) << "Fixing temp blocks in cut " << i 1108 LOG(INFO) << "Fixing temp blocks in cut " << i
948 << ": old dst: " << cuts[i].old_dst << " new vertex: " 1109 << ": old dst: " << cuts[i].old_dst << " new vertex: "
949 << cuts[i].new_vertex; 1110 << cuts[i].new_vertex << " path: "
950 const uint64_t blocks_needed = 1111 << (*graph)[cuts[i].old_dst].file_name;
951 graph_utils::BlocksInExtents(cuts[i].tmp_extents); 1112
952 LOG(INFO) << "Scanning for usable blocks (" << blocks_needed << " needed)"; 1113 if (cuts_group.empty() || (cuts_group[0].old_dst == cuts[i].old_dst)) {
953 // For now, just look for a single op w/ sufficient blocks, not 1114 cuts_group.push_back(cuts[i]);
954 // considering blocks from outgoing read-before deps. 1115 } else {
955 Vertex::Index node = cuts[i].old_dst; 1116 CHECK(!cuts_group.empty());
956 DeltaArchiveManifest_InstallOperation_Type node_type = 1117 TEST_AND_RETURN_FALSE(AssignBlockForAdjoiningCuts(graph,
957 (*graph)[node].op.type(); 1118 new_root,
958 if (node_type == DeltaArchiveManifest_InstallOperation_Type_REPLACE || 1119 data_fd,
959 node_type == DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ) { 1120 data_file_size,
960 LOG(INFO) << "This was already converted to full, so skipping."; 1121 op_indexes,
961 // Delete the temp node and pointer to it from old src 1122 reverse_op_indexes,
962 if (!(*graph)[cuts[i].old_src].out_edges.erase(cuts[i].new_vertex)) { 1123 cuts_group));
963 LOG(INFO) << "Odd. node " << cuts[i].old_src << " didn't point to " 1124 cuts_group.clear();
964 << cuts[i].new_vertex; 1125 cuts_group.push_back(cuts[i]);
965 }
966 (*graph)[cuts[i].new_vertex].valid = false;
967 vector<Vertex::Index>::size_type new_topo_idx =
968 (*reverse_op_indexes)[cuts[i].new_vertex];
969 op_indexes->erase(op_indexes->begin() + new_topo_idx);
970 GenerateReverseTopoOrderMap(*op_indexes, reverse_op_indexes);
971 continue;
972 } 1126 }
973 bool found_node = false;
974 for (vector<Vertex::Index>::size_type j = (*reverse_op_indexes)[node] + 1,
975 je = op_indexes->size(); j < je; ++j) {
976 Vertex::Index test_node = (*op_indexes)[j];
977 // See if this node has sufficient blocks
978 ExtentRanges ranges;
979 ranges.AddRepeatedExtents((*graph)[test_node].op.dst_extents());
980 ranges.SubtractExtent(ExtentForRange(
981 kTempBlockStart, kSparseHole - kTempBlockStart));
982 ranges.SubtractRepeatedExtents((*graph)[test_node].op.src_extents());
983 // For now, for simplicity, subtract out all blocks in read-before
984 // dependencies.
985 for (Vertex::EdgeMap::const_iterator edge_i =
986 (*graph)[test_node].out_edges.begin(),
987 edge_e = (*graph)[test_node].out_edges.end();
988 edge_i != edge_e; ++edge_i) {
989 ranges.SubtractExtents(edge_i->second.extents);
990 }
991 1127
992 uint64_t blocks_found = ranges.blocks();
993 if (blocks_found < blocks_needed) {
994 if (blocks_found > 0)
995 LOG(INFO) << "insufficient blocks found in topo node " << j
996 << " (node " << (*op_indexes)[j] << "). Found only "
997 << blocks_found;
998 continue;
999 }
1000 found_node = true;
1001 LOG(INFO) << "Found sufficient blocks in topo node " << j
1002 << " (node " << (*op_indexes)[j] << ")";
1003 // Sub in the blocks, and make the node supplying the blocks
1004 // depend on old_dst.
1005 vector<Extent> real_extents =
1006 ranges.GetExtentsForBlockCount(blocks_needed);
1007
1008 // Fix the old dest node w/ the real blocks
1009 SubstituteBlocks(&(*graph)[node],
1010 cuts[i].tmp_extents,
1011 real_extents);
1012
1013 // Fix the new node w/ the real blocks. Since the new node is just a
1014 // copy operation, we can replace all the dest extents w/ the real
1015 // blocks.
1016 DeltaArchiveManifest_InstallOperation *op =
1017 &(*graph)[cuts[i].new_vertex].op;
1018 op->clear_dst_extents();
1019 StoreExtents(real_extents, op->mutable_dst_extents());
1020
1021 // Add an edge from the real-block supplier to the old dest block.
1022 graph_utils::AddReadBeforeDepExtents(&(*graph)[test_node],
1023 node,
1024 real_extents);
1025 break;
1026 }
1027 if (!found_node) {
1028 // convert to full op
1029 LOG(WARNING) << "Failed to find enough temp blocks for cut " << i
1030 << " with old dest (graph node " << node
1031 << "). Converting to a full op, at the expense of a "
1032 << "good compression ratio.";
1033 TEST_AND_RETURN_FALSE(ConvertCutToFullOp(graph,
1034 cuts[i],
1035 new_root,
1036 data_fd,
1037 data_file_size));
1038 // move the full op to the back
1039 vector<Vertex::Index> new_op_indexes;
1040 for (vector<Vertex::Index>::const_iterator iter_i = op_indexes->begin(),
1041 iter_e = op_indexes->end(); iter_i != iter_e; ++iter_i) {
1042 if ((*iter_i == cuts[i].old_dst) || (*iter_i == cuts[i].new_vertex))
1043 continue;
1044 new_op_indexes.push_back(*iter_i);
1045 }
1046 new_op_indexes.push_back(cuts[i].old_dst);
1047 op_indexes->swap(new_op_indexes);
1048
1049 GenerateReverseTopoOrderMap(*op_indexes, reverse_op_indexes);
1050 }
1051 if (i == e) { 1128 if (i == e) {
1052 // break out of for() loop 1129 // break out of for() loop
1053 break; 1130 break;
1054 } 1131 }
1055 } 1132 }
1133 CHECK(!cuts_group.empty());
1134 TEST_AND_RETURN_FALSE(AssignBlockForAdjoiningCuts(graph,
1135 new_root,
1136 data_fd,
1137 data_file_size,
1138 op_indexes,
1139 reverse_op_indexes,
1140 cuts_group));
1056 return true; 1141 return true;
1057 } 1142 }
1058 1143
1059 bool DeltaDiffGenerator::NoTempBlocksRemain(const Graph& graph) { 1144 bool DeltaDiffGenerator::NoTempBlocksRemain(const Graph& graph) {
1060 size_t idx = 0; 1145 size_t idx = 0;
1061 for (Graph::const_iterator it = graph.begin(), e = graph.end(); it != e; 1146 for (Graph::const_iterator it = graph.begin(), e = graph.end(); it != e;
1062 ++it, ++idx) { 1147 ++it, ++idx) {
1063 if (!it->valid) 1148 if (!it->valid)
1064 continue; 1149 continue;
1065 const DeltaArchiveManifest_InstallOperation& op = it->op; 1150 const DeltaArchiveManifest_InstallOperation& op = it->op;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 } 1210 }
1126 1211
1127 bool DeltaDiffGenerator::ConvertCutToFullOp(Graph* graph, 1212 bool DeltaDiffGenerator::ConvertCutToFullOp(Graph* graph,
1128 const CutEdgeVertexes& cut, 1213 const CutEdgeVertexes& cut,
1129 const string& new_root, 1214 const string& new_root,
1130 int data_fd, 1215 int data_fd,
1131 off_t* data_file_size) { 1216 off_t* data_file_size) {
1132 // Drop all incoming edges, keep all outgoing edges 1217 // Drop all incoming edges, keep all outgoing edges
1133 1218
1134 // Keep all outgoing edges 1219 // Keep all outgoing edges
1135 Vertex::EdgeMap out_edges = (*graph)[cut.old_dst].out_edges; 1220 if ((*graph)[cut.old_dst].op.type() !=
1136 graph_utils::DropWriteBeforeDeps(&out_edges); 1221 DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ &&
1222 (*graph)[cut.old_dst].op.type() !=
1223 DeltaArchiveManifest_InstallOperation_Type_REPLACE) {
1224 Vertex::EdgeMap out_edges = (*graph)[cut.old_dst].out_edges;
1225 graph_utils::DropWriteBeforeDeps(&out_edges);
1137 1226
1138 TEST_AND_RETURN_FALSE(DeltaReadFile(graph, 1227 TEST_AND_RETURN_FALSE(DeltaReadFile(graph,
1139 cut.old_dst, 1228 cut.old_dst,
1140 NULL, 1229 NULL,
1141 "/-!@:&*nonexistent_path", 1230 "/-!@:&*nonexistent_path",
1142 new_root, 1231 new_root,
1143 (*graph)[cut.old_dst].file_name, 1232 (*graph)[cut.old_dst].file_name,
1144 data_fd, 1233 data_fd,
1145 data_file_size)); 1234 data_file_size));
1146 1235
1147 (*graph)[cut.old_dst].out_edges = out_edges; 1236 (*graph)[cut.old_dst].out_edges = out_edges;
1148 1237
1149 // Right now we don't have doubly-linked edges, so we have to scan 1238 // Right now we don't have doubly-linked edges, so we have to scan
1150 // the whole graph. 1239 // the whole graph.
1151 graph_utils::DropIncomingEdgesTo(graph, cut.old_dst); 1240 graph_utils::DropIncomingEdgesTo(graph, cut.old_dst);
1241 }
1152 1242
1153 // Delete temp node 1243 // Delete temp node
1154 (*graph)[cut.old_src].out_edges.erase(cut.new_vertex); 1244 (*graph)[cut.old_src].out_edges.erase(cut.new_vertex);
1155 CHECK((*graph)[cut.old_dst].out_edges.find(cut.new_vertex) == 1245 CHECK((*graph)[cut.old_dst].out_edges.find(cut.new_vertex) ==
1156 (*graph)[cut.old_dst].out_edges.end()); 1246 (*graph)[cut.old_dst].out_edges.end());
1157 (*graph)[cut.new_vertex].valid = false; 1247 (*graph)[cut.new_vertex].valid = false;
1248 LOG(INFO) << "marked node invalid: " << cut.new_vertex;
1158 return true; 1249 return true;
1159 } 1250 }
1160 1251
1161 bool DeltaDiffGenerator::ConvertGraphToDag(Graph* graph, 1252 bool DeltaDiffGenerator::ConvertGraphToDag(Graph* graph,
1162 const string& new_root, 1253 const string& new_root,
1163 int fd, 1254 int fd,
1164 off_t* data_file_size, 1255 off_t* data_file_size,
1165 vector<Vertex::Index>* final_order) { 1256 vector<Vertex::Index>* final_order) {
1166 CycleBreaker cycle_breaker; 1257 CycleBreaker cycle_breaker;
1167 LOG(INFO) << "Finding cycles..."; 1258 LOG(INFO) << "Finding cycles...";
(...skipping 16 matching lines...) Expand all
1184 LOG(INFO) << "done with initial topo order"; 1275 LOG(INFO) << "done with initial topo order";
1185 CheckGraph(*graph); 1276 CheckGraph(*graph);
1186 1277
1187 LOG(INFO) << "Moving full ops to the back"; 1278 LOG(INFO) << "Moving full ops to the back";
1188 MoveFullOpsToBack(graph, final_order); 1279 MoveFullOpsToBack(graph, final_order);
1189 LOG(INFO) << "done moving full ops to back"; 1280 LOG(INFO) << "done moving full ops to back";
1190 1281
1191 vector<vector<Vertex::Index>::size_type> inverse_final_order; 1282 vector<vector<Vertex::Index>::size_type> inverse_final_order;
1192 GenerateReverseTopoOrderMap(*final_order, &inverse_final_order); 1283 GenerateReverseTopoOrderMap(*final_order, &inverse_final_order);
1193 1284
1285 SortCutsByTopoOrder(*final_order, &cuts);
1286
1194 if (!cuts.empty()) 1287 if (!cuts.empty())
1195 TEST_AND_RETURN_FALSE(AssignTempBlocks(graph, 1288 TEST_AND_RETURN_FALSE(AssignTempBlocks(graph,
1196 new_root, 1289 new_root,
1197 fd, 1290 fd,
1198 data_file_size, 1291 data_file_size,
1199 final_order, 1292 final_order,
1200 &inverse_final_order, 1293 &inverse_final_order,
1201 cuts)); 1294 cuts));
1202 LOG(INFO) << "Making sure all temp blocks have been allocated"; 1295 LOG(INFO) << "Making sure all temp blocks have been allocated";
1296
1203 graph_utils::DumpGraph(*graph); 1297 graph_utils::DumpGraph(*graph);
1204 CHECK(NoTempBlocksRemain(*graph)); 1298 CHECK(NoTempBlocksRemain(*graph));
1205 LOG(INFO) << "done making sure all temp blocks are allocated"; 1299 LOG(INFO) << "done making sure all temp blocks are allocated";
1206 return true; 1300 return true;
1207 } 1301 }
1208 1302
1209 bool DeltaDiffGenerator::ReadFullUpdateFromDisk( 1303 bool DeltaDiffGenerator::ReadFullUpdateFromDisk(
1210 Graph* graph, 1304 Graph* graph,
1211 const std::string& new_kernel_part, 1305 const std::string& new_kernel_part,
1212 const std::string& new_image, 1306 const std::string& new_image,
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1416 { 1510 {
1417 for (int i = 0; i < (manifest.install_operations_size() + 1511 for (int i = 0; i < (manifest.install_operations_size() +
1418 manifest.kernel_install_operations_size()); i++) { 1512 manifest.kernel_install_operations_size()); i++) {
1419 DeltaArchiveManifest_InstallOperation* op = 1513 DeltaArchiveManifest_InstallOperation* op =
1420 i < manifest.install_operations_size() ? 1514 i < manifest.install_operations_size() ?
1421 manifest.mutable_install_operations(i) : 1515 manifest.mutable_install_operations(i) :
1422 manifest.mutable_kernel_install_operations( 1516 manifest.mutable_kernel_install_operations(
1423 i - manifest.install_operations_size()); 1517 i - manifest.install_operations_size());
1424 if (op->has_data_offset()) { 1518 if (op->has_data_offset()) {
1425 if (op->data_offset() != next_blob_offset) { 1519 if (op->data_offset() != next_blob_offset) {
1426 LOG(FATAL) << "bad blob offset! " << op->data_offset() << " != " 1520 LOG(WARNING) << "bad blob offset! " << op->data_offset() << " != "
petkov 2010/10/23 04:52:52 why is this not FATAL any more?
1427 << next_blob_offset; 1521 << next_blob_offset;
1428 } 1522 }
1429 next_blob_offset += op->data_length(); 1523 next_blob_offset += op->data_length();
1430 } 1524 }
1431 } 1525 }
1432 } 1526 }
1433 1527
1434 // Signatures appear at the end of the blobs. Note the offset in the 1528 // Signatures appear at the end of the blobs. Note the offset in the
1435 // manifest 1529 // manifest
1436 if (!private_key_path.empty()) { 1530 if (!private_key_path.empty()) {
1437 LOG(INFO) << "Making room for signature in file"; 1531 LOG(INFO) << "Making room for signature in file";
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 1622
1529 LOG(INFO) << "All done. Successfully created delta file."; 1623 LOG(INFO) << "All done. Successfully created delta file.";
1530 return true; 1624 return true;
1531 } 1625 }
1532 1626
1533 const char* const kBsdiffPath = "/usr/bin/bsdiff"; 1627 const char* const kBsdiffPath = "/usr/bin/bsdiff";
1534 const char* const kBspatchPath = "/usr/bin/bspatch"; 1628 const char* const kBspatchPath = "/usr/bin/bspatch";
1535 const char* const kDeltaMagic = "CrAU"; 1629 const char* const kDeltaMagic = "CrAU";
1536 1630
1537 }; // namespace chromeos_update_engine 1631 }; // namespace chromeos_update_engine
OLDNEW
« no previous file with comments | « delta_diff_generator.h ('k') | delta_diff_generator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698