]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: 'config set <who> <name> <value>'
authorSage Weil <sage@redhat.com>
Mon, 4 Dec 2017 22:54:07 +0000 (16:54 -0600)
committerSage Weil <sage@redhat.com>
Tue, 6 Mar 2018 20:44:48 +0000 (14:44 -0600)
Signed-off-by: Sage Weil <sage@redhat.com>
src/mon/ConfigMonitor.cc
src/mon/ConfigMonitor.h
src/mon/MonCommands.h
src/mon/Monitor.cc

index fc88ae523dc2f9ec1f559172c44a622906bdd012..a790f118bd1908d1e1eb21a63b4e26f9493544d6 100644 (file)
@@ -1,12 +1,11 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
-#include <boost/algorithm/string/split.hpp>
-
 #include "mon/Monitor.h"
 #include "mon/ConfigMonitor.h"
 #include "mon/OSDMonitor.h"
 #include "messages/MConfig.h"
+#include "messages/MMonCommand.h"
 #include "common/Formatter.h"
 
 #define dout_subsys ceph_subsys_mon
@@ -88,7 +87,76 @@ bool ConfigMonitor::prepare_update(MonOpRequestRef op)
   Message *m = op->get_req();
   dout(7) << "prepare_update " << *m
          << " from " << m->get_orig_source_inst() << dendl;
+  switch (m->get_type()) {
+  case MSG_MON_COMMAND:
+    return prepare_command(op);
+  }
+  return false;
+}
+
+bool ConfigMonitor::prepare_command(MonOpRequestRef op)
+{
+  MMonCommand *m = static_cast<MMonCommand*>(op->get_req());
+  stringstream ss;
+  int err = -EINVAL;
+
+  map<string, cmd_vartype> cmdmap;
+  if (!cmdmap_from_json(m->cmd, &cmdmap, ss)) {
+    string rs = ss.str();
+    mon->reply_command(op, -EINVAL, rs, get_last_committed());
+    return true;
+  }
+
+  string prefix;
+  cmd_getval(g_ceph_context, cmdmap, "prefix", prefix);
+
+  if (prefix == "config set") {
+    string who;
+    string name, value;
+    cmd_getval(g_ceph_context, cmdmap, "who", who);
+    cmd_getval(g_ceph_context, cmdmap, "name", name);
+    cmd_getval(g_ceph_context, cmdmap, "value", value);
+
+    OptionMask mask;
+    string section;
+    if (!ConfigMap::parse_mask(who, &section, &mask)) {
+      ss << "unrecognized config target '" << who << "'";
+      err = -EINVAL;
+      goto reply;
+    }
+
+    string key = KEY_PREFIX;
+    if (section.size()) {
+      key += section + "/";
+    }
+    string mask_str = mask.to_str();
+    if (mask_str.size()) {
+      key += mask_str + "/";
+    }
+    key += name;
+    bufferlist bl;
+    bl.append(value);
+
+    MonitorDBStore::TransactionRef t = paxos->get_pending_transaction();
+    t->put(CONFIG_PREFIX, key, bl);
+    goto update;
+  } else {
+    ss << "unknown command " << prefix;
+    err = -EINVAL;
+  }
+
+reply:
+  mon->reply_command(op, err, ss.str(), get_last_committed());
   return false;
+
+update:
+  force_immediate_propose();  // faster response
+  wait_for_finished_proposal(
+    op,
+    new Monitor::C_Command(
+      mon, op, 0, ss.str(),
+      get_last_committed() + 1));
+  return true;
 }
 
 void ConfigMonitor::tick()
index 5559385360ea27b177d4646f3ab2bfd16ce4b90b..721a3ba38dc9862c1db5c8c9a0c5a478133b1b44 100644 (file)
@@ -26,6 +26,8 @@ public:
   bool preprocess_query(MonOpRequestRef op) override;
   bool prepare_update(MonOpRequestRef op) override;
 
+  bool prepare_command(MonOpRequestRef op);
+
   void create_initial() override;
   void update_from_paxos(bool *need_bootstrap) override;
   void create_pending() override;
index 908b5c28bdc4e322e5dc13f4237de6332be0d813..ca4f69e3746f5d9b0e76f9480e3fe3ef1df216c5 100644 (file)
@@ -1092,3 +1092,11 @@ COMMAND("mgr count-metadata name=property,type=CephString",
 COMMAND("mgr versions", \
        "check running versions of ceph-mgr daemons",
        "mgr", "r", "cli,rest")
+
+// ConfigMonitor
+COMMAND("config set" \
+       " name=who,type=CephString" \
+       " name=name,type=CephString" \
+       " name=value,type=CephString", \
+       "set a config option",
+       "config", "rw", "cli,rest")
index 4a23a73f73f5217950f814319bd4e29851b2d095..b582e461ff7ecfcbbe4258ea0e8b568bc1b1f89c 100644 (file)
@@ -3045,6 +3045,10 @@ void Monitor::handle_command(MonOpRequestRef op)
     osdmon()->dispatch(op);
     return;
   }
+  if (module == "config") {
+    configmon()->dispatch(op);
+    return;
+  }
 
   if (module == "mon" &&
       /* Let the Monitor class handle the following commands: