diff options
-rw-r--r-- | src/mongo/base/error_codes.err | 1 | ||||
-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, 61 insertions, 32 deletions
diff --git a/src/mongo/base/error_codes.err b/src/mongo/base/error_codes.err index f3bdf3d2ded..b47292a25b7 100644 --- a/src/mongo/base/error_codes.err +++ b/src/mongo/base/error_codes.err @@ -259,6 +259,7 @@ error_code("UnknownFeatureCompatibilityVersion", 258); error_code("KeyedExecutorRetry", 259); error_code("InvalidResumeToken", 260); error_code("TooManyFilesOpen", 261); +error_code("FailPointSetFailed", 262) # 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 5a9742d3935..2fedf14deec 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" @@ -158,6 +159,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; @@ -271,6 +290,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) \ |