Loading fs_mgr/liblp/builder.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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()); Loading fs_mgr/liblp/builder_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading fs_mgr/liblp/include/liblp/metadata_format.h +19 −3 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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: Loading fs_mgr/liblp/io_test.cpp +29 −0 Original line number Diff line number Diff line Loading @@ -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); } fs_mgr/liblp/reader.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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; } Loading Loading
fs_mgr/liblp/builder.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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()); Loading
fs_mgr/liblp/builder_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
fs_mgr/liblp/include/liblp/metadata_format.h +19 −3 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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: Loading
fs_mgr/liblp/io_test.cpp +29 −0 Original line number Diff line number Diff line Loading @@ -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); }
fs_mgr/liblp/reader.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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; } Loading