Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f63251c8 authored by David Anderson's avatar David Anderson Committed by android-build-merger
Browse files

Merge "liblp: Add an attribute to indicate that a partition has been updated."

am: 74a6f4cf

Change-Id: I0f3038c4537e38ce4d09c030bec1079dd941d973
parents f9b9bc7e 74a6f4cf
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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());
+1 −1
Original line number Diff line number Diff line
@@ -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);
+19 −3
Original line number Diff line number Diff line
@@ -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:
+29 −0
Original line number Diff line number Diff line
@@ -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);
}
+9 −2
Original line number Diff line number Diff line
@@ -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;
        }
Loading