cmdctx->reply(r, ss);
return true;
}
- } else if (prefix == "osd safe-to-destroy") {
- vector<string> ids;
- cmd_getval(g_ceph_context, cmdctx->cmdmap, "ids", ids);
+ } else if (prefix == "osd safe-to-destroy" ||
+ prefix == "osd destroy") {
set<int> osds;
- int r;
- cluster_state.with_osdmap([&](const OSDMap& osdmap) {
- r = osdmap.parse_osd_id_list(ids, &osds, &ss);
- });
- if (!r && osds.empty()) {
- ss << "must specify one or more OSDs";
- r = -EINVAL;
+ int r = 0;
+ if (prefix == "osd safe-to-destroy") {
+ vector<string> ids;
+ cmd_getval(g_ceph_context, cmdctx->cmdmap, "ids", ids);
+ cluster_state.with_osdmap([&](const OSDMap& osdmap) {
+ r = osdmap.parse_osd_id_list(ids, &osds, &ss);
+ });
+ if (!r && osds.empty()) {
+ ss << "must specify one or more OSDs";
+ r = -EINVAL;
+ }
+ } else {
+ int64_t id;
+ if (!cmd_getval(g_ceph_context, cmdctx->cmdmap, "id", id)) {
+ r = -EINVAL;
+ ss << "must specify OSD id";
+ } else {
+ osds.insert(id);
+ }
}
if (r < 0) {
cmdctx->reply(r, ss);
<< " aren't still needed.";
r = -EBUSY;
}
+
+ if (r && prefix == "osd destroy") {
+ string sure;
+ if (!cmd_getval(cct, cmdctx->cmdmap, "sure", sure) ||
+ sure != "--force") {
+ ss << "\nYou can proceed with OSD removal by passing --force, but be warned that this will likely mean real, permanent data loss.";
+ } else {
+ r = 0;
+ }
+ }
if (r) {
cmdctx->reply(r, ss);
return true;
}
- ss << "OSD(s) " << osds << " are safe to destroy without reducing data"
- << " durability.";
- cmdctx->reply(0, ss);
+ if (prefix == "osd destroy") {
+ const string cmd =
+ "{"
+ "\"prefix\": \"osd destroy-actual\", "
+ "\"id\": " + stringify(osds) + ", "
+ "\"sure\": \"--yes-i-really-mean-it\""
+ "}";
+ auto on_finish = new ReplyOnFinish(cmdctx);
+ monc->start_mon_command({cmd}, {}, nullptr, &on_finish->outs, on_finish);
+ } else {
+ ss << "OSD(s) " << osds << " are safe to destroy without reducing data"
+ << " durability.";
+ cmdctx->reply(0, ss);
+ }
return true;
} else if (prefix == "osd ok-to-stop") {
vector<string> ids;
"dry run of reweight OSDs by PG distribution [overload-percentage-for-consideration, default 120]", \
"osd", "r", "cli,rest")
+COMMAND("osd destroy " \
+ "name=id,type=CephOsdName " \
+ "name=sure,type=CephString,req=False",
+ "mark osd as being destroyed. Keeps the ID intact (allowing reuse), " \
+ "but removes cephx keys, config-key data and lockbox keys, "\
+ "rendering data permanently unreadable.", \
+ "osd", "rw", "cli,rest")
+
COMMAND("osd safe-to-destroy name=ids,type=CephString,n=N",
"check whether osd(s) can be safely destroyed without reducing data durability",
"osd", "r", "cli,rest")
"type=CephFloat,name=weight,range=0.0|1.0", \
"adjust osd primary-affinity from 0.0 <= <weight> <= 1.0", \
"osd", "rw", "cli,rest")
-COMMAND("osd destroy " \
+COMMAND("osd destroy-actual " \
"name=id,type=CephOsdName " \
"name=sure,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
"mark osd as being destroyed. Keeps the ID intact (allowing reuse), " \
return true;
}
- } else if (prefix == "osd destroy" ||
+ } else if (prefix == "osd destroy-actual" ||
prefix == "osd purge" ||
prefix == "osd purge-new") {
/* Destroying an OSD means that we don't expect to further make use of
int64_t id;
if (!cmd_getval(cct, cmdmap, "id", id)) {
- ss << "unable to parse osd id value '"
- << cmd_vartype_stringify(cmdmap.at("id")) << "";
+ auto p = cmdmap.find("id");
+ if (p == cmdmap.end()) {
+ ss << "no osd id specified";
+ } else {
+ ss << "unable to parse osd id value '"
+ << cmd_vartype_stringify(cmdmap.at("id")) << "";
+ }
err = -EINVAL;
goto reply;
}
- bool is_destroy = (prefix == "osd destroy");
+ bool is_destroy = (prefix == "osd destroy-actual");
if (!is_destroy) {
assert("osd purge" == prefix ||
"osd purge-new" == prefix);