Loading fs_mgr/liblp/builder.cpp +24 −15 Original line number Diff line number Diff line Loading @@ -158,39 +158,48 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::NewForUpdate(const IPartitionO return nullptr; } // Get the list of devices we already have. std::set<std::string> block_devices; for (const auto& block_device : metadata->block_devices) { block_devices.emplace(GetBlockDevicePartitionName(block_device)); // On non-retrofit devices there is only one location for metadata: the // super partition. update_engine will remove and resize partitions as // needed. On the other hand, for retrofit devices, we'll need to // translate block device and group names to update their slot suffixes. auto super_device = GetMetadataSuperBlockDevice(*metadata.get()); if (GetBlockDevicePartitionName(*super_device) == "super") { return New(*metadata.get(), &opener); } auto new_block_devices = metadata->block_devices; // Clear partitions and extents, since they have no meaning on the target // slot. We also clear groups since they are re-added during OTA. metadata->partitions.clear(); metadata->extents.clear(); metadata->groups.clear(); // Add missing block devices. std::string source_slot_suffix = SlotSuffixForSlotNumber(source_slot_number); std::string target_slot_suffix = SlotSuffixForSlotNumber(target_slot_number); for (const auto& block_device : metadata->block_devices) { std::string partition_name = GetBlockDevicePartitionName(block_device); // Translate block devices. auto source_block_devices = std::move(metadata->block_devices); for (const auto& source_block_device : source_block_devices) { std::string partition_name = GetBlockDevicePartitionName(source_block_device); std::string slot_suffix = GetPartitionSlotSuffix(partition_name); if (slot_suffix.empty() || slot_suffix != source_slot_suffix) { continue; // This should never happen. It means that the source metadata // refers to a target or unknown block device. LERROR << "Invalid block device for slot " << source_slot_suffix << ": " << partition_name; return nullptr; } std::string new_name = partition_name.substr(0, partition_name.size() - slot_suffix.size()) + target_slot_suffix; if (block_devices.find(new_name) != block_devices.end()) { continue; } auto new_device = block_device; auto new_device = source_block_device; if (!UpdateBlockDevicePartitionName(&new_device, new_name)) { LERROR << "Partition name too long: " << new_name; return nullptr; } new_block_devices.emplace_back(new_device); metadata->block_devices.emplace_back(new_device); } metadata->block_devices = new_block_devices; return New(*metadata.get(), &opener); } Loading fs_mgr/liblp/io_test.cpp +6 −3 Original line number Diff line number Diff line Loading @@ -665,6 +665,7 @@ TEST(liblp, UpdateRetrofit) { unique_ptr<MetadataBuilder> builder = CreateDefaultBuilder(); ASSERT_NE(builder, nullptr); ASSERT_TRUE(AddDefaultPartitions(builder.get())); ASSERT_TRUE(builder->AddGroup("example", 0)); builder->SetAutoSlotSuffixing(); auto fd = CreateFakeDisk(); Loading @@ -682,9 +683,11 @@ TEST(liblp, UpdateRetrofit) { ASSERT_NE(builder, nullptr); auto updated = builder->Export(); ASSERT_NE(updated, nullptr); ASSERT_EQ(updated->block_devices.size(), static_cast<size_t>(2)); EXPECT_EQ(GetBlockDevicePartitionName(updated->block_devices[0]), "super_a"); EXPECT_EQ(GetBlockDevicePartitionName(updated->block_devices[1]), "super_b"); ASSERT_EQ(updated->block_devices.size(), static_cast<size_t>(1)); EXPECT_EQ(GetBlockDevicePartitionName(updated->block_devices[0]), "super_b"); ASSERT_TRUE(updated->groups.empty()); ASSERT_TRUE(updated->partitions.empty()); ASSERT_TRUE(updated->extents.empty()); } TEST(liblp, UpdateNonRetrofit) { Loading fs_mgr/liblp/reader.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -380,11 +380,10 @@ bool AdjustMetadataForSlot(LpMetadata* metadata, uint32_t slot_number) { continue; } std::string group_name = GetPartitionGroupName(group) + slot_suffix; if (group_name.size() > sizeof(group.name)) { if (!UpdatePartitionGroupName(&group, group_name)) { LERROR << __PRETTY_FUNCTION__ << " group name too long: " << group_name; return false; } strncpy(group.name, group_name.c_str(), sizeof(group.name)); group.flags &= ~LP_GROUP_SLOT_SUFFIXED; } return true; Loading fs_mgr/liblp/utility.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -147,5 +147,13 @@ bool UpdateBlockDevicePartitionName(LpMetadataBlockDevice* device, const std::st return true; } bool UpdatePartitionGroupName(LpMetadataPartitionGroup* group, const std::string& name) { if (name.size() > sizeof(group->name)) { return false; } strncpy(group->name, name.c_str(), sizeof(group->name)); return true; } } // namespace fs_mgr } // namespace android fs_mgr/liblp/utility.h +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ constexpr uint64_t AlignTo(uint64_t base, uint32_t alignment, uint32_t alignment // Update names from C++ strings. bool UpdateBlockDevicePartitionName(LpMetadataBlockDevice* device, const std::string& name); bool UpdatePartitionGroupName(LpMetadataPartitionGroup* group, const std::string& name); } // namespace fs_mgr } // namespace android Loading Loading
fs_mgr/liblp/builder.cpp +24 −15 Original line number Diff line number Diff line Loading @@ -158,39 +158,48 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::NewForUpdate(const IPartitionO return nullptr; } // Get the list of devices we already have. std::set<std::string> block_devices; for (const auto& block_device : metadata->block_devices) { block_devices.emplace(GetBlockDevicePartitionName(block_device)); // On non-retrofit devices there is only one location for metadata: the // super partition. update_engine will remove and resize partitions as // needed. On the other hand, for retrofit devices, we'll need to // translate block device and group names to update their slot suffixes. auto super_device = GetMetadataSuperBlockDevice(*metadata.get()); if (GetBlockDevicePartitionName(*super_device) == "super") { return New(*metadata.get(), &opener); } auto new_block_devices = metadata->block_devices; // Clear partitions and extents, since they have no meaning on the target // slot. We also clear groups since they are re-added during OTA. metadata->partitions.clear(); metadata->extents.clear(); metadata->groups.clear(); // Add missing block devices. std::string source_slot_suffix = SlotSuffixForSlotNumber(source_slot_number); std::string target_slot_suffix = SlotSuffixForSlotNumber(target_slot_number); for (const auto& block_device : metadata->block_devices) { std::string partition_name = GetBlockDevicePartitionName(block_device); // Translate block devices. auto source_block_devices = std::move(metadata->block_devices); for (const auto& source_block_device : source_block_devices) { std::string partition_name = GetBlockDevicePartitionName(source_block_device); std::string slot_suffix = GetPartitionSlotSuffix(partition_name); if (slot_suffix.empty() || slot_suffix != source_slot_suffix) { continue; // This should never happen. It means that the source metadata // refers to a target or unknown block device. LERROR << "Invalid block device for slot " << source_slot_suffix << ": " << partition_name; return nullptr; } std::string new_name = partition_name.substr(0, partition_name.size() - slot_suffix.size()) + target_slot_suffix; if (block_devices.find(new_name) != block_devices.end()) { continue; } auto new_device = block_device; auto new_device = source_block_device; if (!UpdateBlockDevicePartitionName(&new_device, new_name)) { LERROR << "Partition name too long: " << new_name; return nullptr; } new_block_devices.emplace_back(new_device); metadata->block_devices.emplace_back(new_device); } metadata->block_devices = new_block_devices; return New(*metadata.get(), &opener); } Loading
fs_mgr/liblp/io_test.cpp +6 −3 Original line number Diff line number Diff line Loading @@ -665,6 +665,7 @@ TEST(liblp, UpdateRetrofit) { unique_ptr<MetadataBuilder> builder = CreateDefaultBuilder(); ASSERT_NE(builder, nullptr); ASSERT_TRUE(AddDefaultPartitions(builder.get())); ASSERT_TRUE(builder->AddGroup("example", 0)); builder->SetAutoSlotSuffixing(); auto fd = CreateFakeDisk(); Loading @@ -682,9 +683,11 @@ TEST(liblp, UpdateRetrofit) { ASSERT_NE(builder, nullptr); auto updated = builder->Export(); ASSERT_NE(updated, nullptr); ASSERT_EQ(updated->block_devices.size(), static_cast<size_t>(2)); EXPECT_EQ(GetBlockDevicePartitionName(updated->block_devices[0]), "super_a"); EXPECT_EQ(GetBlockDevicePartitionName(updated->block_devices[1]), "super_b"); ASSERT_EQ(updated->block_devices.size(), static_cast<size_t>(1)); EXPECT_EQ(GetBlockDevicePartitionName(updated->block_devices[0]), "super_b"); ASSERT_TRUE(updated->groups.empty()); ASSERT_TRUE(updated->partitions.empty()); ASSERT_TRUE(updated->extents.empty()); } TEST(liblp, UpdateNonRetrofit) { Loading
fs_mgr/liblp/reader.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -380,11 +380,10 @@ bool AdjustMetadataForSlot(LpMetadata* metadata, uint32_t slot_number) { continue; } std::string group_name = GetPartitionGroupName(group) + slot_suffix; if (group_name.size() > sizeof(group.name)) { if (!UpdatePartitionGroupName(&group, group_name)) { LERROR << __PRETTY_FUNCTION__ << " group name too long: " << group_name; return false; } strncpy(group.name, group_name.c_str(), sizeof(group.name)); group.flags &= ~LP_GROUP_SLOT_SUFFIXED; } return true; Loading
fs_mgr/liblp/utility.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -147,5 +147,13 @@ bool UpdateBlockDevicePartitionName(LpMetadataBlockDevice* device, const std::st return true; } bool UpdatePartitionGroupName(LpMetadataPartitionGroup* group, const std::string& name) { if (name.size() > sizeof(group->name)) { return false; } strncpy(group->name, name.c_str(), sizeof(group->name)); return true; } } // namespace fs_mgr } // namespace android
fs_mgr/liblp/utility.h +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ constexpr uint64_t AlignTo(uint64_t base, uint32_t alignment, uint32_t alignment // Update names from C++ strings. bool UpdateBlockDevicePartitionName(LpMetadataBlockDevice* device, const std::string& name); bool UpdatePartitionGroupName(LpMetadataPartitionGroup* group, const std::string& name); } // namespace fs_mgr } // namespace android Loading