]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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" | |
7c673cae FG |
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 | ||
f67539c2 TL |
41 | void mark_svc_event(const std::string &service, const std::string &event) { |
42 | std::string s = service; | |
7c673cae | 43 | s.append(":").append(event); |
11fdf7f2 | 44 | mark_event(s); |
7c673cae FG |
45 | } |
46 | ||
f67539c2 | 47 | void mark_logmon_event(const std::string &event) { |
7c673cae FG |
48 | mark_svc_event("logm", event); |
49 | } | |
f67539c2 | 50 | void mark_osdmon_event(const std::string &event) { |
7c673cae FG |
51 | mark_svc_event("osdmap", event); |
52 | } | |
f67539c2 | 53 | void mark_pgmon_event(const std::string &event) { |
7c673cae FG |
54 | mark_svc_event("pgmap", event); |
55 | } | |
f67539c2 | 56 | void mark_mdsmon_event(const std::string &event) { |
7c673cae FG |
57 | mark_svc_event("mdsmap", event); |
58 | } | |
f67539c2 | 59 | void mark_authmon_event(const std::string &event) { |
7c673cae FG |
60 | mark_svc_event("auth", event); |
61 | } | |
f67539c2 | 62 | void mark_paxos_event(const std::string &event) { |
7c673cae FG |
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; | |
11fdf7f2 | 82 | RefCountedPtr session; |
7c673cae FG |
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() ? | |
181888fb | 90 | ceph_clock_now() : req->get_recv_stamp()), |
7c673cae | 91 | request(req), |
7c673cae FG |
92 | con(NULL), |
93 | forwarded_to_leader(false), | |
94 | op_type(OP_TYPE_NONE) | |
95 | { | |
7c673cae FG |
96 | if (req) { |
97 | con = req->get_connection(); | |
98 | if (con) { | |
11fdf7f2 | 99 | session = con->get_priv(); |
7c673cae FG |
100 | } |
101 | } | |
102 | } | |
103 | ||
f67539c2 | 104 | void _dump(ceph::Formatter *f) const override { |
7c673cae FG |
105 | { |
106 | f->open_array_section("events"); | |
11fdf7f2 | 107 | std::lock_guard l(lock); |
f67539c2 TL |
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()); | |
7c673cae | 119 | } |
f67539c2 TL |
120 | |
121 | f->close_section(); | |
122 | } | |
7c673cae FG |
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: | |
f67539c2 | 134 | void _dump_op_descriptor_unlocked(std::ostream& stream) const override { |
7c673cae FG |
135 | get_req()->print(stream); |
136 | } | |
137 | ||
138 | public: | |
139 | ~MonOpRequest() override { | |
140 | request->put(); | |
7c673cae FG |
141 | } |
142 | ||
143 | MonSession *get_session() const { | |
11fdf7f2 | 144 | return static_cast<MonSession*>(session.get()); |
7c673cae FG |
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) { | |
11fdf7f2 | 161 | session.reset(s); |
7c673cae FG |
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 | } | |
f67539c2 | 182 | void set_type_election_or_ping() { |
7c673cae FG |
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 | } | |
f67539c2 | 202 | bool is_type_election_or_ping() { |
7c673cae FG |
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 | ||
31f18b77 FG |
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 | ||
f67539c2 | 230 | void mark_op_event(const std::string &event) { |
31f18b77 | 231 | if (op) |
11fdf7f2 | 232 | op->mark_event(event); |
31f18b77 FG |
233 | } |
234 | ||
235 | virtual void _finish(int r) = 0; | |
236 | }; | |
237 | ||
7c673cae | 238 | #endif /* MON_OPREQUEST_H_ */ |