]> git.proxmox.com Git - ceph.git/blob - ceph/src/mon/MonOpRequest.h
bump version to 18.2.2-pve1
[ceph.git] / 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 "mon/Session.h"
22 #include "msg/Message.h"
23
24 struct MonOpRequest : public TrackedOp {
25 friend class OpTracker;
26
27 void mark_dispatch() {
28 mark_event("monitor_dispatch");
29 }
30 void mark_wait_for_quorum() {
31 mark_event("wait_for_quorum");
32 }
33 void mark_zap() {
34 mark_event("monitor_zap");
35 }
36 void mark_forwarded() {
37 mark_event("forwarded");
38 forwarded_to_leader = true;
39 }
40
41 void mark_svc_event(const std::string &service, const std::string &event) {
42 std::string s = service;
43 s.append(":").append(event);
44 mark_event(s);
45 }
46
47 void mark_logmon_event(const std::string &event) {
48 mark_svc_event("logm", event);
49 }
50 void mark_osdmon_event(const std::string &event) {
51 mark_svc_event("osdmap", event);
52 }
53 void mark_pgmon_event(const std::string &event) {
54 mark_svc_event("pgmap", event);
55 }
56 void mark_mdsmon_event(const std::string &event) {
57 mark_svc_event("mdsmap", event);
58 }
59 void mark_authmon_event(const std::string &event) {
60 mark_svc_event("auth", event);
61 }
62 void mark_paxos_event(const std::string &event) {
63 mark_svc_event("paxos", event);
64 }
65
66
67 enum op_type_t {
68 OP_TYPE_NONE = 0, ///< no type defined (default)
69 OP_TYPE_SERVICE, ///< belongs to a Paxos Service or similar
70 OP_TYPE_MONITOR, ///< belongs to the Monitor class
71 OP_TYPE_ELECTION, ///< belongs to the Elector class
72 OP_TYPE_PAXOS, ///< refers to Paxos messages
73 OP_TYPE_COMMAND, ///< is a command
74 };
75
76 MonOpRequest(const MonOpRequest &other) = delete;
77 MonOpRequest & operator = (const MonOpRequest &other) = delete;
78
79 private:
80 Message *request;
81 utime_t dequeued_time;
82 RefCountedPtr session;
83 ConnectionRef con;
84 bool forwarded_to_leader;
85 op_type_t op_type;
86
87 MonOpRequest(Message *req, OpTracker *tracker) :
88 TrackedOp(tracker,
89 req->get_recv_stamp().is_zero() ?
90 ceph_clock_now() : req->get_recv_stamp()),
91 request(req),
92 con(NULL),
93 forwarded_to_leader(false),
94 op_type(OP_TYPE_NONE)
95 {
96 if (req) {
97 con = req->get_connection();
98 if (con) {
99 session = con->get_priv();
100 }
101 }
102 }
103
104 void _dump(ceph::Formatter *f) const override {
105 {
106 f->open_array_section("events");
107 std::lock_guard l(lock);
108 for (auto i = events.begin(); i != events.end(); ++i) {
109 f->open_object_section("event");
110 f->dump_string("event", i->str);
111 f->dump_stream("time") << i->stamp;
112
113 auto i_next = i + 1;
114
115 if (i_next < events.end()) {
116 f->dump_float("duration", i_next->stamp - i->stamp);
117 } else {
118 f->dump_float("duration", events.rbegin()->stamp - get_initiated());
119 }
120
121 f->close_section();
122 }
123 f->close_section();
124 f->open_object_section("info");
125 f->dump_int("seq", seq);
126 f->dump_bool("src_is_mon", is_src_mon());
127 f->dump_stream("source") << request->get_source_inst();
128 f->dump_bool("forwarded_to_leader", forwarded_to_leader);
129 f->close_section();
130 }
131 }
132
133 protected:
134 void _dump_op_descriptor(std::ostream& stream) const override {
135 get_req()->print(stream);
136 }
137
138 public:
139 ~MonOpRequest() override {
140 request->put();
141 }
142
143 MonSession *get_session() const {
144 return static_cast<MonSession*>(session.get());
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 session.reset(s);
162 }
163
164 bool is_src_mon() const {
165 return (con && con->get_peer_type() & CEPH_ENTITY_TYPE_MON);
166 }
167
168 typedef boost::intrusive_ptr<MonOpRequest> Ref;
169
170 void set_op_type(op_type_t t) {
171 op_type = t;
172 }
173 void set_type_service() {
174 set_op_type(OP_TYPE_SERVICE);
175 }
176 void set_type_monitor() {
177 set_op_type(OP_TYPE_MONITOR);
178 }
179 void set_type_paxos() {
180 set_op_type(OP_TYPE_PAXOS);
181 }
182 void set_type_election_or_ping() {
183 set_op_type(OP_TYPE_ELECTION);
184 }
185 void set_type_command() {
186 set_op_type(OP_TYPE_COMMAND);
187 }
188
189 op_type_t get_op_type() {
190 return op_type;
191 }
192
193 bool is_type_service() {
194 return (get_op_type() == OP_TYPE_SERVICE);
195 }
196 bool is_type_monitor() {
197 return (get_op_type() == OP_TYPE_MONITOR);
198 }
199 bool is_type_paxos() {
200 return (get_op_type() == OP_TYPE_PAXOS);
201 }
202 bool is_type_election_or_ping() {
203 return (get_op_type() == OP_TYPE_ELECTION);
204 }
205 bool is_type_command() {
206 return (get_op_type() == OP_TYPE_COMMAND);
207 }
208 };
209
210 typedef MonOpRequest::Ref MonOpRequestRef;
211
212 struct C_MonOp : public Context
213 {
214 MonOpRequestRef op;
215
216 explicit C_MonOp(MonOpRequestRef o) :
217 op(o) { }
218
219 void finish(int r) override {
220 if (op && r == -ECANCELED) {
221 op->mark_event("callback canceled");
222 } else if (op && r == -EAGAIN) {
223 op->mark_event("callback retry");
224 } else if (op && r == 0) {
225 op->mark_event("callback finished");
226 }
227 _finish(r);
228 }
229
230 void mark_op_event(const std::string &event) {
231 if (op)
232 op->mark_event(event);
233 }
234
235 virtual void _finish(int r) = 0;
236 };
237
238 #endif /* MON_OPREQUEST_H_ */