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

Commit 81d4ea79 authored by Alessio Balsini's avatar Alessio Balsini
Browse files

dmctl: add replace command



The replace command is used to substitute the current table of a
device-mapper with the provided one.
The new table will be available as soon as the command returns
successfully.

Bug: 137759376
Test: manual
Change-Id: Iaf258d9043fab3a8770702f4e1c8c0e583c81519
Signed-off-by: default avatarAlessio Balsini <balsini@google.com>
parent f7970cee
Loading
Loading
Loading
Loading
+41 −11
Original line number Diff line number Diff line
@@ -197,19 +197,12 @@ class TargetParser final {
    char** argv_;
};

static int DmCreateCmdHandler(int argc, char** argv) {
    if (argc < 1) {
        std::cerr << "Usage: dmctl create <dm-name> [-ro] <targets...>" << std::endl;
        return -EINVAL;
    }
    std::string name = argv[0];

static bool parse_table_args(DmTable* table, int argc, char** argv) {
    // Parse extended options first.
    DmTable table;
    int arg_index = 1;
    while (arg_index < argc && argv[arg_index][0] == '-') {
        if (strcmp(argv[arg_index], "-ro") == 0) {
            table.set_readonly(true);
            table->set_readonly(true);
            arg_index++;
        } else {
            std::cerr << "Unrecognized option: " << argv[arg_index] << std::endl;
@@ -221,15 +214,30 @@ static int DmCreateCmdHandler(int argc, char** argv) {
    TargetParser parser(argc - arg_index, argv + arg_index);
    while (parser.More()) {
        std::unique_ptr<DmTarget> target = parser.Next();
        if (!target || !table.AddTarget(std::move(target))) {
        if (!target || !table->AddTarget(std::move(target))) {
            return -EINVAL;
        }
    }

    if (table.num_targets() == 0) {
    if (table->num_targets() == 0) {
        std::cerr << "Must define at least one target." << std::endl;
        return -EINVAL;
    }
    return 0;
}

static int DmCreateCmdHandler(int argc, char** argv) {
    if (argc < 1) {
        std::cerr << "Usage: dmctl create <dm-name> [-ro] <targets...>" << std::endl;
        return -EINVAL;
    }
    std::string name = argv[0];

    DmTable table;
    int ret = parse_table_args(&table, argc, argv);
    if (ret) {
        return ret;
    }

    DeviceMapper& dm = DeviceMapper::Instance();
    if (!dm.CreateDevice(name, table)) {
@@ -255,6 +263,27 @@ static int DmDeleteCmdHandler(int argc, char** argv) {
    return 0;
}

static int DmReplaceCmdHandler(int argc, char** argv) {
    if (argc < 1) {
        std::cerr << "Usage: dmctl replace <dm-name> <targets...>" << std::endl;
        return -EINVAL;
    }
    std::string name = argv[0];

    DmTable table;
    int ret = parse_table_args(&table, argc, argv);
    if (ret) {
        return ret;
    }

    DeviceMapper& dm = DeviceMapper::Instance();
    if (!dm.LoadTableAndActivate(name, table)) {
        std::cerr << "Failed to replace device-mapper table to: " << name << std::endl;
        return -EIO;
    }
    return 0;
}

static int DmListTargets(DeviceMapper& dm, [[maybe_unused]] int argc,
                         [[maybe_unused]] char** argv) {
    std::vector<DmTargetTypeInfo> targets;
@@ -469,6 +498,7 @@ static std::map<std::string, std::function<int(int, char**)>> cmdmap = {
        // clang-format off
        {"create", DmCreateCmdHandler},
        {"delete", DmDeleteCmdHandler},
        {"replace", DmReplaceCmdHandler},
        {"list", DmListCmdHandler},
        {"help", HelpCmdHandler},
        {"getpath", GetPathCmdHandler},