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

Commit bdc65bf0 authored by Alessio Balsini's avatar Alessio Balsini
Browse files

libdm: suspend and resume devices



In some cases it would be required to suspend the device to succesfully
complete some operations. An example is the suspension of the origin
device that is necessary to avoid data corruption when merging a
snapshot.

Introduce suspend and resume ioctls in libdm.

Bug: 137759376
Test: libdm_test
Change-Id: Id2ff34e930a8b32e570cb9f49da9cc3f65cb499c
Signed-off-by: default avatarAlessio Balsini <balsini@google.com>
parent 244d9b8f
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -162,6 +162,24 @@ DmDeviceState DeviceMapper::GetState(const std::string& name) const {
    return DmDeviceState::SUSPENDED;
}

bool DeviceMapper::ChangeState(const std::string& name, DmDeviceState state) {
    if (state != DmDeviceState::SUSPENDED && state != DmDeviceState::ACTIVE) {
        return false;
    }

    struct dm_ioctl io;
    InitIo(&io, name);

    if (state == DmDeviceState::SUSPENDED) io.flags = DM_SUSPEND_FLAG;

    if (ioctl(fd_, DM_DEV_SUSPEND, &io) < 0) {
        PLOG(ERROR) << "DM_DEV_SUSPEND "
                    << (state == DmDeviceState::SUSPENDED ? "suspend" : "resume") << " failed";
        return false;
    }
    return true;
}

bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table) {
    std::string ignore_path;
    if (!CreateDevice(name, table, &ignore_path, 0ms)) {
+28 −0
Original line number Diff line number Diff line
@@ -166,6 +166,34 @@ TEST(libdm, DmLinear) {
    ASSERT_TRUE(dev.Destroy());
}

TEST(libdm, DmSuspendResume) {
    unique_fd tmp1(CreateTempFile("file_suspend_resume", 512));
    ASSERT_GE(tmp1, 0);

    LoopDevice loop_a(tmp1, 10s);
    ASSERT_TRUE(loop_a.valid());

    DmTable table;
    ASSERT_TRUE(table.Emplace<DmTargetLinear>(0, 1, loop_a.device(), 0));
    ASSERT_TRUE(table.valid());

    TempDevice dev("libdm-test-dm-suspend-resume", table);
    ASSERT_TRUE(dev.valid());
    ASSERT_FALSE(dev.path().empty());

    auto& dm = DeviceMapper::Instance();

    // Test Set and Get status of device.
    vector<DeviceMapper::TargetInfo> targets;
    ASSERT_EQ(dm.GetState(dev.name()), DmDeviceState::ACTIVE);

    ASSERT_TRUE(dm.ChangeState(dev.name(), DmDeviceState::SUSPENDED));
    ASSERT_EQ(dm.GetState(dev.name()), DmDeviceState::SUSPENDED);

    ASSERT_TRUE(dm.ChangeState(dev.name(), DmDeviceState::ACTIVE));
    ASSERT_EQ(dm.GetState(dev.name()), DmDeviceState::ACTIVE);
}

TEST(libdm, DmVerityArgsAvb2) {
    std::string device = "/dev/block/platform/soc/1da4000.ufshc/by-name/vendor_a";
    std::string algorithm = "sha1";
+5 −0
Original line number Diff line number Diff line
@@ -79,6 +79,11 @@ class DeviceMapper final {
    // One of INVALID, SUSPENDED or ACTIVE.
    DmDeviceState GetState(const std::string& name) const;

    // Puts the given device to the specified status, which must be either:
    // - SUSPENDED: suspend the device, or
    // - ACTIVE: resumes the device.
    bool ChangeState(const std::string& name, DmDeviceState state);

    // Creates a device, loads the given table, and activates it. If the device
    // is not able to be activated, it is destroyed, and false is returned.
    // After creation, |path| contains the result of calling