#include "include/xlist.h"
#include "msg/msg_types.h"
+#include "mon/mon_types.h"
#include "auth/AuthServiceHandler.h"
#include "osd/OSDMap.h"
struct MonSession : public RefCountedObject {
ConnectionRef con;
+ int con_type = 0;
+ uint64_t con_features = 0; // zero if AnonConnection
entity_inst_t inst;
utime_t session_timeout;
utime_t time_established;
MonSession(const entity_inst_t& i, Connection *c) :
RefCountedObject(g_ceph_context),
- con(c), inst(i), closed(false), item(this),
+ con(c),
+ con_type(c->get_peer_type()),
+ con_features(0),
+ inst(i), closed(false), item(this),
auid(0),
global_id(0),
osd_epoch(0),
auth_handler(NULL),
proxy_con(NULL), proxy_tid(0) {
time_established = ceph_clock_now();
+ if (c->get_messenger()) {
+ // only fill in features if this is a non-anonymous connection
+ con_features = c->get_features();
+ }
}
~MonSession() override {
//generic_dout(0) << "~MonSession " << this << dendl;
xlist<MonSession*> sessions;
map<string, xlist<Subscription*>* > subs;
multimap<int, MonSession*> by_osd;
+ FeatureMap feature_map; // type -> features -> count
MonSessionMap() {}
~MonSessionMap() {
break;
}
}
+ if (s->con_features) {
+ feature_map.rm(s->con_type, s->con_features);
+ }
s->closed = true;
s->put();
}
sessions.push_back(&s->item);
if (i.name.is_osd())
by_osd.insert(pair<int,MonSession*>(i.name.num(), s));
+ if (s->con_features) {
+ feature_map.add(s->con_type, s->con_features);
+ }
s->get(); // caller gets a ref
return s;
}
#ifndef CEPH_MON_TYPES_H
#define CEPH_MON_TYPES_H
+#include <map>
+
#include "include/utime.h"
#include "include/util.h"
#include "common/Formatter.h"
#define CEPH_MON_ONDISK_MAGIC "ceph mon volume v012"
+// map of entity_type -> features -> count
+struct FeatureMap {
+ std::map<uint32_t,std::map<uint64_t,uint64_t>> m;
+
+ void add(uint32_t type, uint64_t features) {
+ m[type][features]++;
+ }
+
+ void rm(uint32_t type, uint64_t features) {
+ auto p = m.find(type);
+ assert(p != m.end());
+ auto q = p->second.find(features);
+ assert(q != p->second.end());
+ if (--q->second == 0) {
+ p->second.erase(q);
+ if (p->second.empty()) {
+ m.erase(p);
+ }
+ }
+ }
+
+ FeatureMap& operator+=(const FeatureMap& o) {
+ for (auto& p : o.m) {
+ auto &v = m[p.first];
+ for (auto& q : p.second) {
+ v[q.first] += q.second;
+ }
+ }
+ return *this;
+ }
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ ::encode(m, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::iterator& p) {
+ DECODE_START(1, p);
+ ::decode(m, p);
+ DECODE_FINISH(p);
+ }
+
+ void dump(Formatter *f) const {
+ for (auto& p : m) {
+ f->open_object_section(ceph_entity_type_name(p.first));
+ for (auto& q : p.second) {
+ f->open_object_section("group");
+ f->dump_unsigned("features", q.first);
+ f->dump_unsigned("num", q.second);
+ f->close_section();
+ }
+ f->close_section();
+ }
+ }
+};
+WRITE_CLASS_ENCODER(FeatureMap)
+
/**
* leveldb store stats
*