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

Commit d9b581e9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "libdm: Implement zero and linear targets."

parents 2502aa2a bac58aee
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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;
+21 −4
Original line number Diff line number Diff line
@@ -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;
}

@@ -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;
}

@@ -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
+36 −1
Original line number Diff line number Diff line
@@ -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
+7 −1
Original line number Diff line number Diff line
@@ -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
@@ -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:
@@ -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
+29 −2
Original line number Diff line number Diff line
@@ -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_; }
@@ -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
@@ -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