]> git.proxmox.com Git - ceph.git/blame - ceph/src/mon/Session.h
import ceph 15.2.11
[ceph.git] / ceph / src / mon / Session.h
CommitLineData
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) 2004-2006 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 */
14
15#ifndef CEPH_MON_SESSION_H
16#define CEPH_MON_SESSION_H
17
9f95a23c
TL
18#include <string>
19#include <string_view>
20
21#include "include/utime.h"
7c673cae 22#include "include/xlist.h"
9f95a23c
TL
23
24#include "global/global_context.h"
7c673cae 25#include "msg/msg_types.h"
31f18b77 26#include "mon/mon_types.h"
7c673cae
FG
27
28#include "auth/AuthServiceHandler.h"
29#include "osd/OSDMap.h"
30
31#include "MonCap.h"
32
33struct MonSession;
34
35struct Subscription {
36 MonSession *session;
9f95a23c 37 std::string type;
7c673cae
FG
38 xlist<Subscription*>::item type_item;
39 version_t next;
40 bool onetime;
41 bool incremental_onetime; // has CEPH_FEATURE_INCSUBOSDMAP
42
9f95a23c 43 Subscription(MonSession *s, const std::string& t) : session(s), type(t), type_item(this),
7c673cae
FG
44 next(0), onetime(false), incremental_onetime(false) {}
45};
46
47struct MonSession : public RefCountedObject {
48 ConnectionRef con;
31f18b77
FG
49 int con_type = 0;
50 uint64_t con_features = 0; // zero if AnonConnection
11fdf7f2
TL
51 entity_name_t name;
52 entity_addrvec_t addrs;
53 entity_addr_t socket_addr;
7c673cae 54 utime_t session_timeout;
11fdf7f2 55 bool closed = false;
7c673cae 56 xlist<MonSession*>::item item;
9f95a23c 57 std::set<uint64_t> routed_request_tids;
7c673cae 58 MonCap caps;
11fdf7f2
TL
59
60 bool authenticated = false; ///< true if auth handshake is complete
7c673cae 61
9f95a23c 62 std::map<std::string, Subscription*> sub_map;
11fdf7f2 63 epoch_t osd_epoch = 0; ///< the osdmap epoch sent to the mon client
7c673cae 64
11fdf7f2 65 AuthServiceHandler *auth_handler = nullptr;
7c673cae 66 EntityName entity_name;
c5c27e9a
TL
67 uint64_t global_id = 0;
68 global_id_status_t global_id_status = global_id_status_t::NONE;
7c673cae
FG
69
70 ConnectionRef proxy_con;
11fdf7f2
TL
71 uint64_t proxy_tid = 0;
72
9f95a23c
TL
73 std::string remote_host; ///< remote host name
74 std::map<std::string,std::string,std::less<>> last_config; ///< most recently shared config
11fdf7f2
TL
75 bool any_config = false;
76
77 MonSession(Connection *c)
78 : RefCountedObject(g_ceph_context),
79 con(c),
80 item(this) { }
81
82 void _ident(const entity_name_t& n, const entity_addrvec_t& av) {
83 con_type = con->get_peer_type();
84 name = n;
85 addrs = av;
86 socket_addr = con->get_peer_socket_addr();
87 if (con->get_messenger()) {
31f18b77 88 // only fill in features if this is a non-anonymous connection
11fdf7f2 89 con_features = con->get_features();
31f18b77 90 }
7c673cae 91 }
11fdf7f2 92
7c673cae
FG
93 ~MonSession() override {
94 //generic_dout(0) << "~MonSession " << this << dendl;
95 // we should have been removed before we get destructed; see MonSessionMap::remove_session()
11fdf7f2
TL
96 ceph_assert(!item.is_on_list());
97 ceph_assert(sub_map.empty());
7c673cae
FG
98 delete auth_handler;
99 }
100
9f95a23c
TL
101 bool is_capable(std::string service, int mask) {
102 std::map<std::string,std::string> args;
7c673cae
FG
103 return caps.is_capable(
104 g_ceph_context,
7c673cae
FG
105 entity_name,
106 service, "", args,
11fdf7f2
TL
107 mask & MON_CAP_R, mask & MON_CAP_W, mask & MON_CAP_X,
108 get_peer_socket_addr());
109 }
110
111 const entity_addr_t& get_peer_socket_addr() {
112 return socket_addr;
7c673cae 113 }
9f95a23c
TL
114
115 void dump(Formatter *f) const {
116 f->dump_stream("name") << name;
117 f->dump_stream("entity_name") << entity_name;
118 f->dump_object("addrs", addrs);
119 f->dump_object("socket_addr", socket_addr);
120 f->dump_string("con_type", ceph_entity_type_name(con_type));
121 f->dump_unsigned("con_features", con_features);
122 f->dump_stream("con_features_hex") << std::hex << con_features << std::dec;
123 f->dump_string("con_features_release",
124 ceph_release_name(ceph_release_from_features(con_features)));
125 f->dump_bool("open", !closed);
126 f->dump_object("caps", caps);
127 f->dump_bool("authenticated", authenticated);
c5c27e9a
TL
128 f->dump_unsigned("global_id", global_id);
129 f->dump_stream("global_id_status") << global_id_status;
9f95a23c
TL
130 f->dump_unsigned("osd_epoch", osd_epoch);
131 f->dump_string("remote_host", remote_host);
132 }
7c673cae
FG
133};
134
135
136struct MonSessionMap {
137 xlist<MonSession*> sessions;
9f95a23c
TL
138 std::map<std::string, xlist<Subscription*>* > subs;
139 std::multimap<int, MonSession*> by_osd;
31f18b77 140 FeatureMap feature_map; // type -> features -> count
7c673cae
FG
141
142 MonSessionMap() {}
143 ~MonSessionMap() {
144 while (!subs.empty()) {
11fdf7f2 145 ceph_assert(subs.begin()->second->empty());
7c673cae
FG
146 delete subs.begin()->second;
147 subs.erase(subs.begin());
148 }
149 }
150
151 unsigned get_size() const {
152 return sessions.size();
153 }
154
155 void remove_session(MonSession *s) {
11fdf7f2 156 ceph_assert(!s->closed);
9f95a23c 157 for (std::map<std::string,Subscription*>::iterator p = s->sub_map.begin(); p != s->sub_map.end(); ++p) {
7c673cae
FG
158 p->second->type_item.remove_myself();
159 delete p->second;
160 }
161 s->sub_map.clear();
162 s->item.remove_myself();
92f5a8d4
TL
163 if (s->name.is_osd() &&
164 s->name.num() >= 0) {
9f95a23c 165 for (auto p = by_osd.find(s->name.num());
11fdf7f2 166 p->first == s->name.num();
7c673cae
FG
167 ++p)
168 if (p->second == s) {
169 by_osd.erase(p);
170 break;
171 }
172 }
31f18b77
FG
173 if (s->con_features) {
174 feature_map.rm(s->con_type, s->con_features);
175 }
7c673cae
FG
176 s->closed = true;
177 s->put();
178 }
179
11fdf7f2
TL
180 MonSession *new_session(const entity_name_t& n,
181 const entity_addrvec_t& av,
182 Connection *c) {
183 MonSession *s = new MonSession(c);
184 ceph_assert(s);
185 s->_ident(n, av);
186 add_session(s);
187 return s;
188 }
189
190 void add_session(MonSession *s) {
f91f0fd5
TL
191 s->session_timeout = ceph_clock_now();
192 s->session_timeout += g_conf()->mon_session_timeout;
193
7c673cae 194 sessions.push_back(&s->item);
11fdf7f2 195 s->get();
92f5a8d4
TL
196 if (s->name.is_osd() &&
197 s->name.num() >= 0) {
9f95a23c 198 by_osd.insert(std::pair<int,MonSession*>(s->name.num(), s));
11fdf7f2 199 }
31f18b77
FG
200 if (s->con_features) {
201 feature_map.add(s->con_type, s->con_features);
202 }
7c673cae
FG
203 }
204
205 MonSession *get_random_osd_session(OSDMap *osdmap) {
206 // ok, this isn't actually random, but close enough.
207 if (by_osd.empty())
208 return 0;
209 int n = by_osd.rbegin()->first + 1;
210 int r = rand() % n;
211
9f95a23c 212 auto p = by_osd.lower_bound(r);
7c673cae
FG
213 if (p == by_osd.end())
214 --p;
215
216 if (!osdmap) {
217 return p->second;
218 }
219
220 MonSession *s = NULL;
221
9f95a23c
TL
222 auto b = p;
223 auto f = p;
7c673cae
FG
224 bool backward = true, forward = true;
225 while (backward || forward) {
226 if (backward) {
227 if (osdmap->is_up(b->first) &&
11fdf7f2 228 osdmap->get_addrs(b->first) == b->second->con->get_peer_addrs()) {
7c673cae
FG
229 s = b->second;
230 break;
231 }
232 if (b != by_osd.begin())
233 --b;
234 else
235 backward = false;
236 }
237
238 forward = (f != by_osd.end());
239 if (forward) {
240 if (osdmap->is_up(f->first)) {
241 s = f->second;
242 break;
243 }
244 ++f;
245 }
246 }
247
248 return s;
249 }
250
9f95a23c 251 void add_update_sub(MonSession *s, const std::string& what, version_t start, bool onetime, bool incremental_onetime) {
7c673cae
FG
252 Subscription *sub = 0;
253 if (s->sub_map.count(what)) {
254 sub = s->sub_map[what];
255 } else {
256 sub = new Subscription(s, what);
257 s->sub_map[what] = sub;
224ce89b 258
7c673cae
FG
259 if (!subs.count(what))
260 subs[what] = new xlist<Subscription*>;
261 subs[what]->push_back(&sub->type_item);
262 }
263 sub->next = start;
264 sub->onetime = onetime;
265 sub->incremental_onetime = onetime && incremental_onetime;
266 }
267
268 void remove_sub(Subscription *sub) {
269 sub->session->sub_map.erase(sub->type);
270 sub->type_item.remove_myself();
271 delete sub;
272 }
273};
274
9f95a23c 275inline std::ostream& operator<<(std::ostream& out, const MonSession& s)
7c673cae 276{
11fdf7f2
TL
277 out << "MonSession(" << s.name << " " << s.addrs
278 << " is " << (s.closed ? "closed" : "open")
279 << " " << s.caps
280 << ", features 0x" << std::hex << s.con_features << std::dec
1adf2230
AA
281 << " (" << ceph_release_name(ceph_release_from_features(s.con_features))
282 << "))";
7c673cae
FG
283 return out;
284}
285
286#endif