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

Unified Diff: src/platform/update_engine/delta_diff_generator.cc

Issue 1819002: AU: delta compress the kernel partition (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: fixes for review Created 10 years, 8 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/platform/update_engine/delta_diff_generator.h ('k') | src/platform/update_engine/delta_performer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform/update_engine/delta_diff_generator.cc
diff --git a/src/platform/update_engine/delta_diff_generator.cc b/src/platform/update_engine/delta_diff_generator.cc
index 6b880cd2d080503c2728c0c17f56fce804e96966..23c5fc8d8a3a1f975b2a289190c4d17a44be5746 100644
--- a/src/platform/update_engine/delta_diff_generator.cc
+++ b/src/platform/update_engine/delta_diff_generator.cc
@@ -390,6 +390,7 @@ bool WriteUint64AsBigEndian(FileWriter* writer, const uint64_t value) {
void InstallOperationsToManifest(
const Graph& graph,
const vector<Vertex::Index>& order,
+ const vector<DeltaArchiveManifest_InstallOperation>& kernel_ops,
DeltaArchiveManifest* out_manifest) {
for (vector<Vertex::Index>::const_iterator it = order.begin();
it != order.end(); ++it) {
@@ -397,6 +398,12 @@ void InstallOperationsToManifest(
out_manifest->add_install_operations();
*op = graph[*it].op;
}
+ for (vector<DeltaArchiveManifest_InstallOperation>::const_iterator it =
+ kernel_ops.begin(); it != kernel_ops.end(); ++it) {
+ DeltaArchiveManifest_InstallOperation* op =
+ out_manifest->add_kernel_install_operations();
+ *op = *it;
+ }
}
void CheckGraph(const Graph& graph) {
@@ -405,6 +412,55 @@ void CheckGraph(const Graph& graph) {
}
}
+// Delta compresses a kernel partition new_kernel_part with knowledge of
+// the old kernel partition old_kernel_part.
+bool DeltaCompressKernelPartition(
+ const string& old_kernel_part,
+ const string& new_kernel_part,
+ vector<DeltaArchiveManifest_InstallOperation>* ops,
+ int blobs_fd,
+ off_t* blobs_length) {
+ // For now, just bsdiff the kernel partition as a whole.
+ // TODO(adlr): Use knowledge of how the kernel partition is laid out
+ // to more efficiently compress it.
+
+ LOG(INFO) << "Delta compressing kernel partition...";
+
+ // Add a new install operation
+ ops->resize(1);
+ DeltaArchiveManifest_InstallOperation* op = &(*ops)[0];
+ op->set_type(DeltaArchiveManifest_InstallOperation_Type_BSDIFF);
+ op->set_data_offset(*blobs_length);
+
+ // Do the actual compression
+ vector<char> data;
+ TEST_AND_RETURN_FALSE(BsdiffFiles(old_kernel_part, new_kernel_part, &data));
+ TEST_AND_RETURN_FALSE(utils::WriteAll(blobs_fd, &data[0], data.size()));
+ *blobs_length += data.size();
+
+ off_t old_part_size = utils::FileSize(old_kernel_part);
+ TEST_AND_RETURN_FALSE(old_part_size >= 0);
+ off_t new_part_size = utils::FileSize(new_kernel_part);
+ TEST_AND_RETURN_FALSE(new_part_size >= 0);
+
+ op->set_data_length(data.size());
+
+ op->set_src_length(old_part_size);
+ op->set_dst_length(new_part_size);
+
+ // Theres a single src/dest extent for each
+ Extent* src_extent = op->add_src_extents();
+ src_extent->set_start_block(0);
+ src_extent->set_num_blocks((old_part_size + kBlockSize - 1) / kBlockSize);
+
+ Extent* dst_extent = op->add_dst_extents();
+ dst_extent->set_start_block(0);
+ dst_extent->set_num_blocks((new_part_size + kBlockSize - 1) / kBlockSize);
+
+ LOG(INFO) << "Done delta compressing kernel partition.";
+ return true;
+}
+
} // namespace {}
bool DeltaDiffGenerator::ReadFileToDiff(
@@ -653,9 +709,15 @@ bool DeltaDiffGenerator::ReorderDataBlobs(
ScopedFileWriterCloser writer_closer(&writer);
uint64_t out_file_size = 0;
- for (int i = 0; i < manifest->install_operations_size(); i++) {
- DeltaArchiveManifest_InstallOperation* op =
- manifest->mutable_install_operations(i);
+ for (int i = 0; i < (manifest->install_operations_size() +
+ manifest->kernel_install_operations_size()); i++) {
+ DeltaArchiveManifest_InstallOperation* op = NULL;
+ if (i < manifest->install_operations_size()) {
+ op = manifest->mutable_install_operations(i);
+ } else {
+ op = manifest->mutable_kernel_install_operations(
+ i - manifest->install_operations_size());
+ }
if (!op->has_data_offset())
continue;
CHECK(op->has_data_length());
@@ -671,11 +733,14 @@ bool DeltaDiffGenerator::ReorderDataBlobs(
return true;
}
-bool DeltaDiffGenerator::GenerateDeltaUpdateFile(const string& old_root,
- const string& old_image,
- const string& new_root,
- const string& new_image,
- const string& output_path) {
+bool DeltaDiffGenerator::GenerateDeltaUpdateFile(
+ const string& old_root,
+ const string& old_image,
+ const string& new_root,
+ const string& new_image,
+ const std::string& old_kernel_part,
+ const std::string& new_kernel_part,
+ const string& output_path) {
struct stat old_image_stbuf;
TEST_AND_RETURN_FALSE_ERRNO(stat(old_image.c_str(), &old_image_stbuf) == 0);
struct stat new_image_stbuf;
@@ -687,6 +752,10 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(const string& old_root,
LOG_IF(FATAL, old_image_stbuf.st_size % kBlockSize)
<< "Old image not a multiple of block size " << kBlockSize;
+ // Sanity check kernel partition args
+ TEST_AND_RETURN_FALSE(utils::FileSize(old_kernel_part) >= 0);
+ TEST_AND_RETURN_FALSE(utils::FileSize(new_kernel_part) >= 0);
+
vector<Block> blocks(min(old_image_stbuf.st_size / kBlockSize,
new_image_stbuf.st_size / kBlockSize));
LOG(INFO) << "invalid: " << Vertex::kInvalidIndex;
@@ -704,6 +773,8 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(const string& old_root,
LOG(INFO) << "Reading files...";
+ vector<DeltaArchiveManifest_InstallOperation> kernel_ops;
+
DeltaArchiveManifest_InstallOperation final_op;
{
int fd;
@@ -720,12 +791,18 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(const string& old_root,
&data_file_size));
CheckGraph(graph);
- // TODO(adlr): read all the rest of the blocks in
TEST_AND_RETURN_FALSE(ReadUnwrittenBlocks(blocks,
fd,
&data_file_size,
new_image,
&final_op));
+
+ // Read kernel partition
+ TEST_AND_RETURN_FALSE(DeltaCompressKernelPartition(old_kernel_part,
+ new_kernel_part,
+ &kernel_ops,
+ fd,
+ &data_file_size));
}
CheckGraph(graph);
@@ -753,7 +830,7 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(const string& old_root,
// Convert to protobuf Manifest object
DeltaArchiveManifest manifest;
CheckGraph(graph);
- InstallOperationsToManifest(graph, final_order, &manifest);
+ InstallOperationsToManifest(graph, final_order, kernel_ops, &manifest);
{
// Write final operation
DeltaArchiveManifest_InstallOperation* op =
@@ -762,9 +839,9 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(const string& old_root,
CHECK(op->has_type());
LOG(INFO) << "final op length: " << op->data_length();
}
+
CheckGraph(graph);
manifest.set_block_size(kBlockSize);
- // TODO(adlr): set checksums
// Reorder the data blobs with the newly ordered manifest
string ordered_blobs_path;
@@ -780,9 +857,13 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(const string& old_root,
{
vector<uint32_t> written_count(blocks.size(), 0);
uint64_t next_blob_offset = 0;
- for (int i = 0; i < manifest.install_operations_size(); i++) {
+ for (int i = 0; i < (manifest.install_operations_size() +
+ manifest.kernel_install_operations_size()); i++) {
const DeltaArchiveManifest_InstallOperation& op =
- manifest.install_operations(i);
+ i < manifest.install_operations_size() ?
+ manifest.install_operations(i) :
+ manifest.kernel_install_operations(
+ i - manifest.install_operations_size());
for (int j = 0; j < op.dst_extents_size(); j++) {
const Extent& extent = op.dst_extents(j);
for (uint64_t block = extent.start_block();
« no previous file with comments | « src/platform/update_engine/delta_diff_generator.h ('k') | src/platform/update_engine/delta_performer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698