]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: abstract SessionMapStore from SessionMap
authorJohn Spray <john.spray@redhat.com>
Fri, 16 Jan 2015 00:00:56 +0000 (00:00 +0000)
committerJohn Spray <john.spray@redhat.com>
Fri, 16 Jan 2015 00:45:25 +0000 (00:45 +0000)
This is similar to what I did for InodeStore a while back:
introduce a logical separation between the persisted attributers
(and their encoding) and the live/runtime behavioural code.  This
results in a handy SessionMapStore class that can be used for
encode/decode from tools.

Also give it a reset_state method so that it matches the
prototype of the MDSTable subclasses for the benefit of
cephfs-table-tool.

Signed-off-by: John Spray <john.spray@redhat.com>
src/mds/MDS.cc
src/mds/SessionMap.cc
src/mds/SessionMap.h
src/test/encoding/types.h

index af6440fce94ede59132d382c0020c8a178099444..fc00797d20ed019e6164d66a93ff69814bfdf760 100644 (file)
@@ -1768,6 +1768,8 @@ void MDS::boot_create()
 
   mdcache->init_layouts();
 
+  sessionmap.set_rank(whoami);
+
   // start with a fresh journal
   dout(10) << "boot_create creating fresh journal" << dendl;
   mdlog->create(fin.new_sub());
@@ -1852,6 +1854,7 @@ void MDS::boot_start(BootStep step, int r)
         inotable->load(gather.new_sub());
 
         dout(2) << "boot_start " << step << ": opening sessionmap" << dendl;
+        sessionmap.set_rank(whoami);
         sessionmap.load(gather.new_sub());
 
         dout(2) << "boot_start " << step << ": opening mds log" << dendl;
index 2f703efc87a37200fd564a28fad44e7a54ca6453..4fa43d9cd544a79d3045e8dc7043dfc0d602d329 100644 (file)
@@ -25,7 +25,7 @@
 
 #define dout_subsys ceph_subsys_mds
 #undef dout_prefix
-#define dout_prefix *_dout << "mds." << mds->get_nodeid() << ".sessionmap "
+#define dout_prefix *_dout << "mds." << rank << ".sessionmap "
 
 
 class SessionMapIOContext : public MDSIOContextBase
@@ -162,7 +162,7 @@ void SessionMap::_save_finish(version_t v)
 
 // -------------------
 
-void SessionMap::encode(bufferlist& bl) const
+void SessionMapStore::encode(bufferlist& bl) const
 {
   uint64_t pre = -1;     // for 0.19 compatibility; we forgot an encoding prefix.
   ::encode(pre, bl);
@@ -184,7 +184,35 @@ void SessionMap::encode(bufferlist& bl) const
   ENCODE_FINISH(bl);
 }
 
-void SessionMap::decode(bufferlist::iterator& p)
+/**
+ * Deserialize sessions, and update by_state index
+ */
+void SessionMap::decode(bufferlist::iterator &p)
+{
+  // Populate `sessions`
+  SessionMapStore::decode(p);
+
+  // Update `by_state`
+  for (ceph::unordered_map<entity_name_t, Session*>::iterator i = session_map.begin();
+       i != session_map.end(); ++i) {
+    Session *s = i->second;
+    if (by_state.count(s->get_state()) == 0)
+      by_state[s->get_state()] = new xlist<Session*>;
+    by_state[s->get_state()]->push_back(&s->item_session_list);
+  }
+}
+
+uint64_t SessionMap::set_state(Session *session, int s) {
+  if (session->state != s) {
+    session->set_state(s);
+    if (by_state.count(s) == 0)
+      by_state[s] = new xlist<Session*>;
+    by_state[s]->push_back(&session->item_session_list);
+  }
+  return session->get_state_seq();
+}
+
+void SessionMapStore::decode(bufferlist::iterator& p)
 {
   utime_t now = ceph_clock_now(g_ceph_context);
   uint64_t pre;
@@ -200,7 +228,7 @@ void SessionMap::decode(bufferlist::iterator& p)
       ::decode(inst.name, p);
       Session *s = get_or_add_session(inst);
       if (s->is_closed())
-       set_state(s, Session::STATE_OPEN);
+        s->set_state(Session::STATE_OPEN);
       s->decode(p);
     }
 
@@ -228,13 +256,13 @@ void SessionMap::decode(bufferlist::iterator& p)
       } else {
        session_map[s->info.inst.name] = s;
       }
-      set_state(s, Session::STATE_OPEN);
+      s->set_state(Session::STATE_OPEN);
       s->last_cap_renew = now;
     }
   }
 }
 
-void SessionMap::dump(Formatter *f) const
+void SessionMapStore::dump(Formatter *f) const
 {
   f->open_array_section("Sessions");
   for (ceph::unordered_map<entity_name_t,Session*>::const_iterator p = session_map.begin();
@@ -253,10 +281,10 @@ void SessionMap::dump(Formatter *f) const
   f->close_section(); // Sessions
 }
 
-void SessionMap::generate_test_instances(list<SessionMap*>& ls)
+void SessionMapStore::generate_test_instances(list<SessionMapStore*>& ls)
 {
   // pretty boring for now
-  ls.push_back(new SessionMap(NULL));
+  ls.push_back(new SessionMapStore());
 }
 
 void SessionMap::wipe()
@@ -420,3 +448,4 @@ void Session::decode(bufferlist::iterator &p)
 
   _update_human_name();
 }
