Merge PR #22717 into master

* refs/pull/22717/head:
	mgr/DaemonServer: osd purge: accept --yes-i-really-mean-it too
	mon,mgr: guard 'osd purge' with safe-to-destroy check
	mon/MonCommands: hide 'osd destroy-actual'
	mon/MonCommands: add HIDDEN flag
	mon,mgr: guard 'osd destroy' with 'osd safe-to-destroy' check
	mon/MonCommand: deprecate 'osd rm'
	mon/OSDMonitor: point users at 'ceph osd safe-to-destroy' for purge|destroy

Reviewed-by: Kefu Chai <kchai@redhat.com>
Reviewed-by: Josh Durgin <jdurgin@redhat.com>
This commit is contained in:
Sage Weil 2018-08-03 10:56:36 -05:00
commit dd475adea1
7 changed files with 101 additions and 29 deletions

View File

@ -1,3 +1,10 @@
14.0.1
------
* The 'ceph osd rm' command has been deprecated. Users should use
'ceph osd destroy' or 'ceph osd purge' (but after first confirming it is
safe to do so via the 'ceph osd safe-to-destroy' command).
>=13.1.0
--------

View File

@ -1201,17 +1201,29 @@ bool DaemonServer::handle_command(MCommand *m)
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" ||
prefix == "osd purge") {
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);
@ -1272,13 +1284,37 @@ bool DaemonServer::handle_command(MCommand *m)
<< " aren't still needed.";
r = -EBUSY;
}
if (r && (prefix == "osd destroy" ||
prefix == "osd purge")) {
string sure;
if (!cmd_getval(cct, cmdctx->cmdmap, "sure", sure) ||
(sure != "--force" &&
sure != "--yes-i-really-mean-it" /* for backward compat */)) {
ss << "\nYou can proceed 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" ||
prefix == "osd purge") {
const string cmd =
"{"
"\"prefix\": \"" + prefix + "-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;

View File

@ -107,6 +107,20 @@ COMMAND("osd test-reweight-by-pg " \
"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 purge " \
"name=id,type=CephOsdName " \
"name=sure,type=CephString,req=false", \
"purge all osd data from the monitors including the OSD id " \
"and CRUSH position", \
"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")

View File

@ -31,6 +31,7 @@ struct MonCommand {
static const uint64_t FLAG_DEPRECATED = 1 << 2;
static const uint64_t FLAG_MGR = 1 << 3;
static const uint64_t FLAG_POLL = 1 << 4;
static const uint64_t FLAG_HIDDEN = 1 << 5;
bool has_flag(uint64_t flag) const { return (flags & flag) != 0; }
void set_flag(uint64_t flag) { flags |= flag; }
@ -91,6 +92,10 @@ struct MonCommand {
return has_flag(MonCommand::FLAG_MGR);
}
bool is_hidden() const {
return has_flag(MonCommand::FLAG_HIDDEN);
}
static void encode_array(const MonCommand *cmds, int size, bufferlist &bl) {
ENCODE_START(2, 1, bl);
uint16_t s = size;

View File

@ -114,6 +114,7 @@
* MGR - command goes to ceph-mgr (for luminous+)
* POLL - command is intended to be called periodically by the
* client (see iostat)
* HIDDEN - command is hidden (no reported by help etc)
*
* A command should always be first considered DEPRECATED before being
* considered OBSOLETE, giving due consideration to users and conforming
@ -774,11 +775,12 @@ COMMAND("osd in " \
"set osd(s) <id> [<id>...] in, "
"can use <any|all> to automatically set all previously out osds in", \
"osd", "rw", "cli,rest")
COMMAND("osd rm " \
COMMAND_WITH_FLAG("osd rm " \
"name=ids,type=CephString,n=N", \
"remove osd(s) <id> [<id>...], "
"or use <any|all> to remove all osds", \
"osd", "rw", "cli,rest")
"osd", "rw", "cli,rest",
FLAG(DEPRECATED))
COMMAND("osd add-noup " \
"name=ids,type=CephString,n=N", \
"mark osd(s) <id> [<id>...] as noup, " \
@ -869,25 +871,25 @@ COMMAND("osd primary-affinity " \
"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_WITH_FLAG("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), " \
"but removes cephx keys, config-key data and lockbox keys, "\
"rendering data permanently unreadable.", \
"osd", "rw", "cli,rest")
"osd", "rw", "cli,rest", FLAG(HIDDEN))
COMMAND("osd purge-new " \
"name=id,type=CephOsdName " \
"name=sure,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
"purge all traces of an OSD that was partially created but never " \
"started", \
"osd", "rw", "cli,rest")
COMMAND("osd purge " \
COMMAND_WITH_FLAG("osd purge-actual " \
"name=id,type=CephOsdName " \
"name=sure,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
"purge all osd data from the monitors. Combines `osd destroy`, " \
"`osd rm`, and `osd crush rm`.", \
"osd", "rw", "cli,rest")
"osd", "rw", "cli,rest", FLAG(HIDDEN))
COMMAND("osd lost " \
"name=id,type=CephOsdName " \
"name=sure,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \

View File

@ -2977,7 +2977,9 @@ void Monitor::handle_command(MonOpRequestRef op)
paxos_service[PAXOS_MGR].get())->get_command_descs();
for (auto& c : leader_mon_commands) {
commands.push_back(c);
if (!c.is_hidden()) {
commands.push_back(c);
}
}
format_command_descriptions(commands, f, &rdata);

View File

@ -10640,8 +10640,8 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
return true;
}
} else if (prefix == "osd destroy" ||
prefix == "osd purge" ||
} else if (prefix == "osd destroy-actual" ||
prefix == "osd purge-actual" ||
prefix == "osd purge-new") {
/* Destroying an OSD means that we don't expect to further make use of
* the OSDs data (which may even become unreadable after this operation),
@ -10665,24 +10665,30 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
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 ||
assert("osd purge-actual" == prefix ||
"osd purge-new" == prefix);
}
string sure;
if (!cmd_getval(cct, cmdmap, "sure", sure) ||
sure != "--yes-i-really-mean-it") {
ss << "Are you SURE? This will mean real, permanent data loss, as well "
<< "as cephx and lockbox keys. Pass --yes-i-really-mean-it if you "
<< "really do.";
ss << "Are you SURE? Did you verify with 'ceph osd safe-to-destroy'? "
<< "This will mean real, permanent data loss, as well "
<< "as deletion of cephx and lockbox keys. "
<< "Pass --yes-i-really-mean-it if you really do.";
err = -EPERM;
goto reply;
} else if (!osdmap.exists(id)) {