asok_hook,
"dump snapshots");
ceph_assert(r == 0);
- r = admin_socket->register_command("session evict name=client_id,type=CephString",
+ r = admin_socket->register_command("session evict name=filters,type=CephString,n=N,req=false",
asok_hook,
- "Evict a CephFS client");
+ "Evict client session(s) based on a filter");
+ ceph_assert(r == 0);
+ r = admin_socket->register_command("client evict name=filters,type=CephString,n=N,req=false",
+ asok_hook,
+ "Evict client session(s) based on a filter");
+ ceph_assert(r == 0);
+ r = admin_socket->register_command("session kill name=client_id,type=CephString",
+ asok_hook,
+ "Evict a client session by id");
ceph_assert(r == 0);
r = admin_socket->register_command("session ls",
asok_hook,
const std::vector<MDSDaemon::MDSCommand>& MDSDaemon::get_commands()
{
static const std::vector<MDSCommand> commands = {
- MDSCommand("session kill name=session_id,type=CephInt", "End a client session"),
MDSCommand("session ls name=filters,type=CephString,n=N,req=false", "List client sessions"),
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",
}
cmd_getval(cct, cmdmap, "format", format);
- if (prefix == "session kill") {
- if (mds_rank == NULL) {
- r = -EINVAL;
- ss << "MDS not active";
- goto out;
- }
- // FIXME harmonize `session kill` with admin socket session evict
- int64_t session_id = 0;
- bool got = cmd_getval(cct, cmdmap, "session_id", session_id);
- ceph_assert(got);
- bool killed = mds_rank->evict_client(session_id, false,
- g_conf()->mds_session_blacklist_on_evict,
- ss);
- if (!killed)
- r = -ENOENT;
- } else {
+ if (true) {
// Give MDSRank a shot at the command
if (!mds_rank) {
ss << "MDS not active";
std::function<void(int,const std::string&,bufferlist&)> on_finish)
{
int r = 0;
- ostringstream ss;
+ stringstream ss;
bufferlist outbl;
if (command == "dump_ops_in_flight" ||
command == "ops") {
heartbeat_reset();
dump_sessions(SessionFilter(), f);
- } else if (command == "session evict") {
+ } else if (command == "session evict" ||
+ command == "client evict") {
+ std::lock_guard l(mds_lock);
+ std::vector<std::string> filter_args;
+ cmd_getval(g_ceph_context, cmdmap, "filters", filter_args);
+
+ SessionFilter filter;
+ r = filter.parse(filter_args, &ss);
+ if (r != 0) {
+ r = -EINVAL;
+ goto out;
+ }
+ evict_clients(filter, on_finish);
+ return;
+ } else if (command == "session kill") {
std::string client_id;
- const bool got_arg = cmd_getval(g_ceph_context, cmdmap, "client_id", client_id);
- if(!got_arg) {
+ if (!cmd_getval(g_ceph_context, cmdmap, "client_id", client_id)) {
ss << "Invalid client_id specified";
r = -ENOENT;
goto out;
g_conf()->mds_session_blacklist_on_evict, ss);
if (!evicted) {
dout(15) << ss.str() << dendl;
- r = -EBUSY;
+ r = -ENOENT;
}
} else if (command == "session config") {
int64_t client_id;
* MDSRank after calling it (we could have gone into shutdown): just
* send your result back to the calling client and finish.
*/
-void MDSRankDispatcher::evict_clients(const SessionFilter &filter, const cref_t<MCommand> &m)
+void MDSRankDispatcher::evict_clients(
+ const SessionFilter &filter,
+ std::function<void(int,const std::string&,bufferlist&)> on_finish)
{
- C_MDS_Send_Command_Reply *reply = new C_MDS_Send_Command_Reply(this, m);
-
+ bufferlist outbl;
if (is_any_replay()) {
- reply->send(-EAGAIN, "MDS is replaying log");
- delete reply;
+ on_finish(-EAGAIN, "MDS is replaying log", outbl);
return;
}
Session *s = p.second;
- if (filter.match(*s, std::bind(&Server::waiting_for_reconnect, server, std::placeholders::_1))) {
+ if (filter.match(*s, std::bind(&Server::waiting_for_reconnect, server,
+ std::placeholders::_1))) {
victims.push_back(s);
}
}
dout(20) << __func__ << " matched " << victims.size() << " sessions" << dendl;
if (victims.empty()) {
- reply->send(0, "");
- delete reply;
+ on_finish(0, {}, outbl);
return;
}
- C_GatherBuilder gather(g_ceph_context, reply);
+ C_GatherBuilder gather(g_ceph_context,
+ new LambdaContext([on_finish](int r) {
+ bufferlist bl;
+ on_finish(r, {}, bl);
+ }));
for (const auto s : victims) {
std::stringstream ss;
evict_client(s->get_client().v, false,
dump_sessions(filter, &f);
f.flush(*ds);
return true;
- } else if (prefix == "session evict" || prefix == "client evict") {
- std::vector<std::string> filter_args;
- cmd_getval(g_ceph_context, cmdmap, "filters", filter_args);
-
- SessionFilter filter;
- *r = filter.parse(filter_args, ss);
- if (*r != 0) {
- return true;
- }
-
- evict_clients(filter, m);
-
- *need_reply = false;
- return true;
} else if (prefix == "session config" || prefix == "client config") {
int64_t client_id;
std::string option;