]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: infer client version by client metadata and connection's features
authorYan, Zheng <zyan@redhat.com>
Mon, 21 May 2018 11:54:16 +0000 (19:54 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 12 Jul 2018 14:08:45 +0000 (22:08 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/Server.cc
src/mds/Server.h
src/mds/cephfs_features.h
src/mds/mdstypes.cc
src/mds/mdstypes.h

index 6c09976160d6e66da6ca2b99845bdfd079720150..ab51181c6384ed8871fa836dc648a64186f7ae9b 100644 (file)
@@ -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<size_t> 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);
index a23bb8c080835914fb9751d675da94b194f19618..39a4dcc6683efe8437041c67b83c5d4532ce3e92 100644 (file)
@@ -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);
index e141fd84dedd52794226bf35ff6a1e9a40df8c3c..1c54354b63e9f5b7daf5e16cc232ede67098c418 100644 (file)
 // 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,                        \
 }
 
index 499be4135e661b02f141f46d3e35b53f5314be07..846345d649d6fa4ac7af39ecf010e644f6e42935 100644 (file)
@@ -368,6 +368,15 @@ void old_rstat_t::generate_test_instances(list<old_rstat_t*>& 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<size_t>& array)
 {
   if (!array.empty()) {
index 4453c46f5d913ee1674b8ae2a88f87c53cb95055..b512dcc2d6f065979f8385008f7329bdba3dea80 100644 (file)
@@ -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<size_t>& array);
   feature_bitset_t& operator=(const feature_bitset_t& other) {
     _vec = other._vec;