pgmon()->dispatch(m);
return;
}
- if (m->cmd[0] == "mon") {
+ if (m->cmd[0] == "mon" &&
+ ((m->cmd.size() < 3 ) || m->cmd[1] != "tell")) {
monmon()->dispatch(m);
return;
}
ss << " " << combined;
rs = ss.str();
r = 0;
+ } else if (m->cmd[0] == "mon" && m->cmd.size() >= 3 && m->cmd[1] == "tell") {
+ if (m->cmd[2] == "*") { // send to all mons and do myself
+ char *num = new char[8];
+ for (unsigned i = 0; i < monmap->size(); ++i) {
+ if (monmap->get_inst(i) != messenger->get_myinst()) {
+ sprintf(num, "%d", i);
+ m->cmd[2] = num;
+ messenger->send_message(m, monmap->get_inst(i));
+ }
+ }
+ handle_mon_tell(m);
+ rs = "delivered command to all mons";
+ r = 0;
+ } else {
+ // find target
+ int target = atoi(m->cmd[2].c_str());
+ stringstream ss;
+ if (target == 0 && m->cmd[2] != "0") {
+ ss << "could not parse target " << m->cmd[2];
+ rs = ss.str();
+ } else {
+ // send to target, or handle if it's me
+ if (monmap->get_inst(target) != messenger->get_myinst()) {
+ messenger->send_message(m, monmap->get_inst(target));
+ ss << "forwarded to target mon" << m->cmd[2];
+ rs = ss.str();
+ r = 0;
+ }
+ else {
+ handle_mon_tell(m);
+ rs = "interpreting...(see clog for more information)";
+ r = 0;
+ }
+ }
+ if (m->get_source().is_mon()) {
+ // don't respond directly to sender, just put in log and back out
+ m->put();
+ return;
+ }
+ }
}
} else
rs = "no command";
reply_command(m, r, rs, rdata, 0);
}
+/**
+ * Handle commands of the format "ceph mon tell x", where x
+ * is a mon number. This function presumes it's supposed
+ * to execute the actual command; delivery is handled by
+ */
+void Monitor::handle_mon_tell(MMonCommand *m)
+{
+ dout(0) << "handle_command " << *m << dendl;
+ stringstream ss;
+
+ // remove monitor direction instructions
+ m->cmd.erase(m->cmd.begin());
+ m->cmd.erase(m->cmd.begin());
+ m->cmd.erase(m->cmd.begin());
+
+ if ((m->cmd.size()) && (m->cmd[0] == "heap")) {
+ if (!ceph_using_tcmalloc())
+ ss << "tcmalloc not enabled, can't use heap profiler commands\n";
+ else
+ ceph_heap_profiler_handle_command(m->cmd, clog);
+ } else {
+ ss << "unrecognized command " << m->cmd;
+ }
+
+ if (!ss.eof())
+ clog.error(ss);
+}
+
void Monitor::reply_command(MMonCommand *m, int rc, const string &rs, version_t version)
{
bufferlist rdata;
#include "auth/cephx/CephxKeyServer.h"
+#include "perfglue/heap_profiler.h"
+
#include <memory>
class MonitorStore;
void handle_subscribe(MMonSubscribe *m);
void handle_mon_get_map(MMonGetMap *m);
void handle_command(class MMonCommand *m);
+ void handle_mon_tell(MMonCommand *m);
void handle_observe(MMonObserve *m);
void handle_route(MRoute *m);