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

Commit 5cb50a24 authored by David Anderson's avatar David Anderson
Browse files

liblp: Add MetadataBuilder helpers for pruning unused groups.

These will help update_engine clear the target slot before applying an OTA.

Bug: 117182932
Test: liblp_test gtest
Change-Id: I6ad370e617f22f2098245a0028a93488f9ac8674
parent 11440493
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -47,6 +47,9 @@ cc_test {
    cppflags: [
    cppflags: [
        "-Wno-unused-parameter",
        "-Wno-unused-parameter",
    ],
    ],
    static_libs: [
        "libgmock",
    ],
    shared_libs: [
    shared_libs: [
        "liblp",
        "liblp",
        "libbase",
        "libbase",
+32 −1
Original line number Original line Diff line number Diff line
@@ -339,7 +339,7 @@ Partition* MetadataBuilder::FindPartition(const std::string& name) {
    return nullptr;
    return nullptr;
}
}


PartitionGroup* MetadataBuilder::FindGroup(const std::string& group_name) const {
PartitionGroup* MetadataBuilder::FindGroup(const std::string& group_name) {
    for (const auto& group : groups_) {
    for (const auto& group : groups_) {
        if (group->name() == group_name) {
        if (group->name() == group_name) {
            return group.get();
            return group.get();
@@ -624,5 +624,36 @@ bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_s
    return true;
    return true;
}
}


std::vector<std::string> MetadataBuilder::ListGroups() const {
    std::vector<std::string> 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<std::string> 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 fs_mgr
}  // namespace android
}  // namespace android
+31 −1
Original line number Original line Diff line number Diff line
@@ -14,13 +14,16 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#include <fs_mgr.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <gtest/gtest.h>
#include <liblp/builder.h>
#include <liblp/builder.h>
#include "fs_mgr.h"

#include "utility.h"
#include "utility.h"


using namespace std;
using namespace std;
using namespace android::fs_mgr;
using namespace android::fs_mgr;
using ::testing::ElementsAre;


TEST(liblp, BuildBasic) {
TEST(liblp, BuildBasic) {
    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
@@ -542,3 +545,30 @@ TEST(liblp, RemoveAndAddFirstPartition) {
    p = builder->AddPartition("vendor_a", "foo_a", 0);
    p = builder->AddPartition("vendor_a", "foo_a", 0);
    ASSERT_TRUE(p && builder->ResizePartition(p, 1_GiB));
    ASSERT_TRUE(p && builder->ResizePartition(p, 1_GiB));
}
}

TEST(liblp, ListGroups) {
    BlockDeviceInfo device_info(1024 * 1024, 0, 0, 4096);
    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
    ASSERT_NE(builder, nullptr);
    ASSERT_TRUE(builder->AddGroup("example", 0));

    std::vector<std::string> groups = builder->ListGroups();
    ASSERT_THAT(groups, ElementsAre("default", "example"));
}

TEST(liblp, RemoveGroupAndPartitions) {
    BlockDeviceInfo device_info(1024 * 1024, 0, 0, 4096);
    unique_ptr<MetadataBuilder> 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);
}
+9 −1
Original line number Original line Diff line number Diff line
@@ -199,6 +199,9 @@ class MetadataBuilder {
    // Find a partition by name. If no partition is found, nullptr is returned.
    // Find a partition by name. If no partition is found, nullptr is returned.
    Partition* FindPartition(const std::string& name);
    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
    // Grow or shrink a partition to the requested size. This size will be
    // rounded UP to the nearest block (512 bytes).
    // rounded UP to the nearest block (512 bytes).
    //
    //
@@ -215,6 +218,12 @@ class MetadataBuilder {
    uint64_t AllocatableSpace() const;
    uint64_t AllocatableSpace() const;
    uint64_t UsedSpace() const;
    uint64_t UsedSpace() const;


    // Return a list of all group names.
    std::vector<std::string> 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 GetBlockDeviceInfo(BlockDeviceInfo* info) const;
    bool UpdateBlockDeviceInfo(const BlockDeviceInfo& info);
    bool UpdateBlockDeviceInfo(const BlockDeviceInfo& info);


@@ -229,7 +238,6 @@ class MetadataBuilder {
    bool GrowPartition(Partition* partition, uint64_t aligned_size);
    bool GrowPartition(Partition* partition, uint64_t aligned_size);
    void ShrinkPartition(Partition* partition, uint64_t aligned_size);
    void ShrinkPartition(Partition* partition, uint64_t aligned_size);
    uint64_t AlignSector(uint64_t sector) const;
    uint64_t AlignSector(uint64_t sector) const;
    PartitionGroup* FindGroup(const std::string& group_name) const;
    uint64_t TotalSizeOfGroup(PartitionGroup* group) const;
    uint64_t TotalSizeOfGroup(PartitionGroup* group) const;


    struct Interval {
    struct Interval {