]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
messages: MForward: pack a bufferlist instead of a message
authorJoao Eduardo Luis <joao@redhat.com>
Wed, 11 Feb 2015 14:48:22 +0000 (14:48 +0000)
committerJoao Eduardo Luis <joao@suse.de>
Thu, 16 Jul 2015 16:08:39 +0000 (17:08 +0100)
Signed-off-by: Joao Eduardo Luis <joao@redhat.com>
src/messages/MForward.h
src/mon/Monitor.cc

index 92a739364ca632fc989180dfa98238eafc137a28..4d1abff3f8bf4d17d389bae7a6a0aa1359d28a64 100644 (file)
 
 struct MForward : public Message {
   uint64_t tid;
-  PaxosServiceMessage *msg;
   entity_inst_t client;
   MonCap client_caps;
   uint64_t con_features;
   EntityName entity_name;
+  PaxosServiceMessage *msg;   // incoming message
+  bufferlist msg_bl;          // outgoing message
 
   static const int HEAD_VERSION = 3;
   static const int COMPAT_VERSION = 1;
 
   MForward() : Message(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
-               tid(0), msg(NULL), con_features(0) {}
+               tid(0), con_features(0), msg(NULL) {}
   //the message needs to have caps filled in!
   MForward(uint64_t t, PaxosServiceMessage *m, uint64_t feat) :
     Message(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
-    tid(t), msg(m) {
+    tid(t), msg(NULL) {
     client = m->get_source_inst();
     client_caps = m->get_session()->caps;
     con_features = feat;
+    set_message(m, feat);
   }
   MForward(uint64_t t, PaxosServiceMessage *m, uint64_t feat,
-          const MonCap& caps) :
+           const MonCap& caps) :
     Message(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
-    tid(t), msg(m), client_caps(caps) {
+    tid(t), client_caps(caps), msg(NULL) {
     client = m->get_source_inst();
     con_features = feat;
+    set_message(m, feat);
   }
 private:
   ~MForward() {
-    if (msg) msg->put();
+    if (msg) {
+      // message was unclaimed
+      msg->put();
+      msg = NULL;
+    }
+  }
+
+  PaxosServiceMessage *get_msg_from_bl() {
+    bufferlist::iterator p = msg_bl.begin();
+    return (msg_bl.length() ?
+        (PaxosServiceMessage*)decode_message(NULL, 0, p) : NULL);
   }
 
 public:
@@ -61,7 +74,7 @@ public:
     ::encode(tid, payload);
     ::encode(client, payload);
     ::encode(client_caps, payload, features);
-    encode_message(msg, features, payload);
+    payload.append(msg_bl);
     ::encode(con_features, payload);
     ::encode(entity_name, payload);
   }
@@ -88,13 +101,34 @@ public:
 
   }
 
+  void set_message(PaxosServiceMessage *m, uint64_t features) {
+    encode_message(m, features, msg_bl);
+
+    // keep a pointer to the message.  We will not use it except for print(),
+    // and we will drop it in the dtor if it is not claimed.
+    // we could avoid doing this if only we had a const bufferlist iterator :)
+    msg = m;
+  }
+
+  PaxosServiceMessage *claim_message() {
+    if (!msg) {
+      return get_msg_from_bl();
+    }
+
+    PaxosServiceMessage *m = msg;
+    msg = NULL;
+    return m;
+  }
+
   const char *get_type_name() const { return "forward"; }
   void print(ostream& o) const {
-    if (msg)
+    if (msg) {
       o << "forward(" << *msg << " caps " << client_caps
        << " tid " << tid
         << " con_features " << con_features << ") to leader";
-    else o << "forward(??? ) to leader";
+    } else {
+      o << "forward(??? ) to leader";
+    }
   }
 };
   
index 60caa424058b5e72e84a0f274cee8863dbce4ad0..b7bb061ff9ef86d49b17ca0d71776b330feb0936 100644 (file)
@@ -3052,7 +3052,8 @@ void Monitor::forward_request_leader(PaxosServiceMessage *req)
     dout(10) << "forward_request " << rr->tid << " request " << *req
             << " features " << rr->con_features << dendl;
 
-    MForward *forward = new MForward(rr->tid, req,
+    MForward *forward = new MForward(rr->tid,
+                                     req,
                                     rr->con_features,
                                     rr->session->caps);
     forward->set_priority(req->get_priority());
@@ -3103,8 +3104,11 @@ void Monitor::handle_forward(MForward *m)
   } else {
     // see PaxosService::dispatch(); we rely on this being anon
     // (c->msgr == NULL)
+    PaxosServiceMessage *req = m->claim_message();
+    assert(req != NULL);
+
     ConnectionRef c(new AnonConnection(cct));
-    MonSession *s = new MonSession(m->msg->get_source_inst(),
+    MonSession *s = new MonSession(req->get_source_inst(),
                                   static_cast<Connection*>(c.get()));
     c->set_priv(s->get());
     c->set_peer_addr(m->client.addr);
@@ -3119,8 +3123,6 @@ void Monitor::handle_forward(MForward *m)
     s->proxy_con = m->get_connection();
     s->proxy_tid = m->tid;
 
-    PaxosServiceMessage *req = m->msg;
-    m->msg = NULL;  // so ~MForward doesn't delete it
     req->set_connection(c);
 
     // not super accurate, but better than nothing.