Index: delta_diff_generator.cc |
diff --git a/delta_diff_generator.cc b/delta_diff_generator.cc |
index 43192ee31ac9dd67475823893aa947e462155b99..b447f1105af9f141e22d219182eae3fe2c97941c 100644 |
--- a/delta_diff_generator.cc |
+++ b/delta_diff_generator.cc |
@@ -47,6 +47,8 @@ using std::vector; |
namespace chromeos_update_engine { |
typedef DeltaDiffGenerator::Block Block; |
+typedef map<const DeltaArchiveManifest_InstallOperation*, |
+ const string*> OperationNameMap; |
namespace { |
const size_t kBlockSize = 4096; // bytes |
@@ -376,24 +378,37 @@ bool WriteUint64AsBigEndian(FileWriter* writer, const uint64_t value) { |
return true; |
} |
-// Adds each operation from the graph to the manifest in the order |
-// specified by 'order'. |
+// Adds each operation from |graph| to |out_manifest| in the order specified by |
+// |order| while building |out_op_name_map| with operation to name |
+// mappings. Adds all |kernel_ops| to |out_manifest|. Filters out no-op |
+// operations. |
void InstallOperationsToManifest( |
const Graph& graph, |
const vector<Vertex::Index>& order, |
const vector<DeltaArchiveManifest_InstallOperation>& kernel_ops, |
- DeltaArchiveManifest* out_manifest) { |
+ DeltaArchiveManifest* out_manifest, |
+ OperationNameMap* out_op_name_map) { |
for (vector<Vertex::Index>::const_iterator it = order.begin(); |
it != order.end(); ++it) { |
+ const Vertex& vertex = graph[*it]; |
+ const DeltaArchiveManifest_InstallOperation& add_op = vertex.op; |
+ if (DeltaDiffGenerator::IsNoopOperation(add_op)) { |
+ continue; |
+ } |
DeltaArchiveManifest_InstallOperation* op = |
out_manifest->add_install_operations(); |
- *op = graph[*it].op; |
+ *op = add_op; |
+ (*out_op_name_map)[op] = &vertex.file_name; |
} |
for (vector<DeltaArchiveManifest_InstallOperation>::const_iterator it = |
kernel_ops.begin(); it != kernel_ops.end(); ++it) { |
+ const DeltaArchiveManifest_InstallOperation& add_op = *it; |
+ if (DeltaDiffGenerator::IsNoopOperation(add_op)) { |
+ continue; |
+ } |
DeltaArchiveManifest_InstallOperation* op = |
out_manifest->add_kernel_install_operations(); |
- *op = *it; |
+ *op = add_op; |
} |
} |
@@ -453,22 +468,20 @@ struct DeltaObject { |
off_t size; |
}; |
-void ReportPayloadUsage(const Graph& graph, |
- const DeltaArchiveManifest& manifest, |
- const int64_t manifest_metadata_size) { |
+void ReportPayloadUsage(const DeltaArchiveManifest& manifest, |
+ const int64_t manifest_metadata_size, |
+ const OperationNameMap& op_name_map) { |
vector<DeltaObject> objects; |
off_t total_size = 0; |
- // Graph nodes with information about file names. |
- for (Vertex::Index node = 0; node < graph.size(); node++) { |
- const Vertex& vertex = graph[node]; |
- if (!vertex.valid) { |
- continue; |
- } |
- objects.push_back(DeltaObject(vertex.file_name, |
- vertex.op.type(), |
- vertex.op.data_length())); |
- total_size += vertex.op.data_length(); |
+ // Rootfs install operations. |
+ for (int i = 0; i < manifest.install_operations_size(); ++i) { |
+ const DeltaArchiveManifest_InstallOperation& op = |
+ manifest.install_operations(i); |
+ objects.push_back(DeltaObject(*op_name_map.find(&op)->second, |
+ op.type(), |
+ op.data_length())); |
+ total_size += op.data_length(); |
} |
// Kernel install operations. |
@@ -912,6 +925,14 @@ bool TempBlocksExistInExtents(const T& extents) { |
} // namespace {} |
+// Returns true if |op| is a no-op operation that doesn't do any useful work |
+// (e.g., a move operation that copies blocks onto themselves). |
+bool DeltaDiffGenerator::IsNoopOperation( |
+ const DeltaArchiveManifest_InstallOperation& op) { |
+ return (op.type() == DeltaArchiveManifest_InstallOperation_Type_MOVE && |
+ ExpandExtents(op.src_extents()) == ExpandExtents(op.dst_extents())); |
+} |
+ |
bool DeltaDiffGenerator::AssignTempBlocks( |
Graph* graph, |
const string& new_root, |
@@ -1370,9 +1391,13 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile( |
// Convert to protobuf Manifest object |
DeltaArchiveManifest manifest; |
+ OperationNameMap op_name_map; |
CheckGraph(graph); |
- InstallOperationsToManifest(graph, final_order, kernel_ops, &manifest); |
- |
+ InstallOperationsToManifest(graph, |
+ final_order, |
+ kernel_ops, |
+ &manifest, |
+ &op_name_map); |
CheckGraph(graph); |
manifest.set_block_size(kBlockSize); |
@@ -1386,10 +1411,9 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile( |
temp_file_path, |
ordered_blobs_path)); |
- // Check that install op blobs are in order and that all blocks are written. |
+ // Check that install op blobs are in order. |
uint64_t next_blob_offset = 0; |
{ |
- vector<uint32_t> written_count(blocks.size(), 0); |
for (int i = 0; i < (manifest.install_operations_size() + |
manifest.kernel_install_operations_size()); i++) { |
DeltaArchiveManifest_InstallOperation* op = |
@@ -1397,14 +1421,6 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile( |
manifest.mutable_install_operations(i) : |
manifest.mutable_kernel_install_operations( |
i - manifest.install_operations_size()); |
- for (int j = 0; j < op->dst_extents_size(); j++) { |
- const Extent& extent = op->dst_extents(j); |
- for (uint64_t block = extent.start_block(); |
- block < (extent.start_block() + extent.num_blocks()); block++) { |
- if (block < blocks.size()) |
- written_count[block]++; |
- } |
- } |
if (op->has_data_offset()) { |
if (op->data_offset() != next_blob_offset) { |
LOG(FATAL) << "bad blob offset! " << op->data_offset() << " != " |
@@ -1413,12 +1429,6 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile( |
next_blob_offset += op->data_length(); |
} |
} |
- // check all blocks written to |
- for (vector<uint32_t>::size_type i = 0; i < written_count.size(); i++) { |
- if (written_count[i] == 0) { |
- LOG(FATAL) << "block " << i << " not written!"; |
- } |
- } |
} |
// Signatures appear at the end of the blobs. Note the offset in the |
@@ -1514,7 +1524,7 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile( |
int64_t manifest_metadata_size = |
strlen(kDeltaMagic) + 2 * sizeof(uint64_t) + serialized_manifest.size(); |
- ReportPayloadUsage(graph, manifest, manifest_metadata_size); |
+ ReportPayloadUsage(manifest, manifest_metadata_size, op_name_map); |
LOG(INFO) << "All done. Successfully created delta file."; |
return true; |