Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / messages / MForward.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2004-2010 Sage Weil <sage@newdream.net>
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software 
11  * Foundation.  See file COPYING.
12  * 
13  * Client requests often need to get forwarded from some monitor
14  * to the leader. This class encapsulates the original message
15  * along with the client's caps so the leader can do proper permissions
16  * checking.
17  */
18
19 #ifndef CEPH_MFORWARD_H
20 #define CEPH_MFORWARD_H
21
22 #include "msg/Message.h"
23 #include "mon/MonCap.h"
24 #include "include/encoding.h"
25 #include "include/stringify.h"
26
27 struct MForward : public Message {
28   uint64_t tid;
29   entity_inst_t client;
30   MonCap client_caps;
31   uint64_t con_features;
32   EntityName entity_name;
33   PaxosServiceMessage *msg;   // incoming or outgoing message
34
35   string msg_desc;  // for operator<< only
36   
37   static const int HEAD_VERSION = 3;
38   static const int COMPAT_VERSION = 3;
39
40   MForward() : Message(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
41                tid(0), con_features(0), msg(NULL) {}
42   //the message needs to have caps filled in!
43   MForward(uint64_t t, PaxosServiceMessage *m, uint64_t feat) :
44     Message(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
45     tid(t), msg(NULL) {
46     client = m->get_source_inst();
47     client_caps = m->get_session()->caps;
48     con_features = feat;
49     // we may need to reencode for the target mon
50     msg->clear_payload();
51     msg = (PaxosServiceMessage*)m->get();
52   }
53   MForward(uint64_t t, PaxosServiceMessage *m, uint64_t feat,
54            const MonCap& caps) :
55     Message(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
56     tid(t), client_caps(caps), msg(NULL) {
57     client = m->get_source_inst();
58     con_features = feat;
59     msg = (PaxosServiceMessage*)m->get();
60   }
61 private:
62   ~MForward() override {
63     if (msg) {
64       // message was unclaimed
65       msg->put();
66       msg = NULL;
67     }
68   }
69
70 public:
71   void encode_payload(uint64_t features) override {
72     ::encode(tid, payload);
73     ::encode(client, payload, features);
74     ::encode(client_caps, payload, features);
75     // Encode client message with intersection of target and source
76     // features.  This could matter if the semantics of the encoded
77     // message are changed when reencoding with more features than the
78     // client had originally.  That should never happen, but we may as
79     // well be defensive here.
80     if (con_features != features) {
81       msg->clear_payload();
82     }
83     encode_message(msg, features & con_features, payload);
84     ::encode(con_features, payload);
85     ::encode(entity_name, payload);
86   }
87
88   void decode_payload() override {
89     bufferlist::iterator p = payload.begin();
90     ::decode(tid, p);
91     ::decode(client, p);
92     ::decode(client_caps, p);
93     msg = (PaxosServiceMessage *)decode_message(NULL, 0, p);
94     ::decode(con_features, p);
95     ::decode(entity_name, p);
96   }
97
98   PaxosServiceMessage *claim_message() {
99     // let whoever is claiming the message deal with putting it.
100     assert(msg);
101     msg_desc = stringify(*msg);
102     PaxosServiceMessage *m = msg;
103     msg = NULL;
104     return m;
105   }
106
107   const char *get_type_name() const override { return "forward"; }
108   void print(ostream& o) const override {
109     o << "forward(";
110     if (msg) {
111       o << *msg;
112     } else {
113       o << msg_desc;
114     }
115     o << " caps " << client_caps
116       << " tid " << tid
117       << " con_features " << con_features << ")";
118   }
119 };
120   
121 #endif