Skip to content

Commit b155bb6

Browse files
Nathan Typanskivisemet
Nathan Typanski
authored andcommitted
SERVER-23168 fix shell crashes on ctrl+c
Previously, unauthenticated shell connections would crash the shell on ctrl+c, and any connections to mongos would crash the shell on ctrl+c. Check for currentOp failures and add checks for mongos-specific currentOp results to fix this. Closes #1104. Signed-off-by: Max Hirschhorn <max.hirschhorn@mongodb.com> - Log a warning if the "client" field in the currentOp response isn't a string instead of throwing an exception.
1 parent 27e090c commit b155bb6

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

src/mongo/shell/shell_utils.cpp

+35-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
* then also delete it in the license file.
2828
*/
2929

30+
#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
31+
3032
#include "mongo/platform/basic.h"
3133

3234
#include "mongo/shell/shell_utils.h"
@@ -42,6 +44,7 @@
4244
#include "mongo/shell/shell_utils_extended.h"
4345
#include "mongo/shell/shell_utils_launcher.h"
4446
#include "mongo/util/concurrency/threadlocal.h"
47+
#include "mongo/util/log.h"
4548
#include "mongo/util/processinfo.h"
4649
#include "mongo/util/quick_exit.h"
4750
#include "mongo/util/text.h"
@@ -324,9 +327,39 @@ void ConnectionRegistry::killOperationsOnAllConnections(bool withPrompt) const {
324327

325328
BSONObj currentOpRes;
326329
conn->runPseudoCommand("admin", "currentOp", "$cmd.sys.inprog", {}, currentOpRes);
330+
if (!currentOpRes["inprog"].isABSONObj()) {
331+
// We don't have permissions (or the call didn't succeed) - go to the next connection.
332+
continue;
333+
}
327334
auto inprog = currentOpRes["inprog"].embeddedObject();
328-
BSONForEach(op, inprog) {
329-
if (uris.count(op["client"].String())) {
335+
for (const auto op : inprog) {
336+
// For sharded clusters, `client_s` is used instead and `client` is not present.
337+
string client;
338+
if (auto elem = op["client"]) {
339+
// mongod currentOp client
340+
if (elem.type() != String) {
341+
warning() << "Ignoring operation " << op["opid"].toString(false)
342+
<< "; expected 'client' field in currentOp response to have type "
343+
"string, but found "
344+
<< typeName(elem.type());
345+
continue;
346+
}
347+
client = elem.str();
348+
} else if (auto elem = op["client_s"]) {
349+
// mongos currentOp client
350+
if (elem.type() != String) {
351+
warning() << "Ignoring operation " << op["opid"].toString(false)
352+
<< "; expected 'client_s' field in currentOp response to have type "
353+
"string, but found "
354+
<< typeName(elem.type());
355+
continue;
356+
}
357+
client = elem.str();
358+
} else {
359+
// Internal operation, like TTL index.
360+
continue;
361+
}
362+
if (uris.count(client)) {
330363
if (!withPrompt || prompter.confirm()) {
331364
BSONObjBuilder cmdBob;
332365
BSONObj info;

0 commit comments

Comments
 (0)