From: Yan, Zheng Date: Sat, 8 Jun 2019 09:33:14 +0000 (+0800) Subject: mds: ignore sessionmap version mismatch if mds_wipe_sessions is set X-Git-Tag: v13.2.7~262^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5a5a5f99cc1cc42e5d993c52d0d557ffbb0b8fab;p=ceph.git mds: ignore sessionmap version mismatch if mds_wipe_sessions is set Signed-off-by: "Yan, Zheng" (cherry picked from commit cd6f65b404c80c8fcf4f8579b34ae1ddea001751) Conflicts: src/mds/journal.cc --- diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc index 0b7310b81d7c..e2ff8b337d36 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 2cb2cb558efb..8d020a973c21 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -608,33 +608,6 @@ public: s.insert(p->second); } - 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) { assert(session_map.count(w)); @@ -724,6 +697,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 5cc1078bb598..d36dd1806f5b 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -1528,12 +1528,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; @@ -1559,17 +1560,17 @@ 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(); } assert(sessionmapv == mds->sessionmap.get_version()); } else { - mds->clog->error() << "journal replay sessionmap v " << sessionmapv - << " -(1|2) > table " << mds->sessionmap.get_version(); - assert(g_conf->mds_wipe_sessions); + 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); } @@ -1670,7 +1671,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; @@ -1700,7 +1701,13 @@ void ESession::replay(MDSRank *mds) } else { mds->sessionmap.replay_advance_version(); } - assert(mds->sessionmap.get_version() == cmapv); + 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) {