summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Typanski <nathan.typanski@mongodb.com>2016-07-31 16:51:56 -0400
committerMax Hirschhorn <max.hirschhorn@mongodb.com>2016-07-31 16:51:56 -0400
commitb155bb65881db1e271e847f1960c1bc6e736b450 (patch)
tree6bc3328fae00679fae5f38a36c7c0fc177a15205
parent27e090c6d8727145852bcecad1910ad9ec86159a (diff)
downloadmongo-b155bb65881db1e271e847f1960c1bc6e736b450.tar.gz
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.
-rw-r--r--src/mongo/shell/shell_utils.cpp37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp
index 1d723a4c54c..b0e17a79067 100644
--- a/src/mongo/shell/shell_utils.cpp
+++ b/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;