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

Unified Diff: delta_diff_generator.cc

Issue 3550020: AU: support for generating new style full updates. (Closed) Base URL: ssh://git@chromiumos-git/update_engine.git
Patch Set: fixes for review Created 10 years, 2 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 | « delta_diff_generator.h ('k') | delta_performer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: delta_diff_generator.cc
diff --git a/delta_diff_generator.cc b/delta_diff_generator.cc
index 676629aa03658b7490bd2e9430245d64ae281a4d..9a5219df20de9dad746ee07f2546b9928343e4b1 100644
--- a/delta_diff_generator.cc
+++ b/delta_diff_generator.cc
@@ -6,6 +6,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -47,9 +48,10 @@ namespace chromeos_update_engine {
typedef DeltaDiffGenerator::Block Block;
namespace {
-const size_t kBlockSize = 4096;
+const size_t kBlockSize = 4096; // bytes
const size_t kRootFSPartitionSize = 1 * 1024 * 1024 * 1024; // 1 GiB
const uint64_t kVersionNumber = 1;
+const uint64_t kFullUpdateChunkSize = 128 * 1024; // bytes
// Stores all Extents for a file into 'out'. Returns true on success.
bool GatherExtents(const string& path,
@@ -1119,6 +1121,82 @@ bool DeltaDiffGenerator::ConvertGraphToDag(Graph* graph,
return true;
}
+bool DeltaDiffGenerator::ReadFullUpdateFromDisk(
+ Graph* graph,
+ const std::string& new_kernel_part,
+ const std::string& new_image,
+ int fd,
+ off_t* data_file_size,
+ off_t chunk_size,
+ vector<DeltaArchiveManifest_InstallOperation>* kernel_ops,
+ std::vector<Vertex::Index>* final_order) {
+ TEST_AND_RETURN_FALSE(chunk_size > 0);
+ TEST_AND_RETURN_FALSE((chunk_size % kBlockSize) == 0);
+
+ // Get the sizes early in the function, so we can fail fast if the user
+ // passed us bad paths.
+ const off_t image_size = utils::FileSize(new_image);
+ TEST_AND_RETURN_FALSE(image_size >= 0);
+ const off_t kernel_size = utils::FileSize(new_kernel_part);
+ TEST_AND_RETURN_FALSE(kernel_size >= 0);
+
+ off_t part_sizes[] = { image_size, kernel_size };
+ string paths[] = { new_image, new_kernel_part };
+
+ for (int partition = 0; partition < 2; ++partition) {
+ const string& path = paths[partition];
+ LOG(INFO) << "compressing " << path;
+
+ int in_fd = open(path.c_str(), O_RDONLY, 0);
+ TEST_AND_RETURN_FALSE(in_fd >= 0);
+ ScopedFdCloser in_fd_closer(&in_fd);
+
+ for (off_t bytes_left = part_sizes[partition], counter = 0, offset = 0;
+ bytes_left > 0;
+ bytes_left -= chunk_size, ++counter, offset += chunk_size) {
+ LOG(INFO) << "offset = " << offset;
+ DeltaArchiveManifest_InstallOperation* op = NULL;
+ if (partition == 0) {
+ graph->resize(graph->size() + 1);
+ graph->back().file_name = path + StringPrintf("-%" PRIi64, counter);
+ op = &graph->back().op;
+ final_order->push_back(graph->size() - 1);
+ } else {
+ kernel_ops->resize(kernel_ops->size() + 1);
+ op = &kernel_ops->back();
+ }
+ LOG(INFO) << "have an op";
+
+ vector<char> buf(min(bytes_left, chunk_size));
+ LOG(INFO) << "buf size: " << buf.size();
+ ssize_t bytes_read = -1;
+
+ TEST_AND_RETURN_FALSE(utils::PReadAll(
+ in_fd, &buf[0], buf.size(), offset, &bytes_read));
+ TEST_AND_RETURN_FALSE(bytes_read == static_cast<ssize_t>(buf.size()));
+
+ vector<char> buf_compressed;
+
+ TEST_AND_RETURN_FALSE(BzipCompress(buf, &buf_compressed));
+ const bool compress = buf_compressed.size() < buf.size();
+ const vector<char>& use_buf = compress ? buf_compressed : buf;
+ if (compress) {
+ op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ);
+ } else {
+ op->set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE);
+ }
+ op->set_data_offset(*data_file_size);
+ *data_file_size += use_buf.size();
+ op->set_data_length(use_buf.size());
+ Extent* dst_extent = op->add_dst_extents();
+ dst_extent->set_start_block(offset / kBlockSize);
+ dst_extent->set_num_blocks(chunk_size / kBlockSize);
+ }
+ }
+
+ return true;
+}
+
bool DeltaDiffGenerator::GenerateDeltaUpdateFile(
const string& old_root,
const string& old_image,
@@ -1129,18 +1207,23 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(
const string& output_path,
const string& private_key_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;
TEST_AND_RETURN_FALSE_ERRNO(stat(new_image.c_str(), &new_image_stbuf) == 0);
- LOG_IF(WARNING, new_image_stbuf.st_size != old_image_stbuf.st_size)
- << "Old and new images are different sizes.";
+ if (!old_image.empty()) {
+ TEST_AND_RETURN_FALSE_ERRNO(stat(old_image.c_str(), &old_image_stbuf) == 0);
+ LOG_IF(WARNING, new_image_stbuf.st_size != old_image_stbuf.st_size)
+ << "Old and new images are different sizes.";
+ LOG_IF(FATAL, old_image_stbuf.st_size % kBlockSize)
+ << "Old image not a multiple of block size " << kBlockSize;
+ // Sanity check kernel partition arg
+ TEST_AND_RETURN_FALSE(utils::FileSize(old_kernel_part) >= 0);
+ } else {
+ old_image_stbuf.st_size = 0;
+ }
LOG_IF(FATAL, new_image_stbuf.st_size % kBlockSize)
<< "New image not a multiple of block size " << kBlockSize;
- 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);
+ // Sanity check kernel partition arg
TEST_AND_RETURN_FALSE(utils::FileSize(new_kernel_part) >= 0);
vector<Block> blocks(max(old_image_stbuf.st_size / kBlockSize,
@@ -1163,7 +1246,8 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(
vector<DeltaArchiveManifest_InstallOperation> kernel_ops;
vector<Vertex::Index> final_order;
- {
+ if (!old_image.empty()) {
+ // Delta update
int fd;
TEST_AND_RETURN_FALSE(
utils::MakeTempFile(kTempFileTemplate, &temp_file_path, &fd));
@@ -1206,6 +1290,17 @@ bool DeltaDiffGenerator::GenerateDeltaUpdateFile(
fd,
&data_file_size,
&final_order));
+ } else {
+ // Full update
+ int fd = 0;
+ TEST_AND_RETURN_FALSE(ReadFullUpdateFromDisk(&graph,
+ new_kernel_part,
+ new_image,
+ fd,
+ &data_file_size,
+ kFullUpdateChunkSize,
+ &kernel_ops,
+ &final_order));
}
// Convert to protobuf Manifest object
« no previous file with comments | « delta_diff_generator.h ('k') | delta_performer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698