]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: ignore sessionmap version mismatch if mds_wipe_sessions is set 28456/head
authorYan, Zheng <zyan@redhat.com>
Sat, 8 Jun 2019 09:33:14 +0000 (17:33 +0800)
committerYan, Zheng <zyan@redhat.com>
Sat, 8 Jun 2019 13:45:07 +0000 (21:45 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/SessionMap.cc
src/mds/SessionMap.h
src/mds/journal.cc

index 3a9f465418f5808a9c790db2a53f9061fe4e35b6..bd27ed7ac158741d2d0bbdf33d605d59d6f564cd 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 add18631049099c8bc916748f1e137bbec7743d9..6238828e4eed8181a71285ad749c778e61f5c492 100644 (file)
@@ -656,33 +656,6 @@ public:
     get_client_sessions(f);
   }
 
-  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) {
     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_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 0888725985e6415bd1c2ac8e2023b44c3daec1a9..75b14edc92cddca9816c99820f85fa8075918d4c 100644 (file)
@@ -1481,12 +1481,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;
@@ -1512,16 +1513,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);
@@ -1615,7 +1616,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;
@@ -1646,6 +1647,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) {