Loading fs_mgr/libdm/dm.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,9 @@ bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable& io->data_size = ioctl_buffer.size(); io->data_start = sizeof(struct dm_ioctl); io->target_count = static_cast<uint32_t>(table.num_targets()); if (table.readonly()) { io->flags |= DM_READONLY_FLAG; } if (ioctl(fd_, DM_TABLE_LOAD, io)) { PLOG(ERROR) << "DM_TABLE_LOAD failed"; return false; Loading fs_mgr/libdm/dm_table.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ namespace android { namespace dm { bool DmTable::AddTarget(std::unique_ptr<DmTarget>&& /* target */) { bool DmTable::AddTarget(std::unique_ptr<DmTarget>&& target) { targets_.push_back(std::move(target)); return true; } Loading @@ -31,6 +32,14 @@ bool DmTable::RemoveTarget(std::unique_ptr<DmTarget>&& /* target */) { } bool DmTable::valid() const { if (targets_.empty()) { LOG(ERROR) << "Device-mapper table must have at least one target."; return ""; } if (targets_[0]->start() != 0) { LOG(ERROR) << "Device-mapper table must start at logical sector 0."; return ""; } return true; } Loading @@ -38,15 +47,23 @@ uint64_t DmTable::num_sectors() const { return valid() ? num_sectors_ : 0; } // Returns a string represnetation of the table that is ready to be passed // down to the kernel for loading // Returns a string representation of the table that is ready to be passed // down to the kernel for loading. // // Implementation must verify there are no gaps in the table, table starts // with sector == 0, and iterate over each target to get its table // serialized. std::string DmTable::Serialize() const { if (!valid()) { return ""; } std::string table; for (const auto& target : targets_) { table += target->Serialize(); } return table; } } // namespace dm } // namespace android fs_mgr/libdm/dm_target.cpp +36 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,41 @@ #include <android-base/logging.h> #include <android-base/macros.h> #include <libdm/dm.h> namespace android { namespace dm {} // namespace dm namespace dm { std::string DmTarget::Serialize() const { // Create a string containing a dm_target_spec, parameter data, and an // explicit null terminator. std::string data(sizeof(dm_target_spec), '\0'); data += GetParameterString(); data.push_back('\0'); // The kernel expects each target to be 8-byte aligned. size_t padding = DM_ALIGN(data.size()) - data.size(); for (size_t i = 0; i < padding; i++) { data.push_back('\0'); } // Finally fill in the dm_target_spec. struct dm_target_spec* spec = reinterpret_cast<struct dm_target_spec*>(&data[0]); spec->sector_start = start(); spec->length = size(); strlcpy(spec->target_type, name().c_str(), sizeof(spec->target_type)); spec->next = (uint32_t)data.size(); return data; } std::string DmTargetZero::GetParameterString() const { // The zero target type has no additional parameters. return ""; } std::string DmTargetLinear::GetParameterString() const { return block_device_ + " " + std::to_string(physical_sector_); } } // namespace dm } // namespace android fs_mgr/libdm/include/libdm/dm_table.h +7 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ namespace dm { class DmTable { public: DmTable() : num_sectors_(0){}; DmTable() : num_sectors_(0), readonly_(false) {} // 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 @@ -59,6 +59,9 @@ class DmTable { // as part of the DM_TABLE_LOAD ioctl. std::string Serialize() const; void set_readonly(bool readonly) { readonly_ = readonly; } bool readonly() const { return readonly_; } ~DmTable() = default; private: Loading @@ -70,6 +73,9 @@ class DmTable { // Total size in terms of # of sectors, as calculated by looking at the last and the first // target in 'target_'. uint64_t num_sectors_; // True if the device should be read-only; false otherwise. bool readonly_; }; } // namespace dm Loading fs_mgr/libdm/include/libdm/dm_target.h +29 −2 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ class DmTarget { virtual ~DmTarget() = default; // Returns name of the target. virtual const std::string& name() const = 0; virtual std::string name() const = 0; // Return the first logical sector represented by this target. uint64_t start() const { return start_; } Loading @@ -67,7 +67,12 @@ class DmTarget { // Function that converts this object to a string of arguments that can // be passed to the kernel for adding this target in a table. Each target (e.g. verity, linear) // must implement this, for it to be used on a device. virtual std::string Serialize() const = 0; std::string Serialize() const; protected: // Get the parameter string that is passed to the end of the dm_target_spec // for this target type. virtual std::string GetParameterString() const = 0; private: // logical sector number start and total length (in terms of 512-byte sectors) represented Loading @@ -75,6 +80,28 @@ class DmTarget { uint64_t start_, length_; }; class DmTargetZero final : public DmTarget { public: DmTargetZero(uint64_t start, uint64_t length) : DmTarget(start, length) {} std::string name() const override { return "zero"; } std::string GetParameterString() const override; }; class DmTargetLinear final : public DmTarget { public: DmTargetLinear(uint64_t start, uint64_t length, const std::string& block_device, uint64_t physical_sector) : DmTarget(start, length), block_device_(block_device), physical_sector_(physical_sector) {} std::string name() const override { return "linear"; } std::string GetParameterString() const override; private: std::string block_device_; uint64_t physical_sector_; }; } // namespace dm } // namespace android Loading Loading
fs_mgr/libdm/dm.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,9 @@ bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable& io->data_size = ioctl_buffer.size(); io->data_start = sizeof(struct dm_ioctl); io->target_count = static_cast<uint32_t>(table.num_targets()); if (table.readonly()) { io->flags |= DM_READONLY_FLAG; } if (ioctl(fd_, DM_TABLE_LOAD, io)) { PLOG(ERROR) << "DM_TABLE_LOAD failed"; return false; Loading
fs_mgr/libdm/dm_table.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ namespace android { namespace dm { bool DmTable::AddTarget(std::unique_ptr<DmTarget>&& /* target */) { bool DmTable::AddTarget(std::unique_ptr<DmTarget>&& target) { targets_.push_back(std::move(target)); return true; } Loading @@ -31,6 +32,14 @@ bool DmTable::RemoveTarget(std::unique_ptr<DmTarget>&& /* target */) { } bool DmTable::valid() const { if (targets_.empty()) { LOG(ERROR) << "Device-mapper table must have at least one target."; return ""; } if (targets_[0]->start() != 0) { LOG(ERROR) << "Device-mapper table must start at logical sector 0."; return ""; } return true; } Loading @@ -38,15 +47,23 @@ uint64_t DmTable::num_sectors() const { return valid() ? num_sectors_ : 0; } // Returns a string represnetation of the table that is ready to be passed // down to the kernel for loading // Returns a string representation of the table that is ready to be passed // down to the kernel for loading. // // Implementation must verify there are no gaps in the table, table starts // with sector == 0, and iterate over each target to get its table // serialized. std::string DmTable::Serialize() const { if (!valid()) { return ""; } std::string table; for (const auto& target : targets_) { table += target->Serialize(); } return table; } } // namespace dm } // namespace android
fs_mgr/libdm/dm_target.cpp +36 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,41 @@ #include <android-base/logging.h> #include <android-base/macros.h> #include <libdm/dm.h> namespace android { namespace dm {} // namespace dm namespace dm { std::string DmTarget::Serialize() const { // Create a string containing a dm_target_spec, parameter data, and an // explicit null terminator. std::string data(sizeof(dm_target_spec), '\0'); data += GetParameterString(); data.push_back('\0'); // The kernel expects each target to be 8-byte aligned. size_t padding = DM_ALIGN(data.size()) - data.size(); for (size_t i = 0; i < padding; i++) { data.push_back('\0'); } // Finally fill in the dm_target_spec. struct dm_target_spec* spec = reinterpret_cast<struct dm_target_spec*>(&data[0]); spec->sector_start = start(); spec->length = size(); strlcpy(spec->target_type, name().c_str(), sizeof(spec->target_type)); spec->next = (uint32_t)data.size(); return data; } std::string DmTargetZero::GetParameterString() const { // The zero target type has no additional parameters. return ""; } std::string DmTargetLinear::GetParameterString() const { return block_device_ + " " + std::to_string(physical_sector_); } } // namespace dm } // namespace android
fs_mgr/libdm/include/libdm/dm_table.h +7 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ namespace dm { class DmTable { public: DmTable() : num_sectors_(0){}; DmTable() : num_sectors_(0), readonly_(false) {} // 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 @@ -59,6 +59,9 @@ class DmTable { // as part of the DM_TABLE_LOAD ioctl. std::string Serialize() const; void set_readonly(bool readonly) { readonly_ = readonly; } bool readonly() const { return readonly_; } ~DmTable() = default; private: Loading @@ -70,6 +73,9 @@ class DmTable { // Total size in terms of # of sectors, as calculated by looking at the last and the first // target in 'target_'. uint64_t num_sectors_; // True if the device should be read-only; false otherwise. bool readonly_; }; } // namespace dm Loading
fs_mgr/libdm/include/libdm/dm_target.h +29 −2 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ class DmTarget { virtual ~DmTarget() = default; // Returns name of the target. virtual const std::string& name() const = 0; virtual std::string name() const = 0; // Return the first logical sector represented by this target. uint64_t start() const { return start_; } Loading @@ -67,7 +67,12 @@ class DmTarget { // Function that converts this object to a string of arguments that can // be passed to the kernel for adding this target in a table. Each target (e.g. verity, linear) // must implement this, for it to be used on a device. virtual std::string Serialize() const = 0; std::string Serialize() const; protected: // Get the parameter string that is passed to the end of the dm_target_spec // for this target type. virtual std::string GetParameterString() const = 0; private: // logical sector number start and total length (in terms of 512-byte sectors) represented Loading @@ -75,6 +80,28 @@ class DmTarget { uint64_t start_, length_; }; class DmTargetZero final : public DmTarget { public: DmTargetZero(uint64_t start, uint64_t length) : DmTarget(start, length) {} std::string name() const override { return "zero"; } std::string GetParameterString() const override; }; class DmTargetLinear final : public DmTarget { public: DmTargetLinear(uint64_t start, uint64_t length, const std::string& block_device, uint64_t physical_sector) : DmTarget(start, length), block_device_(block_device), physical_sector_(physical_sector) {} std::string name() const override { return "linear"; } std::string GetParameterString() const override; private: std::string block_device_; uint64_t physical_sector_; }; } // namespace dm } // namespace android Loading