diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp index bbdec5b77..49536551b 100644 --- a/fs_mgr/liblp/Android.bp +++ b/fs_mgr/liblp/Android.bp @@ -47,6 +47,9 @@ cc_test { cppflags: [ "-Wno-unused-parameter", ], + static_libs: [ + "libgmock", + ], shared_libs: [ "liblp", "libbase", diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp index 963e1b36a..2c57a35b9 100644 --- a/fs_mgr/liblp/builder.cpp +++ b/fs_mgr/liblp/builder.cpp @@ -339,7 +339,7 @@ Partition* MetadataBuilder::FindPartition(const std::string& name) { return nullptr; } -PartitionGroup* MetadataBuilder::FindGroup(const std::string& group_name) const { +PartitionGroup* MetadataBuilder::FindGroup(const std::string& group_name) { for (const auto& group : groups_) { if (group->name() == group_name) { return group.get(); @@ -624,5 +624,36 @@ bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_s return true; } +std::vector MetadataBuilder::ListGroups() const { + std::vector names; + for (const auto& group : groups_) { + names.emplace_back(group->name()); + } + return names; +} + +void MetadataBuilder::RemoveGroupAndPartitions(const std::string& group_name) { + if (group_name == "default") { + // Cannot remove the default group. + return; + } + std::vector partition_names; + for (const auto& partition : partitions_) { + if (partition->group_name() == group_name) { + partition_names.emplace_back(partition->name()); + } + } + + for (const auto& partition_name : partition_names) { + RemovePartition(partition_name); + } + for (auto iter = groups_.begin(); iter != groups_.end(); iter++) { + if ((*iter)->name() == group_name) { + groups_.erase(iter); + break; + } + } +} + } // namespace fs_mgr } // namespace android diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp index f72b8e1a2..27ad25082 100644 --- a/fs_mgr/liblp/builder_test.cpp +++ b/fs_mgr/liblp/builder_test.cpp @@ -14,13 +14,16 @@ * limitations under the License. */ +#include +#include #include #include -#include "fs_mgr.h" + #include "utility.h" using namespace std; using namespace android::fs_mgr; +using ::testing::ElementsAre; TEST(liblp, BuildBasic) { unique_ptr builder = MetadataBuilder::New(1024 * 1024, 1024, 2); @@ -542,3 +545,30 @@ TEST(liblp, RemoveAndAddFirstPartition) { p = builder->AddPartition("vendor_a", "foo_a", 0); ASSERT_TRUE(p && builder->ResizePartition(p, 1_GiB)); } + +TEST(liblp, ListGroups) { + BlockDeviceInfo device_info(1024 * 1024, 0, 0, 4096); + unique_ptr builder = MetadataBuilder::New(device_info, 1024, 1); + ASSERT_NE(builder, nullptr); + ASSERT_TRUE(builder->AddGroup("example", 0)); + + std::vector groups = builder->ListGroups(); + ASSERT_THAT(groups, ElementsAre("default", "example")); +} + +TEST(liblp, RemoveGroupAndPartitions) { + BlockDeviceInfo device_info(1024 * 1024, 0, 0, 4096); + unique_ptr builder = MetadataBuilder::New(device_info, 1024, 1); + ASSERT_NE(builder, nullptr); + ASSERT_TRUE(builder->AddGroup("example", 0)); + ASSERT_NE(builder->AddPartition("system", "default", 0), nullptr); + ASSERT_NE(builder->AddPartition("vendor", "example", 0), nullptr); + + builder->RemoveGroupAndPartitions("example"); + ASSERT_NE(builder->FindPartition("system"), nullptr); + ASSERT_EQ(builder->FindPartition("vendor"), nullptr); + ASSERT_THAT(builder->ListGroups(), ElementsAre("default")); + + builder->RemoveGroupAndPartitions("default"); + ASSERT_NE(builder->FindPartition("system"), nullptr); +} diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h index 30dc3001a..7e07df464 100644 --- a/fs_mgr/liblp/include/liblp/builder.h +++ b/fs_mgr/liblp/include/liblp/builder.h @@ -199,6 +199,9 @@ class MetadataBuilder { // Find a partition by name. If no partition is found, nullptr is returned. Partition* FindPartition(const std::string& name); + // Find a group by name. If no group is found, nullptr is returned. + PartitionGroup* FindGroup(const std::string& name); + // Grow or shrink a partition to the requested size. This size will be // rounded UP to the nearest block (512 bytes). // @@ -215,6 +218,12 @@ class MetadataBuilder { uint64_t AllocatableSpace() const; uint64_t UsedSpace() const; + // Return a list of all group names. + std::vector ListGroups() const; + + // Remove all partitions belonging to a group, then remove the group. + void RemoveGroupAndPartitions(const std::string& group_name); + bool GetBlockDeviceInfo(BlockDeviceInfo* info) const; bool UpdateBlockDeviceInfo(const BlockDeviceInfo& info); @@ -229,7 +238,6 @@ class MetadataBuilder { bool GrowPartition(Partition* partition, uint64_t aligned_size); void ShrinkPartition(Partition* partition, uint64_t aligned_size); uint64_t AlignSector(uint64_t sector) const; - PartitionGroup* FindGroup(const std::string& group_name) const; uint64_t TotalSizeOfGroup(PartitionGroup* group) const; struct Interval {