Merge "liblp: Add an attribute to indicate that a partition has been updated."
This commit is contained in:
commit
74a6f4cf57
6 changed files with 65 additions and 7 deletions
|
|
@ -232,7 +232,7 @@ MetadataBuilder::MetadataBuilder() : auto_slot_suffixing_(false) {
|
|||
memset(&header_, 0, sizeof(header_));
|
||||
header_.magic = LP_METADATA_HEADER_MAGIC;
|
||||
header_.major_version = LP_METADATA_MAJOR_VERSION;
|
||||
header_.minor_version = LP_METADATA_MINOR_VERSION;
|
||||
header_.minor_version = LP_METADATA_MINOR_VERSION_MIN;
|
||||
header_.header_size = sizeof(header_);
|
||||
header_.partitions.entry_size = sizeof(LpMetadataPartition);
|
||||
header_.extents.entry_size = sizeof(LpMetadataExtent);
|
||||
|
|
@ -796,6 +796,11 @@ std::unique_ptr<LpMetadata> MetadataBuilder::Export() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (partition->attributes() & LP_PARTITION_ATTR_UPDATED) {
|
||||
static const uint16_t kMinVersion = LP_METADATA_VERSION_FOR_UPDATED_ATTR;
|
||||
metadata->header.minor_version = std::max(metadata->header.minor_version, kMinVersion);
|
||||
}
|
||||
|
||||
strncpy(part.name, partition->name().c_str(), sizeof(part.name));
|
||||
part.first_extent_index = static_cast<uint32_t>(metadata->extents.size());
|
||||
part.num_extents = static_cast<uint32_t>(partition->extents().size());
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ TEST_F(BuilderTest, BuilderExport) {
|
|||
const LpMetadataHeader& header = exported->header;
|
||||
EXPECT_EQ(header.magic, LP_METADATA_HEADER_MAGIC);
|
||||
EXPECT_EQ(header.major_version, LP_METADATA_MAJOR_VERSION);
|
||||
EXPECT_EQ(header.minor_version, LP_METADATA_MINOR_VERSION);
|
||||
EXPECT_EQ(header.minor_version, LP_METADATA_MINOR_VERSION_MIN);
|
||||
|
||||
ASSERT_EQ(exported->partitions.size(), 2);
|
||||
ASSERT_EQ(exported->extents.size(), 3);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,11 @@ extern "C" {
|
|||
|
||||
/* Current metadata version. */
|
||||
#define LP_METADATA_MAJOR_VERSION 10
|
||||
#define LP_METADATA_MINOR_VERSION 0
|
||||
#define LP_METADATA_MINOR_VERSION_MIN 0
|
||||
#define LP_METADATA_MINOR_VERSION_MAX 1
|
||||
|
||||
/* Metadata version needed to use the UPDATED partition attribute. */
|
||||
#define LP_METADATA_VERSION_FOR_UPDATED_ATTR 1
|
||||
|
||||
/* Attributes for the LpMetadataPartition::attributes field.
|
||||
*
|
||||
|
|
@ -58,8 +62,20 @@ extern "C" {
|
|||
*/
|
||||
#define LP_PARTITION_ATTR_SLOT_SUFFIXED (1 << 1)
|
||||
|
||||
/* Mask that defines all valid attributes. */
|
||||
#define LP_PARTITION_ATTRIBUTE_MASK (LP_PARTITION_ATTR_READONLY | LP_PARTITION_ATTR_SLOT_SUFFIXED)
|
||||
/* This flag is applied automatically when using MetadataBuilder::NewForUpdate.
|
||||
* It signals that the partition was created (or modified) for a snapshot-based
|
||||
* update. If this flag is not present, the partition was likely flashed via
|
||||
* fastboot.
|
||||
*/
|
||||
#define LP_PARTITION_ATTR_UPDATED (1 << 2)
|
||||
|
||||
/* Mask that defines all valid attributes. When changing this, make sure to
|
||||
* update ParseMetadata().
|
||||
*/
|
||||
#define LP_PARTITION_ATTRIBUTE_MASK_V0 \
|
||||
(LP_PARTITION_ATTR_READONLY | LP_PARTITION_ATTR_SLOT_SUFFIXED)
|
||||
#define LP_PARTITION_ATTRIBUTE_MASK_V1 (LP_PARTITION_ATTRIBUTE_MASK_V0 | LP_PARTITION_ATTR_UPDATED)
|
||||
#define LP_PARTITION_ATTRIBUTE_MASK LP_PARTITION_ATTRIBUTE_MASK_V1
|
||||
|
||||
/* Default name of the physical partition that holds logical partition entries.
|
||||
* The layout of this partition will look like:
|
||||
|
|
|
|||
|
|
@ -713,3 +713,32 @@ TEST_F(LiblpTest, UpdateNonRetrofit) {
|
|||
ASSERT_EQ(updated->block_devices.size(), static_cast<size_t>(1));
|
||||
EXPECT_EQ(GetBlockDevicePartitionName(updated->block_devices[0]), "super");
|
||||
}
|
||||
|
||||
TEST_F(LiblpTest, UpdateVirtualAB) {
|
||||
ON_CALL(*GetMockedPropertyFetcher(), GetBoolProperty("ro.virtual_ab.enabled", _))
|
||||
.WillByDefault(Return(true));
|
||||
|
||||
unique_fd fd = CreateFlashedDisk();
|
||||
ASSERT_GE(fd, 0);
|
||||
|
||||
DefaultPartitionOpener opener(fd);
|
||||
auto builder = MetadataBuilder::NewForUpdate(opener, "super", 0, 1);
|
||||
ASSERT_NE(builder, nullptr);
|
||||
auto updated = builder->Export();
|
||||
ASSERT_NE(updated, nullptr);
|
||||
ASSERT_TRUE(UpdatePartitionTable(opener, "super", *updated.get(), 1));
|
||||
|
||||
// Validate old slot.
|
||||
auto metadata = ReadMetadata(opener, "super", 0);
|
||||
ASSERT_NE(metadata, nullptr);
|
||||
ASSERT_EQ(metadata->header.minor_version, 0);
|
||||
ASSERT_GE(metadata->partitions.size(), 1);
|
||||
ASSERT_EQ(metadata->partitions[0].attributes & LP_PARTITION_ATTR_UPDATED, 0);
|
||||
|
||||
// Validate new slot.
|
||||
metadata = ReadMetadata(opener, "super", 1);
|
||||
ASSERT_NE(metadata, nullptr);
|
||||
ASSERT_EQ(metadata->header.minor_version, 1);
|
||||
ASSERT_GE(metadata->partitions.size(), 1);
|
||||
ASSERT_NE(metadata->partitions[0].attributes & LP_PARTITION_ATTR_UPDATED, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ static bool ValidateMetadataHeader(const LpMetadataHeader& header) {
|
|||
}
|
||||
// Check that the version is compatible.
|
||||
if (header.major_version != LP_METADATA_MAJOR_VERSION ||
|
||||
header.minor_version > LP_METADATA_MINOR_VERSION) {
|
||||
header.minor_version > LP_METADATA_MINOR_VERSION_MAX) {
|
||||
LERROR << "Logical partition metadata has incompatible version.";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -245,6 +245,13 @@ static std::unique_ptr<LpMetadata> ParseMetadata(const LpMetadataGeometry& geome
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t valid_attributes = 0;
|
||||
if (metadata->header.minor_version >= LP_METADATA_VERSION_FOR_UPDATED_ATTR) {
|
||||
valid_attributes = LP_PARTITION_ATTRIBUTE_MASK_V1;
|
||||
} else {
|
||||
valid_attributes = LP_PARTITION_ATTRIBUTE_MASK_V0;
|
||||
}
|
||||
|
||||
// ValidateTableSize ensured that |cursor| is valid for the number of
|
||||
// entries in the table.
|
||||
uint8_t* cursor = buffer.get() + header.partitions.offset;
|
||||
|
|
@ -253,7 +260,7 @@ static std::unique_ptr<LpMetadata> ParseMetadata(const LpMetadataGeometry& geome
|
|||
memcpy(&partition, cursor, sizeof(partition));
|
||||
cursor += header.partitions.entry_size;
|
||||
|
||||
if (partition.attributes & ~LP_PARTITION_ATTRIBUTE_MASK) {
|
||||
if (partition.attributes & ~valid_attributes) {
|
||||
LERROR << "Logical partition has invalid attribute set.";
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ bool UpdateMetadataForInPlaceSnapshot(LpMetadata* metadata, uint32_t source_slot
|
|||
<< "; this partition should not belong to this group!";
|
||||
continue; // not adding to new_partition_ptrs
|
||||
}
|
||||
partition.attributes |= LP_PARTITION_ATTR_UPDATED;
|
||||
partition.group_index = std::distance(new_group_ptrs.begin(), it);
|
||||
new_partition_ptrs.push_back(&partition);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue