119 lines
3.8 KiB
C++
119 lines
3.8 KiB
C++
|
// Copyright (c) Vitaliy Filippov, 2019+
|
||
|
// License: VNPL-1.1 (see README.md for details)
|
||
|
|
||
|
#include "base64.h"
|
||
|
#include "cluster_client.h"
|
||
|
#include "cli.h"
|
||
|
|
||
|
void cli_tool_t::change_parent(inode_t cur, inode_t new_parent)
|
||
|
{
|
||
|
auto cur_cfg_it = cli->st_cli.inode_config.find(cur);
|
||
|
if (cur_cfg_it == cli->st_cli.inode_config.end())
|
||
|
{
|
||
|
fprintf(stderr, "Inode 0x%lx disappeared\n", cur);
|
||
|
exit(1);
|
||
|
}
|
||
|
inode_config_t new_cfg = cur_cfg_it->second;
|
||
|
std::string cur_name = new_cfg.name;
|
||
|
std::string cur_cfg_key = base64_encode(cli->st_cli.etcd_prefix+
|
||
|
"/config/inode/"+std::to_string(INODE_POOL(cur))+
|
||
|
"/"+std::to_string(INODE_NO_POOL(cur)));
|
||
|
new_cfg.parent_id = new_parent;
|
||
|
json11::Json::object cur_cfg_json = cli->st_cli.serialize_inode_cfg(&new_cfg);
|
||
|
waiting++;
|
||
|
cli->st_cli.etcd_txn_slow(json11::Json::object {
|
||
|
{ "compare", json11::Json::array {
|
||
|
json11::Json::object {
|
||
|
{ "target", "MOD" },
|
||
|
{ "key", cur_cfg_key },
|
||
|
{ "result", "LESS" },
|
||
|
{ "mod_revision", new_cfg.mod_revision+1 },
|
||
|
},
|
||
|
} },
|
||
|
{ "success", json11::Json::array {
|
||
|
json11::Json::object {
|
||
|
{ "request_put", json11::Json::object {
|
||
|
{ "key", cur_cfg_key },
|
||
|
{ "value", base64_encode(json11::Json(cur_cfg_json).dump()) },
|
||
|
} }
|
||
|
},
|
||
|
} },
|
||
|
}, [this, new_parent, cur, cur_name](std::string err, json11::Json res)
|
||
|
{
|
||
|
if (err != "")
|
||
|
{
|
||
|
fprintf(stderr, "Error changing parent of %s: %s\n", cur_name.c_str(), err.c_str());
|
||
|
exit(1);
|
||
|
}
|
||
|
if (!res["succeeded"].bool_value())
|
||
|
{
|
||
|
fprintf(stderr, "Inode %s was modified during snapshot deletion\n", cur_name.c_str());
|
||
|
exit(1);
|
||
|
}
|
||
|
if (new_parent)
|
||
|
{
|
||
|
auto new_parent_it = cli->st_cli.inode_config.find(new_parent);
|
||
|
std::string new_parent_name = new_parent_it != cli->st_cli.inode_config.end()
|
||
|
? new_parent_it->second.name : "<unknown>";
|
||
|
printf(
|
||
|
"Parent of layer %s (inode %lu in pool %u) changed to %s (inode %lu in pool %u)\n",
|
||
|
cur_name.c_str(), INODE_NO_POOL(cur), INODE_POOL(cur),
|
||
|
new_parent_name.c_str(), INODE_NO_POOL(new_parent), INODE_POOL(new_parent)
|
||
|
);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf(
|
||
|
"Parent of layer %s (inode %lu in pool %u) detached\n",
|
||
|
cur_name.c_str(), INODE_NO_POOL(cur), INODE_POOL(cur)
|
||
|
);
|
||
|
}
|
||
|
waiting--;
|
||
|
ringloop->wakeup();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
void cli_tool_t::etcd_txn(json11::Json txn)
|
||
|
{
|
||
|
waiting++;
|
||
|
cli->st_cli.etcd_txn_slow(txn, [this](std::string err, json11::Json res)
|
||
|
{
|
||
|
waiting--;
|
||
|
if (err != "")
|
||
|
{
|
||
|
fprintf(stderr, "Error reading from etcd: %s\n", err.c_str());
|
||
|
exit(1);
|
||
|
}
|
||
|
etcd_result = res;
|
||
|
ringloop->wakeup();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
inode_config_t* cli_tool_t::get_inode_cfg(const std::string & name)
|
||
|
{
|
||
|
for (auto & ic: cli->st_cli.inode_config)
|
||
|
{
|
||
|
if (ic.second.name == name)
|
||
|
{
|
||
|
return &ic.second;
|
||
|
}
|
||
|
}
|
||
|
fprintf(stderr, "Layer %s not found\n", name.c_str());
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
void cli_tool_t::parse_config(json11::Json cfg)
|
||
|
{
|
||
|
color = !cfg["no-color"].bool_value();
|
||
|
json_output = cfg["json"].bool_value();
|
||
|
iodepth = cfg["iodepth"].uint64_value();
|
||
|
if (!iodepth)
|
||
|
iodepth = 32;
|
||
|
parallel_osds = cfg["parallel_osds"].uint64_value();
|
||
|
if (!parallel_osds)
|
||
|
parallel_osds = 4;
|
||
|
log_level = cfg["log_level"].int64_value();
|
||
|
progress = cfg["progress"].uint64_value() ? true : false;
|
||
|
list_first = cfg["wait-list"].uint64_value() ? true : false;
|
||
|
}
|