diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-07-07 01:08:06 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-07-07 01:08:06 +0000 |
commit | ae5c096fdc54bcc77c15ad89fdd15b57294a07d7 (patch) | |
tree | ac9f414cebc9bd9cd28c43f2119d2e19dc03fbd4 | |
parent | 64d985b2cb4743815f8d548b7c523a47ef02c11f (diff) | |
parent | 2ce3ddfee1c0e8e35a62b2321f9895f9d35640df (diff) | |
download | core-ae5c096fdc54bcc77c15ad89fdd15b57294a07d7.tar.gz |
Snap for 6657150 from 2ce3ddfee1c0e8e35a62b2321f9895f9d35640df to rvc-release
Change-Id: Iec3e1c17991f947e056cb7df619fb4ec6782ee3a
-rw-r--r-- | fs_mgr/liblp/builder.cpp | 17 | ||||
-rw-r--r-- | fs_mgr/liblp/include/liblp/builder.h | 6 | ||||
-rw-r--r-- | fs_mgr/liblp/utility.cpp | 39 | ||||
-rw-r--r-- | fs_mgr/liblp/utility.h | 4 |
4 files changed, 59 insertions, 7 deletions
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp index 2f516fa9b..5554f7794 100644 --- a/fs_mgr/liblp/builder.cpp +++ b/fs_mgr/liblp/builder.cpp @@ -204,11 +204,18 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::NewForUpdate(const IPartitionO } } - if (IPropertyFetcher::GetInstance()->GetBoolProperty("ro.virtual_ab.enabled", false) && - !always_keep_source_slot) { - if (!UpdateMetadataForInPlaceSnapshot(metadata.get(), source_slot_number, - target_slot_number)) { - return nullptr; + if (IPropertyFetcher::GetInstance()->GetBoolProperty("ro.virtual_ab.enabled", false)) { + if (always_keep_source_slot) { + // always_keep_source_slot implies the target build does not support snapshots. + // Clear unsupported attributes. + SetMetadataHeaderV0(metadata.get()); + } else { + // !always_keep_source_slot implies the target build supports snapshots. Do snapshot + // updates. + if (!UpdateMetadataForInPlaceSnapshot(metadata.get(), source_slot_number, + target_slot_number)) { + return nullptr; + } } } diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h index bd3915061..6c7a70728 100644 --- a/fs_mgr/liblp/include/liblp/builder.h +++ b/fs_mgr/liblp/include/liblp/builder.h @@ -209,8 +209,10 @@ class MetadataBuilder { // metadata may not have the target slot's devices listed yet, in which // case, it is automatically upgraded to include all available block // devices. - // If |always_keep_source_slot| is set, on a Virtual A/B device, source slot - // partitions are kept. This is useful when applying a downgrade package. + // If |always_keep_source_slot| is set, on a Virtual A/B device + // - source slot partitions are kept. + // - UPDATED flag is cleared. + // This is useful when applying a downgrade package. static std::unique_ptr<MetadataBuilder> NewForUpdate(const IPartitionOpener& opener, const std::string& source_partition, uint32_t source_slot_number, diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp index 48c5c8318..d8e171b10 100644 --- a/fs_mgr/liblp/utility.cpp +++ b/fs_mgr/liblp/utility.cpp @@ -15,6 +15,7 @@ */ #include <fcntl.h> +#include <inttypes.h> #include <stdint.h> #include <sys/stat.h> #include <unistd.h> @@ -29,6 +30,7 @@ #include <vector> #include <android-base/file.h> +#include <android-base/stringprintf.h> #include <ext4_utils/ext4_utils.h> #include <openssl/sha.h> @@ -285,5 +287,42 @@ bool UpdateMetadataForInPlaceSnapshot(LpMetadata* metadata, uint32_t source_slot return true; } +inline std::string ToHexString(uint64_t value) { + return android::base::StringPrintf("0x%" PRIx64, value); +} + +void SetMetadataHeaderV0(LpMetadata* metadata) { + if (metadata->header.minor_version <= LP_METADATA_MINOR_VERSION_MIN) { + return; + } + LINFO << "Forcefully setting metadata header version " << LP_METADATA_MAJOR_VERSION << "." + << metadata->header.minor_version << " to " << LP_METADATA_MAJOR_VERSION << "." + << LP_METADATA_MINOR_VERSION_MIN; + metadata->header.minor_version = LP_METADATA_MINOR_VERSION_MIN; + metadata->header.header_size = sizeof(LpMetadataHeaderV1_0); + + // Retrofit Virtual A/B devices should have version 10.1, so flags shouldn't be set. + // Warn if this is the case, but zero it out anyways. + if (metadata->header.flags) { + LWARN << "Zeroing unexpected flags: " << ToHexString(metadata->header.flags); + } + + // Zero out all fields beyond LpMetadataHeaderV0. + static_assert(sizeof(metadata->header) > sizeof(LpMetadataHeaderV1_0)); + memset(reinterpret_cast<uint8_t*>(&metadata->header) + sizeof(LpMetadataHeaderV1_0), 0, + sizeof(metadata->header) - sizeof(LpMetadataHeaderV1_0)); + + // Clear partition attributes unknown to V0. + // On retrofit Virtual A/B devices, UPDATED flag may be set, so only log info here. + for (auto& partition : metadata->partitions) { + if (partition.attributes & ~LP_PARTITION_ATTRIBUTE_MASK_V0) { + LINFO << "Clearing " << GetPartitionName(partition) + << " partition attribute: " << ToHexString(partition.attributes); + } + + partition.attributes &= LP_PARTITION_ATTRIBUTE_MASK_V0; + } +} + } // namespace fs_mgr } // namespace android diff --git a/fs_mgr/liblp/utility.h b/fs_mgr/liblp/utility.h index 06617696c..1d86edd4e 100644 --- a/fs_mgr/liblp/utility.h +++ b/fs_mgr/liblp/utility.h @@ -103,6 +103,10 @@ bool SetBlockReadonly(int fd, bool readonly); bool UpdateMetadataForInPlaceSnapshot(LpMetadata* metadata, uint32_t source_slot_number, uint32_t target_slot_number); +// Forcefully set metadata header version to 1.0, clearing any incompatible flags and attributes +// so that when downgrading to a build with liblp V0, the device still boots. +void SetMetadataHeaderV0(LpMetadata* metadata); + } // namespace fs_mgr } // namespace android |