summaryrefslogtreecommitdiffstats
path: root/fs_mgr/liblp
diff options
context:
space:
mode:
Diffstat (limited to 'fs_mgr/liblp')
-rw-r--r--fs_mgr/liblp/builder.cpp39
-rw-r--r--fs_mgr/liblp/io_test.cpp9
-rw-r--r--fs_mgr/liblp/reader.cpp3
-rw-r--r--fs_mgr/liblp/utility.cpp8
-rw-r--r--fs_mgr/liblp/utility.h1
5 files changed, 40 insertions, 20 deletions
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index b51afc17b..7035f42e5 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -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);
}
diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp
index b539d776a..9f3314d34 100644
--- a/fs_mgr/liblp/io_test.cpp
+++ b/fs_mgr/liblp/io_test.cpp
@@ -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();
@@ -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) {
diff --git a/fs_mgr/liblp/reader.cpp b/fs_mgr/liblp/reader.cpp
index 305e6c79d..24c6b2c31 100644
--- a/fs_mgr/liblp/reader.cpp
+++ b/fs_mgr/liblp/reader.cpp
@@ -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;
diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp
index 4f20b6bf8..60ddbdd12 100644
--- a/fs_mgr/liblp/utility.cpp
+++ b/fs_mgr/liblp/utility.cpp
@@ -145,5 +145,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
diff --git a/fs_mgr/liblp/utility.h b/fs_mgr/liblp/utility.h
index 55ecb5a59..8b70919d6 100644
--- a/fs_mgr/liblp/utility.h
+++ b/fs_mgr/liblp/utility.h
@@ -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