]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: notify clients if the session has already opened
authorXiubo Li <xiubli@redhat.com>
Wed, 9 Mar 2022 07:42:56 +0000 (15:42 +0800)
committerXiubo Li <xiubli@redhat.com>
Mon, 5 Dec 2022 00:52:10 +0000 (08:52 +0800)
If the connection was accidently closed due to the socket issue or
something else the client will try to open the opened sessions, for
now the MDS will just discard the session open request.

But the client will keep waiting the reply from the mds forever.

We need to tell the clients what has happened instead of discard it
directly. And when the client get the session open reply, it can
do what needed.

Fixes: https://tracker.ceph.com/issues/53911
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit f232b020fc36ba33d6ef144bdb9e607beb135763)

src/client/Client.cc
src/mds/Server.cc
src/mds/cephfs_features.cc
src/mds/cephfs_features.h

index 99c46f8ee99b9cbaa291d9712eb85a0348be859d..c701e0ba0f5472c8b3dcbc35807d07edbdc6617e 100644 (file)
@@ -2314,6 +2314,18 @@ void Client::handle_client_session(const MConstRef<MClientSession>& m)
   switch (m->get_op()) {
   case CEPH_SESSION_OPEN:
     {
+      if (session->state == MetaSession::STATE_OPEN) {
+        ldout(cct, 10) << "mds." << from << " already opened, ignore it"
+                       << dendl;
+        return;
+      }
+      /*
+       * The connection maybe broken and the session in client side
+       * has been reinitialized, need to update the seq anyway.
+       */
+      if (!session->seq && m->get_seq())
+        session->seq = m->get_seq();
+
       feature_bitset_t missing_features(CEPHFS_FEATURES_CLIENT_REQUIRED);
       missing_features -= m->supported_features;
       if (!missing_features.empty()) {
index 89d3199564cd765661dd1bb973fa1e1487b22907..d8bb5bf0b95dda127bef572a8361367dec730d74 100644 (file)
@@ -582,7 +582,23 @@ void Server::handle_client_session(const cref_t<MClientSession> &m)
        session->is_stale() ||
        session->is_killing() ||
        terminating_sessions) {
-      dout(10) << "currently open|opening|stale|killing, dropping this req" << dendl;
+      if (m->supported_features.test(CEPHFS_FEATURE_NOTIFY_SESSION_STATE)) {
+       if (session->is_open() && !mds->is_stopping()) {
+          dout(10) << "currently already opened" << dendl;
+
+          auto reply = make_message<MClientSession>(CEPH_SESSION_OPEN,
+                                                    session->get_push_seq());
+          if (session->info.has_feature(CEPHFS_FEATURE_MIMIC))
+            reply->supported_features = supported_features;
+          mds->send_message_client(reply, session);
+          if (mdcache->is_readonly()) {
+            auto m = make_message<MClientSession>(CEPH_SESSION_FORCE_RO);
+            mds->send_message_client(m, session);
+          }
+       }
+      }
+      dout(10) << "currently " << session->get_state_name()
+               << ", dropping this req" << dendl;
       return;
     }
     ceph_assert(session->is_closed() || session->is_closing());
index deec59a286045f0bd8f2a7cffff11aadc6f83a42..afa7e7d4cd48ac8929ca2c7698bfa91abfb1fafd 100644 (file)
@@ -23,6 +23,7 @@ static const std::array feature_names
   "deleg_ino",
   "metric_collect",
   "alternate_name",
+  "notify_session_state",
 };
 static_assert(feature_names.size() == CEPHFS_FEATURE_MAX + 1);
 
index ddc760e2c01f7ec78e02cfb13ae579b9f56e7f9b..169af793fc0146607d31517c530fde7f99801bc5 100644 (file)
@@ -30,20 +30,21 @@ namespace ceph {
 #define CEPHFS_CURRENT_RELEASE  CEPH_RELEASE_PACIFIC
 
 // The first 5 bits are reserved for old ceph releases.
-#define CEPHFS_FEATURE_JEWEL           5
-#define CEPHFS_FEATURE_KRAKEN          6
-#define CEPHFS_FEATURE_LUMINOUS                7
-#define CEPHFS_FEATURE_MIMIC           8
-#define CEPHFS_FEATURE_REPLY_ENCODING   9
-#define CEPHFS_FEATURE_RECLAIM_CLIENT  10
-#define CEPHFS_FEATURE_LAZY_CAP_WANTED  11
-#define CEPHFS_FEATURE_MULTI_RECONNECT  12
-#define CEPHFS_FEATURE_NAUTILUS         12
-#define CEPHFS_FEATURE_DELEG_INO        13
-#define CEPHFS_FEATURE_OCTOPUS          13
-#define CEPHFS_FEATURE_METRIC_COLLECT   14
-#define CEPHFS_FEATURE_ALTERNATE_NAME   15
-#define CEPHFS_FEATURE_MAX              15
+#define CEPHFS_FEATURE_JEWEL                5
+#define CEPHFS_FEATURE_KRAKEN               6
+#define CEPHFS_FEATURE_LUMINOUS             7
+#define CEPHFS_FEATURE_MIMIC                8
+#define CEPHFS_FEATURE_REPLY_ENCODING       9
+#define CEPHFS_FEATURE_RECLAIM_CLIENT       10
+#define CEPHFS_FEATURE_LAZY_CAP_WANTED      11
+#define CEPHFS_FEATURE_MULTI_RECONNECT      12
+#define CEPHFS_FEATURE_NAUTILUS             12
+#define CEPHFS_FEATURE_DELEG_INO            13
+#define CEPHFS_FEATURE_OCTOPUS              13
+#define CEPHFS_FEATURE_METRIC_COLLECT       14
+#define CEPHFS_FEATURE_ALTERNATE_NAME       15
+#define CEPHFS_FEATURE_NOTIFY_SESSION_STATE 16
+#define CEPHFS_FEATURE_MAX                  16
 
 #define CEPHFS_FEATURES_ALL {          \
   0, 1, 2, 3, 4,                       \
@@ -60,6 +61,7 @@ namespace ceph {
   CEPHFS_FEATURE_OCTOPUS,               \
   CEPHFS_FEATURE_METRIC_COLLECT,        \
   CEPHFS_FEATURE_ALTERNATE_NAME,        \
+  CEPHFS_FEATURE_NOTIFY_SESSION_STATE,  \
 }
 
 #define CEPHFS_METRIC_FEATURES_ALL {           \