diff options
author | Ben Caimano <ben.caimano@10gen.com> | 2018-06-08 18:53:14 -0400 |
---|---|---|
committer | Ben Caimano <ben.caimano@10gen.com> | 2018-09-07 16:52:31 -0400 |
commit | 5445067793ec31b5dbdf7076fe710586f9a63414 (patch) | |
tree | 89950bf93ed0472f68842a046b5fa106c3f207c7 /src/mongo | |
parent | e631a9531fbc3d80945a72d15ae0ac83c76d51af (diff) | |
download | mongo-5445067793ec31b5dbdf7076fe710586f9a63414.tar.gz |
SERVER-35517 Add failpoint mechanism to the mongo shell
(cherry picked from commit d1ef07466b2da86ad1933c1e607ef3f3364ba100)
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/base/error_codes.err | 2 | ||||
-rw-r--r-- | src/mongo/db/commands/fail_point_cmd.cpp | 44 | ||||
-rw-r--r-- | src/mongo/shell/shell_utils.cpp | 20 | ||||
-rw-r--r-- | src/mongo/util/fail_point_service.cpp | 21 | ||||
-rw-r--r-- | src/mongo/util/fail_point_service.h | 7 |
5 files changed, 62 insertions, 32 deletions
diff --git a/src/mongo/base/error_codes.err b/src/mongo/base/error_codes.err index c268819ed3f..258d6bdbeeb 100644 --- a/src/mongo/base/error_codes.err +++ b/src/mongo/base/error_codes.err @@ -261,6 +261,8 @@ error_code("InvalidResumeToken", 260); error_code("TooManyLogicalSessions", 261); error_code("ExceededTimeLimit", 262); error_code("OperationNotSupportedInTransaction", 263); +error_code("TooManyFilesOpen", 264); +error_code("FailPointSetFailed", 266) # Error codes 4000-8999 are reserved. diff --git a/src/mongo/db/commands/fail_point_cmd.cpp b/src/mongo/db/commands/fail_point_cmd.cpp index 567d5f9db0e..23876f2ad83 100644 --- a/src/mongo/db/commands/fail_point_cmd.cpp +++ b/src/mongo/db/commands/fail_point_cmd.cpp @@ -41,9 +41,6 @@ namespace mongo { -using std::string; -using std::stringstream; - /** * Command for modifying installed fail points. * @@ -65,19 +62,19 @@ using std::stringstream; * data: <Object> // optional arbitrary object to store. * } */ -class FaultInjectCmd : public ErrmsgCommandDeprecated { +class FaultInjectCmd : public BasicCommand { public: - FaultInjectCmd() : ErrmsgCommandDeprecated("configureFailPoint") {} + FaultInjectCmd() : BasicCommand("configureFailPoint") {} AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { return AllowedOnSecondary::kAlways; } - virtual bool supportsWriteConcern(const BSONObj& cmd) const override { + bool supportsWriteConcern(const BSONObj& cmd) const override { return false; } - virtual bool adminOnly() const { + bool adminOnly() const override { return true; } @@ -86,35 +83,20 @@ public: } // No auth needed because it only works when enabled via command line. - virtual void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) const {} + void addRequiredPrivileges(const std::string& dbname, + const BSONObj& cmdObj, + std::vector<Privilege>* out) const override {} std::string help() const override { return "modifies the settings of a fail point"; } - bool errmsgRun(OperationContext* opCtx, - const string& dbname, - const BSONObj& cmdObj, - string& errmsg, - BSONObjBuilder& result) { - const string failPointName(cmdObj.firstElement().str()); - FailPointRegistry* registry = getGlobalFailPointRegistry(); - FailPoint* failPoint = registry->getFailPoint(failPointName); - - if (failPoint == nullptr) { - errmsg = failPointName + " not found"; - return false; - } - - FailPoint::Mode mode; - FailPoint::ValType val; - BSONObj data; - std::tie(mode, val, data) = uassertStatusOK(FailPoint::parseBSON(cmdObj)); - - failPoint->setMode(mode, val, data); - warning() << "failpoint: " << failPointName << " set to: " << failPoint->toBSON(); + bool run(OperationContext* opCtx, + const std::string& dbname, + const BSONObj& cmdObj, + BSONObjBuilder& result) override { + const std::string failPointName(cmdObj.firstElement().str()); + setGlobalFailPoint(failPointName, cmdObj); return true; } diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp index fb146fae121..7112fe9fa12 100644 --- a/src/mongo/shell/shell_utils.cpp +++ b/src/mongo/shell/shell_utils.cpp @@ -41,6 +41,7 @@ #include "mongo/shell/shell_options.h" #include "mongo/shell/shell_utils_extended.h" #include "mongo/shell/shell_utils_launcher.h" +#include "mongo/util/fail_point_service.h" #include "mongo/util/log.h" #include "mongo/util/processinfo.h" #include "mongo/util/quick_exit.h" @@ -169,6 +170,24 @@ BSONObj getBuildInfo(const BSONObj& a, void* data) { return BSON("" << b.done()); } +BSONObj _setShellFailPoint(const BSONObj& a, void* data) { + if (a.nFields() != 1) { + uasserted(ErrorCodes::BadValue, + str::stream() << "_setShellFailPoint takes exactly 1 argument, but was given " + << a.nFields()); + } + + if (!a.firstElement().isABSONObj()) { + uasserted(ErrorCodes::BadValue, + str::stream() << "_setShellFailPoint given a non-object as an argument."); + } + + auto cmdObj = a.firstElement().Obj(); + setGlobalFailPoint(cmdObj.firstElement().str(), cmdObj); + + return BSON("" << true); +} + BSONObj computeSHA256Block(const BSONObj& a, void* data) { std::vector<ConstDataRange> blocks; @@ -286,6 +305,7 @@ void installShellUtils(Scope& scope) { scope.injectNative("_srand", JSSrand); scope.injectNative("_rand", JSRand); scope.injectNative("_isWindows", isWindows); + scope.injectNative("_setShellFailPoint", _setShellFailPoint); scope.injectNative("interpreterVersion", interpreterVersion); scope.injectNative("getBuildInfo", getBuildInfo); scope.injectNative("computeSHA256Block", computeSHA256Block); diff --git a/src/mongo/util/fail_point_service.cpp b/src/mongo/util/fail_point_service.cpp index b308b8a27c8..671684fc510 100644 --- a/src/mongo/util/fail_point_service.cpp +++ b/src/mongo/util/fail_point_service.cpp @@ -26,10 +26,15 @@ * then also delete it in the license file. */ +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kCommand + #include "mongo/platform/basic.h" #include "mongo/util/fail_point_service.h" +#include "mongo/util/assert_util.h" +#include "mongo/util/log.h" + namespace mongo { using std::unique_ptr; @@ -54,6 +59,22 @@ FailPointRegistry* getGlobalFailPointRegistry() { return _fpRegistry.get(); } +void setGlobalFailPoint(const std::string& failPointName, const BSONObj& cmdObj) { + FailPointRegistry* registry = getGlobalFailPointRegistry(); + FailPoint* failPoint = registry->getFailPoint(failPointName); + + if (failPoint == nullptr) + uasserted(ErrorCodes::FailPointSetFailed, failPointName + " not found"); + + FailPoint::Mode mode; + FailPoint::ValType val; + BSONObj data; + std::tie(mode, val, data) = uassertStatusOK(FailPoint::parseBSON(cmdObj)); + + failPoint->setMode(mode, val, data); + warning() << "failpoint: " << failPointName << " set to: " << failPoint->toBSON(); +} + FailPointEnableBlock::FailPointEnableBlock(const std::string& failPointName) { _failPoint = getGlobalFailPointRegistry()->getFailPoint(failPointName); invariant(_failPoint != nullptr); diff --git a/src/mongo/util/fail_point_service.h b/src/mongo/util/fail_point_service.h index b9d21f5ebff..88168d8c32f 100644 --- a/src/mongo/util/fail_point_service.h +++ b/src/mongo/util/fail_point_service.h @@ -40,9 +40,14 @@ namespace mongo { FailPointRegistry* getGlobalFailPointRegistry(); /** + * Set a fail point in the global registry to a given value via BSON + * @throw DBException If no failpoint called failPointName exists. + */ +void setGlobalFailPoint(const std::string& failPointName, const BSONObj& cmdObj); + +/** * Convenience macro for defining a fail point. Must be used at namespace scope. * Note: that means never at local scope (inside functions) or class scope. - * * NOTE: Never use in header files, only sources. */ #define MONGO_FAIL_POINT_DEFINE(fp) \ |