For debugging where an operation may be stuck.
Fixes: https://tracker.ceph.com/issues/62086
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
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",
#include "ScrubStack.h"
#include "events/ESubtreeMap.h"
#include "events/ELid.h"
+#include "Mutation.h"
#include "MDSRank.h"
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<string> 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<const MDRequestImpl*>(&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, {""}, 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";
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());
}
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
std::unique_ptr<BatchOp> 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<MClientRequest> release_client_request();
void reset_peer_request(const ceph::cref_t<MMDSPeerRequest>& req=nullptr);
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;
};