From 3a0e0ce24662bdad57a26611bffbbde5dd78ed16 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Sat, 8 Jun 2019 17:33:14 +0800 Subject: [PATCH] mds: ignore sessionmap version mismatch if mds_wipe_sessions is set Signed-off-by: "Yan, Zheng" (cherry picked from commit cd6f65b404c80c8fcf4f8579b34ae1ddea001751) --- src/mds/SessionMap.cc | 40 ++++++++++++++++++++++++++++++++++++++++ src/mds/SessionMap.h | 35 ++++++++--------------------------- src/mds/journal.cc | 21 ++++++++++++++------- 3 files changed, 62 insertions(+), 34 deletions(-) diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc index 2572089e641f0..5d1a3dd0e11d3 100644 --- a/src/mds/SessionMap.cc +++ b/src/mds/SessionMap.cc @@ -712,6 +712,46 @@ void SessionMap::replay_advance_version() projected = version; } +void SessionMap::replay_open_sessions(version_t event_cmapv, + map& client_map, + map& client_metadata_map) +{ + unsigned already_saved; + + if (version + client_map.size() < event_cmapv) + goto bad; + + // Server::finish_force_open_sessions() marks sessions dirty one by one. + // Marking a session dirty may flush all existing dirty sessions. So it's + // possible that some sessions are already saved in sessionmap. + already_saved = client_map.size() - (event_cmapv - version); + for (const auto& p : client_map) { + Session *s = get_or_add_session(p.second); + auto q = client_metadata_map.find(p.first); + if (q != client_metadata_map.end()) + s->info.client_metadata.merge(q->second); + + if (already_saved > 0) { + if (s->is_closed()) + goto bad; + + --already_saved; + continue; + } + + set_state(s, Session::STATE_OPEN); + replay_dirty_session(s); + } + return; + +bad: + mds->clog->error() << "error replaying open sessions(" << client_map.size() + << ") sessionmap v " << event_cmapv << " table " << version; + ceph_assert(g_conf()->mds_wipe_sessions); + mds->sessionmap.wipe(); + mds->sessionmap.set_version(event_cmapv); +} + version_t SessionMap::mark_projected(Session *s) { dout(20) << __func__ << " s=" << s << " name=" << s->info.inst.name diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index 0cba0a1065ae5..de2d4a51b52c7 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -656,33 +656,6 @@ public: get_client_sessions(f); } - void replay_open_sessions(version_t event_cmapv, - map& client_map, - map& client_metadata_map) { - // Server::finish_force_open_sessions() marks sessions dirty one by one. - // Marking a session dirty may flush all existing dirty sessions. So it's - // possible that some sessions are already saved in sessionmap. - ceph_assert(version + client_map.size() >= event_cmapv); - unsigned already_saved = client_map.size() - (event_cmapv - version); - for (map::iterator p = client_map.begin(); - p != client_map.end(); - ++p) { - Session *s = get_or_add_session(p->second); - auto q = client_metadata_map.find(p->first); - if (q != client_metadata_map.end()) - s->info.client_metadata.merge(q->second); - - if (already_saved > 0) { - ceph_assert(s->is_open()); - --already_saved; - continue; - } - - set_state(s, Session::STATE_OPEN); - replay_dirty_session(s); - } - } - // helpers entity_inst_t& get_inst(entity_name_t w) { ceph_assert(session_map.count(w)); @@ -769,6 +742,14 @@ public: */ void replay_advance_version(); + /** + * During replay, open sessions, advance versions and + * mark these sessions as dirty. + */ + void replay_open_sessions(version_t event_cmapv, + map& client_map, + map& client_metadata_map); + /** * For these session IDs, if a session exists with this ID, and it has * dirty completed_requests, then persist it immediately diff --git a/src/mds/journal.cc b/src/mds/journal.cc index f22d123c8dd27..0d3f41a7343b4 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -1483,12 +1483,13 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDSlaveUpdate *slaveup) } } if (sessionmapv) { + unsigned diff = (used_preallocated_ino && !preallocated_inos.empty()) ? 2 : 1; if (mds->sessionmap.get_version() >= sessionmapv) { dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv << " <= table " << mds->sessionmap.get_version() << dendl; - } else if (mds->sessionmap.get_version() + 2 >= sessionmapv) { + } else if (mds->sessionmap.get_version() + diff == sessionmapv) { dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv - << " -(1|2) == table " << mds->sessionmap.get_version() + << " - " << diff << " == table " << mds->sessionmap.get_version() << " prealloc " << preallocated_inos << " used " << used_preallocated_ino << dendl; @@ -1514,16 +1515,16 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDSlaveUpdate *slaveup) } else { dout(10) << "EMetaBlob.replay no session for " << client_name << dendl; - if (used_preallocated_ino) { + if (used_preallocated_ino) mds->sessionmap.replay_advance_version(); - } + if (!preallocated_inos.empty()) mds->sessionmap.replay_advance_version(); } ceph_assert(sessionmapv == mds->sessionmap.get_version()); } else { - mds->clog->error() << "journal replay sessionmap v " << sessionmapv - << " -(1|2) > table " << mds->sessionmap.get_version(); + mds->clog->error() << "EMetaBlob.replay sessionmap v " << sessionmapv + << " - " << diff << " > table " << mds->sessionmap.get_version(); ceph_assert(g_conf()->mds_wipe_sessions); mds->sessionmap.wipe(); mds->sessionmap.set_version(sessionmapv); @@ -1617,7 +1618,7 @@ void ESession::replay(MDSRank *mds) if (mds->sessionmap.get_version() >= cmapv) { dout(10) << "ESession.replay sessionmap " << mds->sessionmap.get_version() << " >= " << cmapv << ", noop" << dendl; - } else { + } else if (mds->sessionmap.get_version() + 1 == cmapv) { dout(10) << "ESession.replay sessionmap " << mds->sessionmap.get_version() << " < " << cmapv << " " << (open ? "open":"close") << " " << client_inst << dendl; Session *session; @@ -1648,6 +1649,12 @@ void ESession::replay(MDSRank *mds) mds->sessionmap.replay_advance_version(); } ceph_assert(mds->sessionmap.get_version() == cmapv); + } else { + mds->clog->error() << "ESession.replay sessionmap v " << cmapv + << " - 1 > table " << mds->sessionmap.get_version(); + ceph_assert(g_conf()->mds_wipe_sessions); + mds->sessionmap.wipe(); + mds->sessionmap.set_version(cmapv); } if (inos.size() && inotablev) { -- 2.39.5