From 44148347ec1840cd4a1878dc066b6e727c7aec8a Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Mon, 21 May 2018 19:54:16 +0800 Subject: [PATCH] mds: infer client version by client metadata and connection's features Signed-off-by: "Yan, Zheng" --- src/mds/Server.cc | 41 +++++++++++++++++++++++++++++++++++++++ src/mds/Server.h | 1 + src/mds/cephfs_features.h | 12 +++++++++--- src/mds/mdstypes.cc | 9 +++++++++ src/mds/mdstypes.h | 2 +- 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 6c09976160d..ab51181c638 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -373,6 +373,9 @@ void Server::handle_client_session(MClientSession *m) client_metadata_t client_metadata(std::move(m->metadata), std::move(m->supported_features)); + if (client_metadata.features.empty()) + infer_supported_features(session, client_metadata); + dout(20) << __func__ << " CEPH_SESSION_REQUEST_OPEN metadata entries:" << dendl; dout(20) << " features: '" << client_metadata.features << dendl; for (auto& p : client_metadata) { @@ -977,6 +980,9 @@ void Server::handle_client_reconnect(MClientReconnect *m) } else if (mdcache->is_readonly()) { error_str = "mds is readonly"; } else { + if (session->info.client_metadata.features.empty()) + infer_supported_features(session, session->info.client_metadata); + feature_bitset_t missing_features = required_client_features; missing_features -= session->info.client_metadata.features; if (!missing_features.empty()) { @@ -1085,6 +1091,35 @@ void Server::handle_client_reconnect(MClientReconnect *m) m->put(); } +void Server::infer_supported_features(Session *session, client_metadata_t& client_metadata) +{ + int supported = -1; + auto it = client_metadata.find("ceph_version"); + if (it != client_metadata.end()) { + // user space client + if (it->second.compare(0, 16, "ceph version 12.") == 0) + supported = CEPHFS_FEATURE_LUMINOUS; + else if (session->connection->has_feature(CEPH_FEATURE_FS_CHANGE_ATTR)) + supported = CEPHFS_FEATURE_KRAKEN; + } else { + it = client_metadata.find("kernel_version"); + if (it != client_metadata.end()) { + // kernel client + if (session->connection->has_feature(CEPH_FEATURE_NEW_OSDOP_ENCODING)) + supported = CEPHFS_FEATURE_LUMINOUS; + } + } + if (supported == -1 && + session->connection->has_feature(CEPH_FEATURE_FS_FILE_LAYOUT_V2)) + supported = CEPHFS_FEATURE_JEWEL; + + if (supported >= 0) { + unsigned long value = (1UL << (supported + 1)) - 1; + client_metadata.features = std::move(feature_bitset_t(value)); + dout(10) << __func__ << " got '" << client_metadata.features << "'" << dendl; + } +} + void Server::update_required_client_features() { vector bits = CEPHFS_FEATURES_MDS_REQUIRED; @@ -1092,6 +1127,12 @@ void Server::update_required_client_features() int min_compat = mds->mdsmap->get_min_compat_client(); if (min_compat >= CEPH_RELEASE_MIMIC) bits.push_back(CEPHFS_FEATURE_MIMIC); + else if (min_compat >= CEPH_RELEASE_LUMINOUS) + bits.push_back(CEPHFS_FEATURE_LUMINOUS); + else if (min_compat >= CEPH_RELEASE_KRAKEN) + bits.push_back(CEPHFS_FEATURE_KRAKEN); + else if (min_compat >= CEPH_RELEASE_JEWEL) + bits.push_back(CEPHFS_FEATURE_JEWEL); std::sort(bits.begin(), bits.end()); required_client_features = feature_bitset_t(bits); diff --git a/src/mds/Server.h b/src/mds/Server.h index a23bb8c0808..39a4dcc6683 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -132,6 +132,7 @@ public: void journal_close_session(Session *session, int state, Context *on_safe); void reconnect_clients(MDSInternalContext *reconnect_done_); void handle_client_reconnect(class MClientReconnect *m); + void infer_supported_features(Session *session, client_metadata_t& client_metadata); void update_required_client_features(); //void process_reconnect_cap(CInode *in, int from, ceph_mds_cap_reconnect& capinfo); diff --git a/src/mds/cephfs_features.h b/src/mds/cephfs_features.h index e141fd84ded..1c54354b63e 100644 --- a/src/mds/cephfs_features.h +++ b/src/mds/cephfs_features.h @@ -18,11 +18,17 @@ // Please add feature bits for later ceph releases and update // Server::update_required_client_features(). -// The first 8 bits are reserved for old ceph releases. -#define CEPHFS_FEATURE_MIMIC 8 +// 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_FEATURES_ALL { \ - 0, 1, 2, 3, 4, 5, 6, 7, \ + 0, 1, 2, 3, 4, \ + CEPHFS_FEATURE_JEWEL, \ + CEPHFS_FEATURE_KRAKEN, \ + CEPHFS_FEATURE_LUMINOUS, \ CEPHFS_FEATURE_MIMIC, \ } diff --git a/src/mds/mdstypes.cc b/src/mds/mdstypes.cc index 499be4135e6..846345d649d 100644 --- a/src/mds/mdstypes.cc +++ b/src/mds/mdstypes.cc @@ -368,6 +368,15 @@ void old_rstat_t::generate_test_instances(list& ls) /* * feature_bitset_t */ +feature_bitset_t::feature_bitset_t(unsigned long value) +{ + if (value) { + for (size_t i = 0; i < sizeof(value) * 8; i += bits_per_block) { + _vec.push_back((block_type)(value >> i)); + } + } +} + feature_bitset_t::feature_bitset_t(const vector& array) { if (!array.empty()) { diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h index 4453c46f5d9..b512dcc2d6f 100644 --- a/src/mds/mdstypes.h +++ b/src/mds/mdstypes.h @@ -1067,9 +1067,9 @@ public: typedef uint64_t block_type; static const size_t bits_per_block = sizeof(block_type) * 8; - feature_bitset_t() {} feature_bitset_t(const feature_bitset_t& other) : _vec(other._vec) {} feature_bitset_t(feature_bitset_t&& other) : _vec(std::move(other._vec)) {} + feature_bitset_t(unsigned long value = 0); feature_bitset_t(const vector& array); feature_bitset_t& operator=(const feature_bitset_t& other) { _vec = other._vec; -- 2.39.5