| Index: delta_diff_generator.cc
|
| diff --git a/delta_diff_generator.cc b/delta_diff_generator.cc
|
| index f024481b048ade7128ce4e672a8f54c1437e16b7..3dcd2cbd2390f00944b5052116038ee64f5b1dea 100644
|
| --- a/delta_diff_generator.cc
|
| +++ b/delta_diff_generator.cc
|
| @@ -54,6 +54,13 @@ const size_t kRootFSPartitionSize = 1 * 1024 * 1024 * 1024; // 1 GiB
|
| const uint64_t kVersionNumber = 1;
|
| const uint64_t kFullUpdateChunkSize = 128 * 1024; // bytes
|
|
|
| +static const char* kInstallOperationTypes[] = {
|
| + "REPLACE",
|
| + "REPLACE_BZ",
|
| + "MOVE",
|
| + "BSDIFF"
|
| +};
|
| +
|
| // Stores all Extents for a file into 'out'. Returns true on success.
|
| bool GatherExtents(const string& path,
|
| google::protobuf::RepeatedPtrField<Extent>* out) {
|
| @@ -163,7 +170,8 @@ bool DeltaReadFile(Graph* graph,
|
| TEST_AND_RETURN_FALSE(DeltaDiffGenerator::ReadFileToDiff(old_root + path,
|
| new_root + path,
|
| &data,
|
| - &operation));
|
| + &operation,
|
| + true));
|
|
|
| // Write the data
|
| if (operation.type() != DeltaArchiveManifest_InstallOperation_Type_MOVE) {
|
| @@ -395,51 +403,40 @@ void CheckGraph(const Graph& graph) {
|
| }
|
| }
|
|
|
| -// Delta compresses a kernel partition new_kernel_part with knowledge of
|
| -// the old kernel partition old_kernel_part.
|
| +// Delta compresses a kernel partition |new_kernel_part| with knowledge of the
|
| +// old kernel partition |old_kernel_part|. If |old_kernel_part| is an empty
|
| +// string, generates a full update of the partition.
|
| 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...";
|
| + LOG_IF(INFO, old_kernel_part.empty()) << "Generating full kernel update...";
|
|
|
| // Add a new install operation
|
| ops->resize(1);
|
| DeltaArchiveManifest_InstallOperation* op = &(*ops)[0];
|
| - op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ);
|
| - op->set_data_offset(*blobs_length);
|
|
|
| - // Do the actual compression
|
| vector<char> data;
|
| - TEST_AND_RETURN_FALSE(utils::ReadFile(new_kernel_part, &data));
|
| - TEST_AND_RETURN_FALSE(!data.empty());
|
| -
|
| - vector<char> data_bz;
|
| - TEST_AND_RETURN_FALSE(BzipCompress(data, &data_bz));
|
| - CHECK(!data_bz.empty());
|
| -
|
| - TEST_AND_RETURN_FALSE(utils::WriteAll(blobs_fd, &data_bz[0], data_bz.size()));
|
| - *blobs_length += data_bz.size();
|
| -
|
| - off_t new_part_size = utils::FileSize(new_kernel_part);
|
| - TEST_AND_RETURN_FALSE(new_part_size >= 0);
|
| -
|
| - op->set_data_length(data_bz.size());
|
| + TEST_AND_RETURN_FALSE(DeltaDiffGenerator::ReadFileToDiff(old_kernel_part,
|
| + new_kernel_part,
|
| + &data,
|
| + op,
|
| + false));
|
|
|
| - op->set_dst_length(new_part_size);
|
| + // Write the data
|
| + if (op->type() != DeltaArchiveManifest_InstallOperation_Type_MOVE) {
|
| + op->set_data_offset(*blobs_length);
|
| + op->set_data_length(data.size());
|
| + }
|
|
|
| - // There's a single dest extent
|
| - Extent* dst_extent = op->add_dst_extents();
|
| - dst_extent->set_start_block(0);
|
| - dst_extent->set_num_blocks((new_part_size + kBlockSize - 1) / kBlockSize);
|
| + TEST_AND_RETURN_FALSE(utils::WriteAll(blobs_fd, &data[0], data.size()));
|
| + *blobs_length += data.size();
|
|
|
| - LOG(INFO) << "Done compressing kernel partition.";
|
| + LOG(INFO) << "Done delta compressing kernel partition: "
|
| + << kInstallOperationTypes[op->type()];
|
| return true;
|
| }
|
|
|
| @@ -456,13 +453,6 @@ struct DeltaObject {
|
| off_t size;
|
| };
|
|
|
| -static const char* kInstallOperationTypes[] = {
|
| - "REPLACE",
|
| - "REPLACE_BZ",
|
| - "MOVE",
|
| - "BSDIFF"
|
| -};
|
| -
|
| void ReportPayloadUsage(const Graph& graph,
|
| const DeltaArchiveManifest& manifest,
|
| const int64_t manifest_metadata_size) {
|
| @@ -517,7 +507,8 @@ bool DeltaDiffGenerator::ReadFileToDiff(
|
| const string& old_filename,
|
| const string& new_filename,
|
| vector<char>* out_data,
|
| - DeltaArchiveManifest_InstallOperation* out_op) {
|
| + DeltaArchiveManifest_InstallOperation* out_op,
|
| + bool gather_extents) {
|
| // Read new data in
|
| vector<char> new_data;
|
| TEST_AND_RETURN_FALSE(utils::ReadFile(new_filename, &new_data));
|
| @@ -544,10 +535,13 @@ bool DeltaDiffGenerator::ReadFileToDiff(
|
|
|
| // Do we have an original file to consider?
|
| struct stat old_stbuf;
|
| - if (0 != stat(old_filename.c_str(), &old_stbuf)) {
|
| + bool no_original = old_filename.empty();
|
| + if (!no_original && 0 != stat(old_filename.c_str(), &old_stbuf)) {
|
| // If stat-ing the old file fails, it should be because it doesn't exist.
|
| TEST_AND_RETURN_FALSE(errno == ENOTDIR || errno == ENOENT);
|
| - } else {
|
| + no_original = true;
|
| + }
|
| + if (!no_original) {
|
| // Read old data
|
| vector<char> old_data;
|
| TEST_AND_RETURN_FALSE(utils::ReadFile(old_filename, &old_data));
|
| @@ -576,13 +570,26 @@ bool DeltaDiffGenerator::ReadFileToDiff(
|
|
|
| if (operation.type() == DeltaArchiveManifest_InstallOperation_Type_MOVE ||
|
| operation.type() == DeltaArchiveManifest_InstallOperation_Type_BSDIFF) {
|
| - TEST_AND_RETURN_FALSE(
|
| - GatherExtents(old_filename, operation.mutable_src_extents()));
|
| + if (gather_extents) {
|
| + TEST_AND_RETURN_FALSE(
|
| + GatherExtents(old_filename, operation.mutable_src_extents()));
|
| + } else {
|
| + Extent* src_extent = operation.add_src_extents();
|
| + src_extent->set_start_block(0);
|
| + src_extent->set_num_blocks(
|
| + (old_stbuf.st_size + kBlockSize - 1) / kBlockSize);
|
| + }
|
| operation.set_src_length(old_stbuf.st_size);
|
| }
|
|
|
| - TEST_AND_RETURN_FALSE(
|
| - GatherExtents(new_filename, operation.mutable_dst_extents()));
|
| + if (gather_extents) {
|
| + TEST_AND_RETURN_FALSE(
|
| + GatherExtents(new_filename, operation.mutable_dst_extents()));
|
| + } else {
|
| + Extent* dst_extent = operation.add_dst_extents();
|
| + dst_extent->set_start_block(0);
|
| + dst_extent->set_num_blocks((new_data.size() + kBlockSize - 1) / kBlockSize);
|
| + }
|
| operation.set_dst_length(new_data.size());
|
|
|
| out_data->swap(data);
|
| @@ -1273,8 +1280,6 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(
|
| TEST_AND_RETURN_FALSE(old_image_block_size == new_image_block_size);
|
| LOG_IF(WARNING, old_image_block_count != new_image_block_count)
|
| << "Old and new images have different block counts.";
|
| - // Sanity check kernel partition arg
|
| - TEST_AND_RETURN_FALSE(utils::FileSize(old_kernel_part) >= 0);
|
| }
|
| // Sanity check kernel partition arg
|
| TEST_AND_RETURN_FALSE(utils::FileSize(new_kernel_part) >= 0);
|
|
|