]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: tell client why it's rejected
authorYan, Zheng <zyan@redhat.com>
Fri, 11 May 2018 14:39:24 +0000 (22:39 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 12 Jul 2018 14:08:44 +0000 (22:08 +0800)
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/client/Client.cc
src/mds/Server.cc

index b763b36795f54a700970ac4ac4e604b1fe911424..d653c5bbfe4f6c059b385be94018dae092cda383 100644 (file)
@@ -2108,9 +2108,18 @@ void Client::handle_client_session(MClientSession *m)
     break;
 
   case CEPH_SESSION_REJECT:
-    rejected_by_mds[session->mds_num] = session->addrs;
-    _closed_mds_session(session);
+    {
+      std::string_view error_str;
+      auto it = m->metadata.find("error_string");
+      if (it != m->metadata.end())
+       error_str = it->second;
+      else
+       error_str = "unknown error";
+      lderr(cct) << "mds." << from << " rejected us (" << error_str << ")" << dendl;
 
+      rejected_by_mds[session->mds_num] = session->addrs;
+      _closed_mds_session(session);
+    }
     break;
 
   default:
index e249a2872aa0c7297a7df7bcdd1bd71599a496c8..02cc8db6012677b0e5f2b358f50d501496fe8d72 100644 (file)
@@ -301,7 +301,6 @@ public:
 void Server::handle_client_session(MClientSession *m)
 {
   version_t pv;
-  bool blacklisted = false;
   Session *session = mds->get_session(m);
 
   dout(3) << "handle_client_session " << *m << " from " << m->get_source() << dendl;
@@ -352,19 +351,26 @@ void Server::handle_client_session(MClientSession *m)
       return;
     }
 
-    blacklisted = mds->objecter->with_osdmap(
-        [session](const OSDMap &osd_map) -> bool {
-          return osd_map.is_blacklisted(session->info.inst.addr);
-        });
-
-    if (blacklisted) {
-      dout(10) << "rejecting blacklisted client " << session->info.inst.addr << dendl;
-      mds->send_message_client(new MClientSession(CEPH_SESSION_REJECT), session);
-      m->put();
-      return;
-    }
-
     {
+      auto send_reject_message = [this, session](std::string_view err_str) {
+       MClientSession *m = new MClientSession(CEPH_SESSION_REJECT);
+       if (session->info.has_feature(CEPHFS_FEATURE_MIMIC))
+         m->metadata["error_string"] = err_str;
+       mds->send_message_client(m, session);
+      };
+
+      bool blacklisted = mds->objecter->with_osdmap(
+         [session](const OSDMap &osd_map) -> bool {
+           return osd_map.is_blacklisted(session->info.inst.addr);
+         });
+
+      if (blacklisted) {
+       dout(10) << "rejecting blacklisted client " << session->info.inst.addr << dendl;
+       send_reject_message("blacklisted");
+       session->clear();
+       break;
+      }
+
       client_metadata_t client_metadata(std::move(m->metadata),
                                        std::move(m->supported_features));
       dout(20) << __func__ << " CEPH_SESSION_REQUEST_OPEN metadata entries:" << dendl;
@@ -376,7 +382,9 @@ void Server::handle_client_session(MClientSession *m)
       feature_bitset_t missing_features(CEPHFS_FEATURES_MDS_REQUIRED);
       missing_features -= client_metadata.features;
       if (!missing_features.empty()) {
-       mds->send_message_client(new MClientSession(CEPH_SESSION_REJECT), session);
+       stringstream ss;
+       ss << "missing required features '" << missing_features << "'";
+       send_reject_message(ss.str());
        mds->clog->warn() << "client session lacks required features '"
                          << missing_features << "' denied (" << session->info.inst << ")";
        session->clear();
@@ -389,14 +397,23 @@ void Server::handle_client_session(MClientSession *m)
       it = client_metadata.find("root");
       if (it != client_metadata.end()) {
        auto claimed_root = it->second;
+       stringstream ss;
+       bool denied = false;
        // claimed_root has a leading "/" which we strip before passing
        // into caps check
-       if (claimed_root.empty() || claimed_root[0] != '/' ||
-           !session->auth_caps.path_capable(claimed_root.substr(1))) {
+       if (claimed_root.empty() || claimed_root[0] != '/') {
+         denied = true;
+         ss << "invalue root '" << claimed_root << "'";
+       } else if (!session->auth_caps.path_capable(claimed_root.substr(1))) {
+         denied = true;
+         ss << "non-allowable root '" << claimed_root << "'";
+       }
+
+       if (denied) {
          // Tell the client we're rejecting their open
-         mds->send_message_client(new MClientSession(CEPH_SESSION_REJECT), session);
-         mds->clog->warn() << "client session with invalid root '" << claimed_root
-                           << "' denied (" << session->info.inst << ")";
+         send_reject_message(ss.str());
+         mds->clog->warn() << "client session with " << ss.str()
+                           << " denied (" << session->info.inst << ")";
          session->clear();
          break;
        }