update_engine: Remove sparse hole extents.
Whenever there is an extent beginning with a sparse hole, that extent
will be filtered out. Extents are now read in from the partition rather
than the file itself in ReadFileToDiff. src/dst_length are set to the
number of blocks in src/dst_extents * block_size.
This was tested manually with _GenerateSinglePayload to generate a delta
payload between test images.
BUG=chromium:469792,chromium:474497
TEST=`FEATURES=test emerge-link update_engine` and manual testing.
Change-Id: I384ec3f16f7fd9087159817358308f22d29e9edf
Reviewed-on: https://chromium-review.googlesource.com/264442
Reviewed-by: Don Garrett <dgarrett@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
Commit-Queue: Allie Wood <alliewood@chromium.org>
Tested-by: Allie Wood <alliewood@chromium.org>
diff --git a/utils.cc b/utils.cc
index c076682..31b25af 100644
--- a/utils.cc
+++ b/utils.cc
@@ -1691,6 +1691,32 @@
return false;
}
+bool ReadExtents(const std::string& path, vector<Extent>* extents,
+ chromeos::Blob* out_data, ssize_t out_data_size,
+ size_t block_size) {
+ chromeos::Blob data(out_data_size);
+ ssize_t bytes_read = 0;
+ int fd = open(path.c_str(), O_RDONLY);
+ TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
+ ScopedFdCloser fd_closer(&fd);
+
+ for (const Extent& extent : *extents) {
+ ssize_t bytes_read_this_iteration = 0;
+ ssize_t bytes = extent.num_blocks() * block_size;
+ TEST_AND_RETURN_FALSE(bytes_read + bytes <= out_data_size);
+ TEST_AND_RETURN_FALSE(utils::PReadAll(fd,
+ &data[bytes_read],
+ bytes,
+ extent.start_block() * block_size,
+ &bytes_read_this_iteration));
+ TEST_AND_RETURN_FALSE(bytes_read_this_iteration == bytes);
+ bytes_read += bytes_read_this_iteration;
+ }
+ TEST_AND_RETURN_FALSE(out_data_size == bytes_read);
+ *out_data = data;
+ return true;
+}
+
} // namespace utils
} // namespace chromeos_update_engine