Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / mon / MonOpRequest.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) 2015 Red Hat <contact@redhat.com>
7  * Copyright (C) 2015 SUSE LINUX GmbH
8  *
9  * This is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software
12  * Foundation.  See file COPYING.
13  */
14
15 #ifndef MON_OPREQUEST_H_
16 #define MON_OPREQUEST_H_
17 #include <iosfwd>
18 #include <stdint.h>
19
20 #include "common/TrackedOp.h"
21 #include "include/memory.h"
22 #include "mon/Session.h"
23 #include "msg/Message.h"
24
25 struct MonOpRequest : public TrackedOp {
26   friend class OpTracker;
27
28   void mark_dispatch() {
29     mark_event("monitor_dispatch");
30   }
31   void mark_wait_for_quorum() {
32     mark_event("wait_for_quorum");
33   }
34   void mark_zap() {
35     mark_event("monitor_zap");
36   }
37   void mark_forwarded() {
38     mark_event("forwarded");
39     forwarded_to_leader = true;
40   }
41
42   void mark_svc_event(const string &service, const string &event) {
43     string s = service;
44     s.append(":").append(event);
45     mark_event_string(s);
46   }
47
48   void mark_logmon_event(const string &event) {
49     mark_svc_event("logm", event);
50   }
51   void mark_osdmon_event(const string &event) {
52     mark_svc_event("osdmap", event);
53   }
54   void mark_pgmon_event(const string &event) {
55     mark_svc_event("pgmap", event);
56   }
57   void mark_mdsmon_event(const string &event) {
58     mark_svc_event("mdsmap", event);
59   }
60   void mark_authmon_event(const string &event) {
61     mark_svc_event("auth", event);
62   }
63   void mark_paxos_event(const string &event) {
64     mark_svc_event("paxos", event);
65   }
66
67
68   enum op_type_t {
69     OP_TYPE_NONE    = 0,      ///< no type defined (default)
70     OP_TYPE_SERVICE,          ///< belongs to a Paxos Service or similar
71     OP_TYPE_MONITOR,          ///< belongs to the Monitor class
72     OP_TYPE_ELECTION,         ///< belongs to the Elector class
73     OP_TYPE_PAXOS,            ///< refers to Paxos messages
74     OP_TYPE_COMMAND,          ///< is a command
75   };
76
77   MonOpRequest(const MonOpRequest &other) = delete;
78   MonOpRequest & operator = (const MonOpRequest &other) = delete;
79
80 private:
81   Message *request;
82   utime_t dequeued_time;
83   MonSession *session;
84   ConnectionRef con;
85   bool forwarded_to_leader;
86   op_type_t op_type;
87
88   MonOpRequest(Message *req, OpTracker *tracker) :
89     TrackedOp(tracker,
90       req->get_recv_stamp().is_zero() ?
91       ceph_clock_now() : req->get_recv_stamp()),
92     request(req),
93     session(NULL),
94     con(NULL),
95     forwarded_to_leader(false),
96     op_type(OP_TYPE_NONE)
97   {
98     mark_event("header_read", request->get_recv_stamp());
99     mark_event("throttled", request->get_throttle_stamp());
100     mark_event("all_read", request->get_recv_complete_stamp());
101     mark_event("dispatched", request->get_dispatch_stamp());
102
103     if (req) {
104       con = req->get_connection();
105       if (con) {
106         session = static_cast<MonSession*>(con->get_priv());
107       }
108     }
109   }
110
111   void _dump(Formatter *f) const override {
112     {
113       f->open_array_section("events");
114       Mutex::Locker l(lock);
115       for (auto& i : events) {
116         f->dump_object("event", i);
117       }
118       f->close_section();
119       f->open_object_section("info");
120       f->dump_int("seq", seq);
121       f->dump_bool("src_is_mon", is_src_mon());
122       f->dump_stream("source") << request->get_source_inst();
123       f->dump_bool("forwarded_to_leader", forwarded_to_leader);
124       f->close_section();
125     }
126   }
127
128 protected:
129   void _dump_op_descriptor_unlocked(ostream& stream) const override {
130     get_req()->print(stream);
131   }
132
133 public:
134   ~MonOpRequest() override {
135     request->put();
136     // certain ops may not have a session (e.g., AUTH or PING)
137     if (session)
138       session->put();
139   }
140
141   MonSession *get_session() const {
142     if (!session)
143       return NULL;
144     return session;
145   }
146
147   template<class T>
148   T *get_req() const { return static_cast<T*>(request); }
149
150   Message *get_req() const { return get_req<Message>(); }
151
152   int get_req_type() const {
153     if (!request)
154       return 0;
155     return request->get_type();
156   }
157
158   ConnectionRef get_connection() { return con; }
159
160   void set_session(MonSession *s) {
161     if (session) {
162       // we will be rewriting the existing session; drop the ref.
163       session->put();
164     }
165
166     if (s == NULL) {
167       session = NULL;
168     } else {
169       session = static_cast<MonSession*>(s->get());
170     }
171   }
172
173   bool is_src_mon() const {
174     return (con && con->get_peer_type() & CEPH_ENTITY_TYPE_MON);
175   }
176
177   typedef boost::intrusive_ptr<MonOpRequest> Ref;
178
179   void set_op_type(op_type_t t) {
180     op_type = t;
181   }
182   void set_type_service() {
183     set_op_type(OP_TYPE_SERVICE);
184   }
185   void set_type_monitor() {
186     set_op_type(OP_TYPE_MONITOR);
187   }
188   void set_type_paxos() {
189     set_op_type(OP_TYPE_PAXOS);
190   }
191   void set_type_election() {
192     set_op_type(OP_TYPE_ELECTION);
193   }
194   void set_type_command() {
195     set_op_type(OP_TYPE_COMMAND);
196   }
197
198   op_type_t get_op_type() {
199     return op_type;
200   }
201
202   bool is_type_service() {
203     return (get_op_type() == OP_TYPE_SERVICE);
204   }
205   bool is_type_monitor() {
206     return (get_op_type() == OP_TYPE_MONITOR);
207   }
208   bool is_type_paxos() {
209     return (get_op_type() == OP_TYPE_PAXOS);
210   }
211   bool is_type_election() {
212     return (get_op_type() == OP_TYPE_ELECTION);
213   }
214   bool is_type_command() {
215     return (get_op_type() == OP_TYPE_COMMAND);
216   }
217 };
218
219 typedef MonOpRequest::Ref MonOpRequestRef;
220
221 struct C_MonOp : public Context
222 {
223   MonOpRequestRef op;
224
225   explicit C_MonOp(MonOpRequestRef o) :
226     op(o) { }
227
228   void finish(int r) override {
229     if (op && r == -ECANCELED) {
230       op->mark_event("callback canceled");
231     } else if (op && r == -EAGAIN) {
232       op->mark_event("callback retry");
233     } else if (op && r == 0) {
234       op->mark_event("callback finished");
235     }
236     _finish(r);
237   }
238
239   void mark_op_event(const string &event) {
240     if (op)
241       op->mark_event_string(event);
242   }
243
244   virtual void _finish(int r) = 0;
245 };
246
247 #endif /* MON_OPREQUEST_H_ */