Merge "libdm: Implement LoadTableAndActivate."

This commit is contained in:
Treehugger Robot 2018-06-21 19:01:49 +00:00 committed by Gerrit Code Review
commit 2e98fd23c3
5 changed files with 57 additions and 19 deletions

View file

@ -94,8 +94,37 @@ DmDeviceState DeviceMapper::state(const std::string& /* name */) const {
return DmDeviceState::INVALID;
}
bool DeviceMapper::LoadTableAndActivate(const std::string& /* name */, const DmTable& /* table */) {
return false;
bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table) {
if (!CreateDevice(name)) {
return false;
}
if (!LoadTableAndActivate(name, table)) {
DeleteDevice(name);
return false;
}
return true;
}
bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable& table) {
std::string ioctl_buffer(sizeof(struct dm_ioctl), 0);
ioctl_buffer += table.Serialize();
struct dm_ioctl* io = reinterpret_cast<struct dm_ioctl*>(&ioctl_buffer[0]);
InitIo(io, name);
io->data_size = ioctl_buffer.size();
io->data_start = sizeof(struct dm_ioctl);
io->target_count = static_cast<uint32_t>(table.num_targets());
if (ioctl(fd_, DM_TABLE_LOAD, io)) {
PLOG(ERROR) << "DM_TABLE_LOAD failed";
return false;
}
InitIo(io, name);
if (ioctl(fd_, DM_DEV_SUSPEND, io)) {
PLOG(ERROR) << "DM_TABLE_SUSPEND resume failed";
return false;
}
return true;
}
// Reads all the available device mapper targets and their corresponding

View file

@ -34,8 +34,8 @@ bool DmTable::valid() const {
return true;
}
uint64_t DmTable::size() const {
return valid() ? size_ : 0;
uint64_t DmTable::num_sectors() const {
return valid() ? num_sectors_ : 0;
}
// Returns a string represnetation of the table that is ready to be passed

View file

@ -69,14 +69,6 @@ class DeviceMapper final {
uint64_t dev_;
};
// Creates a device mapper device with given name.
// Return 'true' on success and 'false' on failure to
// create OR if a device mapper device with the same name already
// exists.
// TODO(b/110035986): Make this method private and to be only
// called through LoadTableAndActivate() below.
bool CreateDevice(const std::string& name);
// Removes a device mapper device with the given name.
// Returns 'true' on success, false otherwise.
bool DeleteDevice(const std::string& name);
@ -90,9 +82,14 @@ class DeviceMapper final {
// One of INVALID, SUSPENDED or ACTIVE.
DmDeviceState state(const std::string& name) const;
// Loads the device mapper table from parameter into the underlying
// device mapper device with given name and activate / resumes the device in the process.
// If a device mapper device with the 'name', doesn't exist, it will be created.
// 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.
bool CreateDevice(const std::string& name, const DmTable& table);
// Loads the device mapper table from parameter into the underlying device
// mapper device with given name and activate / resumes the device in the
// process. A device with the given name must already exist.
//
// Returns 'true' on success, false otherwise.
bool LoadTableAndActivate(const std::string& name, const DmTable& table);
@ -140,6 +137,12 @@ class DeviceMapper final {
}
}
// Creates a device mapper device with given name.
// Return 'true' on success and 'false' on failure to
// create OR if a device mapper device with the same name already
// exists.
bool CreateDevice(const std::string& name);
int fd_;
// Non-copyable & Non-movable
DeviceMapper(const DeviceMapper&) = delete;

View file

@ -30,7 +30,7 @@ namespace dm {
class DmTable {
public:
DmTable() : size_(0){};
DmTable() : num_sectors_(0){};
// 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
@ -48,9 +48,12 @@ class DmTable {
// table is malformed.
bool valid() const;
// Returns the toatl number of targets.
size_t num_targets() const { return targets_.size(); }
// Returns the total size represented by the table in terms of number of 512-byte sectors.
// NOTE: This function will overlook if there are any gaps in the targets added in the table.
uint64_t size() const;
uint64_t num_sectors() const;
// Returns the string represntation of the table that is ready to be passed into the kernel
// as part of the DM_TABLE_LOAD ioctl.
@ -66,7 +69,7 @@ class DmTable {
// Total size in terms of # of sectors, as calculated by looking at the last and the first
// target in 'target_'.
uint64_t size_;
uint64_t num_sectors_;
};
} // namespace dm

View file

@ -34,6 +34,7 @@
#include <vector>
using DeviceMapper = ::android::dm::DeviceMapper;
using DmTable = ::android::dm::DmTable;
using DmTarget = ::android::dm::DmTarget;
using DmBlockDevice = ::android::dm::DeviceMapper::DmBlockDevice;
@ -53,9 +54,11 @@ static int DmCreateCmdHandler(int argc, char** argv) {
return -EINVAL;
}
DmTable table;
std::string name = argv[0];
DeviceMapper& dm = DeviceMapper::Instance();
if (!dm.CreateDevice(name)) {
if (!dm.CreateDevice(name, table)) {
std::cerr << "Failed to create device-mapper device with name: " << name << std::endl;
return -EIO;
}