]> git.proxmox.com Git - ceph.git/blame - ceph/src/mon/Session.h
bump version to 12.0.3-pve3
[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
18#include "include/xlist.h"
19#include "msg/msg_types.h"
20
21#include "auth/AuthServiceHandler.h"
22#include "osd/OSDMap.h"
23
24#include "MonCap.h"
25
26struct MonSession;
27
28struct Subscription {
29 MonSession *session;
30 string type;
31 xlist<Subscription*>::item type_item;
32 version_t next;
33 bool onetime;
34 bool incremental_onetime; // has CEPH_FEATURE_INCSUBOSDMAP
35
36 Subscription(MonSession *s, const string& t) : session(s), type(t), type_item(this),
37 next(0), onetime(false), incremental_onetime(false) {}
38};
39
40struct MonSession : public RefCountedObject {
41 ConnectionRef con;
42 entity_inst_t inst;
43 utime_t session_timeout;
44 utime_t time_established;
45 bool closed;
46 xlist<MonSession*>::item item;
47 set<uint64_t> routed_request_tids;
48 MonCap caps;
49 uint64_t auid;
50 uint64_t global_id;
51
52 map<string, Subscription*> sub_map;
53 epoch_t osd_epoch; // the osdmap epoch sent to the mon client
54
55 AuthServiceHandler *auth_handler;
56 EntityName entity_name;
57
58 ConnectionRef proxy_con;
59 uint64_t proxy_tid;
60
61 MonSession(const entity_inst_t& i, Connection *c) :
62 RefCountedObject(g_ceph_context),
63 con(c), inst(i), closed(false), item(this),
64 auid(0),
65 global_id(0),
66 osd_epoch(0),
67 auth_handler(NULL),
68 proxy_con(NULL), proxy_tid(0) {
69 time_established = ceph_clock_now();
70 }
71 ~MonSession() override {
72 //generic_dout(0) << "~MonSession " << this << dendl;
73 // we should have been removed before we get destructed; see MonSessionMap::remove_session()
74 assert(!item.is_on_list());
75 assert(sub_map.empty());
76 delete auth_handler;
77 }
78
79 bool is_capable(string service, int mask) {
80 map<string,string> args;
81 return caps.is_capable(
82 g_ceph_context,
83 CEPH_ENTITY_TYPE_MON,
84 entity_name,
85 service, "", args,
86 mask & MON_CAP_R, mask & MON_CAP_W, mask & MON_CAP_X);
87 }
88};
89
90
91struct MonSessionMap {
92 xlist<MonSession*> sessions;
93 map<string, xlist<Subscription*>* > subs;
94 multimap<int, MonSession*> by_osd;
95
96 MonSessionMap() {}
97 ~MonSessionMap() {
98 while (!subs.empty()) {
99 assert(subs.begin()->second->empty());
100 delete subs.begin()->second;
101 subs.erase(subs.begin());
102 }
103 }
104
105 unsigned get_size() const {
106 return sessions.size();
107 }
108
109 void remove_session(MonSession *s) {
110 assert(!s->closed);
111 for (map<string,Subscription*>::iterator p = s->sub_map.begin(); p != s->sub_map.end(); ++p) {
112 p->second->type_item.remove_myself();
113 delete p->second;
114 }
115 s->sub_map.clear();
116 s->item.remove_myself();
117 if (s->inst.name.is_osd()) {
118 for (multimap<int,MonSession*>::iterator p = by_osd.find(s->inst.name.num());
119 p->first == s->inst.name.num();
120 ++p)
121 if (p->second == s) {
122 by_osd.erase(p);
123 break;
124 }
125 }
126 s->closed = true;
127 s->put();
128 }
129
130 MonSession *new_session(const entity_inst_t& i, Connection *c) {
131 MonSession *s = new MonSession(i, c);
132 assert(s);
133 sessions.push_back(&s->item);
134 if (i.name.is_osd())
135 by_osd.insert(pair<int,MonSession*>(i.name.num(), s));
136 s->get(); // caller gets a ref
137 return s;
138 }
139
140 MonSession *get_random_osd_session(OSDMap *osdmap) {
141 // ok, this isn't actually random, but close enough.
142 if (by_osd.empty())
143 return 0;
144 int n = by_osd.rbegin()->first + 1;
145 int r = rand() % n;
146
147 multimap<int,MonSession*>::iterator p = by_osd.lower_bound(r);
148 if (p == by_osd.end())
149 --p;
150
151 if (!osdmap) {
152 return p->second;
153 }
154
155 MonSession *s = NULL;
156
157 multimap<int,MonSession*>::iterator b = p, f = p;
158 bool backward = true, forward = true;
159 while (backward || forward) {
160 if (backward) {
161 if (osdmap->is_up(b->first) &&
162 osdmap->get_addr(b->first) == b->second->con->get_peer_addr()) {
163 s = b->second;
164 break;
165 }
166 if (b != by_osd.begin())
167 --b;
168 else
169 backward = false;
170 }
171
172 forward = (f != by_osd.end());
173 if (forward) {
174 if (osdmap->is_up(f->first)) {
175 s = f->second;
176 break;
177 }
178 ++f;
179 }
180 }
181
182 return s;
183 }
184
185 void add_update_sub(MonSession *s, const string& what, version_t start, bool onetime, bool incremental_onetime) {
186 Subscription *sub = 0;
187 if (s->sub_map.count(what)) {
188 sub = s->sub_map[what];
189 } else {
190 sub = new Subscription(s, what);
191 s->sub_map[what] = sub;
192
193 if (!subs.count(what))
194 subs[what] = new xlist<Subscription*>;
195 subs[what]->push_back(&sub->type_item);
196 }
197 sub->next = start;
198 sub->onetime = onetime;
199 sub->incremental_onetime = onetime && incremental_onetime;
200 }
201
202 void remove_sub(Subscription *sub) {
203 sub->session->sub_map.erase(sub->type);
204 sub->type_item.remove_myself();
205 delete sub;
206 }
207};
208
209inline ostream& operator<<(ostream& out, const MonSession& s)
210{
211 out << "MonSession(" << s.inst << " is "
212 << (s.closed ? "closed" : "open");
213 out << s.caps << ")";
214 return out;
215}
216
217#endif