diff --git a/src/mon/MonClient.cc b/src/mon/MonClient.cc index a77a5f899a6..3782902cb07 100644 --- a/src/mon/MonClient.cc +++ b/src/mon/MonClient.cc @@ -882,6 +882,23 @@ void MonClient::handle_mon_command_ack(MMonCommandAck *ack) ack->put(); } +int MonClient::_cancel_mon_command(uint64_t tid, int r) +{ + assert(monc_lock.is_locked()); + + map::iterator it = mon_commands.find(tid); + if (it == mon_commands.end()) { + ldout(cct, 10) << __func__ << " tid " << tid << " dne" << dendl; + return -ENOENT; + } + + ldout(cct, 10) << __func__ << " tid " << tid << dendl; + + MonCommand *cmd = it->second; + _finish_command(cmd, -ETIMEDOUT, ""); + return 0; +} + void MonClient::_finish_command(MonCommand *r, int ret, string rs) { ldout(cct, 10) << "_finish_command " << r->tid << " = " << ret << " " << rs << dendl; @@ -907,6 +924,10 @@ int MonClient::start_mon_command(const vector& cmd, r->poutbl = outbl; r->prs = outs; r->onfinish = onfinish; + if (cct->_conf->rados_mon_op_timeout > 0) { + r->ontimeout = new C_CancelMonCommand(r->tid, this); + timer.add_event_after(cct->_conf->rados_mon_op_timeout, r->ontimeout); + } mon_commands[r->tid] = r; _send_command(r); // can't fail diff --git a/src/mon/MonClient.h b/src/mon/MonClient.h index 1404f35786d..9aea5ad9382 100644 --- a/src/mon/MonClient.h +++ b/src/mon/MonClient.h @@ -344,18 +344,30 @@ private: bufferlist *poutbl; string *prs; int *prval; - Context *onfinish; + Context *onfinish, *ontimeout; MonCommand(uint64_t t) : target_rank(-1), tid(t), - poutbl(NULL), prs(NULL), prval(NULL), onfinish(NULL) + poutbl(NULL), prs(NULL), prval(NULL), onfinish(NULL), ontimeout(NULL) {} }; map mon_commands; + class C_CancelMonCommand : public Context + { + uint64_t tid; + MonClient *monc; + public: + C_CancelMonCommand(uint64_t tid, MonClient *monc) : tid(tid), monc(monc) {} + void finish(int r) { + monc->_cancel_mon_command(tid, -ETIMEDOUT); + } + }; + void _send_command(MonCommand *r); void _resend_mon_commands(); + int _cancel_mon_command(uint64_t tid, int r); void _finish_command(MonCommand *r, int ret, string rs); void handle_mon_command_ack(MMonCommandAck *ack);