AU: When applying delta locally, get source checksums
When applying a delta on the host, we need to calculate the original
checksums for the rootfs/kernel for the delta performer. This CL does
that.
Also:
- Log old/new checksums in performer
- Add base64 encode function to OmahaHashCalculator
BUG=8062
TEST=unittests; applied delta on host
Review URL: http://codereview.chromium.org/4042004
Change-Id: I953d7dd34cb65269e9b44e22c87a13a7f52e66d4
diff --git a/delta_diff_generator.cc b/delta_diff_generator.cc
index b447f11..03b59d9 100644
--- a/delta_diff_generator.cc
+++ b/delta_diff_generator.cc
@@ -611,9 +611,9 @@
return true;
}
-bool InitializePartitionInfo(bool is_kernel,
- const string& partition,
- PartitionInfo* info) {
+bool DeltaDiffGenerator::InitializePartitionInfo(bool is_kernel,
+ const string& partition,
+ PartitionInfo* info) {
int64_t size = 0;
if (is_kernel) {
size = utils::FileSize(partition);
@@ -641,25 +641,25 @@
const string& new_rootfs,
DeltaArchiveManifest* manifest) {
if (!old_kernel.empty()) {
- TEST_AND_RETURN_FALSE(
- InitializePartitionInfo(true,
- old_kernel,
- manifest->mutable_old_kernel_info()));
+ TEST_AND_RETURN_FALSE(DeltaDiffGenerator::InitializePartitionInfo(
+ true,
+ old_kernel,
+ manifest->mutable_old_kernel_info()));
}
- TEST_AND_RETURN_FALSE(
- InitializePartitionInfo(true,
- new_kernel,
- manifest->mutable_new_kernel_info()));
+ TEST_AND_RETURN_FALSE(DeltaDiffGenerator::InitializePartitionInfo(
+ true,
+ new_kernel,
+ manifest->mutable_new_kernel_info()));
if (!old_rootfs.empty()) {
- TEST_AND_RETURN_FALSE(
- InitializePartitionInfo(false,
- old_rootfs,
- manifest->mutable_old_rootfs_info()));
+ TEST_AND_RETURN_FALSE(DeltaDiffGenerator::InitializePartitionInfo(
+ false,
+ old_rootfs,
+ manifest->mutable_old_rootfs_info()));
}
- TEST_AND_RETURN_FALSE(
- InitializePartitionInfo(false,
- new_rootfs,
- manifest->mutable_new_rootfs_info()));
+ TEST_AND_RETURN_FALSE(DeltaDiffGenerator::InitializePartitionInfo(
+ false,
+ new_rootfs,
+ manifest->mutable_new_rootfs_info()));
return true;
}
diff --git a/delta_diff_generator.h b/delta_diff_generator.h
index 9fbe0a5..3156fd6 100644
--- a/delta_diff_generator.h
+++ b/delta_diff_generator.h
@@ -215,6 +215,10 @@
// (e.g., a move operation that copies blocks onto themselves).
static bool IsNoopOperation(const DeltaArchiveManifest_InstallOperation& op);
+ static bool InitializePartitionInfo(bool is_kernel,
+ const std::string& partition,
+ PartitionInfo* info);
+
private:
// This should never be constructed
DISALLOW_IMPLICIT_CONSTRUCTORS(DeltaDiffGenerator);
diff --git a/delta_performer.cc b/delta_performer.cc
index 134316e..e14ad4e 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -165,6 +165,33 @@
return -err;
}
+namespace {
+
+void LogPartitionInfoHash(const PartitionInfo& info, const string& tag) {
+ string sha256;
+ if (OmahaHashCalculator::Base64Encode(info.hash().data(),
+ info.hash().size(),
+ &sha256)) {
+ LOG(INFO) << "PartitionInfo " << tag << " sha256:" << sha256
+ << " length:" << tag.size();
+ } else {
+ LOG(ERROR) << "Base64Encode failed for tag: " << tag;
+ }
+}
+
+void LogPartitionInfo(const DeltaArchiveManifest& manifest) {
+ if (manifest.has_old_kernel_info())
+ LogPartitionInfoHash(manifest.old_kernel_info(), "old_kernel_info");
+ if (manifest.has_old_rootfs_info())
+ LogPartitionInfoHash(manifest.old_rootfs_info(), "old_rootfs_info");
+ if (manifest.has_new_kernel_info())
+ LogPartitionInfoHash(manifest.new_kernel_info(), "new_kernel_info");
+ if (manifest.has_new_rootfs_info())
+ LogPartitionInfoHash(manifest.new_rootfs_info(), "new_rootfs_info");
+}
+
+} // namespace {}
+
// Wrapper around write. Returns bytes written on success or
// -errno on error.
// This function performs as many actions as it can, given the amount of
@@ -207,6 +234,7 @@
manifest_metadata_size_))
<< "Unable to save the manifest metadata size.";
manifest_valid_ = true;
+ LogPartitionInfo(manifest_);
if (!PrimeUpdateState()) {
LOG(ERROR) << "Unable to prime the update state.";
return -EINVAL;
diff --git a/generate_delta_main.cc b/generate_delta_main.cc
index efeeb3b..39a0e08 100644
--- a/generate_delta_main.cc
+++ b/generate_delta_main.cc
@@ -76,7 +76,22 @@
LOG(INFO) << "Setting up preferences under: " << FLAGS_prefs_dir;
LOG_IF(ERROR, !prefs.Init(FilePath(FLAGS_prefs_dir)))
<< "Failed to initialize preferences.";
+ // Get original checksums
+ LOG(INFO) << "Calculating original checksums";
+ PartitionInfo kern_info, root_info;
+ CHECK(DeltaDiffGenerator::InitializePartitionInfo(true, // is_kernel
+ FLAGS_old_kernel,
+ &kern_info));
+ CHECK(DeltaDiffGenerator::InitializePartitionInfo(false, // is_kernel
+ FLAGS_old_image,
+ &root_info));
+ vector<char> kern_hash(kern_info.hash().begin(),
+ kern_info.hash().end());
+ vector<char> root_hash(root_info.hash().begin(),
+ root_info.hash().end());
DeltaPerformer performer(&prefs);
+ performer.set_current_kernel_hash(&kern_hash);
+ performer.set_current_rootfs_hash(&root_hash);
CHECK_EQ(performer.Open(FLAGS_old_image.c_str(), 0, 0), 0);
CHECK(performer.OpenKernel(FLAGS_old_kernel.c_str()));
vector<char> buf(1024 * 1024);
diff --git a/omaha_hash_calculator.cc b/omaha_hash_calculator.cc
index ac4edf4..cf583a9 100644
--- a/omaha_hash_calculator.cc
+++ b/omaha_hash_calculator.cc
@@ -63,18 +63,10 @@
return bytes_processed;
}
-// Call Finalize() when all data has been passed in. This mostly just
-// calls OpenSSL's SHA256_Final() and then base64 encodes the hash.
-bool OmahaHashCalculator::Finalize() {
+bool OmahaHashCalculator::Base64Encode(const void* data,
+ size_t size,
+ string* out) {
bool success = true;
- TEST_AND_RETURN_FALSE(hash_.empty());
- TEST_AND_RETURN_FALSE(raw_hash_.empty());
- raw_hash_.resize(SHA256_DIGEST_LENGTH);
- TEST_AND_RETURN_FALSE(
- SHA256_Final(reinterpret_cast<unsigned char*>(&raw_hash_[0]),
- &ctx_) == 1);
-
- // Convert raw_hash_ to base64 encoding and store it in hash_.
BIO *b64 = BIO_new(BIO_f_base64());
if (!b64)
LOG(INFO) << "BIO_new(BIO_f_base64()) failed";
@@ -84,14 +76,13 @@
if (b64 && bmem) {
b64 = BIO_push(b64, bmem);
success =
- (BIO_write(b64, &raw_hash_[0], raw_hash_.size()) ==
- static_cast<int>(raw_hash_.size()));
+ (BIO_write(b64, data, size) == static_cast<int>(size));
if (success)
success = (BIO_flush(b64) == 1);
BUF_MEM *bptr = NULL;
BIO_get_mem_ptr(b64, &bptr);
- hash_.assign(bptr->data, bptr->length - 1);
+ out->assign(bptr->data, bptr->length - 1);
}
if (b64) {
BIO_free_all(b64);
@@ -100,6 +91,20 @@
return success;
}
+// Call Finalize() when all data has been passed in. This mostly just
+// calls OpenSSL's SHA256_Final() and then base64 encodes the hash.
+bool OmahaHashCalculator::Finalize() {
+ TEST_AND_RETURN_FALSE(hash_.empty());
+ TEST_AND_RETURN_FALSE(raw_hash_.empty());
+ raw_hash_.resize(SHA256_DIGEST_LENGTH);
+ TEST_AND_RETURN_FALSE(
+ SHA256_Final(reinterpret_cast<unsigned char*>(&raw_hash_[0]),
+ &ctx_) == 1);
+
+ // Convert raw_hash_ to base64 encoding and store it in hash_.
+ return Base64Encode(&raw_hash_[0], raw_hash_.size(), &hash_);;
+}
+
bool OmahaHashCalculator::RawHashOfData(const vector<char>& data,
vector<char>* out_hash) {
OmahaHashCalculator calc;
diff --git a/omaha_hash_calculator.h b/omaha_hash_calculator.h
index dc9fe4e..762b8d4 100644
--- a/omaha_hash_calculator.h
+++ b/omaha_hash_calculator.h
@@ -70,6 +70,8 @@
static std::string OmahaHashOfString(const std::string& str);
static std::string OmahaHashOfData(const std::vector<char>& data);
+ static bool Base64Encode(const void* data, size_t size, std::string* out);
+
private:
// If non-empty, the final base64 encoded hash and the raw hash. Will only be
// set to non-empty when Finalize is called.