Loading fs_mgr/liblp/builder.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -150,7 +150,7 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const LpMetadata& metadata return builder; } MetadataBuilder::MetadataBuilder() { MetadataBuilder::MetadataBuilder() : auto_slot_suffixing_(false) { memset(&geometry_, 0, sizeof(geometry_)); geometry_.magic = LP_METADATA_GEOMETRY_MAGIC; geometry_.struct_size = sizeof(geometry_); Loading Loading @@ -564,7 +564,12 @@ std::unique_ptr<LpMetadata> MetadataBuilder::Export() { metadata->geometry = geometry_; // Assign this early so the extent table can read it. metadata->block_devices = block_devices_; for (const auto& block_device : block_devices_) { metadata->block_devices.emplace_back(block_device); if (auto_slot_suffixing_) { metadata->block_devices.back().flags |= LP_BLOCK_DEVICE_SLOT_SUFFIXED; } } std::map<std::string, size_t> group_indices; for (const auto& group : groups_) { Loading Loading @@ -600,6 +605,9 @@ std::unique_ptr<LpMetadata> MetadataBuilder::Export() { part.first_extent_index = static_cast<uint32_t>(metadata->extents.size()); part.num_extents = static_cast<uint32_t>(partition->extents().size()); part.attributes = partition->attributes(); if (auto_slot_suffixing_) { part.attributes |= LP_PARTITION_ATTR_SLOT_SUFFIXED; } auto iter = group_indices.find(partition->group_name()); if (iter == group_indices.end()) { Loading Loading @@ -836,5 +844,9 @@ bool MetadataBuilder::ImportPartition(const LpMetadata& metadata, return true; } void MetadataBuilder::SetAutoSlotSuffixing() { auto_slot_suffixing_ = true; } } // namespace fs_mgr } // namespace android fs_mgr/liblp/include/liblp/builder.h +4 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,9 @@ class MetadataBuilder { // Remove all partitions belonging to a group, then remove the group. void RemoveGroupAndPartitions(const std::string& group_name); // Set the LP_METADATA_AUTO_SLOT_SUFFIXING flag. void SetAutoSlotSuffixing(); bool GetBlockDeviceInfo(const std::string& partition_name, BlockDeviceInfo* info) const; bool UpdateBlockDeviceInfo(const std::string& partition_name, const BlockDeviceInfo& info); Loading Loading @@ -275,6 +278,7 @@ class MetadataBuilder { std::vector<std::unique_ptr<Partition>> partitions_; std::vector<std::unique_ptr<PartitionGroup>> groups_; std::vector<LpMetadataBlockDevice> block_devices_; bool auto_slot_suffixing_; }; // Read BlockDeviceInfo for a given block device. This always returns false Loading fs_mgr/liblp/include/liblp/liblp.h +1 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ std::vector<std::string> GetBlockDevicePartitionNames(const LpMetadata& metadata // Slot suffix helpers. uint32_t SlotNumberForSlotSuffix(const std::string& suffix); std::string SlotSuffixForSlotNumber(uint32_t slot_number); std::string GetPartitionSlotSuffix(const std::string& partition_name); } // namespace fs_mgr Loading fs_mgr/liblp/include/liblp/metadata_format.h +25 −3 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ extern "C" { #define LP_METADATA_HEADER_MAGIC 0x414C5030 /* Current metadata version. */ #define LP_METADATA_MAJOR_VERSION 8 #define LP_METADATA_MAJOR_VERSION 9 #define LP_METADATA_MINOR_VERSION 0 /* Attributes for the LpMetadataPartition::attributes field. Loading @@ -47,10 +47,19 @@ extern "C" { * device mapper, the block device will be created as read-only. */ #define LP_PARTITION_ATTR_NONE 0x0 #define LP_PARTITION_ATTR_READONLY 0x1 #define LP_PARTITION_ATTR_READONLY (1 << 0) /* This flag is only intended to be used with super_empty.img and super.img on * retrofit devices. On these devices there are A and B super partitions, and * we don't know ahead of time which slot the image will be applied to. * * If set, the partition name needs a slot suffix applied. The slot suffix is * determined by the metadata slot number (0 = _a, 1 = _b). */ #define LP_PARTITION_ATTR_SLOT_SUFFIXED (1 << 1) /* Mask that defines all valid attributes. */ #define LP_PARTITION_ATTRIBUTE_MASK (LP_PARTITION_ATTR_READONLY) #define LP_PARTITION_ATTRIBUTE_MASK (LP_PARTITION_ATTR_READONLY | LP_PARTITION_ATTR_SLOT_SUFFIXED) /* Default name of the physical partition that holds logical partition entries. * The layout of this partition will look like: Loading Loading @@ -302,8 +311,21 @@ typedef struct LpMetadataBlockDevice { /* 24: Partition name in the GPT. Any unused characters must be 0. */ char partition_name[36]; /* 60: Flags (see LP_BLOCK_DEVICE_* flags below). */ uint32_t flags; } LpMetadataBlockDevice; /* This flag is only intended to be used with super_empty.img and super.img on * retrofit devices. On these devices there are A and B super partitions, and * we don't know ahead of time which slot the image will be applied to. * * If set, the block device needs a slot suffix applied before being used with * IPartitionOpener. The slot suffix is determined by the metadata slot number * (0 = _a, 1 = _b). */ #define LP_BLOCK_DEVICE_SLOT_SUFFIXED (1 << 0) #ifdef __cplusplus } /* extern "C" */ #endif Loading fs_mgr/liblp/io_test.cpp +25 −1 Original line number Diff line number Diff line Loading @@ -88,11 +88,14 @@ static bool AddDefaultPartitions(MetadataBuilder* builder) { } // Create a temporary disk and flash it with the default partition setup. static unique_fd CreateFlashedDisk() { static unique_fd CreateFlashedDisk(bool auto_slot_suffix = false) { unique_ptr<MetadataBuilder> builder = CreateDefaultBuilder(); if (!builder || !AddDefaultPartitions(builder.get())) { return {}; } if (auto_slot_suffix) { builder->SetAutoSlotSuffixing(); } unique_fd fd = CreateFakeDisk(); if (fd < 0) { return {}; Loading Loading @@ -608,3 +611,24 @@ TEST(liblp, FlashSparseImage) { ASSERT_NE(ReadPrimaryMetadata(fd.get(), geometry, 0), nullptr); ASSERT_NE(ReadBackupMetadata(fd.get(), geometry, 0), nullptr); } TEST(liblp, AutoSlotSuffixing) { auto fd = CreateFlashedDisk(true); ASSERT_GE(fd, 0); TestPartitionOpener opener({{"super", fd}}); auto metadata = ReadMetadata(opener, "super", 1); ASSERT_NE(metadata, nullptr); ASSERT_EQ(metadata->partitions.size(), static_cast<size_t>(1)); EXPECT_EQ(GetPartitionName(metadata->partitions[0]), "system_b"); ASSERT_EQ(metadata->block_devices.size(), static_cast<size_t>(1)); EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[0]), "super_b"); metadata = ReadMetadata(opener, "super", 0); ASSERT_NE(metadata, nullptr); ASSERT_EQ(metadata->partitions.size(), static_cast<size_t>(1)); EXPECT_EQ(GetPartitionName(metadata->partitions[0]), "system_a"); ASSERT_EQ(metadata->block_devices.size(), static_cast<size_t>(1)); EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[0]), "super_a"); } Loading
fs_mgr/liblp/builder.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -150,7 +150,7 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const LpMetadata& metadata return builder; } MetadataBuilder::MetadataBuilder() { MetadataBuilder::MetadataBuilder() : auto_slot_suffixing_(false) { memset(&geometry_, 0, sizeof(geometry_)); geometry_.magic = LP_METADATA_GEOMETRY_MAGIC; geometry_.struct_size = sizeof(geometry_); Loading Loading @@ -564,7 +564,12 @@ std::unique_ptr<LpMetadata> MetadataBuilder::Export() { metadata->geometry = geometry_; // Assign this early so the extent table can read it. metadata->block_devices = block_devices_; for (const auto& block_device : block_devices_) { metadata->block_devices.emplace_back(block_device); if (auto_slot_suffixing_) { metadata->block_devices.back().flags |= LP_BLOCK_DEVICE_SLOT_SUFFIXED; } } std::map<std::string, size_t> group_indices; for (const auto& group : groups_) { Loading Loading @@ -600,6 +605,9 @@ std::unique_ptr<LpMetadata> MetadataBuilder::Export() { part.first_extent_index = static_cast<uint32_t>(metadata->extents.size()); part.num_extents = static_cast<uint32_t>(partition->extents().size()); part.attributes = partition->attributes(); if (auto_slot_suffixing_) { part.attributes |= LP_PARTITION_ATTR_SLOT_SUFFIXED; } auto iter = group_indices.find(partition->group_name()); if (iter == group_indices.end()) { Loading Loading @@ -836,5 +844,9 @@ bool MetadataBuilder::ImportPartition(const LpMetadata& metadata, return true; } void MetadataBuilder::SetAutoSlotSuffixing() { auto_slot_suffixing_ = true; } } // namespace fs_mgr } // namespace android
fs_mgr/liblp/include/liblp/builder.h +4 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,9 @@ class MetadataBuilder { // Remove all partitions belonging to a group, then remove the group. void RemoveGroupAndPartitions(const std::string& group_name); // Set the LP_METADATA_AUTO_SLOT_SUFFIXING flag. void SetAutoSlotSuffixing(); bool GetBlockDeviceInfo(const std::string& partition_name, BlockDeviceInfo* info) const; bool UpdateBlockDeviceInfo(const std::string& partition_name, const BlockDeviceInfo& info); Loading Loading @@ -275,6 +278,7 @@ class MetadataBuilder { std::vector<std::unique_ptr<Partition>> partitions_; std::vector<std::unique_ptr<PartitionGroup>> groups_; std::vector<LpMetadataBlockDevice> block_devices_; bool auto_slot_suffixing_; }; // Read BlockDeviceInfo for a given block device. This always returns false Loading
fs_mgr/liblp/include/liblp/liblp.h +1 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ std::vector<std::string> GetBlockDevicePartitionNames(const LpMetadata& metadata // Slot suffix helpers. uint32_t SlotNumberForSlotSuffix(const std::string& suffix); std::string SlotSuffixForSlotNumber(uint32_t slot_number); std::string GetPartitionSlotSuffix(const std::string& partition_name); } // namespace fs_mgr Loading
fs_mgr/liblp/include/liblp/metadata_format.h +25 −3 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ extern "C" { #define LP_METADATA_HEADER_MAGIC 0x414C5030 /* Current metadata version. */ #define LP_METADATA_MAJOR_VERSION 8 #define LP_METADATA_MAJOR_VERSION 9 #define LP_METADATA_MINOR_VERSION 0 /* Attributes for the LpMetadataPartition::attributes field. Loading @@ -47,10 +47,19 @@ extern "C" { * device mapper, the block device will be created as read-only. */ #define LP_PARTITION_ATTR_NONE 0x0 #define LP_PARTITION_ATTR_READONLY 0x1 #define LP_PARTITION_ATTR_READONLY (1 << 0) /* This flag is only intended to be used with super_empty.img and super.img on * retrofit devices. On these devices there are A and B super partitions, and * we don't know ahead of time which slot the image will be applied to. * * If set, the partition name needs a slot suffix applied. The slot suffix is * determined by the metadata slot number (0 = _a, 1 = _b). */ #define LP_PARTITION_ATTR_SLOT_SUFFIXED (1 << 1) /* Mask that defines all valid attributes. */ #define LP_PARTITION_ATTRIBUTE_MASK (LP_PARTITION_ATTR_READONLY) #define LP_PARTITION_ATTRIBUTE_MASK (LP_PARTITION_ATTR_READONLY | LP_PARTITION_ATTR_SLOT_SUFFIXED) /* Default name of the physical partition that holds logical partition entries. * The layout of this partition will look like: Loading Loading @@ -302,8 +311,21 @@ typedef struct LpMetadataBlockDevice { /* 24: Partition name in the GPT. Any unused characters must be 0. */ char partition_name[36]; /* 60: Flags (see LP_BLOCK_DEVICE_* flags below). */ uint32_t flags; } LpMetadataBlockDevice; /* This flag is only intended to be used with super_empty.img and super.img on * retrofit devices. On these devices there are A and B super partitions, and * we don't know ahead of time which slot the image will be applied to. * * If set, the block device needs a slot suffix applied before being used with * IPartitionOpener. The slot suffix is determined by the metadata slot number * (0 = _a, 1 = _b). */ #define LP_BLOCK_DEVICE_SLOT_SUFFIXED (1 << 0) #ifdef __cplusplus } /* extern "C" */ #endif Loading
fs_mgr/liblp/io_test.cpp +25 −1 Original line number Diff line number Diff line Loading @@ -88,11 +88,14 @@ static bool AddDefaultPartitions(MetadataBuilder* builder) { } // Create a temporary disk and flash it with the default partition setup. static unique_fd CreateFlashedDisk() { static unique_fd CreateFlashedDisk(bool auto_slot_suffix = false) { unique_ptr<MetadataBuilder> builder = CreateDefaultBuilder(); if (!builder || !AddDefaultPartitions(builder.get())) { return {}; } if (auto_slot_suffix) { builder->SetAutoSlotSuffixing(); } unique_fd fd = CreateFakeDisk(); if (fd < 0) { return {}; Loading Loading @@ -608,3 +611,24 @@ TEST(liblp, FlashSparseImage) { ASSERT_NE(ReadPrimaryMetadata(fd.get(), geometry, 0), nullptr); ASSERT_NE(ReadBackupMetadata(fd.get(), geometry, 0), nullptr); } TEST(liblp, AutoSlotSuffixing) { auto fd = CreateFlashedDisk(true); ASSERT_GE(fd, 0); TestPartitionOpener opener({{"super", fd}}); auto metadata = ReadMetadata(opener, "super", 1); ASSERT_NE(metadata, nullptr); ASSERT_EQ(metadata->partitions.size(), static_cast<size_t>(1)); EXPECT_EQ(GetPartitionName(metadata->partitions[0]), "system_b"); ASSERT_EQ(metadata->block_devices.size(), static_cast<size_t>(1)); EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[0]), "super_b"); metadata = ReadMetadata(opener, "super", 0); ASSERT_NE(metadata, nullptr); ASSERT_EQ(metadata->partitions.size(), static_cast<size_t>(1)); EXPECT_EQ(GetPartitionName(metadata->partitions[0]), "system_a"); ASSERT_EQ(metadata->block_devices.size(), static_cast<size_t>(1)); EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[0]), "super_a"); }