Support IsDeltaPayload per <package>.
Mixed full and delta payloads are now supported for multi-payload.
Bug: 36252799
Test: update_engine_unittests
Change-Id: Ic519f8399579c714a65ba9f9f948a389fcc249ed
(cherry picked from commit 4928112f8635f7a5b583171640aee2bda690ba34)
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index ab5e275..94c5c60 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -340,7 +340,7 @@
const InstallPlan::Partition& install_part =
install_plan_->partitions[num_previous_partitions + current_partition_];
// Open source fds if we have a delta payload with minor version >= 2.
- if (install_plan_->payload_type == InstallPayloadType::kDelta &&
+ if (payload_->type == InstallPayloadType::kDelta &&
GetMinorVersion() != kInPlaceMinorPayloadVersion) {
source_path_ = install_part.source_path;
int err;
@@ -431,7 +431,7 @@
if (manifest_.has_minor_version()) {
return manifest_.minor_version();
} else {
- return install_plan_->payload_type == InstallPayloadType::kDelta
+ return payload_->type == InstallPayloadType::kDelta
? kSupportedMinorPayloadVersion
: kFullPayloadMinorVersion;
}
@@ -1427,14 +1427,14 @@
InstallPayloadType actual_payload_type =
has_old_fields ? InstallPayloadType::kDelta : InstallPayloadType::kFull;
- if (install_plan_->payload_type == InstallPayloadType::kUnknown) {
+ if (payload_->type == InstallPayloadType::kUnknown) {
LOG(INFO) << "Detected a '"
<< InstallPayloadTypeToString(actual_payload_type)
<< "' payload.";
- install_plan_->payload_type = actual_payload_type;
- } else if (install_plan_->payload_type != actual_payload_type) {
+ payload_->type = actual_payload_type;
+ } else if (payload_->type != actual_payload_type) {
LOG(ERROR) << "InstallPlan expected a '"
- << InstallPayloadTypeToString(install_plan_->payload_type)
+ << InstallPayloadTypeToString(payload_->type)
<< "' payload but the downloaded manifest contains a '"
<< InstallPayloadTypeToString(actual_payload_type)
<< "' payload.";
diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc
index a3f653b..bc67d93 100644
--- a/payload_consumer/delta_performer_integration_test.cc
+++ b/payload_consumer/delta_performer_integration_test.cc
@@ -719,12 +719,11 @@
// Update the A image in place.
InstallPlan* install_plan = &state->install_plan;
- install_plan->payloads.resize(1);
install_plan->hash_checks_mandatory = hash_checks_mandatory;
- install_plan->payloads[0].metadata_size = state->metadata_size;
- install_plan->payload_type = (full_kernel && full_rootfs)
- ? InstallPayloadType::kFull
- : InstallPayloadType::kDelta;
+ install_plan->payloads = {{.metadata_size = state->metadata_size,
+ .type = (full_kernel && full_rootfs)
+ ? InstallPayloadType::kFull
+ : InstallPayloadType::kDelta}};
install_plan->source_slot = 0;
install_plan->target_slot = 1;
diff --git a/payload_consumer/delta_performer_unittest.cc b/payload_consumer/delta_performer_unittest.cc
index 3af13ec..1e06e1a 100644
--- a/payload_consumer/delta_performer_unittest.cc
+++ b/payload_consumer/delta_performer_unittest.cc
@@ -103,7 +103,7 @@
uint64_t major_version,
InstallPayloadType payload_type,
ErrorCode expected) {
- install_plan_.payload_type = payload_type;
+ payload_.type = payload_type;
// The Manifest we are validating.
performer_.manifest_.CopyFrom(manifest);
@@ -338,7 +338,7 @@
};
TEST_F(DeltaPerformerTest, FullPayloadWriteTest) {
- install_plan_.payload_type = InstallPayloadType::kFull;
+ payload_.type = InstallPayloadType::kFull;
brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
std::end(kRandomString));
expected_data.resize(4096); // block size
@@ -357,7 +357,7 @@
}
TEST_F(DeltaPerformerTest, ShouldCancelTest) {
- install_plan_.payload_type = InstallPayloadType::kFull;
+ payload_.type = InstallPayloadType::kFull;
brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
std::end(kRandomString));
expected_data.resize(4096); // block size
diff --git a/payload_consumer/download_action_unittest.cc b/payload_consumer/download_action_unittest.cc
index 9d85550..7d3ac6c 100644
--- a/payload_consumer/download_action_unittest.cc
+++ b/payload_consumer/download_action_unittest.cc
@@ -141,8 +141,8 @@
uint64_t size = data.size() - 1;
InstallPlan install_plan;
- install_plan.payload_type = InstallPayloadType::kDelta;
- install_plan.payloads.push_back({.size = size});
+ install_plan.payloads.push_back(
+ {.size = size, .type = InstallPayloadType::kDelta});
// We pull off the first byte from data and seek past it.
EXPECT_TRUE(HashCalculator::RawHashOfBytes(
&data[1], data.size() - 1, &install_plan.payloads[0].hash));
diff --git a/payload_consumer/filesystem_verifier_action.cc b/payload_consumer/filesystem_verifier_action.cc
index 4f30582..5edde9e 100644
--- a/payload_consumer/filesystem_verifier_action.cc
+++ b/payload_consumer/filesystem_verifier_action.cc
@@ -204,8 +204,10 @@
if (partition.target_hash != hasher_->raw_hash()) {
LOG(ERROR) << "New '" << partition.name
<< "' partition verification failed.";
- if (install_plan_.payload_type == InstallPayloadType::kFull)
+ if (partition.source_hash.empty()) {
+ // No need to verify source if it is a full payload.
return Cleanup(ErrorCode::kNewRootfsVerificationError);
+ }
// If we have not verified source partition yet, now that the target
// partition does not match, and it's not a full payload, we need to
// switch to kVerifySourceHash step to check if it's because the source
diff --git a/payload_consumer/install_plan.cc b/payload_consumer/install_plan.cc
index 5f004bf..d5d745b 100644
--- a/payload_consumer/install_plan.cc
+++ b/payload_consumer/install_plan.cc
@@ -42,7 +42,6 @@
bool InstallPlan::operator==(const InstallPlan& that) const {
return ((is_resume == that.is_resume) &&
- (payload_type == that.payload_type) &&
(download_url == that.download_url) && (payloads == that.payloads) &&
(source_slot == that.source_slot) &&
(target_slot == that.target_slot) && (partitions == that.partitions));
@@ -67,15 +66,15 @@
for (const auto& payload : payloads) {
payloads_str += base::StringPrintf(
", payload: (size: %" PRIu64 ", metadata_size: %" PRIu64
- ", metadata signature: %s, hash: %s)",
+ ", metadata signature: %s, hash: %s, payload type: %s)",
payload.size,
payload.metadata_size,
payload.metadata_signature.c_str(),
- base::HexEncode(payload.hash.data(), payload.hash.size()).c_str());
+ base::HexEncode(payload.hash.data(), payload.hash.size()).c_str(),
+ InstallPayloadTypeToString(payload.type).c_str());
}
LOG(INFO) << "InstallPlan: " << (is_resume ? "resume" : "new_update")
- << ", payload type: " << InstallPayloadTypeToString(payload_type)
<< ", source_slot: " << BootControlInterface::SlotName(source_slot)
<< ", target_slot: " << BootControlInterface::SlotName(target_slot)
<< ", url: " << download_url << payloads_str << partitions_str
diff --git a/payload_consumer/install_plan.h b/payload_consumer/install_plan.h
index d8d9f57..6dd5a73 100644
--- a/payload_consumer/install_plan.h
+++ b/payload_consumer/install_plan.h
@@ -52,7 +52,6 @@
bool LoadPartitionsFromSlots(BootControlInterface* boot_control);
bool is_resume{false};
- InstallPayloadType payload_type{InstallPayloadType::kUnknown};
std::string download_url; // url to download from
std::string version; // version we are installing.
@@ -61,6 +60,7 @@
uint64_t metadata_size = 0; // size of the metadata
std::string metadata_signature; // signature of the metadata in base64
brillo::Blob hash; // SHA256 hash of the payload
+ InstallPayloadType type{InstallPayloadType::kUnknown};
// Only download manifest and fill in partitions in install plan without
// apply the payload if true. Will be set by DownloadAction when resuming
// multi-payload.
@@ -69,7 +69,8 @@
bool operator==(const Payload& that) const {
return size == that.size && metadata_size == that.metadata_size &&
metadata_signature == that.metadata_signature &&
- hash == that.hash && already_applied == that.already_applied;
+ hash == that.hash && type == that.type &&
+ already_applied == that.already_applied;
}
};
std::vector<Payload> payloads;