]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: ignore sessionmap version mismatch if mds_wipe_sessions is set 28579/head
authorYan, Zheng <zyan@redhat.com>
Sat, 8 Jun 2019 09:33:14 +0000 (17:33 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 17 Jun 2019 01:47:22 +0000 (09:47 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit cd6f65b404c80c8fcf4f8579b34ae1ddea001751)

 Conflicts:
src/mds/journal.cc

src/mds/SessionMap.cc
src/mds/SessionMap.h
src/mds/journal.cc

index 0b7310b81d7c06fbd8acc47b4578900555a2627b..e2ff8b337d36e0ea7460a556cdda39d1e012f2eb 100644 (file)
@@ -712,6 +712,46 @@ void SessionMap::replay_advance_version()
   projected = version;
 }
 
+void SessionMap::replay_open_sessions(version_t event_cmapv,
+                           map<client_t,entity_inst_t>& client_map,
+                           map<client_t,client_metadata_t>& 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
index 2cb2cb558efb71ebd6e0444bda44045933680d0d..8d020a973c21b448ac241a53a49900bdf7ef4450 100644 (file)
@@ -608,33 +608,6 @@ public:
        s.insert(p->second);
   }
 
-  void replay_open_sessions(version_t event_cmapv,
-                           map<client_t,entity_inst_t>& client_map,
-                           map<client_t,client_metadata_t>& 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<client_t,entity_inst_t>::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_t,entity_inst_t>& client_map,
+                           map<client_t,client_metadata_t>& client_metadata_map);
+
   /**
    * For these session IDs, if a session exists with this ID, and it has
    * dirty completed_requests, then persist it immediately
index 5cc1078bb598a35994621438398e71213e1e0448..d36dd1806f5be0ec40dafc64fba540f6718dd680 100644 (file)
@@ -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) {