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