void MDCache::request_kill(const MDRequestRef& mdr)
{
+ if (mdr->killed) {
+ /* ignore duplicate kills */
+ return;
+ }
+
// rollback peer requests is tricky. just let the request proceed.
if (mdr->has_more() &&
(!mdr->more()->witnessed.empty() || !mdr->more()->waiting_on_peer.empty())) {
,asok_hook
,"show the ops currently in flight");
ceph_assert(r == 0);
+ r = admin_socket->register_command("op kill "
+ "name=id,type=CephString,req=true",
+ asok_hook,
+ "kill op");
+ ceph_assert(r == 0);
r = admin_socket->register_command("dump_blocked_ops",
asok_hook,
"show the blocked ops currently in flight");
*css << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
}
}
+ } else if (command == "op kill") {
+ std::string id;
+ if(!cmd_getval(cmdmap, "id", id)) {
+ *css << "malformed id";
+ r = -CEPHFS_EINVAL;
+ goto out;
+ }
+ metareqid_t mrid;
+ try {
+ mrid = metareqid_t(id);
+ } catch (const std::exception& e) {
+ *css << "malformed id: " << e.what();
+ r = -CEPHFS_EINVAL;
+ goto out;
+ }
+ std::lock_guard l(mds_lock);
+ if (!mdcache->have_request(mrid)) {
+ *css << "request does not exist";
+ r = -CEPHFS_ENOENT;
+ goto out;
+ }
+ auto mdr = mdcache->request_get(mrid);
+ {
+ f->open_object_section("result");
+ f->dump_int("result", 0);
+ f->dump_object("request", *mdr);
+ f->close_section();
+ }
+ mdcache->request_kill(mdr);
+ r = 0;
} else if (command == "dump_blocked_ops") {
if (!op_tracker.dump_ops_in_flight(f, true)) {
*css << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
#include <ostream>
#include <set>
#include <map>
+#include <string>
#include <string_view>
#include "common/config.h"
struct metareqid_t {
metareqid_t() {}
metareqid_t(entity_name_t n, ceph_tid_t t) : name(n), tid(t) {}
+ metareqid_t(std::string_view sv) {
+ auto p = sv.find(':');
+ if (p == std::string::npos) {
+ throw std::invalid_argument("invalid format: expected colon");
+ }
+ if (!name.parse(sv.substr(0, p))) {
+ throw std::invalid_argument("invalid format: invalid entity name");
+ }
+ try {
+ tid = std::stoul(std::string(sv.substr(p+1)), nullptr, 0);
+ } catch (const std::invalid_argument& e) {
+ throw std::invalid_argument("invalid format: tid is not a number");
+ } catch (const std::out_of_range& e) {
+ throw std::invalid_argument("invalid format: tid is out of range");
+ }
+ }
void encode(ceph::buffer::list& bl) const {
using ceph::encode;
encode(name, bl);