2021-11-19 02:39:32 +03:00
|
|
|
// Copyright (c) Vitaliy Filippov, 2019+
|
|
|
|
// License: VNPL-1.1 (see README.md for details)
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "cli.h"
|
|
|
|
#include "cluster_client.h"
|
|
|
|
#include "base64.h"
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
// Safely allocate an OSD number
|
|
|
|
struct alloc_osd_t
|
|
|
|
{
|
|
|
|
cli_tool_t *parent;
|
|
|
|
|
|
|
|
uint64_t new_id = 1;
|
|
|
|
|
|
|
|
int state = 0;
|
2022-04-03 20:14:51 +03:00
|
|
|
cli_result_t result;
|
2021-11-19 02:39:32 +03:00
|
|
|
|
|
|
|
bool is_done()
|
|
|
|
{
|
|
|
|
return state == 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
void loop()
|
|
|
|
{
|
|
|
|
if (state == 1)
|
|
|
|
goto resume_1;
|
2021-11-21 00:01:03 +03:00
|
|
|
do
|
2021-11-19 02:39:32 +03:00
|
|
|
{
|
2022-01-23 16:25:47 +03:00
|
|
|
parent->etcd_txn(json11::Json::object {
|
2021-11-19 02:39:32 +03:00
|
|
|
{ "compare", json11::Json::array {
|
|
|
|
json11::Json::object {
|
|
|
|
{ "target", "VERSION" },
|
|
|
|
{ "version", 0 },
|
|
|
|
{ "key", base64_encode(
|
|
|
|
parent->cli->st_cli.etcd_prefix+"/osd/stats/"+std::to_string(new_id)
|
|
|
|
) },
|
|
|
|
},
|
|
|
|
} },
|
|
|
|
{ "success", json11::Json::array {
|
|
|
|
json11::Json::object {
|
|
|
|
{ "request_put", json11::Json::object {
|
|
|
|
{ "key", base64_encode(
|
|
|
|
parent->cli->st_cli.etcd_prefix+"/osd/stats/"+std::to_string(new_id)
|
|
|
|
) },
|
|
|
|
{ "value", base64_encode("{}") },
|
|
|
|
} },
|
|
|
|
},
|
|
|
|
} },
|
|
|
|
{ "failure", json11::Json::array {
|
|
|
|
json11::Json::object {
|
|
|
|
{ "request_range", json11::Json::object {
|
|
|
|
{ "key", base64_encode(parent->cli->st_cli.etcd_prefix+"/osd/stats/") },
|
|
|
|
{ "range_end", base64_encode(parent->cli->st_cli.etcd_prefix+"/osd/stats0") },
|
|
|
|
{ "keys_only", true },
|
|
|
|
} },
|
|
|
|
},
|
|
|
|
} },
|
|
|
|
});
|
|
|
|
resume_1:
|
|
|
|
state = 1;
|
|
|
|
if (parent->waiting > 0)
|
|
|
|
return;
|
2022-04-03 20:14:51 +03:00
|
|
|
if (parent->etcd_err.err)
|
|
|
|
{
|
|
|
|
result = parent->etcd_err;
|
|
|
|
state = 100;
|
|
|
|
return;
|
|
|
|
}
|
2022-01-23 16:25:47 +03:00
|
|
|
if (!parent->etcd_result["succeeded"].bool_value())
|
2021-11-19 02:39:32 +03:00
|
|
|
{
|
|
|
|
std::vector<osd_num_t> used;
|
2022-01-23 16:25:47 +03:00
|
|
|
for (auto kv: parent->etcd_result["responses"][0]["response_range"]["kvs"].array_items())
|
2021-11-19 02:39:32 +03:00
|
|
|
{
|
|
|
|
std::string key = base64_decode(kv["key"].string_value());
|
|
|
|
osd_num_t cur_osd;
|
|
|
|
char null_byte = 0;
|
|
|
|
sscanf(key.c_str() + parent->cli->st_cli.etcd_prefix.length(), "/osd/stats/%lu%c", &cur_osd, &null_byte);
|
|
|
|
if (!cur_osd || null_byte != 0)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Invalid key in etcd: %s\n", key.c_str());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
used.push_back(cur_osd);
|
|
|
|
}
|
|
|
|
std::sort(used.begin(), used.end());
|
|
|
|
if (used[used.size()-1] == used.size())
|
|
|
|
{
|
|
|
|
new_id = used.size()+1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int s = 0, e = used.size();
|
|
|
|
while (e > s+1)
|
|
|
|
{
|
|
|
|
int c = (s+e)/2;
|
|
|
|
if (used[c] == c+1)
|
|
|
|
s = c;
|
|
|
|
else
|
|
|
|
e = c;
|
|
|
|
}
|
|
|
|
new_id = used[e-1]+1;
|
|
|
|
}
|
|
|
|
}
|
2022-01-23 16:25:47 +03:00
|
|
|
} while (!parent->etcd_result["succeeded"].bool_value());
|
2021-11-19 02:39:32 +03:00
|
|
|
state = 100;
|
2022-04-03 20:14:51 +03:00
|
|
|
result = (cli_result_t){
|
|
|
|
.text = std::to_string(new_id),
|
|
|
|
.data = json11::Json(new_id),
|
|
|
|
};
|
2021-11-19 02:39:32 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-04-03 20:14:51 +03:00
|
|
|
std::function<bool(cli_result_t &)> cli_tool_t::start_alloc_osd(json11::Json cfg)
|
2021-11-19 02:39:32 +03:00
|
|
|
{
|
|
|
|
auto alloc_osd = new alloc_osd_t();
|
|
|
|
alloc_osd->parent = this;
|
2022-04-03 20:14:51 +03:00
|
|
|
return [alloc_osd](cli_result_t & result)
|
2021-11-19 02:39:32 +03:00
|
|
|
{
|
|
|
|
alloc_osd->loop();
|
|
|
|
if (alloc_osd->is_done())
|
|
|
|
{
|
2022-04-03 20:14:51 +03:00
|
|
|
result = alloc_osd->result;
|
2021-11-19 02:39:32 +03:00
|
|
|
delete alloc_osd;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
}
|