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 |