Support a range of major and minor version.
In DeltaPerformer we set a supported major and minor version and only
accept that perticular version, but in reality we still support older
versions to test backward comatibility.
This CL change the supported major and minor version to a range to
reflect the truth of which version is supported and moved them to
payload_constants.
This is also useful when we have multi payload and want to reuse old
payload for non system partition while updating the system partition
to use a higher minor version.
Bug: 36289531
Test: update_engine_unittests
Change-Id: I49d73d69e64d78dfc2db21446faa98b3579ff995
Merged-In: I49d73d69e64d78dfc2db21446faa98b3579ff995
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 042861f..81a38e9 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -66,10 +66,6 @@
using std::vector;
namespace chromeos_update_engine {
-
-const uint64_t DeltaPerformer::kSupportedMajorPayloadVersion = 2;
-const uint32_t DeltaPerformer::kSupportedMinorPayloadVersion = 5;
-
const unsigned DeltaPerformer::kProgressLogMaxChunks = 10;
const unsigned DeltaPerformer::kProgressLogTimeoutSeconds = 30;
const unsigned DeltaPerformer::kProgressDownloadWeight = 50;
@@ -468,11 +464,10 @@
uint32_t DeltaPerformer::GetMinorVersion() const {
if (manifest_.has_minor_version()) {
return manifest_.minor_version();
- } else {
- return payload_->type == InstallPayloadType::kDelta
- ? kSupportedMinorPayloadVersion
- : kFullPayloadMinorVersion;
}
+ return payload_->type == InstallPayloadType::kDelta
+ ? kMaxSupportedMinorPayloadVersion
+ : kFullPayloadMinorVersion;
}
bool DeltaPerformer::IsHeaderParsed() const {
@@ -484,8 +479,8 @@
*error = ErrorCode::kSuccess;
if (!IsHeaderParsed()) {
- MetadataParseResult result = payload_metadata_.ParsePayloadHeader(
- payload, supported_major_version_, error);
+ MetadataParseResult result =
+ payload_metadata_.ParsePayloadHeader(payload, error);
if (result != MetadataParseResult::kSuccess)
return result;
@@ -1527,11 +1522,13 @@
return ErrorCode::kUnsupportedMinorPayloadVersion;
}
} else {
- if (manifest_.minor_version() != supported_minor_version_) {
+ if (manifest_.minor_version() < kMinSupportedMinorPayloadVersion ||
+ manifest_.minor_version() > kMaxSupportedMinorPayloadVersion) {
LOG(ERROR) << "Manifest contains minor version "
<< manifest_.minor_version()
- << " not the supported "
- << supported_minor_version_;
+ << " not in the range of supported minor versions ["
+ << kMinSupportedMinorPayloadVersion << ", "
+ << kMaxSupportedMinorPayloadVersion << "].";
return ErrorCode::kUnsupportedMinorPayloadVersion;
}
}
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index b156e2f..57bad26 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -48,9 +48,6 @@
class DeltaPerformer : public FileWriter {
public:
- static const uint64_t kSupportedMajorPayloadVersion;
- static const uint32_t kSupportedMinorPayloadVersion;
-
// Defines the granularity of progress logging in terms of how many "completed
// chunks" we want to report at the most.
static const unsigned kProgressLogMaxChunks;
@@ -391,12 +388,6 @@
base::TimeDelta::FromSeconds(kProgressLogTimeoutSeconds)};
base::Time forced_progress_log_time_;
- // The payload major payload version supported by DeltaPerformer.
- uint64_t supported_major_version_{kSupportedMajorPayloadVersion};
-
- // The delta minor payload version supported by DeltaPerformer.
- uint32_t supported_minor_version_{kSupportedMinorPayloadVersion};
-
DISALLOW_COPY_AND_ASSIGN(DeltaPerformer);
};
diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc
index f415f1d..ef99cc9 100644
--- a/payload_consumer/delta_performer_integration_test.cc
+++ b/payload_consumer/delta_performer_integration_test.cc
@@ -116,13 +116,7 @@
} // namespace
-class DeltaPerformerIntegrationTest : public ::testing::Test {
- public:
- static void SetSupportedVersion(DeltaPerformer* performer,
- uint64_t minor_version) {
- performer->supported_minor_version_ = minor_version;
- }
-};
+class DeltaPerformerIntegrationTest : public ::testing::Test {};
static void CompareFilesByBlock(const string& a_file, const string& b_file,
size_t image_size) {
@@ -752,7 +746,6 @@
string public_key_path = GetBuildArtifactsPath(kUnittestPublicKeyPath);
EXPECT_TRUE(utils::FileExists(public_key_path.c_str()));
(*performer)->set_public_key_path(public_key_path);
- DeltaPerformerIntegrationTest::SetSupportedVersion(*performer, minor_version);
EXPECT_EQ(static_cast<off_t>(state->image_size),
HashCalculator::RawHashOfFile(
diff --git a/payload_consumer/delta_performer_unittest.cc b/payload_consumer/delta_performer_unittest.cc
index 921df99..df1149f 100644
--- a/payload_consumer/delta_performer_unittest.cc
+++ b/payload_consumer/delta_performer_unittest.cc
@@ -172,9 +172,11 @@
brillo::Blob GeneratePayload(const brillo::Blob& blob_data,
const vector<AnnotatedOperation>& aops,
bool sign_payload) {
- return GeneratePayload(blob_data, aops, sign_payload,
- DeltaPerformer::kSupportedMajorPayloadVersion,
- DeltaPerformer::kSupportedMinorPayloadVersion);
+ return GeneratePayload(blob_data,
+ aops,
+ sign_payload,
+ kMaxSupportedMajorPayloadVersion,
+ kMaxSupportedMinorPayloadVersion);
}
brillo::Blob GeneratePayload(const brillo::Blob& blob_data,
@@ -412,9 +414,6 @@
return performer_.source_ecc_recovered_failures_;
}
- void SetSupportedMajorVersion(uint64_t major_version) {
- performer_.supported_major_version_ = major_version;
- }
FakePrefs prefs_;
InstallPlan install_plan_;
InstallPlan::Payload payload_;
@@ -724,7 +723,22 @@
manifest.mutable_old_rootfs_info();
manifest.mutable_new_kernel_info();
manifest.mutable_new_rootfs_info();
- manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
+ manifest.set_minor_version(kMaxSupportedMinorPayloadVersion);
+
+ RunManifestValidation(manifest,
+ kChromeOSMajorPayloadVersion,
+ InstallPayloadType::kDelta,
+ ErrorCode::kSuccess);
+}
+
+TEST_F(DeltaPerformerTest, ValidateManifestDeltaMinGoodTest) {
+ // The Manifest we are validating.
+ DeltaArchiveManifest manifest;
+ manifest.mutable_old_kernel_info();
+ manifest.mutable_old_rootfs_info();
+ manifest.mutable_new_kernel_info();
+ manifest.mutable_new_rootfs_info();
+ manifest.set_minor_version(kMinSupportedMinorPayloadVersion);
RunManifestValidation(manifest,
kChromeOSMajorPayloadVersion,
@@ -737,7 +751,7 @@
DeltaArchiveManifest manifest;
RunManifestValidation(manifest,
- DeltaPerformer::kSupportedMajorPayloadVersion,
+ kMaxSupportedMajorPayloadVersion,
InstallPayloadType::kFull,
ErrorCode::kSuccess);
}
@@ -750,7 +764,7 @@
manifest.mutable_old_rootfs_info();
RunManifestValidation(manifest,
- DeltaPerformer::kSupportedMajorPayloadVersion,
+ kMaxSupportedMajorPayloadVersion,
InstallPayloadType::kDelta,
ErrorCode::kUnsupportedMinorPayloadVersion);
}
@@ -761,7 +775,7 @@
manifest.mutable_old_kernel_info();
manifest.mutable_new_kernel_info();
manifest.mutable_new_rootfs_info();
- manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
+ manifest.set_minor_version(kMaxSupportedMinorPayloadVersion);
RunManifestValidation(manifest,
kChromeOSMajorPayloadVersion,
@@ -775,7 +789,7 @@
manifest.mutable_old_rootfs_info();
manifest.mutable_new_kernel_info();
manifest.mutable_new_rootfs_info();
- manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
+ manifest.set_minor_version(kMaxSupportedMinorPayloadVersion);
RunManifestValidation(manifest,
kChromeOSMajorPayloadVersion,
@@ -789,7 +803,7 @@
PartitionUpdate* partition = manifest.add_partitions();
partition->mutable_old_partition_info();
partition->mutable_new_partition_info();
- manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
+ manifest.set_minor_version(kMaxSupportedMinorPayloadVersion);
RunManifestValidation(manifest,
kBrilloMajorPayloadVersion,
@@ -802,13 +816,12 @@
DeltaArchiveManifest manifest;
// Generate a bad version number.
- manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion +
- 10000);
+ manifest.set_minor_version(kMaxSupportedMinorPayloadVersion + 10000);
// Mark the manifest as a delta payload by setting old_rootfs_info.
manifest.mutable_old_rootfs_info();
RunManifestValidation(manifest,
- DeltaPerformer::kSupportedMajorPayloadVersion,
+ kMaxSupportedMajorPayloadVersion,
InstallPayloadType::kDelta,
ErrorCode::kUnsupportedMinorPayloadVersion);
}
@@ -822,7 +835,7 @@
fake_hardware_.SetBuildTimestamp(2);
RunManifestValidation(manifest,
- DeltaPerformer::kSupportedMajorPayloadVersion,
+ kMaxSupportedMajorPayloadVersion,
InstallPayloadType::kFull,
ErrorCode::kPayloadTimestampError);
}
@@ -988,18 +1001,18 @@
TEST_F(DeltaPerformerTest, ConfVersionsMatch) {
// Test that the versions in update_engine.conf that is installed to the
- // image match the supported delta versions in the update engine.
+ // image match the maximum supported delta versions in the update engine.
uint32_t minor_version;
brillo::KeyValueStore store;
EXPECT_TRUE(store.Load(GetBuildArtifactsPath().Append("update_engine.conf")));
EXPECT_TRUE(utils::GetMinorVersion(store, &minor_version));
- EXPECT_EQ(DeltaPerformer::kSupportedMinorPayloadVersion, minor_version);
+ EXPECT_EQ(kMaxSupportedMinorPayloadVersion, minor_version);
string major_version_str;
uint64_t major_version;
EXPECT_TRUE(store.GetString("PAYLOAD_MAJOR_VERSION", &major_version_str));
EXPECT_TRUE(base::StringToUint64(major_version_str, &major_version));
- EXPECT_EQ(DeltaPerformer::kSupportedMajorPayloadVersion, major_version);
+ EXPECT_EQ(kMaxSupportedMajorPayloadVersion, major_version);
}
} // namespace chromeos_update_engine
diff --git a/payload_consumer/payload_constants.cc b/payload_consumer/payload_constants.cc
index e679316..797e76d 100644
--- a/payload_consumer/payload_constants.cc
+++ b/payload_consumer/payload_constants.cc
@@ -21,6 +21,9 @@
const uint64_t kChromeOSMajorPayloadVersion = 1;
const uint64_t kBrilloMajorPayloadVersion = 2;
+const uint32_t kMinSupportedMinorPayloadVersion = 1;
+const uint32_t kMaxSupportedMinorPayloadVersion = 5;
+
const uint32_t kFullPayloadMinorVersion = 0;
const uint32_t kInPlaceMinorPayloadVersion = 1;
const uint32_t kSourceMinorPayloadVersion = 2;
@@ -28,6 +31,9 @@
const uint32_t kBrotliBsdiffMinorPayloadVersion = 4;
const uint32_t kPuffdiffMinorPayloadVersion = 5;
+const uint64_t kMinSupportedMajorPayloadVersion = 1;
+const uint64_t kMaxSupportedMajorPayloadVersion = 2;
+
const uint64_t kMaxPayloadHeaderSize = 24;
const char kLegacyPartitionNameKernel[] = "boot";
diff --git a/payload_consumer/payload_constants.h b/payload_consumer/payload_constants.h
index ac3e882..43c3137 100644
--- a/payload_consumer/payload_constants.h
+++ b/payload_consumer/payload_constants.h
@@ -31,6 +31,10 @@
// The major version used by Brillo.
extern const uint64_t kBrilloMajorPayloadVersion;
+// The minimum and maximum supported major version.
+extern const uint64_t kMinSupportedMajorPayloadVersion;
+extern const uint64_t kMaxSupportedMajorPayloadVersion;
+
// The minor version used for all full payloads.
extern const uint32_t kFullPayloadMinorVersion;
@@ -49,6 +53,10 @@
// The minor version that allows PUFFDIFF operation.
extern const uint32_t kPuffdiffMinorPayloadVersion;
+// The minimum and maximum supported minor version.
+extern const uint32_t kMinSupportedMinorPayloadVersion;
+extern const uint32_t kMaxSupportedMinorPayloadVersion;
+
// The maximum size of the payload header (anything before the protobuf).
extern const uint64_t kMaxPayloadHeaderSize;
diff --git a/payload_consumer/payload_metadata.cc b/payload_consumer/payload_metadata.cc
index fe2df0a..f700228 100644
--- a/payload_consumer/payload_metadata.cc
+++ b/payload_consumer/payload_metadata.cc
@@ -60,9 +60,7 @@
}
MetadataParseResult PayloadMetadata::ParsePayloadHeader(
- const brillo::Blob& payload,
- uint64_t supported_major_version,
- ErrorCode* error) {
+ const brillo::Blob& payload, ErrorCode* error) {
uint64_t manifest_offset;
// Ensure we have data to cover the major payload version.
if (payload.size() < kDeltaManifestSizeOffset)
@@ -84,8 +82,8 @@
// Switch big endian to host.
major_payload_version_ = be64toh(major_payload_version_);
- if (major_payload_version_ != supported_major_version &&
- major_payload_version_ != kChromeOSMajorPayloadVersion) {
+ if (major_payload_version_ < kMinSupportedMajorPayloadVersion ||
+ major_payload_version_ > kMaxSupportedMajorPayloadVersion) {
LOG(ERROR) << "Bad payload format -- unsupported payload version: "
<< major_payload_version_;
*error = ErrorCode::kUnsupportedMajorPayloadVersion;
diff --git a/payload_consumer/payload_metadata.h b/payload_consumer/payload_metadata.h
index e00b5c1..fc1d128 100644
--- a/payload_consumer/payload_metadata.h
+++ b/payload_consumer/payload_metadata.h
@@ -54,7 +54,6 @@
// metadata. Returns kMetadataParseError if the metadata can't be parsed given
// the payload.
MetadataParseResult ParsePayloadHeader(const brillo::Blob& payload,
- uint64_t supported_major_version,
ErrorCode* error);
// Given the |payload|, verifies that the signed hash of its metadata matches
diff --git a/update_attempter_android.cc b/update_attempter_android.cc
index 7a4d34c..0e9621e 100644
--- a/update_attempter_android.cc
+++ b/update_attempter_android.cc
@@ -349,8 +349,7 @@
}
ErrorCode errorcode;
PayloadMetadata payload_metadata;
- if (payload_metadata.ParsePayloadHeader(
- metadata, kBrilloMajorPayloadVersion, &errorcode) !=
+ if (payload_metadata.ParsePayloadHeader(metadata, &errorcode) !=
MetadataParseResult::kSuccess) {
return LogAndSetError(error,
FROM_HERE,