]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: track connected mon client features
authorSage Weil <sage@redhat.com>
Tue, 30 May 2017 20:09:20 +0000 (16:09 -0400)
committerSage Weil <sage@redhat.com>
Thu, 1 Jun 2017 17:58:23 +0000 (13:58 -0400)
Track counts of entities by their supported features.

Signed-off-by: Sage Weil <sage@redhat.com>
src/mon/Monitor.cc
src/mon/Session.h
src/mon/mon_types.h

index bc8f4fb79fcb17461deba3dd8326afe9262f1cf9..0d56612400477205a5df4f181f10c8820dcc4c0a 100644 (file)
@@ -2242,6 +2242,7 @@ void Monitor::get_mon_status(Formatter *f, ostream& ss)
   monmap->dump(f);
   f->close_section();
 
+  f->dump_object("feature_map", session_map.feature_map);
   f->close_section(); // mon_status
 
   if (free_formatter) {
index 75051bf6312fa7158adafc12cc9fa09dfe7cd0b6..cb59464498336e18bdcdba4fa314987f54cbd70a 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "include/xlist.h"
 #include "msg/msg_types.h"
+#include "mon/mon_types.h"
 
 #include "auth/AuthServiceHandler.h"
 #include "osd/OSDMap.h"
@@ -39,6 +40,8 @@ struct Subscription {
 
 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;
@@ -60,13 +63,20 @@ struct MonSession : public RefCountedObject {
 
   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;
@@ -92,6 +102,7 @@ struct MonSessionMap {
   xlist<MonSession*> sessions;
   map<string, xlist<Subscription*>* > subs;
   multimap<int, MonSession*> by_osd;
+  FeatureMap feature_map; // type -> features -> count
 
   MonSessionMap() {}
   ~MonSessionMap() {
@@ -123,6 +134,9 @@ struct MonSessionMap {
          break;
        }
     }
+    if (s->con_features) {
+      feature_map.rm(s->con_type, s->con_features);
+    }
     s->closed = true;
     s->put();
   }
@@ -133,6 +147,9 @@ struct MonSessionMap {
     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;
   }
index 54bbfb336d06eb5cb324719fc678430da4622e54..ede5aac0aeba53954e0ca3887e33a4a70e469c58 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef CEPH_MON_TYPES_H
 #define CEPH_MON_TYPES_H
 
+#include <map>
+
 #include "include/utime.h"
 #include "include/util.h"
 #include "common/Formatter.h"
@@ -45,6 +47,64 @@ inline const char *get_paxos_name(int p) {
 
 #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
  *