diff options
Diffstat (limited to 'src/mongo/db/commands/fail_point_cmd.cpp')
-rw-r--r-- | src/mongo/db/commands/fail_point_cmd.cpp | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/mongo/db/commands/fail_point_cmd.cpp b/src/mongo/db/commands/fail_point_cmd.cpp new file mode 100644 index 00000000000..88616b39197 --- /dev/null +++ b/src/mongo/db/commands/fail_point_cmd.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2012 10gen Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "mongo/db/commands/fail_point_cmd.h" + +#include "mongo/db/commands.h" +#include "mongo/util/fail_point_service.h" + +namespace mongo { + /** + * Command for modifying installed fail points. + * + * Format + * { + * injectFault: <string>, // name of the fail point. + * mode: <string|Object>, // the new mode to set. Can have one of the + * following format: + * + * 1. 'off' - disable fail point. + * 2. 'alwaysOn' - fail point is always active. + * 3. { period: <n> } - n should be within the range of a 32 bit signed + * integer and this would be the approximate period for every activation. + * For example, for { period: 120 }, the probability of the fail point to + * be activated is 1 in 120. NOT YET SUPPORTED. + * 4. { times: <n> } - n should be positive and within the range of a 32 bit + * signed integer and this is the number of passes on the fail point will + * remain activated. + * + * data: <Object> // optional arbitrary object to store. + * } + */ + class FaultInjectCmd: public Command { + public: + FaultInjectCmd(): Command("configureFailPoint") {} + + virtual bool slaveOk() const { + return true; + } + + virtual LockType locktype() const { + return NONE; + } + + virtual bool adminOnly() const { + return true; + } + + virtual void help(stringstream& h) const { + h << "modifies the settings of a fail point"; + } + + bool run(const string& dbname, + BSONObj& cmdObj, + int, + string& errmsg, + BSONObjBuilder& result, + bool fromRepl) { + const string failPointName(cmdObj.firstElement().str()); + FailPointRegistry* registry = getGlobalFailPointRegistry(); + FailPoint* failPoint = registry->getFailPoint(failPointName); + + if (failPoint == NULL) { + errmsg = failPointName + " not found"; + return false; + } + + FailPoint::Mode mode = FailPoint::alwaysOn; + FailPoint::ValType val = 0; + + const BSONElement modeElem(cmdObj["mode"]); + if (modeElem.eoo()) { + result.appendElements(failPoint->toBSON()); + return true; + } + else if (modeElem.type() == String) { + const string modeStr(modeElem.valuestr()); + + if (modeStr == "off") { + mode = FailPoint::off; + } + else if (modeStr == "alwaysOn") { + mode = FailPoint::alwaysOn; + } + else { + errmsg = "unknown mode: " + modeStr; + return false; + } + } + else if (modeElem.type() == Object) { + const BSONObj modeObj(modeElem.Obj()); + + if (modeObj.hasField("times")) { + mode = FailPoint::nTimes; + const int intVal = modeObj["times"].numberInt(); + + if (intVal < 0) { + errmsg = "times should be positive"; + return false; + } + + val = intVal; + } + else if (modeObj.hasField("period")) { + mode = FailPoint::random; + + // TODO: implement + errmsg = "random is not yet supported"; + return false; + } + else { + errmsg = "invalid mode object"; + return false; + } + } + else { + errmsg = "invalid mode format"; + return false; + } + + BSONObj dataObj; + if (cmdObj.hasField("data")) { + dataObj = cmdObj["data"].Obj(); + } + + failPoint->setMode(mode, val, dataObj); + return true; + } + }; + + scoped_ptr<FaultInjectCmd> _faultInjectCmd(NULL); + + void enableFailPointCmd() { + _faultInjectCmd.reset(new FaultInjectCmd); + } +} |