Loading fs_mgr/libdm/dm.cpp +11 −3 Original line number Diff line number Diff line Loading @@ -289,7 +289,7 @@ bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table) { return true; } bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable& table) { bool DeviceMapper::LoadTable(const std::string& name, const DmTable& table) { std::string ioctl_buffer(sizeof(struct dm_ioctl), 0); ioctl_buffer += table.Serialize(); Loading @@ -305,9 +305,17 @@ bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable& PLOG(ERROR) << "DM_TABLE_LOAD failed"; return false; } return true; } InitIo(io, name); if (ioctl(fd_, DM_DEV_SUSPEND, io)) { bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable& table) { if (!LoadTable(name, table)) { return false; } struct dm_ioctl io; InitIo(&io, name); if (ioctl(fd_, DM_DEV_SUSPEND, &io)) { PLOG(ERROR) << "DM_TABLE_SUSPEND resume failed"; return false; } Loading fs_mgr/libdm/dm_test.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -690,3 +690,23 @@ TEST(libdm, CreateEmptyDevice) { // Empty device should be in suspended state. ASSERT_EQ(DmDeviceState::SUSPENDED, dm.GetState("empty-device")); } TEST(libdm, UeventAfterLoadTable) { static const char* kDeviceName = "libmd-test-uevent-load-table"; DeviceMapper& dm = DeviceMapper::Instance(); ASSERT_TRUE(dm.CreateEmptyDevice(kDeviceName)); DmTable table; table.Emplace<DmTargetError>(0, 1); ASSERT_TRUE(dm.LoadTable(kDeviceName, table)); std::string ignore_path; ASSERT_TRUE(dm.WaitForDevice(kDeviceName, 5s, &ignore_path)); auto info = dm.GetDetailedInfo(kDeviceName); ASSERT_TRUE(info.has_value()); ASSERT_TRUE(info->IsSuspended()); ASSERT_TRUE(dm.DeleteDevice(kDeviceName)); } fs_mgr/libdm/include/libdm/dm.h +8 −1 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ class IDeviceMapper { const std::chrono::milliseconds& timeout_ms) = 0; virtual DmDeviceState GetState(const std::string& name) const = 0; virtual bool LoadTableAndActivate(const std::string& name, const DmTable& table) = 0; virtual bool LoadTable(const std::string& name, const DmTable& table) = 0; virtual bool GetTableInfo(const std::string& name, std::vector<TargetInfo>* table) = 0; virtual bool GetTableStatus(const std::string& name, std::vector<TargetInfo>* table) = 0; virtual bool GetDmDevicePathByName(const std::string& name, std::string* path) = 0; Loading Loading @@ -116,7 +117,7 @@ class DeviceMapper final : public IDeviceMapper { bool IsBufferFull() const { return flags_ & DM_BUFFER_FULL_FLAG; } bool IsInactiveTablePresent() const { return flags_ & DM_INACTIVE_PRESENT_FLAG; } bool IsReadOnly() const { return flags_ & DM_READONLY_FLAG; } bool IsSuspended() const { return flags_ & DM_SUSPEND_FLAG; } bool IsSuspended() const { return !IsActiveTablePresent() || (flags_ & DM_SUSPEND_FLAG); } }; // Removes a device mapper device with the given name. Loading Loading @@ -199,6 +200,12 @@ class DeviceMapper final : public IDeviceMapper { // Returns 'true' on success, false otherwise. bool LoadTableAndActivate(const std::string& name, const DmTable& table) override; // Same as LoadTableAndActivate, but there is no resume step. This puts the // new table in the inactive slot. // // Returns 'true' on success, false otherwise. bool LoadTable(const std::string& name, const DmTable& table) override; // Returns true if a list of available device mapper targets registered in the kernel was // successfully read and stored in 'targets'. Returns 'false' otherwise. bool GetAvailableTargets(std::vector<DmTargetTypeInfo>* targets); Loading fs_mgr/libdm/include/libdm/dm_table.h +3 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ namespace dm { class DmTable { public: DmTable() : num_sectors_(0), readonly_(false) {} DmTable(DmTable&& other) = default; // Adds a target to the device mapper table for a range specified in the target object. // The function will return 'true' if the target was successfully added and doesn't overlap with Loading Loading @@ -70,6 +71,8 @@ class DmTable { void set_readonly(bool readonly) { readonly_ = readonly; } bool readonly() const { return readonly_; } DmTable& operator=(DmTable&& other) = default; ~DmTable() = default; private: Loading fs_mgr/libdm/include/libdm/dm_target.h +8 −0 Original line number Diff line number Diff line Loading @@ -323,6 +323,14 @@ class DmTargetUser final : public DmTarget { std::string control_device_; }; class DmTargetError final : public DmTarget { public: DmTargetError(uint64_t start, uint64_t length) : DmTarget(start, length) {} std::string name() const override { return "error"; } std::string GetParameterString() const override { return ""; } }; } // namespace dm } // namespace android Loading Loading
fs_mgr/libdm/dm.cpp +11 −3 Original line number Diff line number Diff line Loading @@ -289,7 +289,7 @@ bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table) { return true; } bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable& table) { bool DeviceMapper::LoadTable(const std::string& name, const DmTable& table) { std::string ioctl_buffer(sizeof(struct dm_ioctl), 0); ioctl_buffer += table.Serialize(); Loading @@ -305,9 +305,17 @@ bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable& PLOG(ERROR) << "DM_TABLE_LOAD failed"; return false; } return true; } InitIo(io, name); if (ioctl(fd_, DM_DEV_SUSPEND, io)) { bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable& table) { if (!LoadTable(name, table)) { return false; } struct dm_ioctl io; InitIo(&io, name); if (ioctl(fd_, DM_DEV_SUSPEND, &io)) { PLOG(ERROR) << "DM_TABLE_SUSPEND resume failed"; return false; } Loading
fs_mgr/libdm/dm_test.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -690,3 +690,23 @@ TEST(libdm, CreateEmptyDevice) { // Empty device should be in suspended state. ASSERT_EQ(DmDeviceState::SUSPENDED, dm.GetState("empty-device")); } TEST(libdm, UeventAfterLoadTable) { static const char* kDeviceName = "libmd-test-uevent-load-table"; DeviceMapper& dm = DeviceMapper::Instance(); ASSERT_TRUE(dm.CreateEmptyDevice(kDeviceName)); DmTable table; table.Emplace<DmTargetError>(0, 1); ASSERT_TRUE(dm.LoadTable(kDeviceName, table)); std::string ignore_path; ASSERT_TRUE(dm.WaitForDevice(kDeviceName, 5s, &ignore_path)); auto info = dm.GetDetailedInfo(kDeviceName); ASSERT_TRUE(info.has_value()); ASSERT_TRUE(info->IsSuspended()); ASSERT_TRUE(dm.DeleteDevice(kDeviceName)); }
fs_mgr/libdm/include/libdm/dm.h +8 −1 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ class IDeviceMapper { const std::chrono::milliseconds& timeout_ms) = 0; virtual DmDeviceState GetState(const std::string& name) const = 0; virtual bool LoadTableAndActivate(const std::string& name, const DmTable& table) = 0; virtual bool LoadTable(const std::string& name, const DmTable& table) = 0; virtual bool GetTableInfo(const std::string& name, std::vector<TargetInfo>* table) = 0; virtual bool GetTableStatus(const std::string& name, std::vector<TargetInfo>* table) = 0; virtual bool GetDmDevicePathByName(const std::string& name, std::string* path) = 0; Loading Loading @@ -116,7 +117,7 @@ class DeviceMapper final : public IDeviceMapper { bool IsBufferFull() const { return flags_ & DM_BUFFER_FULL_FLAG; } bool IsInactiveTablePresent() const { return flags_ & DM_INACTIVE_PRESENT_FLAG; } bool IsReadOnly() const { return flags_ & DM_READONLY_FLAG; } bool IsSuspended() const { return flags_ & DM_SUSPEND_FLAG; } bool IsSuspended() const { return !IsActiveTablePresent() || (flags_ & DM_SUSPEND_FLAG); } }; // Removes a device mapper device with the given name. Loading Loading @@ -199,6 +200,12 @@ class DeviceMapper final : public IDeviceMapper { // Returns 'true' on success, false otherwise. bool LoadTableAndActivate(const std::string& name, const DmTable& table) override; // Same as LoadTableAndActivate, but there is no resume step. This puts the // new table in the inactive slot. // // Returns 'true' on success, false otherwise. bool LoadTable(const std::string& name, const DmTable& table) override; // Returns true if a list of available device mapper targets registered in the kernel was // successfully read and stored in 'targets'. Returns 'false' otherwise. bool GetAvailableTargets(std::vector<DmTargetTypeInfo>* targets); Loading
fs_mgr/libdm/include/libdm/dm_table.h +3 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ namespace dm { class DmTable { public: DmTable() : num_sectors_(0), readonly_(false) {} DmTable(DmTable&& other) = default; // Adds a target to the device mapper table for a range specified in the target object. // The function will return 'true' if the target was successfully added and doesn't overlap with Loading Loading @@ -70,6 +71,8 @@ class DmTable { void set_readonly(bool readonly) { readonly_ = readonly; } bool readonly() const { return readonly_; } DmTable& operator=(DmTable&& other) = default; ~DmTable() = default; private: Loading
fs_mgr/libdm/include/libdm/dm_target.h +8 −0 Original line number Diff line number Diff line Loading @@ -323,6 +323,14 @@ class DmTargetUser final : public DmTarget { std::string control_device_; }; class DmTargetError final : public DmTarget { public: DmTargetError(uint64_t start, uint64_t length) : DmTarget(start, length) {} std::string name() const override { return "error"; } std::string GetParameterString() const override { return ""; } }; } // namespace dm } // namespace android Loading