summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/dur/journaling_options.js117
-rw-r--r--jstests/libs/config_files/enable_journal.json7
-rw-r--r--src/mongo/db/mongod_options.cpp98
-rw-r--r--src/mongo/db/mongod_options.h15
-rw-r--r--src/mongo/db/mongod_options_init.cpp8
-rw-r--r--src/mongo/util/options_parser/environment.cpp22
-rw-r--r--src/mongo/util/options_parser/environment.h6
7 files changed, 246 insertions, 27 deletions
diff --git a/jstests/dur/journaling_options.js b/jstests/dur/journaling_options.js
new file mode 100644
index 00000000000..1c62c2167b0
--- /dev/null
+++ b/jstests/dur/journaling_options.js
@@ -0,0 +1,117 @@
+var baseName = "jstests_dur_journaling_options";
+
+function removeOptionsAddedByFramework(getCmdLineOptsResult) {
+ // Remove options that we are not interested in checking, but that get set by the test
+ delete getCmdLineOptsResult.parsed.setParameter
+ delete getCmdLineOptsResult.parsed.storage.dbPath
+ delete getCmdLineOptsResult.parsed.net
+ delete getCmdLineOptsResult.parsed.fastsync
+ return getCmdLineOptsResult;
+}
+
+jsTest.log("Testing \"dur\" command line option");
+var mongodSource = MongoRunner.runMongod({ dur : "" });
+var getCmdLineOptsExpected = {
+ "parsed" : {
+ "storage" : {
+ "journal" : {
+ "enabled" : true
+ }
+ }
+ }
+};
+
+var getCmdLineOptsResult = mongodSource.adminCommand("getCmdLineOpts");
+printjson(getCmdLineOptsResult);
+getCmdLineOptsResult = removeOptionsAddedByFramework(getCmdLineOptsResult);
+assert.docEq(getCmdLineOptsResult.parsed, getCmdLineOptsExpected.parsed);
+MongoRunner.stopMongod(mongodSource.port);
+
+jsTest.log("Testing \"nodur\" command line option");
+mongodSource = MongoRunner.runMongod({ nodur : "" });
+getCmdLineOptsExpected = {
+ "parsed" : {
+ "storage" : {
+ "journal" : {
+ "enabled" : false
+ }
+ }
+ }
+};
+
+getCmdLineOptsResult = mongodSource.adminCommand("getCmdLineOpts");
+printjson(getCmdLineOptsResult);
+getCmdLineOptsResult = removeOptionsAddedByFramework(getCmdLineOptsResult);
+assert.docEq(getCmdLineOptsResult.parsed, getCmdLineOptsExpected.parsed);
+MongoRunner.stopMongod(mongodSource.port);
+
+jsTest.log("Testing \"journal\" command line option");
+mongodSource = MongoRunner.runMongod({ journal : "" });
+getCmdLineOptsExpected = {
+ "parsed" : {
+ "storage" : {
+ "journal" : {
+ "enabled" : true
+ }
+ }
+ }
+};
+
+getCmdLineOptsResult = mongodSource.adminCommand("getCmdLineOpts");
+printjson(getCmdLineOptsResult);
+getCmdLineOptsResult = removeOptionsAddedByFramework(getCmdLineOptsResult);
+assert.docEq(getCmdLineOptsResult.parsed, getCmdLineOptsExpected.parsed);
+MongoRunner.stopMongod(mongodSource.port);
+
+jsTest.log("Testing \"nojournal\" command line option");
+mongodSource = MongoRunner.runMongod({ nojournal : "" });
+getCmdLineOptsExpected = {
+ "parsed" : {
+ "storage" : {
+ "journal" : {
+ "enabled" : false
+ }
+ }
+ }
+};
+
+getCmdLineOptsResult = mongodSource.adminCommand("getCmdLineOpts");
+printjson(getCmdLineOptsResult);
+getCmdLineOptsResult = removeOptionsAddedByFramework(getCmdLineOptsResult);
+assert.docEq(getCmdLineOptsResult.parsed, getCmdLineOptsExpected.parsed);
+MongoRunner.stopMongod(mongodSource.port);
+
+jsTest.log("Testing \"storage.journal.enabled\" config file option");
+mongodSource = MongoRunner.runMongod({ config : "jstests/libs/config_files/enable_journal.json" });
+getCmdLineOptsExpected = {
+ "parsed" : {
+ "config" : "jstests/libs/config_files/enable_journal.json",
+ "storage" : {
+ "journal" : {
+ "enabled" : false
+ }
+ }
+ }
+};
+
+getCmdLineOptsResult = mongodSource.adminCommand("getCmdLineOpts");
+printjson(getCmdLineOptsResult);
+getCmdLineOptsResult = removeOptionsAddedByFramework(getCmdLineOptsResult);
+assert.docEq(getCmdLineOptsResult.parsed, getCmdLineOptsExpected.parsed);
+MongoRunner.stopMongod(mongodSource.port);
+
+jsTest.log("Testing with no explicit journal setting");
+mongodSource = MongoRunner.runMongod();
+getCmdLineOptsExpected = {
+ "parsed" : {
+ "storage" : { }
+ }
+};
+
+getCmdLineOptsResult = mongodSource.adminCommand("getCmdLineOpts");
+printjson(getCmdLineOptsResult);
+getCmdLineOptsResult = removeOptionsAddedByFramework(getCmdLineOptsResult);
+assert.docEq(getCmdLineOptsResult.parsed, getCmdLineOptsExpected.parsed);
+MongoRunner.stopMongod(mongodSource.port);
+
+print(baseName + " succeeded.");
diff --git a/jstests/libs/config_files/enable_journal.json b/jstests/libs/config_files/enable_journal.json
new file mode 100644
index 00000000000..d75b94ccbc7
--- /dev/null
+++ b/jstests/libs/config_files/enable_journal.json
@@ -0,0 +1,7 @@
+{
+ "storage" : {
+ "journal" : {
+ "enabled" : false
+ }
+ }
+}
diff --git a/src/mongo/db/mongod_options.cpp b/src/mongo/db/mongod_options.cpp
index d1a9c9cfeb4..7d06ab0b358 100644
--- a/src/mongo/db/mongod_options.cpp
+++ b/src/mongo/db/mongod_options.cpp
@@ -465,6 +465,71 @@ namespace mongo {
return true;
}
+ Status validateMongodOptions(const moe::Environment& params) {
+ if ((params.count("nodur") || params.count("nojournal")) &&
+ (params.count("dur") || params.count("journal"))) {
+ return Status(ErrorCodes::BadValue,
+ "Can't specify both --journal and --nojournal options.");
+ }
+
+ return Status::OK();
+ }
+
+ Status canonicalizeMongodOptions(moe::Environment* params) {
+
+ // "storage.journal.enabled" comes from the config file, so override it if any of "journal",
+ // "nojournal", "dur", and "nodur" are set, since those come from the command line.
+ if (params->count("nodur") || params->count("nojournal")) {
+ Status ret = params->set("storage.journal.enabled", moe::Value(false));
+ if (!ret.isOK()) {
+ return ret;
+ }
+ ret = params->remove("nodur");
+ if (!ret.isOK()) {
+ return ret;
+ }
+ ret = params->remove("nojournal");
+ if (!ret.isOK()) {
+ return ret;
+ }
+ }
+
+ if (params->count("dur") || params->count("journal")) {
+ Status ret = params->set("storage.journal.enabled", moe::Value(true));
+ if (!ret.isOK()) {
+ return ret;
+ }
+ ret = params->remove("dur");
+ if (!ret.isOK()) {
+ return ret;
+ }
+ ret = params->remove("journal");
+ if (!ret.isOK()) {
+ return ret;
+ }
+ }
+
+ // "storage.journal.durOptions" comes from the config file, so override it if "durOptions"
+ // is set since that comes from the command line.
+ if (params->count("durOptions")) {
+ int durOptions;
+ Status ret = params->get("durOptions", &durOptions);
+ if (!ret.isOK()) {
+ return ret;
+ }
+ ret = params->set("storage.journal.debugFlags", moe::Value(durOptions));
+ if (!ret.isOK()) {
+ return ret;
+ }
+ ret = params->remove("durOptions");
+ if (!ret.isOK()) {
+ return ret;
+ }
+ }
+
+ return Status::OK();
+ }
+
Status storeMongodOptions(const moe::Environment& params,
const std::vector<std::string>& args) {
@@ -547,29 +612,11 @@ namespace mongo {
storageGlobalParams.quota = true;
storageGlobalParams.quotaFiles = params["storage.quota.maxFilesPerDB"].as<int>() - 1;
}
- if ((params.count("nodur") || params.count("nojournal")) &&
- (params.count("dur") || params.count("journal"))) {
- return Status(ErrorCodes::BadValue,
- "Can't specify both --journal and --nojournal options.");
- }
- // "storage.journal.enabled" comes from the config file, so check it before we check
- // "journal", "nojournal", "dur", and "nodur", since those come from the command line.
if (params.count("storage.journal.enabled")) {
storageGlobalParams.dur = params["storage.journal.enabled"].as<bool>();
}
- if (params.count("nodur") || params.count("nojournal")) {
- storageGlobalParams.dur = false;
- }
-
- if (params.count("dur") || params.count("journal")) {
- storageGlobalParams.dur = true;
- }
-
- if (params.count("durOptions")) {
- storageGlobalParams.durOptions = params["durOptions"].as<int>();
- }
if (params.count("storage.journal.commitIntervalMs")) {
// don't check if dur is false here as many will just use the default, and will default
// to off on win32. ie no point making life a little more complex by giving an error on
@@ -677,9 +724,10 @@ namespace mongo {
_diaglog.setLevel(x);
}
- if ((params.count("dur") || params.count("journal")) && params.count("repair")) {
+ if ((params.count("storage.journal.enabled") &&
+ params["storage.journal.enabled"].as<bool>() == true) && params.count("repair")) {
return Status(ErrorCodes::BadValue,
- "Can't specify both --journal and --repair options.");
+ "Can't have journaling enabled when using --repair option.");
}
if (params.count("repair")) {
@@ -836,10 +884,9 @@ namespace mongo {
// If we haven't explicitly specified a journal option, default journaling to true for
// the config server role
- if (!params.count("nodur") &&
- !params.count("nojournal") &&
- !params.count("storage.journal.enabled"))
+ if (!params.count("storage.journal.enabled")) {
storageGlobalParams.dur = true;
+ }
if (!params.count("storage.dbPath"))
storageGlobalParams.dbpath = "/data/configdb";
@@ -917,10 +964,7 @@ namespace mongo {
log() << "--pretouch " << replSettings.pretouch << endl;
// Check if we are 32 bit and have not explicitly specified any journaling options
- if (sizeof(void*) == 4 &&
- !(params.count("nodur") || params.count("nojournal") ||
- params.count("dur") || params.count("journal") ||
- params.count("storage.journal.enabled"))) {
+ if (sizeof(void*) == 4 && !params.count("storage.journal.enabled")) {
// trying to make this stand out more like startup warnings
log() << endl;
warning() << "32-bit servers don't have journaling enabled by default. "
diff --git a/src/mongo/db/mongod_options.h b/src/mongo/db/mongod_options.h
index e7c9c4626fe..61112f54f3d 100644
--- a/src/mongo/db/mongod_options.h
+++ b/src/mongo/db/mongod_options.h
@@ -69,5 +69,20 @@ namespace mongo {
bool handlePreValidationMongodOptions(const moe::Environment& params,
const std::vector<std::string>& args);
+ /**
+ * Handle custom validation of mongod options that can not currently be done by using
+ * Constraints in the Environment. See the "validate" function in the Environment class for
+ * more details.
+ */
+ Status validateMongodOptions(const moe::Environment& params);
+
+ /**
+ * Canonicalize mongod options for the given environment.
+ *
+ * For example, the options "dur", "nodur", "journal", "nojournal", and
+ * "storage.journaling.enabled" should all be merged into "storage.journaling.enabled".
+ */
+ Status canonicalizeMongodOptions(moe::Environment* params);
+
Status storeMongodOptions(const moe::Environment& params, const std::vector<std::string>& args);
}
diff --git a/src/mongo/db/mongod_options_init.cpp b/src/mongo/db/mongod_options_init.cpp
index 1ecd743c83b..67bdabdd82b 100644
--- a/src/mongo/db/mongod_options_init.cpp
+++ b/src/mongo/db/mongod_options_init.cpp
@@ -44,6 +44,14 @@ namespace mongo {
if (!ret.isOK()) {
return ret;
}
+ ret = validateMongodOptions(moe::startupOptionsParsed);
+ if (!ret.isOK()) {
+ return ret;
+ }
+ ret = canonicalizeMongodOptions(&moe::startupOptionsParsed);
+ if (!ret.isOK()) {
+ return ret;
+ }
return Status::OK();
}
diff --git a/src/mongo/util/options_parser/environment.cpp b/src/mongo/util/options_parser/environment.cpp
index 9f50ae2797c..f7ace993f7e 100644
--- a/src/mongo/util/options_parser/environment.cpp
+++ b/src/mongo/util/options_parser/environment.cpp
@@ -81,6 +81,28 @@ namespace optionenvironment {
return Status::OK();
}
+ /** Removes a Value from our Environment */
+ Status Environment::remove(const Key& remove_key) {
+
+ // 1. Save old values
+ std::map <Key, Value> old_values = values;
+
+ // 2. Remove value to be removed
+ values.erase(remove_key);
+
+ // 3. Validate only if our environment is already valid
+ if (valid) {
+ Status ret = validate();
+ if (!ret.isOK()) {
+ // 4. Revert to old values if this was invalid
+ values = old_values;
+ return ret;
+ }
+ }
+
+ return Status::OK();
+ }
+
/** Set the default Value for the given Key in our Environment. Always disallow empty values */
Status Environment::setDefault(const Key& add_key, const Value& add_value) {
diff --git a/src/mongo/util/options_parser/environment.h b/src/mongo/util/options_parser/environment.h
index 7ba68919ed4..5f4cfa96ba5 100644
--- a/src/mongo/util/options_parser/environment.h
+++ b/src/mongo/util/options_parser/environment.h
@@ -118,6 +118,12 @@ namespace optionenvironment {
*/
Status set(const Key& key, const Value& value);
+ /** Remove the Value from this Environment with the given Key. If "validate" has
+ * already been called on this Environment, runs all Constraints on the new Environment.
+ * If any of the Constraints fail, reverts to the old Environment and returns an error
+ */
+ Status remove(const Key& key);
+
/** Add a default Value to this Environment with the given Key. Fails if validate has
* already been called on our environment. The get functions will return the default
* if one exists and the value has not been explicitly set.