From: Patrick Donnelly Date: Tue, 18 Jul 2023 01:22:04 +0000 (-0400) Subject: mds: dump locks when printing mutation ops X-Git-Tag: v17.2.8~555^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=fee979a0dc17f9fe38c659887e7dc8d2ec9646d8;p=ceph.git mds: dump locks when printing mutation ops For debugging where an operation may be stuck. Fixes: https://tracker.ceph.com/issues/62086 Signed-off-by: Patrick Donnelly (cherry picked from commit 5c7dea32bb1ee04743f0e4341dcbe06cdb096c2d) Conflicts: src/mds/MDSRank.cc: header conflict --- diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc index 877d9132e71ce..cce7d434c6744 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -258,7 +258,9 @@ void MDSDaemon::set_up_admin_socket() r = admin_socket->register_command("dump_ops_in_flight", asok_hook, "show the ops currently in flight"); ceph_assert(r == 0); - r = admin_socket->register_command("ops", asok_hook, + r = admin_socket->register_command("ops " + "name=flags,type=CephChoices,strings=locks,n=N,req=false ", + asok_hook, "show the ops currently in flight"); ceph_assert(r == 0); r = admin_socket->register_command("dump_blocked_ops", diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 249868adaed25..12a2d5f4a5a64 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -38,6 +38,7 @@ #include "mon/MonClient.h" #include "common/HeartbeatMap.h" #include "ScrubStack.h" +#include "Mutation.h" #include "MDSRank.h" @@ -2610,11 +2611,31 @@ void MDSRankDispatcher::handle_asok_command( int r = 0; CachedStackStringStream css; bufferlist outbl; - if (command == "dump_ops_in_flight" || - command == "ops") { + dout(10) << __func__ << ": " << command << dendl; + if (command == "dump_ops_in_flight") { if (!op_tracker.dump_ops_in_flight(f)) { *css << "op_tracker disabled; set mds_enable_op_tracker=true to enable"; } + } else if (command == "ops") { + vector flags; + cmd_getval(cmdmap, "flags", flags); + std::unique_lock l(mds_lock, std::defer_lock); + auto lambda = OpTracker::default_dumper; + if (flags.size()) { + /* use std::function if we actually want to capture flags someday */ + lambda = [](const TrackedOp& op, Formatter* f) { + auto* req = dynamic_cast(&op); + if (req) { + req->dump_with_mds_lock(f); + } else { + op.dump_type(f); + } + }; + l.lock(); + } + if (!op_tracker.dump_ops_in_flight(f, false, {""}, lambda)) { + *css << "op_tracker disabled; set mds_enable_op_tracker=true to enable"; + } } 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"; diff --git a/src/mds/Mutation.cc b/src/mds/Mutation.cc index 2dcc0a694c300..b52e04a63936e 100644 --- a/src/mds/Mutation.cc +++ b/src/mds/Mutation.cc @@ -469,12 +469,7 @@ void MDRequestImpl::print(ostream &out) const out << ")"; } -void MDRequestImpl::dump(Formatter *f) const -{ - _dump(f); -} - -void MDRequestImpl::_dump(Formatter *f) const +void MDRequestImpl::_dump(Formatter *f, bool has_mds_lock) const { std::lock_guard l(lock); f->dump_string("flag_point", _get_state_string()); @@ -520,6 +515,27 @@ void MDRequestImpl::_dump(Formatter *f) const } f->close_section(); // events } + + if (has_mds_lock) { + f->open_array_section("locks"); + for (auto& l : locks) { + f->open_object_section("lock"); + { + auto* mdsco = l.lock->get_parent(); + f->dump_object("object", *mdsco); + CachedStackStringStream css; + *css << *mdsco; + f->dump_string("object_string", css->strv()); + f->dump_object("lock", *l.lock); + f->dump_int("flags", l.flags); + f->dump_int("wrlock_target", l.wrlock_target); + } + f->close_section(); + } + f->close_section(); + } else { + f->dump_null("locks"); + } } void MDRequestImpl::_dump_op_descriptor(ostream& os) const diff --git a/src/mds/Mutation.h b/src/mds/Mutation.h index e5fa3c9eb0641..6836533b05422 100644 --- a/src/mds/Mutation.h +++ b/src/mds/Mutation.h @@ -396,7 +396,9 @@ struct MDRequestImpl : public MutationImpl { std::unique_ptr release_batch_op(); void print(std::ostream &out) const override; - void dump(ceph::Formatter *f) const override; + void dump_with_mds_lock(ceph::Formatter* f) const { + return _dump(f, true); + } ceph::cref_t release_client_request(); void reset_peer_request(const ceph::cref_t& req=nullptr); @@ -452,7 +454,10 @@ struct MDRequestImpl : public MutationImpl { bool waited_for_osdmap = false; protected: - void _dump(ceph::Formatter *f) const override; + void _dump(ceph::Formatter *f) const override { + _dump(f, false); + } + void _dump(ceph::Formatter *f, bool has_mds_lock) const; void _dump_op_descriptor(std::ostream& stream) const override; };