Chromium Code Reviews| 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 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 e = cuts.end(); it != e; ++it) { | 942 e = cuts.end(); it != e; ++it) { |
| 943 TEST_AND_RETURN_FALSE(DeltaDiffGenerator::ConvertCutToFullOp( | 943 TEST_AND_RETURN_FALSE(DeltaDiffGenerator::ConvertCutToFullOp( |
| 944 graph, | 944 graph, |
| 945 *it, | 945 *it, |
| 946 new_root, | 946 new_root, |
| 947 data_fd, | 947 data_fd, |
| 948 data_file_size)); | 948 data_file_size)); |
| 949 deleted_nodes.insert(it->new_vertex); | 949 deleted_nodes.insert(it->new_vertex); |
| 950 } | 950 } |
| 951 deleted_nodes.insert(cuts[0].old_dst); | 951 deleted_nodes.insert(cuts[0].old_dst); |
| 952 | 952 |
| 953 vector<Vertex::Index> new_op_indexes; | 953 vector<Vertex::Index> new_op_indexes; |
| 954 new_op_indexes.reserve(op_indexes->size()); | 954 new_op_indexes.reserve(op_indexes->size()); |
| 955 for (vector<Vertex::Index>::iterator it = op_indexes->begin(), | 955 for (vector<Vertex::Index>::iterator it = op_indexes->begin(), |
| 956 e = op_indexes->end(); it != e; ++it) { | 956 e = op_indexes->end(); it != e; ++it) { |
| 957 if (utils::SetContainsKey(deleted_nodes, *it)) | 957 if (utils::SetContainsKey(deleted_nodes, *it)) |
| 958 continue; | 958 continue; |
| 959 new_op_indexes.push_back(*it); | 959 new_op_indexes.push_back(*it); |
| 960 } | 960 } |
| 961 new_op_indexes.push_back(cuts[0].old_dst); | 961 new_op_indexes.push_back(cuts[0].old_dst); |
| 962 op_indexes->swap(new_op_indexes); | 962 op_indexes->swap(new_op_indexes); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 988 uint64_t cut_blocks_needed = 0; | 988 uint64_t cut_blocks_needed = 0; |
| 989 for (vector<Extent>::const_iterator jt = it->tmp_extents.begin(), | 989 for (vector<Extent>::const_iterator jt = it->tmp_extents.begin(), |
| 990 je = it->tmp_extents.end(); jt != je; ++jt) { | 990 je = it->tmp_extents.end(); jt != je; ++jt) { |
| 991 cut_blocks_needed += jt->num_blocks(); | 991 cut_blocks_needed += jt->num_blocks(); |
| 992 } | 992 } |
| 993 blocks_needed += cut_blocks_needed; | 993 blocks_needed += cut_blocks_needed; |
| 994 cuts_blocks_needed[&*it] = cut_blocks_needed; | 994 cuts_blocks_needed[&*it] = cut_blocks_needed; |
| 995 } | 995 } |
| 996 LOG(INFO) << "Need to find " << blocks_needed << " blocks for " | 996 LOG(INFO) << "Need to find " << blocks_needed << " blocks for " |
| 997 << cuts.size() << " cuts"; | 997 << cuts.size() << " cuts"; |
| 998 | 998 |
| 999 // Find enough blocks | 999 // Find enough blocks |
| 1000 ExtentRanges scratch_ranges; | 1000 ExtentRanges scratch_ranges; |
| 1001 // Each block that's supplying temp blocks and the corresponding blocks: | 1001 // Each block that's supplying temp blocks and the corresponding blocks: |
| 1002 typedef vector<pair<Vertex::Index, ExtentRanges> > SupplierVector; | 1002 typedef vector<pair<Vertex::Index, ExtentRanges> > SupplierVector; |
| 1003 SupplierVector block_suppliers; | 1003 SupplierVector block_suppliers; |
| 1004 uint64_t scratch_blocks_found = 0; | 1004 uint64_t scratch_blocks_found = 0; |
| 1005 LOG(INFO) << "scan from " << (*reverse_op_indexes)[old_dst] + 1 | 1005 LOG(INFO) << "scan from " << (*reverse_op_indexes)[old_dst] + 1 |
| 1006 << " to " << op_indexes->size(); | 1006 << " to " << op_indexes->size(); |
| 1007 for (vector<Vertex::Index>::size_type i = (*reverse_op_indexes)[old_dst] + 1, | 1007 for (vector<Vertex::Index>::size_type i = (*reverse_op_indexes)[old_dst] + 1, |
| 1008 e = op_indexes->size(); i < e; ++i) { | 1008 e = op_indexes->size(); i < e; ++i) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 TEST_AND_RETURN_FALSE(scratch_ranges.blocks() == scratch_blocks_found); | 1056 TEST_AND_RETURN_FALSE(scratch_ranges.blocks() == scratch_blocks_found); |
| 1057 | 1057 |
| 1058 // Make all the suppliers depend on this node | 1058 // Make all the suppliers depend on this node |
| 1059 for (SupplierVector::iterator it = block_suppliers.begin(), | 1059 for (SupplierVector::iterator it = block_suppliers.begin(), |
| 1060 e = block_suppliers.end(); it != e; ++it) { | 1060 e = block_suppliers.end(); it != e; ++it) { |
| 1061 graph_utils::AddReadBeforeDepExtents( | 1061 graph_utils::AddReadBeforeDepExtents( |
| 1062 &(*graph)[it->first], | 1062 &(*graph)[it->first], |
| 1063 old_dst, | 1063 old_dst, |
| 1064 it->second.GetExtentsForBlockCount(it->second.blocks())); | 1064 it->second.GetExtentsForBlockCount(it->second.blocks())); |
| 1065 } | 1065 } |
| 1066 | 1066 |
| 1067 // Replace temp blocks in each cut | 1067 // Replace temp blocks in each cut |
| 1068 for (vector<CutEdgeVertexes>::const_iterator it = cuts.begin(), | 1068 for (vector<CutEdgeVertexes>::const_iterator it = cuts.begin(), |
| 1069 e = cuts.end(); it != e; ++it) { | 1069 e = cuts.end(); it != e; ++it) { |
| 1070 vector<Extent> real_extents = | 1070 vector<Extent> real_extents = |
| 1071 scratch_ranges.GetExtentsForBlockCount(cuts_blocks_needed[&*it]); | 1071 scratch_ranges.GetExtentsForBlockCount(cuts_blocks_needed[&*it]); |
| 1072 scratch_ranges.SubtractExtents(real_extents); | 1072 scratch_ranges.SubtractExtents(real_extents); |
| 1073 | 1073 |
| 1074 // Fix the old dest node w/ the real blocks | 1074 // Fix the old dest node w/ the real blocks |
| 1075 DeltaDiffGenerator::SubstituteBlocks(&(*graph)[old_dst], | 1075 DeltaDiffGenerator::SubstituteBlocks(&(*graph)[old_dst], |
| 1076 it->tmp_extents, | 1076 it->tmp_extents, |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1335 const string& path = paths[partition]; | 1335 const string& path = paths[partition]; |
| 1336 LOG(INFO) << "compressing " << path; | 1336 LOG(INFO) << "compressing " << path; |
| 1337 | 1337 |
| 1338 int in_fd = open(path.c_str(), O_RDONLY, 0); | 1338 int in_fd = open(path.c_str(), O_RDONLY, 0); |
| 1339 TEST_AND_RETURN_FALSE(in_fd >= 0); | 1339 TEST_AND_RETURN_FALSE(in_fd >= 0); |
| 1340 ScopedFdCloser in_fd_closer(&in_fd); | 1340 ScopedFdCloser in_fd_closer(&in_fd); |
| 1341 | 1341 |
| 1342 for (off_t bytes_left = part_sizes[partition], counter = 0, offset = 0; | 1342 for (off_t bytes_left = part_sizes[partition], counter = 0, offset = 0; |
| 1343 bytes_left > 0; | 1343 bytes_left > 0; |
| 1344 bytes_left -= chunk_size, ++counter, offset += chunk_size) { | 1344 bytes_left -= chunk_size, ++counter, offset += chunk_size) { |
| 1345 LOG(INFO) << "offset = " << offset; | |
| 1346 DeltaArchiveManifest_InstallOperation* op = NULL; | 1345 DeltaArchiveManifest_InstallOperation* op = NULL; |
| 1347 if (partition == 0) { | 1346 if (partition == 0) { |
| 1348 graph->resize(graph->size() + 1); | 1347 graph->resize(graph->size() + 1); |
| 1349 graph->back().file_name = path + StringPrintf("-%" PRIi64, counter); | 1348 graph->back().file_name = path + StringPrintf("-%" PRIi64, counter); |
| 1350 op = &graph->back().op; | 1349 op = &graph->back().op; |
| 1351 final_order->push_back(graph->size() - 1); | 1350 final_order->push_back(graph->size() - 1); |
| 1352 } else { | 1351 } else { |
| 1353 kernel_ops->resize(kernel_ops->size() + 1); | 1352 kernel_ops->resize(kernel_ops->size() + 1); |
| 1354 op = &kernel_ops->back(); | 1353 op = &kernel_ops->back(); |
| 1355 } | 1354 } |
| 1356 LOG(INFO) << "have an op"; | |
| 1357 | 1355 |
| 1358 vector<char> buf(min(bytes_left, chunk_size)); | 1356 vector<char> buf(min(bytes_left, chunk_size)); |
| 1359 LOG(INFO) << "buf size: " << buf.size(); | |
| 1360 ssize_t bytes_read = -1; | 1357 ssize_t bytes_read = -1; |
| 1361 | 1358 |
| 1362 TEST_AND_RETURN_FALSE(utils::PReadAll( | 1359 TEST_AND_RETURN_FALSE(utils::PReadAll( |
| 1363 in_fd, &buf[0], buf.size(), offset, &bytes_read)); | 1360 in_fd, &buf[0], buf.size(), offset, &bytes_read)); |
| 1364 TEST_AND_RETURN_FALSE(bytes_read == static_cast<ssize_t>(buf.size())); | 1361 TEST_AND_RETURN_FALSE(bytes_read == static_cast<ssize_t>(buf.size())); |
| 1365 | 1362 |
| 1366 vector<char> buf_compressed; | 1363 vector<char> buf_compressed; |
| 1367 | 1364 |
| 1368 TEST_AND_RETURN_FALSE(BzipCompress(buf, &buf_compressed)); | 1365 TEST_AND_RETURN_FALSE(BzipCompress(buf, &buf_compressed)); |
| 1369 const bool compress = buf_compressed.size() < buf.size(); | 1366 const bool compress = buf_compressed.size() < buf.size(); |
| 1370 const vector<char>& use_buf = compress ? buf_compressed : buf; | 1367 const vector<char>& use_buf = compress ? buf_compressed : buf; |
| 1371 if (compress) { | 1368 if (compress) { |
| 1372 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ); | 1369 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ); |
| 1373 } else { | 1370 } else { |
| 1374 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE); | 1371 op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE); |
| 1375 } | 1372 } |
| 1376 op->set_data_offset(*data_file_size); | 1373 op->set_data_offset(*data_file_size); |
| 1377 TEST_AND_RETURN_FALSE(utils::WriteAll(fd, &use_buf[0], use_buf.size())); | 1374 TEST_AND_RETURN_FALSE(utils::WriteAll(fd, &use_buf[0], use_buf.size())); |
| 1378 *data_file_size += use_buf.size(); | 1375 *data_file_size += use_buf.size(); |
| 1379 op->set_data_length(use_buf.size()); | 1376 op->set_data_length(use_buf.size()); |
| 1380 Extent* dst_extent = op->add_dst_extents(); | 1377 Extent* dst_extent = op->add_dst_extents(); |
| 1381 dst_extent->set_start_block(offset / kBlockSize); | 1378 dst_extent->set_start_block(offset / kBlockSize); |
| 1382 dst_extent->set_num_blocks(chunk_size / kBlockSize); | 1379 dst_extent->set_num_blocks(chunk_size / kBlockSize); |
| 1380 | |
| 1381 LOG(INFO) << StringPrintf("%.1f", offset * 100.0 / part_sizes[partition]) | |
|
adlr
2010/11/03 18:41:51
how many lines does this produce? Maybe we should
petkov
2010/11/03 18:43:55
850 I guess? I'm OK with verbose output as long as
| |
| 1382 << "% complete (offset: " << offset << ", buf size: " | |
| 1383 << buf.size() << ")"; | |
| 1383 } | 1384 } |
| 1384 } | 1385 } |
| 1385 | 1386 |
| 1386 return true; | 1387 return true; |
| 1387 } | 1388 } |
| 1388 | 1389 |
| 1389 bool DeltaDiffGenerator::GenerateDeltaUpdateFile( | 1390 bool DeltaDiffGenerator::GenerateDeltaUpdateFile( |
| 1390 const string& old_root, | 1391 const string& old_root, |
| 1391 const string& old_image, | 1392 const string& old_image, |
| 1392 const string& new_root, | 1393 const string& new_root, |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1630 | 1631 |
| 1631 LOG(INFO) << "All done. Successfully created delta file."; | 1632 LOG(INFO) << "All done. Successfully created delta file."; |
| 1632 return true; | 1633 return true; |
| 1633 } | 1634 } |
| 1634 | 1635 |
| 1635 const char* const kBsdiffPath = "bsdiff"; | 1636 const char* const kBsdiffPath = "bsdiff"; |
| 1636 const char* const kBspatchPath = "bspatch"; | 1637 const char* const kBspatchPath = "bspatch"; |
| 1637 const char* const kDeltaMagic = "CrAU"; | 1638 const char* const kDeltaMagic = "CrAU"; |
| 1638 | 1639 |
| 1639 }; // namespace chromeos_update_engine | 1640 }; // namespace chromeos_update_engine |
| OLD | NEW |