From fea5131f280ab272c260d7fea75f1302353fc551 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 13 Aug 2018 13:59:10 -0500 Subject: [PATCH] osd: catch cmd_bad_get from do_command Refactor to limit impact of try block. Signed-off-by: Sage Weil --- src/osd/OSD.cc | 72 ++++++++++++++++++++++++++++++++------------------ src/osd/OSD.h | 4 +++ 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 737e2f9c5caa6..e684898fd4319 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -5813,31 +5813,56 @@ COMMAND("smart name=devid,type=CephString,req=False", "osd", "rw", "cli,rest") }; -void OSD::do_command(Connection *con, ceph_tid_t tid, vector& cmd, bufferlist& data) +void OSD::do_command( + Connection *con, ceph_tid_t tid, vector& cmd, bufferlist& data) { + dout(20) << "do_command tid " << tid << " " << cmd << dendl; + int r = 0; stringstream ss, ds; - string rs; bufferlist odata; - - dout(20) << "do_command tid " << tid << " " << cmd << dendl; - cmdmap_t cmdmap; - string prefix; - string format; - string pgidstr; - boost::scoped_ptr f; - if (cmd.empty()) { ss << "no command given"; goto out; } - if (!cmdmap_from_json(cmd, &cmdmap, ss)) { r = -EINVAL; goto out; } + try { + r = _do_command(con, cmdmap, tid, data, odata, ss, ds); + } catch (const bad_cmd_get& e) { + r = -EINVAL; + ss << e.what(); + } + if (r == -EAGAIN) { + return; + } + out: + string rs = ss.str(); + odata.append(ds); + dout(0) << "do_command r=" << r << " " << rs << dendl; + clog->info() << rs; + if (con) { + MCommandReply *reply = new MCommandReply(r, rs); + reply->set_tid(tid); + reply->set_data(odata); + con->send_message(reply); + } +} + +int OSD::_do_command( + Connection *con, cmdmap_t& cmdmap, ceph_tid_t tid, bufferlist& data, + bufferlist& odata, stringstream& ss, stringstream& ds) +{ + int r = 0; + string prefix; + string format; + string pgidstr; + boost::scoped_ptr f; + cmd_getval(cct, cmdmap, "prefix", prefix); if (prefix == "get_command_descriptions") { @@ -5973,11 +5998,17 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector& cmd, buffe // simulate pg cmd= for pg->do-command if (prefix != "pg") cmd_putval(cct, cmdmap, "cmd", prefix); - r = pg->do_command(cmdmap, ss, data, odata, con, tid); + try { + r = pg->do_command(cmdmap, ss, data, odata, con, tid); + } catch (const bad_cmd_get& e) { + pg->unlock(); + ss << e.what(); + return -EINVAL; + } if (r == -EAGAIN) { pg->unlock(); // don't reply, pg will do so async - return; + return -EAGAIN; } } else { ss << "not primary for pgid " << pgid; @@ -5989,7 +6020,7 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector& cmd, buffe // do not reply; they will get newer maps and realize they // need to resend. pg->unlock(); - return; + return -EAGAIN; } pg->unlock(); } else { @@ -6257,21 +6288,12 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector& cmd, buffe } else { - ss << "unrecognized command! " << cmd; + ss << "unrecognized command '" << prefix << "'"; r = -EINVAL; } out: - rs = ss.str(); - odata.append(ds); - dout(0) << "do_command r=" << r << " " << rs << dendl; - clog->info() << rs; - if (con) { - MCommandReply *reply = new MCommandReply(r, rs); - reply->set_tid(tid); - reply->set_data(odata); - con->send_message(reply); - } + return r; } void OSD::probe_smart(const string& only_devid, ostream& ss) diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 3cea85742c8f7..a51a0a8254155 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -2065,6 +2065,10 @@ protected: void handle_command(class MMonCommand *m); void handle_command(class MCommand *m); void do_command(Connection *con, ceph_tid_t tid, vector& cmd, bufferlist& data); + int _do_command( + Connection *con, cmdmap_t& cmdmap, ceph_tid_t tid, bufferlist& data, + bufferlist& odata, stringstream& ss, stringstream& ds); + // -- pg recovery -- void do_recovery(PG *pg, epoch_t epoch_queued, uint64_t pushes_reserved, -- 2.39.5