]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: reworked command interface to use preprocess_ and prepare_command
authorSage Weil <sage@newdream.net>
Thu, 28 Feb 2008 18:21:48 +0000 (10:21 -0800)
committerSage Weil <sage@newdream.net>
Thu, 28 Feb 2008 18:21:48 +0000 (10:21 -0800)
src/mon/MDSMonitor.cc
src/mon/MDSMonitor.h
src/mon/Monitor.cc
src/mon/Monitor.h
src/mon/OSDMonitor.cc
src/mon/OSDMonitor.h

index 37d306f7f42304f31d0d15317103545cc242eb6d..4fdf2fc4e89051c7e852b24eadce50d5b8228ce6 100644 (file)
@@ -21,6 +21,8 @@
 #include "messages/MMDSMap.h"
 #include "messages/MMDSGetMap.h"
 #include "messages/MMDSBeacon.h"
+#include "messages/MMonCommand.h"
+#include "messages/MMonCommandAck.h"
 
 #include "messages/MGenericMessage.h"
 
@@ -155,6 +157,9 @@ bool MDSMonitor::preprocess_query(Message *m)
     handle_mds_getmap((MMDSGetMap*)m);
     return true;
 
+  case MSG_MON_COMMAND:
+    return preprocess_command((MMonCommand*)m);
+
   default:
     assert(0);
     delete m;
@@ -465,16 +470,41 @@ void MDSMonitor::take_over(entity_addr_t addr, int mds)
 }
 
 
