From: Yan, Zheng Date: Thu, 18 Jul 2019 07:31:15 +0000 (+0800) Subject: mds: add command that config individual client session X-Git-Tag: v14.2.8~20^2~6^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0bf4e1652cd0d145f6c3e7260a82801cbf6980ad;p=ceph.git mds: add command that config individual client session For now, the command only can change session's timeout config Fixes: http://tracker.ceph.com/issues/40811 Signed-off-by: "Yan, Zheng" (cherry picked from commit a9c21bdaef3473d99ac362122d441b9d869230dd) --- diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc index 2e9180061969..f42d031f7326 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -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::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"), diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index b0ad94baa913..c448f84f4275 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -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 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); diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index 22b91ca8f790..4bcf9a58c74d 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -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); diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h index 791d65e4d001..1d9688812ef3 100644 --- a/src/mds/mdstypes.h +++ b/src/mds/mdstypes.h @@ -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());