From: John Spray Date: Fri, 16 Jan 2015 00:00:56 +0000 (+0000) Subject: mds: abstract SessionMapStore from SessionMap X-Git-Tag: v0.93~273^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ea153c3f057c8098d2758986fec36cb09df3d9ea;p=ceph.git mds: abstract SessionMapStore from SessionMap 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 --- diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index af6440fce94e..fc00797d20ed 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -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; diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc index 2f703efc87a3..4fa43d9cd544 100644 --- a/src/mds/SessionMap.cc +++ b/src/mds/SessionMap.cc @@ -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::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; + 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; + 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::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& ls) +void SessionMapStore::generate_test_instances(list& 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(); } + diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index 4c38d3c10826..c990adacff93 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -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 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 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& ls); + + void reset_state() + { + session_map.clear(); + } + + SessionMapStore() : version(0), rank(MDS_RANK_NONE) {} + virtual ~SessionMapStore() {}; +}; + +class SessionMap : public SessionMapStore { public: - map* > by_state; - + MDS *mds; + public: // i am lazy - version_t version, projected, committing, committed; + version_t projected, committing, committed; + map* > by_state; + uint64_t set_state(Session *session, int state); map > 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 &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; - by_state[s]->push_back(&session->item_session_list); - } - return session->state_seq; - } + void dump(); void get_client_set(set& s) { @@ -400,11 +425,6 @@ public: inodeno_t ino; list waiting_for_load; - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& blp); - void dump(Formatter *f) const; - static void generate_test_instances(list& ls); - object_t get_object_name(); void load(MDSInternalContextBase *onload); diff --git a/src/test/encoding/types.h b/src/test/encoding/types.h index 4e96f378fd32..4a70574f8e5e 100644 --- a/src/test/encoding/types.h +++ b/src/test/encoding/types.h @@ -178,7 +178,7 @@ TYPE(InoTable) TYPEWITHSTRAYDATA(SnapServer) #include "mds/SessionMap.h" -TYPE(SessionMap) +TYPE(SessionMapStore) #include "mds/events/ECommitted.h" TYPE(ECommitted)