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

Side by Side Diff: delta_diff_generator.cc

Issue 5684002: Add support for bsdiff of file system metadata blocks (Closed) Base URL: http://git.chromium.org/git/update_engine.git@master
Patch Set: Created 10 years 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
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>
11 #include <sys/types.h> 11 #include <sys/types.h>
12 12
13 #include <base/logging.h>
petkov 2010/12/10 00:46:55 move this block of includes after the c++ headers
thieule 2010/12/14 23:11:21 Done.
14 #include <base/string_util.h>
15 #include <bzlib.h>
16
petkov 2010/12/10 00:46:55 no need for blank line
thieule 2010/12/14 23:11:21 Done.
17 #include <ext2fs/ext2_io.h>
18 #include <ext2fs/ext2fs.h>
19
13 #include <algorithm> 20 #include <algorithm>
14 #include <map> 21 #include <map>
15 #include <set> 22 #include <set>
16 #include <string> 23 #include <string>
17 #include <utility> 24 #include <utility>
18 #include <vector> 25 #include <vector>
19 26
20 #include <base/logging.h>
21 #include <base/string_util.h>
22 #include <bzlib.h>
23
24 #include "update_engine/bzip.h" 27 #include "update_engine/bzip.h"
25 #include "update_engine/cycle_breaker.h" 28 #include "update_engine/cycle_breaker.h"
26 #include "update_engine/extent_mapper.h" 29 #include "update_engine/extent_mapper.h"
27 #include "update_engine/extent_ranges.h" 30 #include "update_engine/extent_ranges.h"
28 #include "update_engine/file_writer.h" 31 #include "update_engine/file_writer.h"
29 #include "update_engine/filesystem_iterator.h" 32 #include "update_engine/filesystem_iterator.h"
30 #include "update_engine/full_update_generator.h" 33 #include "update_engine/full_update_generator.h"
31 #include "update_engine/graph_types.h" 34 #include "update_engine/graph_types.h"
32 #include "update_engine/graph_utils.h" 35 #include "update_engine/graph_utils.h"
33 #include "update_engine/omaha_hash_calculator.h" 36 #include "update_engine/omaha_hash_calculator.h"
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 blocks, 237 blocks,
235 old_root, 238 old_root,
236 new_root, 239 new_root,
237 fs_iter.GetPartialPath(), 240 fs_iter.GetPartialPath(),
238 data_fd, 241 data_fd,
239 data_file_size)); 242 data_file_size));
240 } 243 }
241 return true; 244 return true;
242 } 245 }
243 246
247 // Read data from the specified extents.
248 bool ReadExtentsData(const ext2_filsys fs,
249 const vector<Extent>& extents,
250 vector<char>* data) {
251 // Resize the data buffer to hold all data in the extents
252 size_t num_data_blocks = 0;
253 for (vector<Extent>::const_iterator it = extents.begin();
254 it != extents.end(); it++) {
255 num_data_blocks += it->num_blocks();
256 }
257
258 data->resize(num_data_blocks * kBlockSize);
259
260 // Read in the data blocks
261 const size_t max_read_blocks = 256;
262 vector<Block>::size_type blocks_copied_count = 0;
263 for (vector<Extent>::const_iterator it = extents.begin();
264 it != extents.end(); it++) {
265 vector<Block>::size_type blocks_read = 0;
266 while (blocks_read < it->num_blocks()) {
267 const int copy_block_cnt =
268 min(max_read_blocks,
269 static_cast<vector<char>::size_type>(
270 it->num_blocks() - blocks_read));
271 TEST_AND_RETURN_FALSE_ERRCODE(
272 io_channel_read_blk(fs->io,
273 it->start_block() + blocks_read,
274 copy_block_cnt,
275 &(*data)[blocks_copied_count * kBlockSize]));
276 blocks_read += copy_block_cnt;
277 blocks_copied_count += copy_block_cnt;
278 }
279 }
280
281 return true;
282 }
283
284 // Compute the bsdiff between two metadata blobs.
285 bool ComputeMetadataBsdiff(const vector<char>& old_metadata,
286 const vector<char>& new_metadata,
287 vector<char>* bsdiff_delta) {
288 const string kTempFileTemplate("/tmp/CrAU_temp_data.XXXXXX");
289
290 // Write the metadata buffers to temporary files
291 int old_fd;
292 string temp_old_file_path;
293 TEST_AND_RETURN_FALSE(
294 utils::MakeTempFile(kTempFileTemplate, &temp_old_file_path, &old_fd));
295 TEST_AND_RETURN_FALSE(old_fd >= 0);
296 ScopedPathUnlinker temp_old_file_path_unlinker(temp_old_file_path);
297 ScopedFdCloser old_fd_closer(&old_fd);
298 TEST_AND_RETURN_FALSE(utils::WriteAll(old_fd,
299 &old_metadata[0],
300 old_metadata.size()));
301
302 int new_fd;
303 string temp_new_file_path;
304 TEST_AND_RETURN_FALSE(
305 utils::MakeTempFile(kTempFileTemplate, &temp_new_file_path, &new_fd));
306 TEST_AND_RETURN_FALSE(new_fd >= 0);
307 ScopedPathUnlinker temp_new_file_path_unlinker(temp_new_file_path);
308 ScopedFdCloser new_fd_closer(&new_fd);
309 TEST_AND_RETURN_FALSE(utils::WriteAll(new_fd,
310 &new_metadata[0],
311 new_metadata.size()));
312
313 // Perform bsdiff on these files
314 TEST_AND_RETURN_FALSE(
315 BsdiffFiles(temp_old_file_path, temp_new_file_path, bsdiff_delta));
316 CHECK_GT(bsdiff_delta->size(), 0);
317
318 return true;
319 }
320
321 // Add the specified metadata extents to the graph and blocks vector.
322 bool AddMetadataExtents(Graph* graph,
323 vector<Block>* blocks,
324 const ext2_filsys fs_old,
325 const ext2_filsys fs_new,
326 const string& metadata_name,
327 const vector<Extent>& extents,
328 int data_fd,
329 off_t* data_file_size) {
330 vector<char> data; // Data blob that will be written to delta file.
331
332 // Read in the metadata blocks from the old and new image.
333 vector<char> old_data;
334 TEST_AND_RETURN_FALSE(ReadExtentsData(fs_old, extents, &old_data));
335
336 vector<char> new_data;
337 TEST_AND_RETURN_FALSE(ReadExtentsData(fs_new, extents, &new_data));
338
339 // Determine the best way to compress this.
340 vector<char> new_data_bz;
341 TEST_AND_RETURN_FALSE(BzipCompress(new_data, &new_data_bz));
342 CHECK(!new_data_bz.empty());
343
344 DeltaArchiveManifest_InstallOperation op;
345 size_t current_best_size = 0;
346 if (new_data.size() <= new_data_bz.size()) {
347 op.set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE);
348 current_best_size = new_data.size();
349 data = new_data;
350 } else {
351 op.set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ);
352 current_best_size = new_data_bz.size();
353 data = new_data_bz;
354 }
355
356 if (old_data == new_data) {
357 // No change in data.
358 op.set_type(DeltaArchiveManifest_InstallOperation_Type_MOVE);
359 current_best_size = 0;
360 data.clear();
361 } else {
362 // Try bsdiff of old to new data
363 vector<char> bsdiff_delta;
364 TEST_AND_RETURN_FALSE(ComputeMetadataBsdiff(old_data,
365 new_data,
366 &bsdiff_delta));
367 CHECK_GT(bsdiff_delta.size(), 0);
368
369 if (bsdiff_delta.size() < current_best_size) {
370 op.set_type(DeltaArchiveManifest_InstallOperation_Type_BSDIFF);
371 current_best_size = bsdiff_delta.size();
372 data = bsdiff_delta;
373 }
374 }
375
376 CHECK_EQ(data.size(), current_best_size);
377
378 // Set the source and dest extents to be the same since the filesystem
379 // structures are identical
380 if (op.type() == DeltaArchiveManifest_InstallOperation_Type_MOVE ||
381 op.type() == DeltaArchiveManifest_InstallOperation_Type_BSDIFF) {
382 DeltaDiffGenerator::StoreExtents(extents, op.mutable_src_extents());
383 op.set_src_length(old_data.size());
384 }
385
386 DeltaDiffGenerator::StoreExtents(extents, op.mutable_dst_extents());
387 op.set_dst_length(new_data.size());
388
389 // Write data to output file
390 if (op.type() != DeltaArchiveManifest_InstallOperation_Type_MOVE) {
391 op.set_data_offset(*data_file_size);
392 op.set_data_length(data.size());
393 }
394
395 TEST_AND_RETURN_FALSE(utils::WriteAll(data_fd, &data[0], data.size()));
396 *data_file_size += data.size();
397
398 // Now, insert into graph and blocks vector
399 graph->resize(graph->size() + 1);
400 Vertex::Index vertex = graph->size() - 1;
401 (*graph)[vertex].op = op;
402 CHECK((*graph)[vertex].op.has_type());
403 (*graph)[vertex].file_name = metadata_name;
404
405 TEST_AND_RETURN_FALSE(AddInstallOpToBlocksVector((*graph)[vertex].op,
406 blocks,
407 *graph,
408 vertex));
409
410 return true;
411 }
412
413 // Reads the file system metadata extents.
414 bool ReadFilesystemMetadata(Graph* graph,
415 vector<Block>* blocks,
416 const ext2_filsys fs_old,
417 const ext2_filsys fs_new,
418 int data_fd,
419 off_t* data_file_size) {
420 LOG(INFO) << "Processing <rootfs-metadata>";
421
422 // Read all the extents that belong to the main file system metadata.
423 // The metadata blocks are at the the start of each block group and goes
petkov 2010/12/10 00:46:55 typo: the the
thieule 2010/12/14 23:11:21 Done.
424 // until the end of the inode table.
425 for (dgrp_t bg = 0; bg < fs_old->group_desc_count; bg++) {
426 struct ext2_group_desc* group_desc = &fs_old->group_desc[bg];
427 __u32 num_metadata_blocks = (group_desc->bg_inode_table +
428 fs_old->inode_blocks_per_group) -
429 (bg * fs_old->super->s_blocks_per_group);
430 __u32 bg_start_block = bg * fs_old->super->s_blocks_per_group;
431
432 // Due to bsdiff slowness, we're going to break each block group down
petkov 2010/12/10 00:46:55 would it be better for the payload size to not bre
thieule 2010/12/14 23:11:21 I ran this without breaking up into chunks and bsd
433 // into metadata chunks and feed them to bsdiff.
434 __u32 num_chunks = 4;
435 __u32 blocks_per_chunk = num_metadata_blocks / num_chunks;
436 __u32 curr_block = bg_start_block;
437 for (__u32 chunk = 0; chunk < num_chunks; chunk++) {
438
petkov 2010/12/10 00:46:55 remove blank line
thieule 2010/12/14 23:11:21 Done.
439 __u32 end_block = 0;
440 if (chunk < num_chunks - 1) {
441 end_block = curr_block + blocks_per_chunk;
442 } else {
443 end_block = bg_start_block + num_metadata_blocks;
444 }
445
446 vector<Extent> extents;
447 for (__u32 i = curr_block; i < end_block; i++) {
petkov 2010/12/10 00:46:55 there's an ExtentForRange utility in extent_ranges
thieule 2010/12/14 23:11:21 Done.
448 graph_utils::AppendBlockToExtents(&extents, i);
449 }
450
451 std::stringstream metadata_name;
452 metadata_name << "<rootfs-bg-" << bg << "-" << chunk << "-metadata>";
petkov 2010/12/10 00:46:55 maybe use StringPrintf instead?
thieule 2010/12/14 23:11:21 Done.
453
454 LOG(INFO) << "Processing " << metadata_name.str();
455
456 TEST_AND_RETURN_FALSE(AddMetadataExtents(graph,
457 blocks,
458 fs_old,
459 fs_new,
460 metadata_name.str(),
461 extents,
462 data_fd,
463 data_file_size));
464
465 curr_block += blocks_per_chunk;
466 }
467 }
468
469 return true;
470 }
471
472 // Processes all blocks belonging to an inode
473 int ProcessInodeAllBlocks(ext2_filsys fs,
474 blk_t* blocknr,
475 e2_blkcnt_t blockcnt,
476 blk_t ref_blk,
477 int ref_offset,
478 void* priv) {
479 vector<Extent>* extents = static_cast<vector<Extent>*>(priv);
480 graph_utils::AppendBlockToExtents(extents, *blocknr);
481 return 0;
482 }
483
484 // Processes only indirect, double indirect or triple indirect metadata
485 // blocks belonging to an inode
486 int ProcessInodeMetadataBlocks(ext2_filsys fs,
487 blk_t* blocknr,
488 e2_blkcnt_t blockcnt,
489 blk_t ref_blk,
490 int ref_offset,
491 void* priv) {
492 vector<Extent>* extents = static_cast<vector<Extent>*>(priv);
493 if (blockcnt < 0) {
494 graph_utils::AppendBlockToExtents(extents, *blocknr);
495 }
496 return 0;
497 }
498
499 // Read inode metadata blocks.
500 bool ReadInodeMetadata(Graph* graph,
501 vector<Block>* blocks,
502 const ext2_filsys fs_old,
503 const ext2_filsys fs_new,
504 int data_fd,
505 off_t* data_file_size) {
506 TEST_AND_RETURN_FALSE_ERRCODE(ext2fs_read_inode_bitmap(fs_old));
507
508 TEST_AND_RETURN_FALSE_ERRCODE(ext2fs_read_inode_bitmap(fs_new));
509
510 ext2_inode_scan iscan;
511 TEST_AND_RETURN_FALSE_ERRCODE(ext2fs_open_inode_scan(fs_old, 0, &iscan));
512
513 ext2_ino_t ino;
514 ext2_inode old_inode;
515 while (true) {
516 // Get the next inode on both file systems
517 errcode_t error = ext2fs_get_next_inode(iscan, &ino, &old_inode);
518 if (error) {
519 LOG(ERROR) << "Failed to retrieve next inode (" << error << ")";
520 break;
521 }
522
523 if (ino == 0) {
524 break;
525 }
526
527 if (ino == EXT2_RESIZE_INO) {
528 continue;
529 }
530
531 ext2_inode new_inode;
532 error = ext2fs_read_inode(fs_new, ino, &new_inode);
533 if (error) {
534 LOG(ERROR) << "Failed to retrieve new inode (" << error << ")";
535 continue;
536 }
537
538 // Skip inodes that are not in use
539 if (!ext2fs_test_inode_bitmap(fs_old->inode_map, ino) ||
540 !ext2fs_test_inode_bitmap(fs_new->inode_map, ino)) {
541 continue;
542 }
543
544 // Skip inodes that have no data blocks
545 if (old_inode.i_blocks == 0 || new_inode.i_blocks == 0) {
546 continue;
547 }
548
549 // Skip inodes that are not the same type
550 bool is_old_dir = (ext2fs_check_directory(fs_old, ino) == 0);
551 bool is_new_dir = (ext2fs_check_directory(fs_new, ino) == 0);
552 if (is_old_dir != is_new_dir) {
553 continue;
554 }
555
556 // Process the inodes metadata blocks
557 // For normal files, metadata blocks are indirect, double indirect
558 // and triple indirect blocks (no data blocks). For directories and
559 // the journal, all blocks are considered metadata blocks.
560 LOG(INFO) << "Processing inode " << ino << " metadata";
561
562 bool all_blocks = ((ino == EXT2_JOURNAL_INO) || is_old_dir || is_new_dir);
563
564 vector<Extent> old_extents;
565 error = ext2fs_block_iterate2(fs_old, ino, 0, NULL,
566 all_blocks ? ProcessInodeAllBlocks :
567 ProcessInodeMetadataBlocks,
568 &old_extents);
569 if (error) {
570 LOG(ERROR) << "Failed to enumerate old inode " << ino
571 << " blocks (" << error << ")";
572 continue;
573 }
574
575 vector<Extent> new_extents;
576 error = ext2fs_block_iterate2(fs_new, ino, 0, NULL,
577 all_blocks ? ProcessInodeAllBlocks :
578 ProcessInodeMetadataBlocks,
579 &new_extents);
580 if (error) {
581 LOG(ERROR) << "Failed to enumerate new inode " << ino
582 << " blocks (" << error << ")";
583 continue;
584 }
585
586 // Skip inode if there are no metadata blocks
587 if (old_extents.size() == 0 || new_extents.size() == 0) {
588 continue;
589 }
590
591 // Make sure the two inodes have the same metadata blocks
592 if (old_extents.size() != new_extents.size()) {
593 continue;
594 }
595
596 bool same_metadata_extents = true;
597 vector<Extent>::iterator it_old;
598 vector<Extent>::iterator it_new;
599 for (it_old = old_extents.begin(),
600 it_new = new_extents.begin();
601 it_old != old_extents.end() && it_new != new_extents.end();
602 it_old++, it_new++) {
603 if (it_old->start_block() != it_new->start_block() ||
604 it_old->num_blocks() != it_new->num_blocks()) {
605 same_metadata_extents = false;
606 break;
607 }
608 }
609
610 if (!same_metadata_extents) {
611 continue;
612 }
613
614 // We have identical inode metadata blocks, we can now add them to
615 // our graph and blocks vector
616 std::stringstream metadata_name;
617 metadata_name << "<rootfs-inode-" << ino << "-metadata>";
618 TEST_AND_RETURN_FALSE(AddMetadataExtents(graph,
619 blocks,
620 fs_old,
621 fs_new,
622 metadata_name.str(),
623 old_extents,
624 data_fd,
625 data_file_size));
626 }
627
628 ext2fs_close_inode_scan(iscan);
629
630 return true;
631 }
632
244 // This class allocates non-existent temp blocks, starting from 633 // This class allocates non-existent temp blocks, starting from
245 // kTempBlockStart. Other code is responsible for converting these 634 // kTempBlockStart. Other code is responsible for converting these
246 // temp blocks into real blocks, as the client can't read or write to 635 // temp blocks into real blocks, as the client can't read or write to
247 // these blocks. 636 // these blocks.
248 class DummyExtentAllocator { 637 class DummyExtentAllocator {
249 public: 638 public:
250 explicit DummyExtentAllocator() 639 explicit DummyExtentAllocator()
251 : next_block_(kTempBlockStart) {} 640 : next_block_(kTempBlockStart) {}
252 vector<Extent> Allocate(const uint64_t block_count) { 641 vector<Extent> Allocate(const uint64_t block_count) {
253 vector<Extent> ret(1); 642 vector<Extent> ret(1);
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 dst_extent->set_num_blocks((new_data.size() + kBlockSize - 1) / kBlockSize); 1002 dst_extent->set_num_blocks((new_data.size() + kBlockSize - 1) / kBlockSize);
614 } 1003 }
615 operation.set_dst_length(new_data.size()); 1004 operation.set_dst_length(new_data.size());
616 1005
617 out_data->swap(data); 1006 out_data->swap(data);
618 *out_op = operation; 1007 *out_op = operation;
619 1008
620 return true; 1009 return true;
621 } 1010 }
622 1011
1012 bool DeltaDiffGenerator::DeltaReadMetadata(Graph* graph,
1013 vector<Block>* blocks,
1014 const string& old_image,
1015 const string& new_image,
1016 int data_fd,
1017 off_t* data_file_size) {
1018 // Open the two file systems.
1019 ext2_filsys fs_old;
1020 TEST_AND_RETURN_FALSE_ERRCODE(ext2fs_open(old_image.c_str(), 0, 0, 0,
1021 unix_io_manager, &fs_old));
1022 ScopedExt2fsCloser fs_old_closer(fs_old);
1023
1024 ext2_filsys fs_new;
1025 TEST_AND_RETURN_FALSE_ERRCODE(ext2fs_open(new_image.c_str(), 0, 0, 0,
1026 unix_io_manager, &fs_new));
1027 ScopedExt2fsCloser fs_new_closer(fs_new);
1028
1029 // Make sure these two file systems are the same.
petkov 2010/12/10 00:46:55 clarify that if they aren't the same we'll just se
thieule 2010/12/14 23:11:21 Done.
1030 if (fs_old->blocksize != fs_new->blocksize ||
1031 fs_old->fragsize != fs_new->fragsize ||
1032 fs_old->group_desc_count != fs_new->group_desc_count ||
1033 fs_old->inode_blocks_per_group != fs_new->inode_blocks_per_group ||
1034 fs_old->super->s_inodes_count != fs_new->super->s_inodes_count ||
1035 fs_old->super->s_blocks_count != fs_new->super->s_blocks_count) {
1036 return true;
1037 }
1038
1039 // Process the main file system metadata (superblock, inode tables, etc)
1040 TEST_AND_RETURN_FALSE(ReadFilesystemMetadata(graph,
1041 blocks,
1042 fs_old,
1043 fs_new,
1044 data_fd,
1045 data_file_size));
1046
1047 // Process each inode metadata blocks.
1048 TEST_AND_RETURN_FALSE(ReadInodeMetadata(graph,
1049 blocks,
1050 fs_old,
1051 fs_new,
1052 data_fd,
1053 data_file_size));
1054
1055 return true;
1056 }
1057
623 bool DeltaDiffGenerator::InitializePartitionInfo(bool is_kernel, 1058 bool DeltaDiffGenerator::InitializePartitionInfo(bool is_kernel,
624 const string& partition, 1059 const string& partition,
625 PartitionInfo* info) { 1060 PartitionInfo* info) {
626 int64_t size = 0; 1061 int64_t size = 0;
627 if (is_kernel) { 1062 if (is_kernel) {
628 size = utils::FileSize(partition); 1063 size = utils::FileSize(partition);
629 } else { 1064 } else {
630 int block_count = 0, block_size = 0; 1065 int block_count = 0, block_size = 0;
631 TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(partition, 1066 TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(partition,
632 &block_count, 1067 &block_count,
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 1818
1384 TEST_AND_RETURN_FALSE(DeltaReadFiles(&graph, 1819 TEST_AND_RETURN_FALSE(DeltaReadFiles(&graph,
1385 &blocks, 1820 &blocks,
1386 old_root, 1821 old_root,
1387 new_root, 1822 new_root,
1388 fd, 1823 fd,
1389 &data_file_size)); 1824 &data_file_size));
1390 LOG(INFO) << "done reading normal files"; 1825 LOG(INFO) << "done reading normal files";
1391 CheckGraph(graph); 1826 CheckGraph(graph);
1392 1827
1828 LOG(INFO) << "Starting metadata processing";
1829 TEST_AND_RETURN_FALSE(DeltaReadMetadata(&graph,
1830 &blocks,
1831 old_image,
1832 new_image,
1833 fd,
1834 &data_file_size));
1835 LOG(INFO) << "Done metadata processing";
1836 CheckGraph(graph);
1837
1393 graph.resize(graph.size() + 1); 1838 graph.resize(graph.size() + 1);
1394 TEST_AND_RETURN_FALSE(ReadUnwrittenBlocks(blocks, 1839 TEST_AND_RETURN_FALSE(ReadUnwrittenBlocks(blocks,
1395 fd, 1840 fd,
1396 &data_file_size, 1841 &data_file_size,
1397 new_image, 1842 new_image,
1398 &graph.back())); 1843 &graph.back()));
1399 1844
1400 // Final scratch block (if there's space) 1845 // Final scratch block (if there's space)
1401 if (blocks.size() < (kRootFSPartitionSize / kBlockSize)) { 1846 if (blocks.size() < (kRootFSPartitionSize / kBlockSize)) {
1402 scratch_vertex = graph.size(); 1847 scratch_vertex = graph.size();
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 2028
1584 LOG(INFO) << "All done. Successfully created delta file."; 2029 LOG(INFO) << "All done. Successfully created delta file.";
1585 return true; 2030 return true;
1586 } 2031 }
1587 2032
1588 const char* const kBsdiffPath = "bsdiff"; 2033 const char* const kBsdiffPath = "bsdiff";
1589 const char* const kBspatchPath = "bspatch"; 2034 const char* const kBspatchPath = "bspatch";
1590 const char* const kDeltaMagic = "CrAU"; 2035 const char* const kDeltaMagic = "CrAU";
1591 2036
1592 }; // namespace chromeos_update_engine 2037 }; // namespace chromeos_update_engine
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698