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: Alessio Balsini <balsini@google.com>
This commit is contained in:
parent
f7970cee69
commit
81d4ea79e2
1 changed files with 41 additions and 11 deletions
|
@ -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},
|
||||
|
|
Loading…
Reference in a new issue