+bool MDSMonitor::preprocess_command(MMonCommand *m)
+{
+  int r = -1;
+  bufferlist rdata;
+  stringstream ss;
 
-int MDSMonitor::do_command(vector<string>& cmd, bufferlist& data, 
-                          bufferlist& rdata, string &rs)
+  if (m->cmd.size() > 1) {
+    if (m->cmd[1] == "getmap") {
+      mdsmap.encode(rdata);
+      ss << "got mdsmap epoch " << mdsmap.get_epoch();
+      r = 0;
+    }
+  }
+
+  if (r != -1) {
+    string rs;
+    ss >> rs;
+    MMonCommandAck *reply = new MMonCommandAck(r, rs);
+    reply->set_data(rdata);
+    mon->messenger->send_message(reply, m->inst);
+    delete m;
+    return true;
+  } else
+    return false;
+}
+
+bool MDSMonitor::prepare_command(MMonCommand *m)
 {
   int r = -EINVAL;
   stringstream ss;
+  bufferlist rdata;
 
-  if (cmd.size() > 1) {
-    if (cmd[1] == "stop" && cmd.size() > 2) {
-      int who = atoi(cmd[2].c_str());
+  if (m->cmd.size() > 1) {
+    if (m->cmd[1] == "stop" && m->cmd.size() > 2) {
+      int who = atoi(m->cmd[2].c_str());
       if (mdsmap.is_active(who)) {
        r = 0;
        ss << "telling mds" << who << " to stop";
@@ -484,19 +514,29 @@ int MDSMonitor::do_command(vector<string>& cmd, bufferlist& data,
        ss << "mds" << who << " not active (" << mdsmap.get_state_name(mdsmap.get_state(who)) << ")";
       }
     }
-    else if (cmd[1] == "set_max_mds" && cmd.size() > 2) {
-      pending_mdsmap.max_mds = atoi(cmd[2].c_str());
+    else if (m->cmd[1] == "set_max_mds" && m->cmd.size() > 2) {
+      pending_mdsmap.max_mds = atoi(m->cmd[2].c_str());
       r = 0;
       ss << "max_mds = " << pending_mdsmap.max_mds;
     }
   }
-  if (r == -EINVAL) {
+  if (r == -EINVAL) 
     ss << "unrecognized command";
-  } 
-  
-  // reply
+  string rs;
   getline(ss, rs);
-  return r;
+
+  if (r >= 0) {
+    // success.. delay reply
+    paxos->wait_for_commit(new Monitor::C_Command(mon, m, r, rs));
+    return true;
+  } else {
+    // reply immediately
+    MMonCommandAck *reply = new MMonCommandAck(r, rs);
+    reply->set_data(rdata);
+    mon->messenger->send_message(reply, m->inst);
+    delete m;
+    return false;
+  }
 }
 
 
index aaf90b4a8db44fe5c33bb811316b182954f440bc..2dd5f9e840b4bb57dd1cb02236a1062bcde6b74f 100644 (file)
@@ -31,6 +31,7 @@ using namespace std;
 
 class MMDSBeacon;
 class MMDSGetMap;
+class MMonCommand;
 
 class MDSMonitor : public PaxosService {
  public:
@@ -79,8 +80,8 @@ class MDSMonitor : public PaxosService {
 
   void take_over(entity_addr_t addr, int mds);
 
-  int do_command(vector<string>& cmd, bufferlist& data, 
-                bufferlist& rdata, string &rs);
+  bool preprocess_command(MMonCommand *m);
+  bool prepare_command(MMonCommand *m);
 
   // beacons
   map<entity_addr_t, utime_t> last_beacon;
index 4369cddd8ac224eb904409fdb0a67a1e0f79e528..4d2bebcab17b3934b0db05aadba4311f0107f596 100644 (file)
@@ -196,51 +196,38 @@ void Monitor::lose_election(epoch_t epoch, int l)
   pgmon->election_finished();
 }
 
-
-int Monitor::do_command(vector<string>& cmd, bufferlist& data, 
-                       bufferlist& rdata, string &rs)
+void Monitor::handle_command(MMonCommand *m)
 {
-  if (cmd.empty()) {
+  dout(0) << "handle_command " << *m << dendl;
+  string rs;
+  if (!m->cmd.empty()) {
+    if (m->cmd[0] == "mds") {
+      mdsmon->dispatch(m);
+      return;
+    }
+    if (m->cmd[0] == "osd") {
+      osdmon->dispatch(m);
+      return;
+    }
+    if (m->cmd[0] == "stop") {
+      do_stop();
+      return;
+    }
+    rs = "unrecognized subsystem";
+  } else 
     rs = "no command";
-    return -EINVAL;
-  }
-
-  if (cmd[0] == "stop") {
-    rs = "stopping";
-    do_stop();
-    return 0;
-  }
-  if (cmd[0] == "mds") 
-    return mdsmon->do_command(cmd, data, rdata, rs);
-
-  if (cmd[0] == "osd") 
-    return osdmon->do_command(cmd, data, rdata, rs);
-
-  // huh.
-  rs = "unrecognized subsystem '" + cmd[0] + "'";
-  return -EINVAL;
+  MMonCommandAck *reply = new MMonCommandAck(-EINVAL, rs);
+  messenger->send_message(reply, m->inst);
+  delete m;
 }
 
-void Monitor::handle_command(MMonCommand *m)
+void Monitor::finish_command(MMonCommand *m, int rc, const string &rs)
 {
-  dout(0) << "handle_command " << *m << dendl;
-  
-  string rs;         // return string
-  bufferlist rdata;  // return data
-  int rc = do_command(m->cmd, m->get_data(), rdata, rs);
-  if (rc == -EROFS && !is_leader()) {
-    dout(10) << "forwarding command to leader" << dendl;
-    messenger->send_message(m, monmap->get_inst(get_leader()));
-    return;
-  }
-
   MMonCommandAck *reply = new MMonCommandAck(rc, rs);
-  reply->set_data(rdata);
   messenger->send_message(reply, m->inst);
   delete m;
 }
 
-
 void Monitor::do_stop()
 {
   dout(0) << "do_stop -- initiating shutdown" << dendl;
index 2e11c01b7a17d6f7e95d500cdb0149fb75075089..3534ef7ef0ffadbb02d7ad7225a1303fbcb44d66 100644 (file)
@@ -119,8 +119,19 @@ public:
   void handle_ping_ack(class MPingAck *m);
   void handle_command(class MMonCommand *m);
 
-  int do_command(vector<string>& cmd, bufferlist& data, 
-                bufferlist& rdata, string &rs);
+  void finish_command(MMonCommand *m, int rc, const string &rs);
+public:
+  struct C_Command : public Context {
+    Monitor *mon;
+    MMonCommand *m;
+    int rc;
+    string rs;
+    C_Command(Monitor *_mm, MMonCommand *_m, int r, string& s) :
+      mon(_mm), m(_m), rc(r), rs(s) {}
+    void finish(int r) {
+      mon->finish_command(m, rc, rs);
+    }
+  };
 
  public:
   Monitor(int w, Messenger *m, MonMap *mm) : 
index 358e4f2a6edc771785ac1b405795f46b87f2698c..855fb6d5eda63dc2376639abdfb32b4948117149 100644 (file)
 #include "messages/MOSDBoot.h"
 #include "messages/MOSDIn.h"
 #include "messages/MOSDOut.h"
+#include "messages/MMonCommand.h"
+#include "messages/MMonCommandAck.h"
 
 #include "common/Timer.h"
 
 #include "config.h"
 
+#include <sstream>
 
 #define  dout(l) if (l<=g_conf.debug || l<=g_conf.debug_mon) *_dout << dbeginl << g_clock.now() << " mon" << mon->whoami << (mon->is_starting() ? (const char*)"(starting)":(mon->is_leader() ? (const char*)"(leader)":(mon->is_peon() ? (const char*)"(peon)":(const char*)"(?\?)"))) << ".osd e" << osdmap.get_epoch() << " "
 #define  derr(l) if (l<=g_conf.debug || l<=g_conf.debug_mon) *_derr << dbeginl << g_clock.now() << " mon" << mon->whoami << (mon->is_starting() ? (const char*)"(starting)":(mon->is_leader() ? (const char*)"(leader)":(mon->is_peon() ? (const char*)"(peon)":(const char*)"(?\?)"))) << ".osd e" << osdmap.get_epoch() << " "
@@ -409,6 +412,9 @@ bool OSDMonitor::preprocess_query(Message *m)
     handle_osd_getmap((MOSDGetMap*)m);
     return true;
     
+  case MSG_MON_COMMAND:
+    return preprocess_command((MMonCommand*)m);
+
     // damp updates
   case MSG_OSD_FAILURE:
     return preprocess_failure((MOSDFailure*)m);
@@ -439,6 +445,9 @@ bool OSDMonitor::prepare_update(Message *m)
   case MSG_OSD_BOOT:
     return prepare_boot((MOSDBoot*)m);
 
+  case MSG_MON_COMMAND:
+    return prepare_command((MMonCommand*)m);
+    
     /*
   case MSG_OSD_IN:
     return prepare_in((MOSDIn*)m);
@@ -456,6 +465,7 @@ bool OSDMonitor::prepare_update(Message *m)
 
 bool OSDMonitor::should_propose(double& delay)
 {
+  dout(10) << "should_propose" << dendl;
   if (osdmap.epoch == 1) {
     if (pending_inc.new_up.size() == (unsigned)g_conf.num_osd) {
       delay = 0.0;
@@ -852,6 +862,51 @@ void OSDMonitor::mark_all_down()
 }
 
 
+
+bool OSDMonitor::preprocess_command(MMonCommand *m)
+{
+  int r = -1;
+  bufferlist rdata;
+  stringstream ss;
+
+  if (m->cmd.size() > 1) {
+    if (m->cmd[1] == "getmap") {
+      osdmap.encode(rdata);
+      ss << "got osdmap epoch " << osdmap.get_epoch();
+      r = 0;
+    }
+    else if (m->cmd[1] == "getcrushmap") {
+      osdmap.crush._encode(rdata);
+      ss << "got crush map from osdmap epoch " << osdmap.get_epoch();
+      r = 0;
+    }
+  }
+  if (r != -1) {
+    string rs;
+    ss >> rs;
+    MMonCommandAck *reply = new MMonCommandAck(r, rs);
+    reply->set_data(rdata);
+    mon->messenger->send_message(reply, m->inst);
+    delete m;
+    return true;
+  } else
+    return false;
+}
+
+bool OSDMonitor::prepare_command(MMonCommand *m)
+{
+  if (m->cmd.size() > 1) {
+    if (m->cmd[1] == "setcrushmap") {
+      dout(10) << "prepare_command setting new crush map" << dendl;
+      pending_inc.crush = m->get_data();
+      string rs = "set crush map";
+      paxos->wait_for_commit(new Monitor::C_Command(mon, m, 0, rs));
+      return true;
+    }
+  }
+  return false;
+}
+/*
 int OSDMonitor::do_command(vector<string>& cmd, bufferlist& data, 
                           bufferlist& rdata, string &rs)
 {
@@ -866,11 +921,9 @@ int OSDMonitor::do_command(vector<string>& cmd, bufferlist& data,
     return 0;
   }
   if (cmd[1] == "setcrushmap") {
-    if (!mon->is_leader()) return -EROFS;
-    // HACK
-    pending_inc.crush = data;
-    propose_pending();
+    return -EAGAIN;
   }
   rs = "unknown command";
   return -EINVAL;
 }
+*/
index 94893d1d2b59ebaa10849e2c278d9858888b1e22..cee68642e7ad2a580c09195b7aa23c0b35746d78 100644 (file)
@@ -31,6 +31,7 @@ using namespace std;
 
 class Monitor;
 class MOSDBoot;
+class MMonCommand;
 
 class OSDMonitor : public PaxosService {
 public:
@@ -121,8 +122,9 @@ private:
 
   void tick();  // check state, take actions
 
-  int do_command(vector<string>& cmd, bufferlist& data, 
-                bufferlist& rdata, string &rs);
+  bool preprocess_command(MMonCommand *m);
+  bool prepare_command(MMonCommand *m);
+  void finish_command(MMonCommand *m, int rc, const string &rs);
 
   void mark_all_down();