From b172605060f5a55ad217975c6f0a61ec557942df Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 30 May 2017 18:29:03 -0400 Subject: [PATCH] mon/OSDMonitor: validate set-require-min-compat-client against connected clients Prevent the user from setting a require_min_compat_client if a disallowed client is currently connected to the mon cluster. Instead, you'll get an error like Error EPERM: cannot set require_min_compat_client to luminous: 1 connected client(s) look like jewel (missing 0x800000000200000); add --yes-i-really-mean-it to do it anyway Signed-off-by: Sage Weil --- src/mon/MonCommands.h | 3 ++- src/mon/OSDMonitor.cc | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index d42b59d7e95..9ab4f44a4a8 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -613,7 +613,8 @@ COMMAND("osd set-nearfull-ratio " \ "set usage ratio at which OSDs are marked near-full", "osd", "rw", "cli,rest") COMMAND("osd set-require-min-compat-client " \ - "name=version,type=CephString", + "name=version,type=CephString " \ + "name=sure,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \ "set the minimum client version we will maintain compatibility with", "osd", "rw", "cli,rest") COMMAND("osd pause", "pause osd", "osd", "rw", "cli,rest") diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 1c85408ea12..1d8403bed10 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -7511,6 +7511,45 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, err = -EPERM; goto reply; } + string sure; + cmd_getval(g_ceph_context, cmdmap, "sure", sure); + if (sure != "--yes-i-really-mean-it") { + FeatureMap m; + mon->get_combined_feature_map(&m); + uint64_t features = ceph_release_features(vno); + bool first = true; + bool ok = true; + for (int type : { + CEPH_ENTITY_TYPE_CLIENT, + CEPH_ENTITY_TYPE_MDS, + CEPH_ENTITY_TYPE_MGR }) { + auto p = m.m.find(type); + if (p == m.m.end()) { + continue; + } + for (auto& q : p->second) { + uint64_t missing = ~q.first & features; + if (missing) { + if (first) { + ss << "cannot set require_min_compat_client to " << v << ": "; + } else { + ss << "; "; + } + first = false; + ss << q.second << " connected " << ceph_entity_type_name(type) + << "(s) look like " << ceph_release_name( + ceph_release_from_features(q.first)) + << " (missing 0x" << std::hex << missing << std::dec << ")"; + ok = false; + } + } + } + if (!ok) { + ss << "; add --yes-i-really-mean-it to do it anyway"; + err = -EPERM; + goto reply; + } + } ss << "set require_min_compat_client to " << ceph_release_name(vno); pending_inc.new_require_min_compat_client = vno; getline(ss, rs); -- 2.39.5