update_engine: Avoid emitting a MOVE to 0.
Workaround the bug where we can't emit a MOVE to the block 0 by excluding
it from the inplace generator graph and re-adding the operation later.
BUG=chromium:500423
TEST=delta_generator from lulu-R43-6946.31.0 to R45-7174.0.0, test image.
Change-Id: I3f16c2ae58b0f31869a39af6a45f7798960c722b
Reviewed-on: https://chromium-review.googlesource.com/278020
Tested-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Trybot-Ready: Filipe Brandenburger <filbranden@chromium.org>
diff --git a/payload_generator/delta_diff_generator.cc b/payload_generator/delta_diff_generator.cc
index 8676086..61ac4ad 100644
--- a/payload_generator/delta_diff_generator.cc
+++ b/payload_generator/delta_diff_generator.cc
@@ -297,10 +297,21 @@
off_t chunk_blocks,
int data_fd,
off_t* data_file_size,
+ bool skip_block_0,
bool src_ops_allowed) {
ExtentRanges old_visited_blocks;
ExtentRanges new_visited_blocks;
+ // We can't produce a MOVE operation with a 0 block as neither source nor
+ // destination, so we avoid generating an operation for the block 0 here, and
+ // we will add an operation for it in the InplaceGenerator. Excluding both
+ // old and new blocks ensures that identical images would still produce empty
+ // deltas.
+ if (skip_block_0) {
+ old_visited_blocks.AddBlock(0);
+ new_visited_blocks.AddBlock(0);
+ }
+
map<string, vector<Extent>> old_files_map;
if (old_fs) {
vector<FilesystemInterface::File> old_files;
@@ -622,15 +633,16 @@
block_size,
new_kernel_size / block_size);
- DeltaReadFilesystem(aops,
- old_kernel_part,
- new_kernel_part,
- old_kernel_fs.get(),
- new_kernel_fs.get(),
- -1, // chunk_blocks
- blobs_fd,
- blobs_length,
- src_ops_allowed);
+ TEST_AND_RETURN_FALSE(DeltaReadFilesystem(aops,
+ old_kernel_part,
+ new_kernel_part,
+ old_kernel_fs.get(),
+ new_kernel_fs.get(),
+ -1, // chunk_blocks
+ blobs_fd,
+ blobs_length,
+ false, // skip_block_0
+ src_ops_allowed));
LOG(INFO) << "Done delta compressing kernel partition.";
return true;
@@ -782,6 +794,7 @@
chunk_blocks,
data_file_fd,
data_file_size,
+ false, // skip_block_0
true)); // src_ops_allowed
LOG(INFO) << "done reading normal files";
diff --git a/payload_generator/delta_diff_generator.h b/payload_generator/delta_diff_generator.h
index 53a2968..b3b5cee 100644
--- a/payload_generator/delta_diff_generator.h
+++ b/payload_generator/delta_diff_generator.h
@@ -69,6 +69,7 @@
off_t chunk_blocks,
int data_fd,
off_t* data_file_size,
+ bool skip_block_0,
bool src_ops_allowed);
// For a given file |name| append operations to |aops| to produce it in the
diff --git a/payload_generator/inplace_generator.cc b/payload_generator/inplace_generator.cc
index 64c8226..9494d73 100644
--- a/payload_generator/inplace_generator.cc
+++ b/payload_generator/inplace_generator.cc
@@ -726,6 +726,7 @@
chunk_blocks,
data_file_fd,
data_file_size,
+ true, // skip_block_0
false)); // src_ops_allowed
// Convert the rootfs operations to the graph.
Graph graph;
@@ -788,6 +789,19 @@
rootfs_ops->back().name = vertex.file_name;
}
+ // Re-add the operation for the block 0.
+ TEST_AND_RETURN_FALSE(DeltaDiffGenerator::DeltaReadFile(
+ rootfs_ops,
+ config.source.rootfs.path,
+ config.target.rootfs.path,
+ vector<Extent>{ExtentForRange(0, 1)},
+ vector<Extent>{ExtentForRange(0, 1)},
+ "<block-0>", // operation name
+ -1, // chunk_blocks
+ data_file_fd,
+ data_file_size,
+ false)); // src_ops_allowed
+
return true;
}