Permalink
Browse files

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.
  • Loading branch information...
1 parent 27e090c commit b155bb65881db1e271e847f1960c1bc6e736b450 @nathantypanski nathantypanski committed with visemet Jul 31, 2016
Showing with 35 additions and 2 deletions.
  1. +35 −2 src/mongo/shell/shell_utils.cpp
@@ -27,6 +27,8 @@
* then also delete it in the license file.
*/
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
+
#include "mongo/platform/basic.h"
#include "mongo/shell/shell_utils.h"
@@ -42,6 +44,7 @@
#include "mongo/shell/shell_utils_extended.h"
#include "mongo/shell/shell_utils_launcher.h"
#include "mongo/util/concurrency/threadlocal.h"
+#include "mongo/util/log.h"
#include "mongo/util/processinfo.h"
#include "mongo/util/quick_exit.h"
#include "mongo/util/text.h"
@@ -324,9 +327,39 @@ void ConnectionRegistry::killOperationsOnAllConnections(bool withPrompt) const {
BSONObj currentOpRes;
conn->runPseudoCommand("admin", "currentOp", "$cmd.sys.inprog", {}, currentOpRes);
+ if (!currentOpRes["inprog"].isABSONObj()) {
+ // We don't have permissions (or the call didn't succeed) - go to the next connection.
+ continue;
+ }
auto inprog = currentOpRes["inprog"].embeddedObject();
- BSONForEach(op, inprog) {
- if (uris.count(op["client"].String())) {
+ for (const auto op : inprog) {
+ // For sharded clusters, `client_s` is used instead and `client` is not present.
+ string client;
+ if (auto elem = op["client"]) {
+ // mongod currentOp client
+ if (elem.type() != String) {
+ warning() << "Ignoring operation " << op["opid"].toString(false)
+ << "; expected 'client' field in currentOp response to have type "
+ "string, but found "
+ << typeName(elem.type());
+ continue;
+ }
+ client = elem.str();
+ } else if (auto elem = op["client_s"]) {
+ // mongos currentOp client
+ if (elem.type() != String) {
+ warning() << "Ignoring operation " << op["opid"].toString(false)
+ << "; expected 'client_s' field in currentOp response to have type "
+ "string, but found "
+ << typeName(elem.type());
+ continue;
+ }
+ client = elem.str();
+ } else {
+ // Internal operation, like TTL index.
+ continue;
+ }
+ if (uris.count(client)) {
if (!withPrompt || prompter.confirm()) {
BSONObjBuilder cmdBob;
BSONObj info;

0 comments on commit b155bb6

Please sign in to comment.