return arg_desc;
}
+std::string cmddesc_get_prenautilus_compat(const std::string &cmddesc)
+{
+ std::vector<std::string> out;
+ stringstream ss(cmddesc);
+ std::string word;
+ bool changed = false;
+ while (std::getline(ss, word, ' ')) {
+ // if no , or =, must be a plain word to put out
+ if (word.find_first_of(",=") == string::npos) {
+ out.push_back(word);
+ continue;
+ }
+ auto desckv = cmddesc_get_args(word);
+ auto j = desckv.find("type");
+ if (j != desckv.end() && j->second == "CephBool") {
+ // Instruct legacy clients or mons to send --foo-bar string in place
+ // of a 'true'/'false' value
+ std::ostringstream oss;
+ oss << std::string("--") << desckv["name"];
+ std::string val = oss.str();
+ std::replace(val.begin(), val.end(), '_', '-');
+ desckv["type"] = "CephChoices";
+ desckv["strings"] = val;
+ std::ostringstream fss;
+ for (auto k = desckv.begin(); k != desckv.end(); ++k) {
+ if (k != desckv.begin()) {
+ fss << ",";
+ }
+ fss << k->first << "=" << k->second;
+ }
+ out.push_back(fss.str());
+ changed = true;
+ } else {
+ out.push_back(word);
+ }
+ }
+ if (!changed) {
+ return cmddesc;
+ }
+ std::string o;
+ for (auto i = out.begin(); i != out.end(); ++i) {
+ if (i != out.begin()) {
+ o += " ";
+ }
+ o += *i;
+ }
+ return o;
+}
+
/**
* Read a command description list out of cmd, and dump it to f.
* A signature description is a set of space-separated words;
typedef std::map<std::string, cmd_vartype, std::less<>> cmdmap_t;
std::string cmddesc_get_prefix(const std::string &cmddesc);
+std::string cmddesc_get_prenautilus_compat(const std::string &cmddesc);
void dump_cmd_to_json(ceph::Formatter *f, uint64_t features,
const std::string& cmd);
void dump_cmd_and_help_to_json(ceph::Formatter *f,
#include "Monitor.h"
#include "common/version.h"
#include "common/blkdev.h"
+#include "common/cmdparse.h"
#include "osd/OSDMap.h"
}
MonCommand::encode_vector(local_mon_commands, local_mon_commands_bl);
+ prenautilus_local_mon_commands = local_mon_commands;
+ for (auto& i : prenautilus_local_mon_commands) {
+ std::string n = cmddesc_get_prenautilus_compat(i.cmdstring);
+ if (n != i.cmdstring) {
+ dout(20) << " pre-nautilus cmd " << i.cmdstring << " -> " << n << dendl;
+ i.cmdstring = n;
+ }
+ }
+ MonCommand::encode_vector(prenautilus_local_mon_commands, prenautilus_local_mon_commands_bl);
+
// assume our commands until we have an election. this only means
// we won't reply with EINVAL before the election; any command that
// actually matters will wait until we have quorum etc and then
vector<MonCommand> local_mon_commands; // commands i support
bufferlist local_mon_commands_bl; // encoded version of above
+ vector<MonCommand> prenautilus_local_mon_commands;
+ bufferlist prenautilus_local_mon_commands_bl;
+
Messenger *mgr_messenger;
MgrClient mgr_client;
uint64_t mgr_proxy_bytes = 0; // in-flight proxied mgr command message bytes
bufferlist *rdata);
const std::vector<MonCommand> &get_local_commands(mon_feature_t f) {
- return local_mon_commands;
+ if (f.contains_all(ceph::features::mon::FEATURE_NAUTILUS)) {
+ return local_mon_commands;
+ } else {
+ return prenautilus_local_mon_commands;
+ }
}
const bufferlist& get_local_commands_bl(mon_feature_t f) {
- return local_mon_commands_bl;
+ if (f.contains_all(ceph::features::mon::FEATURE_NAUTILUS)) {
+ return local_mon_commands_bl;
+ } else {
+ return prenautilus_local_mon_commands_bl;
+ }
}
void set_leader_commands(const std::vector<MonCommand>& cmds) {
leader_mon_commands = cmds;