From f232b020fc36ba33d6ef144bdb9e607beb135763 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 9 Mar 2022 15:42:56 +0800 Subject: [PATCH] mds: notify clients if the session has already opened 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 --- src/client/Client.cc | 12 ++++++++++++ src/mds/Server.cc | 18 +++++++++++++++++- src/mds/cephfs_features.cc | 1 + src/mds/cephfs_features.h | 30 ++++++++++++++++-------------- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 24fad1256d3f..efae15466e11 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -2316,6 +2316,18 @@ void Client::handle_client_session(const MConstRef& 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()) { diff --git a/src/mds/Server.cc b/src/mds/Server.cc index f5a89a96b730..8d881167656f 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -585,7 +585,23 @@ void Server::handle_client_session(const cref_t &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(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(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()); diff --git a/src/mds/cephfs_features.cc b/src/mds/cephfs_features.cc index 3709ca8b9b4a..419cf8d54977 100644 --- a/src/mds/cephfs_features.cc +++ b/src/mds/cephfs_features.cc @@ -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); diff --git a/src/mds/cephfs_features.h b/src/mds/cephfs_features.h index 85a636e9b3f2..1b94e66f8aef 100644 --- a/src/mds/cephfs_features.h +++ b/src/mds/cephfs_features.h @@ -30,20 +30,21 @@ namespace ceph { #define CEPHFS_CURRENT_RELEASE CEPH_RELEASE_QUINCY // 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 { \ -- 2.47.3