+
index 4c38d3c10826d6d4775179a41725989a9e45582c..c990adacff93537e03d5dc371863202dd77fb173 100644 (file)
@@ -82,13 +82,20 @@ private:
   int importing_count;
   friend class SessionMap;
 
-
   // Human (friendly) name is soft state generated from client metadata
   void _update_human_name();
   std::string human_name;
 
 public:
 
+  inline int get_state() const {return state;}
+  void set_state(int new_state)
+  {
+    if (state != new_state) {
+      state = new_state;
+      state_seq++;
+    }
+  }
   void decode(bufferlist::iterator &p);
   void set_client_metadata(std::map<std::string, std::string> const &meta);
   std::string get_human_name() const {return human_name;}
@@ -255,28 +262,65 @@ public:
 
 class MDS;
 
-class SessionMap {
+/**
+ * Encapsulate the serialized state associated with SessionMap.  Allows
+ * encode/decode outside of live MDS instance.
+ */
+class SessionMapStore {
 public:
-  MDS *mds;
-private:
   ceph::unordered_map<entity_name_t, Session*> session_map;
+  version_t version;
+  mds_rank_t rank;
+
+  virtual void encode(bufferlist& bl) const;
+  virtual void decode(bufferlist::iterator& blp);
+  void dump(Formatter *f) const;
+
+  void set_rank(mds_rank_t r)
+  {
+    rank = r;
+  }
+
+  Session* get_or_add_session(const entity_inst_t& i) {
+    Session *s;
+    if (session_map.count(i.name)) {
+      s = session_map[i.name];
+    } else {
+      s = session_map[i.name] = new Session;
+      s->info.inst = i;
+      s->last_cap_renew = ceph_clock_now(g_ceph_context);
+    }
+
+    return s;
+  }
+
+  static void generate_test_instances(list<SessionMapStore*>& ls);
+
+  void reset_state()
+  {
+    session_map.clear();
+  }
+
+  SessionMapStore() : version(0), rank(MDS_RANK_NONE) {}
+  virtual ~SessionMapStore() {};
+};
+
+class SessionMap : public SessionMapStore {
 public:
-  map<int,xlist<Session*>* > by_state;
-  
+  MDS *mds;
+
 public:  // i am lazy
-  version_t version, projected, committing, committed;
+  version_t projected, committing, committed;
+  map<int,xlist<Session*>* > by_state;
+  uint64_t set_state(Session *session, int state);
   map<version_t, list<MDSInternalContextBase*> > commit_waiters;
 
-public:
-  SessionMap(MDS *m) : mds(m), 
-                      version(0), projected(0), committing(0), committed(0) 
+  SessionMap(MDS *m) : mds(m),
+                      projected(0), committing(0), committed(0) 
   { }
-  
-  //for the dencoder
-  SessionMap() : mds(NULL), version(0), projected(0),
-                committing(0), committed(0) {}
-    
+
   // sessions
+  void decode(bufferlist::iterator& blp);
   bool empty() { return session_map.empty(); }
   const ceph::unordered_map<entity_name_t, Session*> &get_sessions() const
   {
@@ -315,17 +359,7 @@ public:
       return p->second;
     }
   }
-  Session* get_or_add_session(const entity_inst_t& i) {
-    Session *s;
-    if (session_map.count(i.name)) {
-      s = session_map[i.name];
-    } else {
-      s = session_map[i.name] = new Session;
-      s->info.inst = i;
-      s->last_cap_renew = ceph_clock_now(g_ceph_context);
-    }
-    return s;
-  }
+
   void add_session(Session *s);
   void remove_session(Session *s);
   void touch_session(Session *session);
@@ -335,16 +369,7 @@ public:
       return 0;
     return by_state[state]->front();
   }
-  uint64_t set_state(Session *session, int s) {
-    if (session->state != s) {
-      session->state = s;
-      session->state_seq++;
-      if (by_state.count(s) == 0)
-       by_state[s] = new xlist<Session*>;
-      by_state[s]->push_back(&session->item_session_list);
-    }
-    return session->state_seq;
-  }
+
   void dump();
 
   void get_client_set(set<client_t>& s) {
@@ -400,11 +425,6 @@ public:
   inodeno_t ino;
   list<MDSInternalContextBase*> waiting_for_load;
 
-  void encode(bufferlist& bl) const;
-  void decode(bufferlist::iterator& blp);
-  void dump(Formatter *f) const;
-  static void generate_test_instances(list<SessionMap*>& ls);
-
   object_t get_object_name();
 
   void load(MDSInternalContextBase *onload);
index 4e96f378fd3290d452d9870fbfe98b21a569ea92..4a70574f8e5e94154f21144ebd2da33ecbd108ca 100644 (file)
@@ -178,7 +178,7 @@ TYPE(InoTable)
 TYPEWITHSTRAYDATA(SnapServer)
 
 #include "mds/SessionMap.h"
-TYPE(SessionMap)
+TYPE(SessionMapStore)
 
 #include "mds/events/ECommitted.h"
 TYPE(ECommitted)