]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add command that config individual client session
authorYan, Zheng <zyan@redhat.com>
Thu, 18 Jul 2019 07:31:15 +0000 (15:31 +0800)
committerNathan Cutler <ncutler@suse.com>
Tue, 21 Jan 2020 16:43:01 +0000 (17:43 +0100)
For now, the command only can change session's timeout config

Fixes: http://tracker.ceph.com/issues/40811
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit a9c21bdaef3473d99ac362122d441b9d869230dd)

src/mds/MDSDaemon.cc
src/mds/MDSRank.cc
src/mds/MDSRank.h
src/mds/mdstypes.h

index 2e9180061969beb2f3f6d0e2ca0e7f7253f89a82..f42d031f7326f3dbc8b43ede5d1bc1245e228f26 100644 (file)
@@ -271,16 +271,23 @@ void MDSDaemon::set_up_admin_socket()
                                     asok_hook,
                                     "Evict a CephFS client");
   ceph_assert(r == 0);
-  r = admin_socket->register_command("osdmap barrier",
-                                    "osdmap barrier name=target_epoch,type=CephInt",
-                                    asok_hook,
-                                    "Wait until the MDS has this OSD map epoch");
-  ceph_assert(r == 0);
   r = admin_socket->register_command("session ls",
                                     "session ls",
                                     asok_hook,
                                     "Enumerate connected CephFS clients");
   ceph_assert(r == 0);
+  r = admin_socket->register_command("session config",
+                                    "session config name=client_id,type=CephInt,req=true "
+                                    "name=option,type=CephString,req=true "
+                                    "name=value,type=CephString,req=false ",
+                                    asok_hook,
+                                    "Config a CephFS client session");
+  assert(r == 0);
+  r = admin_socket->register_command("osdmap barrier",
+                                    "osdmap barrier name=target_epoch,type=CephInt",
+                                    asok_hook,
+                                    "Wait until the MDS has this OSD map epoch");
+  ceph_assert(r == 0);
   r = admin_socket->register_command("flush journal",
                                     "flush journal",
                                     asok_hook,
@@ -563,6 +570,10 @@ const std::vector<MDSDaemon::MDSCommand>& MDSDaemon::get_commands()
     MDSCommand("client ls name=filters,type=CephString,n=N,req=false", "List client sessions"),
     MDSCommand("session evict name=filters,type=CephString,n=N,req=false", "Evict client session(s)"),
     MDSCommand("client evict name=filters,type=CephString,n=N,req=false", "Evict client session(s)"),
+    MDSCommand("session config name=client_id,type=CephInt name=option,type=CephString name=value,type=CephString,req=false",
+       "Config a client session"),
+    MDSCommand("client config name=client_id,type=CephInt name=option,type=CephString name=value,type=CephString,req=false",
+       "Config a client session"),
     MDSCommand("damage ls", "List detected metadata damage"),
     MDSCommand("damage rm name=damage_id,type=CephInt", "Remove a damage table entry"),
     MDSCommand("version", "report version of MDS"),
index b0ad94baa913cbf893116321464ad7a857690997..c448f84f427559f3eb4c4b9c5d6448a4f9ea35d5 100644 (file)
@@ -2498,6 +2498,18 @@ bool MDSRankDispatcher::handle_asok_command(std::string_view command,
       ss << dss.str();
     }
     mds_lock.Unlock();
+  } else if (command == "session config") {
+    int64_t client_id;
+    std::string option;
+    std::string value;
+
+    cmd_getval(g_ceph_context, cmdmap, "client_id", client_id);
+    cmd_getval(g_ceph_context, cmdmap, "option", option);
+    bool got_value = cmd_getval(g_ceph_context, cmdmap, "value", value);
+
+    mds_lock.Lock();
+    config_client(client_id, !got_value, option, value, ss);
+    mds_lock.Unlock();
   } else if (command == "scrub_path") {
     string path;
     vector<string> scrubop_vec;
@@ -3305,6 +3317,42 @@ void MDSRankDispatcher::handle_osd_map()
   objecter->maybe_request_map();
 }
 
+int MDSRank::config_client(int64_t session_id, bool remove,
+                          const std::string& option, const std::string& value,
+                          std::ostream& ss)
+{
+  Session *session = sessionmap.get_session(entity_name_t(CEPH_ENTITY_TYPE_CLIENT, session_id));
+  if (!session) {
+    ss << "session " << session_id << " not in sessionmap!";
+    return -ENOENT;
+  }
+
+  if (option == "timeout") {
+    if (remove) {
+      auto it = session->info.client_metadata.find("timeout");
+      if (it == session->info.client_metadata.end()) {
+       ss << "Nonexistent config: " << option;
+       return -ENODATA;
+      }
+      session->info.client_metadata.erase(it);
+    } else {
+      char *end;
+      strtoul(value.c_str(), &end, 0);
+      if (*end) {
+       ss << "Invalid config for timeout: " << value;
+       return -EINVAL;
+      }
+      session->info.client_metadata[option] = value;
+    }
+    //sessionmap._mark_dirty(session, true);
+  } else {
+    ss << "Invalid config option: " << option;
+    return -EINVAL;
+  }
+
+  return 0;
+}
+
 bool MDSRank::evict_client(int64_t session_id,
     bool wait, bool blacklist, std::ostream& err_ss,
     Context *on_killed)
@@ -3506,6 +3554,17 @@ bool MDSRankDispatcher::handle_command(
 
     *need_reply = false;
     return true;
+  } else if (prefix == "session config" || prefix == "client config") {
+    int64_t client_id;
+    std::string option;
+    std::string value;
+
+    cmd_getval(g_ceph_context, cmdmap, "client_id", client_id);
+    cmd_getval(g_ceph_context, cmdmap, "option", option);
+    bool got_value = cmd_getval(g_ceph_context, cmdmap, "value", value);
+
+    *r = config_client(client_id, !got_value, option, value, *ss);
+    return true;
   } else if (prefix == "damage ls") {
     JSONFormatter f(true);
     damage_table.dump(&f);
index 22b91ca8f790b55b3867f017721f536431d550fe..4bcf9a58c74d1ee608b33bb74283205a27bacac1 100644 (file)
@@ -459,6 +459,9 @@ class MDSRank {
 
     bool evict_client(int64_t session_id, bool wait, bool blacklist,
                       std::ostream& ss, Context *on_killed=nullptr);
+    int config_client(int64_t session_id, bool remove,
+                     const std::string& option, const std::string& value,
+                     std::ostream& ss);
 
     void mark_base_recursively_scrubbed(inodeno_t ino);
 
index 791d65e4d0013a03e7cbab34447b69d8bc572a47..1d9688812ef39c1b22665adb7363df15d37776c0 100644 (file)
@@ -1141,6 +1141,7 @@ struct client_metadata_t {
   iterator find(const std::string& key) const { return kv_map.find(key); }
   iterator begin() const { return kv_map.begin(); }
   iterator end() const { return kv_map.end(); }
+  void erase(iterator it) { kv_map.erase(it); }
   std::string& operator[](const std::string& key) { return kv_map[key]; }
   void merge(const client_metadata_t& other) {
     kv_map.insert(other.kv_map.begin(), other.kv_map.end());