summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorShaun Verch <shaun.verch@10gen.com>2013-09-18 14:02:36 -0400
committerShaun Verch <shaun.verch@10gen.com>2013-10-04 16:58:54 -0400
commit6fc951d492881a32754bc3e38e8b5eca78929197 (patch)
tree73c2afe3120a8a87cf3bc8379e53461b2cf05b1e /src/mongo
parent99372153dfe9dd9251e49371d872b5f27dfd6f2c (diff)
downloadmongo-6fc951d492881a32754bc3e38e8b5eca78929197.tar.gz
SERVER-8510 Get rid of CmdLine struct and use new option handling style
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/SConscript34
-rw-r--r--src/mongo/client/clientAndShell.cpp4
-rw-r--r--src/mongo/client/dbclient_rs.cpp3
-rw-r--r--src/mongo/client/dbclient_rs_test.cpp1
-rw-r--r--src/mongo/client/dbclientcursor.cpp1
-rw-r--r--src/mongo/client/distlock.cpp2
-rw-r--r--src/mongo/client/examples/mongoperf.cpp4
-rw-r--r--src/mongo/client/scoped_db_conn_test.cpp1
-rw-r--r--src/mongo/db/auth/privilege_parser_test.cpp4
-rw-r--r--src/mongo/db/auth/security_key.cpp3
-rw-r--r--src/mongo/db/auth/user_management_commands_parser_test.cpp4
-rw-r--r--src/mongo/db/btree.cpp2
-rw-r--r--src/mongo/db/client.cpp4
-rw-r--r--src/mongo/db/client.h16
-rw-r--r--src/mongo/db/clientcursor.cpp4
-rw-r--r--src/mongo/db/cloner.cpp11
-rw-r--r--src/mongo/db/cmdline.cpp566
-rw-r--r--src/mongo/db/cmdline.h214
-rw-r--r--src/mongo/db/commands.cpp2
-rw-r--r--src/mongo/db/commands/authentication_commands.cpp6
-rw-r--r--src/mongo/db/commands/index_stats.cpp4
-rw-r--r--src/mongo/db/commands/isself.cpp11
-rw-r--r--src/mongo/db/commands/mr.cpp3
-rw-r--r--src/mongo/db/commands/parameters.cpp29
-rw-r--r--src/mongo/db/commands/pipeline_command.cpp3
-rw-r--r--src/mongo/db/commands/server_status.cpp5
-rw-r--r--src/mongo/db/commands/storage_details.cpp4
-rw-r--r--src/mongo/db/commands/write_commands/batch_executor.cpp5
-rw-r--r--src/mongo/db/curop.h2
-rw-r--r--src/mongo/db/curop_test.cpp2
-rw-r--r--src/mongo/db/database.cpp5
-rw-r--r--src/mongo/db/database.h7
-rw-r--r--src/mongo/db/database_holder.cpp4
-rw-r--r--src/mongo/db/db.cpp500
-rw-r--r--src/mongo/db/dbcommands.cpp21
-rw-r--r--src/mongo/db/dbcommands_admin.cpp7
-rw-r--r--src/mongo/db/dbcommands_generic.cpp7
-rw-r--r--src/mongo/db/dbeval.cpp5
-rw-r--r--src/mongo/db/dbhelpers.cpp5
-rw-r--r--src/mongo/db/dbmessage.h2
-rw-r--r--src/mongo/db/dbwebserver.cpp18
-rw-r--r--src/mongo/db/driverHelpers.cpp1
-rw-r--r--src/mongo/db/dur.cpp31
-rw-r--r--src/mongo/db/dur.h2
-rw-r--r--src/mongo/db/dur_commitjob.cpp2
-rw-r--r--src/mongo/db/dur_commitjob.h1
-rw-r--r--src/mongo/db/dur_journal.cpp16
-rw-r--r--src/mongo/db/dur_preplogbuffer.cpp3
-rw-r--r--src/mongo/db/dur_recover.cpp26
-rw-r--r--src/mongo/db/durop.cpp2
-rw-r--r--src/mongo/db/explain.cpp6
-rw-r--r--src/mongo/db/extsort.cpp7
-rw-r--r--src/mongo/db/index_rebuilder.cpp2
-rw-r--r--src/mongo/db/initialize_server_global_state.cpp55
-rw-r--r--src/mongo/db/initialize_server_global_state.h9
-rw-r--r--src/mongo/db/instance.cpp23
-rw-r--r--src/mongo/db/instance.h5
-rw-r--r--src/mongo/db/introspect.cpp7
-rw-r--r--src/mongo/db/log_process_details.cpp5
-rw-r--r--src/mongo/db/mongod_options.cpp444
-rw-r--r--src/mongo/db/mongod_options.h23
-rw-r--r--src/mongo/db/namespace_details.cpp2
-rw-r--r--src/mongo/db/namespace_details.h4
-rw-r--r--src/mongo/db/ops/query.cpp5
-rw-r--r--src/mongo/db/pdfile.cpp36
-rw-r--r--src/mongo/db/pipeline/document_source_cursor.cpp5
-rw-r--r--src/mongo/db/pipeline/document_source_merge_cursors.cpp1
-rw-r--r--src/mongo/db/query/new_find.cpp8
-rw-r--r--src/mongo/db/query_plan.cpp6
-rw-r--r--src/mongo/db/queryoptimizercursorimpl.cpp4
-rw-r--r--src/mongo/db/range_deleter_db_env.cpp3
-rw-r--r--src/mongo/db/repl/consensus.cpp3
-rw-r--r--src/mongo/db/repl/health.cpp5
-rw-r--r--src/mongo/db/repl/heartbeat.cpp5
-rw-r--r--src/mongo/db/repl/master_slave.cpp45
-rw-r--r--src/mongo/db/repl/oplog.cpp22
-rw-r--r--src/mongo/db/repl/repl_start.cpp5
-rw-r--r--src/mongo/db/repl/replication_server_status.cpp3
-rw-r--r--src/mongo/db/repl/replication_server_status.h21
-rw-r--r--src/mongo/db/repl/replset_commands.cpp1
-rw-r--r--src/mongo/db/repl/replset_web_handler.cpp6
-rw-r--r--src/mongo/db/repl/rs.cpp3
-rw-r--r--src/mongo/db/repl/rs.h2
-rw-r--r--src/mongo/db/repl/rs_config.cpp8
-rw-r--r--src/mongo/db/repl/rs_initiate.cpp8
-rw-r--r--src/mongo/db/repl/rs_sync.cpp3
-rw-r--r--src/mongo/db/restapi.cpp2
-rw-r--r--src/mongo/db/server_options.cpp273
-rw-r--r--src/mongo/db/server_options.h99
-rw-r--r--src/mongo/db/sorter/sorter.cpp18
-rw-r--r--src/mongo/db/sorter/sorter_test.cpp15
-rw-r--r--src/mongo/db/startup_warnings.cpp209
-rw-r--r--src/mongo/db/startup_warnings.h32
-rw-r--r--src/mongo/db/stats/snapshots.cpp2
-rw-r--r--src/mongo/db/storage/data_file.cpp14
-rw-r--r--src/mongo/db/storage/durable_mapped_file.cpp9
-rw-r--r--src/mongo/db/storage/extent_manager.cpp4
-rw-r--r--src/mongo/db/storage/namespace_index.cpp15
-rw-r--r--src/mongo/db/storage_options.cpp62
-rw-r--r--src/mongo/db/storage_options.h117
-rw-r--r--src/mongo/db/write_concern.cpp2
-rw-r--r--src/mongo/dbtests/documentsourcetests.cpp5
-rw-r--r--src/mongo/dbtests/framework.cpp32
-rw-r--r--src/mongo/dbtests/mmaptests.cpp15
-rw-r--r--src/mongo/dbtests/pdfiletests.cpp6
-rw-r--r--src/mongo/dbtests/perf/perftest.cpp2
-rw-r--r--src/mongo/dbtests/perftests.cpp10
-rw-r--r--src/mongo/dbtests/replsettests.cpp5
-rw-r--r--src/mongo/dbtests/repltests.cpp4
-rw-r--r--src/mongo/s/balance.cpp3
-rw-r--r--src/mongo/s/balancer_policy_tests.cpp2
-rw-r--r--src/mongo/s/commands_admin.cpp2
-rw-r--r--src/mongo/s/config.cpp3
-rw-r--r--src/mongo/s/config_server_tests.cpp1
-rw-r--r--src/mongo/s/d_migrate.cpp6
-rw-r--r--src/mongo/s/d_split.cpp2
-rw-r--r--src/mongo/s/grid.cpp5
-rw-r--r--src/mongo/s/mongos_options.cpp151
-rw-r--r--src/mongo/s/mongos_options.h21
-rw-r--r--src/mongo/s/mongos_persistence_stubs.cpp34
-rw-r--r--src/mongo/s/server.cpp177
-rw-r--r--src/mongo/s/shard_conn_test.cpp1
-rw-r--r--src/mongo/s/shard_test.cpp1
-rw-r--r--src/mongo/s/version_mongos.cpp63
-rw-r--r--src/mongo/s/version_mongos.h32
-rw-r--r--src/mongo/shell/dbshell.cpp13
-rw-r--r--src/mongo/tools/bridge.cpp4
-rw-r--r--src/mongo/tools/sniffer.cpp2
-rw-r--r--src/mongo/tools/tool.cpp12
-rw-r--r--src/mongo/util/assert_util.h6
-rw-r--r--src/mongo/util/cmdline_utils/SConscript10
-rw-r--r--src/mongo/util/cmdline_utils/censor_cmdline.cpp161
-rw-r--r--src/mongo/util/cmdline_utils/censor_cmdline.h49
-rw-r--r--src/mongo/util/cmdline_utils/censor_cmdline_test.cpp (renamed from src/mongo/db/cmdline_test.cpp)132
-rw-r--r--src/mongo/util/debug_util.cpp5
-rw-r--r--src/mongo/util/mmap.cpp1
-rw-r--r--src/mongo/util/net/hostandport.h16
-rw-r--r--src/mongo/util/net/listen.cpp7
-rw-r--r--src/mongo/util/net/message.h18
-rw-r--r--src/mongo/util/net/message_port.cpp1
-rw-r--r--src/mongo/util/net/message_port.h4
-rw-r--r--src/mongo/util/net/message_server_port.cpp3
-rw-r--r--src/mongo/util/net/sock.cpp8
-rw-r--r--src/mongo/util/net/sock_test.cpp4
-rw-r--r--src/mongo/util/net/ssl_options.cpp13
-rw-r--r--src/mongo/util/options_parser/environment.cpp144
-rw-r--r--src/mongo/util/options_parser/environment.h36
-rw-r--r--src/mongo/util/options_parser/environment_test.cpp55
-rw-r--r--src/mongo/util/options_parser/options_parser_test.cpp21
-rw-r--r--src/mongo/util/paths.h11
-rw-r--r--src/mongo/util/version.cpp156
151 files changed, 2665 insertions, 2102 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index 679a0a091ba..67ddee7fd4c 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -28,7 +28,8 @@ env.SConscript(['base/SConscript',
's/SConscript',
'unittest/SConscript',
'util/concurrency/SConscript',
- 'util/options_parser/SConscript'])
+ 'util/options_parser/SConscript',
+ 'util/cmdline_utils/SConscript'])
def add_exe( v ):
return "${PROGPREFIX}%s${PROGSUFFIX}" % v
@@ -371,6 +372,8 @@ env.StaticLibrary("coredb", [
'db/exec/working_set',
'$BUILD_DIR/mongo/foundation',
'$BUILD_DIR/third_party/shim_snappy',
+ 'server_options',
+ '$BUILD_DIR/mongo/util/cmdline_utils/cmdline_utils',
])
coreServerFiles = [ "db/client_basic.cpp",
@@ -542,6 +545,8 @@ serverOnlyFiles = [ "db/curop.cpp",
"db/compact.cpp",
"db/dbcommands_admin.cpp",
"db/write_concern.cpp",
+ "db/startup_warnings.cpp",
+ "db/storage_options.cpp",
# most commands are only for mongod
"db/commands/apply_ops.cpp",
@@ -563,16 +568,12 @@ serverOnlyFiles = [ "db/curop.cpp",
"db/pipeline/document_source_cursor.cpp",
"db/driverHelpers.cpp" ]
-env.Library("dbcmdline", ["db/cmdline.cpp", "db/server_options.cpp"],
+env.Library("server_options", ["db/server_options.cpp"],
LIBDEPS=['bson',
'server_parameters',
'$BUILD_DIR/mongo/util/options_parser/options_parser',
+ '$BUILD_DIR/mongo/util/cmdline_utils/cmdline_utils',
])
-env.CppUnitTest('cmdline_test', 'db/cmdline_test.cpp',
- LIBDEPS=['bson',
- 'dbcmdline',
- '$BUILD_DIR/mongo/util/options_parser/options_parser',
- ])
env.CppUnitTest('diskloc_test', 'db/diskloc_test.cpp', LIBDEPS=[])
@@ -609,6 +610,8 @@ mongosLibraryFiles = [
"s/balancer_policy.cpp",
"s/writeback_listener.cpp",
"s/version_manager.cpp",
+ "s/version_mongos.cpp",
+ "s/mongos_persistence_stubs.cpp",
]
env.Library( "mongoscore",
@@ -618,15 +621,19 @@ env.Library( "mongoscore",
] )
env.CppUnitTest( "balancer_policy_test" , [ "s/balancer_policy_tests.cpp" ] ,
- LIBDEPS=["mongoscore", "coreshard", "mongocommon","coreserver","coredb","dbcmdline","mongodandmongos"] ,
- NO_CRUTCH=True)
+ LIBDEPS=["mongoscore",
+ "coreshard",
+ "mongocommon",
+ "coreserver",
+ "coredb",
+ "mongodandmongos"],
+ NO_CRUTCH=True)
env.CppUnitTest("dbclient_rs_test", [ "client/dbclient_rs_test.cpp" ],
LIBDEPS=[
"coredb",
"coreserver",
"coreshard",
- "dbcmdline",
"mocklib",
"mongocommon",
"mongodandmongos",
@@ -638,7 +645,6 @@ env.CppUnitTest("scoped_db_conn_test", [ "client/scoped_db_conn_test.cpp" ],
"coredb",
"coreserver",
"coreshard",
- "dbcmdline",
"mongocommon",
"mongodandmongos",
"mongoscore"],
@@ -651,7 +657,6 @@ env.CppUnitTest("shard_conn_test", [ "s/shard_conn_test.cpp" ],
"mongocommon",
"coreserver",
"coredb",
- "dbcmdline",
"mongodandmongos",
"mocklib",
"$BUILD_DIR/mongo/db/auth/authmocks"],
@@ -663,7 +668,6 @@ env.CppUnitTest("shard_test", [ "s/shard_test.cpp" ],
"mongocommon",
"coreserver",
"coredb",
- "dbcmdline",
"mongodandmongos",
"mocklib"],
NO_CRUTCH=True)
@@ -674,7 +678,6 @@ env.CppUnitTest('config_server_tests', [ 's/config_server_tests.cpp' ],
"mongocommon",
"coreserver",
"coredb",
- "dbcmdline",
"mongodandmongos",
"mocklib"],
NO_CRUTCH=True)
@@ -735,7 +738,6 @@ env.StaticLibrary("serveronly", serverOnlyFiles,
"db/fts/ftsmongod",
"db/common",
"db/ops/update_driver",
- "dbcmdline",
"defaultversion",
"geoparser",
"geoquery",
@@ -820,7 +822,7 @@ env.Install( '#/', [
# mongos
mongos = env.Program(
"mongos", [ "s/server.cpp", "s/mongos_options.cpp" ] ,
- LIBDEPS=["mongoscore", "coreserver", "coredb", "mongocommon", "coreshard", "dbcmdline", "ntservice",
+ LIBDEPS=["mongoscore", "coreserver", "coredb", "mongocommon", "coreshard", "ntservice",
"mongodandmongos", "s/upgrade", "s/write_ops", "s/write_op_impl"])
env.Install( '#/', mongos )
diff --git a/src/mongo/client/clientAndShell.cpp b/src/mongo/client/clientAndShell.cpp
index a7dd940aa8e..34eec1bbeb0 100644
--- a/src/mongo/client/clientAndShell.cpp
+++ b/src/mongo/client/clientAndShell.cpp
@@ -19,14 +19,14 @@
#include "mongo/client/clientOnly-private.h"
#include "mongo/db/client_basic.h"
-#include "mongo/db/cmdline.h"
+#include "mongo/db/server_options.h"
#include "mongo/s/shard.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/timer.h"
namespace mongo {
- CmdLine cmdLine;
+ ServerGlobalParams serverGlobalParams;
const char * curNs = "in client mode";
diff --git a/src/mongo/client/dbclient_rs.cpp b/src/mongo/client/dbclient_rs.cpp
index 4c94696c829..69419586fae 100644
--- a/src/mongo/client/dbclient_rs.cpp
+++ b/src/mongo/client/dbclient_rs.cpp
@@ -451,7 +451,8 @@ namespace mongo {
: _lock( "ReplicaSetMonitor instance" ),
_checkConnectionLock( "ReplicaSetMonitor check connection lock" ),
_name( name ), _master(-1),
- _nextSlave(0), _failedChecks(0), _localThresholdMillis(cmdLine.defaultLocalThresholdMillis) {
+ _nextSlave(0), _failedChecks(0),
+ _localThresholdMillis(serverGlobalParams.defaultLocalThresholdMillis) {
uassert( 13642 , "need at least 1 node for a replica set" , servers.size() > 0 );
diff --git a/src/mongo/client/dbclient_rs_test.cpp b/src/mongo/client/dbclient_rs_test.cpp
index 9cef022a91d..a423211ba65 100644
--- a/src/mongo/client/dbclient_rs_test.cpp
+++ b/src/mongo/client/dbclient_rs_test.cpp
@@ -35,7 +35,6 @@
namespace mongo {
// Symbols defined to build the binary correctly.
- CmdLine cmdLine;
bool inShutdown() {
return false;
diff --git a/src/mongo/client/dbclientcursor.cpp b/src/mongo/client/dbclientcursor.cpp
index 1c9ba855ff1..f6dc5758579 100644
--- a/src/mongo/client/dbclientcursor.cpp
+++ b/src/mongo/client/dbclientcursor.cpp
@@ -20,7 +20,6 @@
#include "mongo/client/dbclientcursor.h"
#include "mongo/client/connpool.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/dbmessage.h"
#include "mongo/db/namespace_string.h"
#include "mongo/s/shard.h"
diff --git a/src/mongo/client/distlock.cpp b/src/mongo/client/distlock.cpp
index 6097733d5aa..56e8e296d06 100644
--- a/src/mongo/client/distlock.cpp
+++ b/src/mongo/client/distlock.cpp
@@ -50,7 +50,7 @@ namespace mongo {
// cache process string
stringstream ss;
- ss << getHostName() << ":" << cmdLine.port << ":" << time(0) << ":" << rand();
+ ss << getHostName() << ":" << serverGlobalParams.port << ":" << time(0) << ":" << rand();
_cachedProcessString = new string( ss.str() );
}
diff --git a/src/mongo/client/examples/mongoperf.cpp b/src/mongo/client/examples/mongoperf.cpp
index 8acfc40c21e..e535f187d59 100644
--- a/src/mongo/client/examples/mongoperf.cpp
+++ b/src/mongo/client/examples/mongoperf.cpp
@@ -33,7 +33,6 @@
#include <boost/thread/thread.hpp>
#include "mongo/bson/util/atomic_int.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
#include "mongo/util/logfile.h"
@@ -56,9 +55,6 @@ bo options;
unsigned long long len; // file len
const unsigned PG = 4096;
unsigned nThreadsRunning = 0;
-namespace mongo {
- CmdLine cmdLine;
-}
// as this is incremented A LOT, at some point this becomes a bottleneck if very high ops/second (in cache) things are happening.
AtomicUInt iops;
diff --git a/src/mongo/client/scoped_db_conn_test.cpp b/src/mongo/client/scoped_db_conn_test.cpp
index 749e3e52701..9c651bf374c 100644
--- a/src/mongo/client/scoped_db_conn_test.cpp
+++ b/src/mongo/client/scoped_db_conn_test.cpp
@@ -51,7 +51,6 @@ namespace {
namespace mongo {
// Symbols defined to build the binary correctly.
- CmdLine cmdLine;
bool inShutdown() {
scoped_lock sl(shutDownMutex);
diff --git a/src/mongo/db/auth/privilege_parser_test.cpp b/src/mongo/db/auth/privilege_parser_test.cpp
index 6f91f03cf66..1b0c67116ed 100644
--- a/src/mongo/db/auth/privilege_parser_test.cpp
+++ b/src/mongo/db/auth/privilege_parser_test.cpp
@@ -32,13 +32,13 @@
#include "mongo/db/auth/privilege.h"
#include "mongo/db/auth/privilege_parser.h"
-#include "mongo/db/cmdline.h"
+#include "mongo/db/server_options.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
// Crutches to make the test compile
- CmdLine cmdLine;
+ ServerGlobalParams serverGlobalParams;
bool inShutdown() {
return false;
}
diff --git a/src/mongo/db/auth/security_key.cpp b/src/mongo/db/auth/security_key.cpp
index 1ee9be06a99..e69696d6a6b 100644
--- a/src/mongo/db/auth/security_key.cpp
+++ b/src/mongo/db/auth/security_key.cpp
@@ -141,7 +141,8 @@ namespace mongo {
internalSecurity.user->getName().getUser().toString(), str);
internalSecurity.user->setCredentials(credentials);
- if (cmdLine.clusterAuthMode == "keyfile" || cmdLine.clusterAuthMode == "sendKeyfile") {
+ if (serverGlobalParams.clusterAuthMode == "keyfile" ||
+ serverGlobalParams.clusterAuthMode == "sendKeyfile") {
setInternalUserAuthParams(
BSON(saslCommandMechanismFieldName << "MONGODB-CR" <<
saslCommandUserSourceFieldName <<
diff --git a/src/mongo/db/auth/user_management_commands_parser_test.cpp b/src/mongo/db/auth/user_management_commands_parser_test.cpp
index d578bdbc9dc..84f516aef2c 100644
--- a/src/mongo/db/auth/user_management_commands_parser_test.cpp
+++ b/src/mongo/db/auth/user_management_commands_parser_test.cpp
@@ -23,15 +23,15 @@
#include "mongo/client/auth_helpers.h"
#include "mongo/db/auth/authz_manager_external_state_mock.h"
#include "mongo/db/auth/authorization_manager.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/auth/user_management_commands_parser.h"
#include "mongo/db/jsobj.h"
+#include "mongo/db/server_options.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
// Crutches to make the test compile
- CmdLine cmdLine;
+ ServerGlobalParams serverGlobalParams;
bool inShutdown() {
return false;
}
diff --git a/src/mongo/db/btree.cpp b/src/mongo/db/btree.cpp
index c0222bb2b86..e7a44a4e370 100644
--- a/src/mongo/db/btree.cpp
+++ b/src/mongo/db/btree.cpp
@@ -106,7 +106,7 @@ namespace mongo {
template< class V >
void BucketBasics<V>::assertWritable() {
- if( cmdLine.dur )
+ if (storageGlobalParams.dur)
dur::assertAlreadyDeclared(this, V::BucketSize);
}
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp
index 174f598b20a..b670267098c 100644
--- a/src/mongo/db/client.cpp
+++ b/src/mongo/db/client.cpp
@@ -56,6 +56,7 @@
#include "mongo/db/jsobj.h"
#include "mongo/db/pagefault.h"
#include "mongo/db/repl/rs.h"
+#include "mongo/db/storage_options.h"
#include "mongo/s/chunk_version.h"
#include "mongo/s/d_logic.h"
#include "mongo/s/stale_exception.h" // for SendStaleConfigException
@@ -252,7 +253,8 @@ namespace mongo {
Client::Context::Context(const std::string& ns , Database * db) :
_client( currentClient.get() ),
_oldContext( _client->_context ),
- _path( mongo::dbpath ), // is this right? could be a different db? may need a dassert for this
+ _path(storageGlobalParams.dbpath), // is this right? could be a different db?
+ // may need a dassert for this
_justCreated(false),
_doVersion( true ),
_ns( ns ),
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index a1541b22ccb..4bfa9a56fbd 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -43,6 +43,7 @@
#include "mongo/db/lasterror.h"
#include "mongo/db/lockstate.h"
#include "mongo/db/stats/top.h"
+#include "mongo/db/storage_options.h"
#include "mongo/util/concurrency/rwlock.h"
#include "mongo/util/concurrency/threadlocal.h"
#include "mongo/util/paths.h"
@@ -160,14 +161,12 @@ namespace mongo {
~GodScope();
};
- //static void assureDatabaseIsOpen(const string& ns, string path=dbpath);
-
/** "read lock, and set my context, all in one operation"
* This handles (if not recursively locked) opening an unopened database.
*/
class ReadContext : boost::noncopyable {
public:
- ReadContext(const std::string& ns, const std::string& path=dbpath);
+ ReadContext(const std::string& ns, const std::string& path=storageGlobalParams.dbpath);
Context& ctx() { return *c.get(); }
private:
scoped_ptr<Lock::DBRead> lk;
@@ -180,7 +179,8 @@ namespace mongo {
class Context : boost::noncopyable {
public:
/** this is probably what you want */
- Context(const string& ns, const std::string& path=dbpath, bool doVersion=true);
+ Context(const string& ns, const std::string& path=storageGlobalParams.dbpath,
+ bool doVersion=true);
/** note: this does not call finishInit -- i.e., does not call
shardVersionOk() for example.
@@ -195,13 +195,15 @@ namespace mongo {
Client* getClient() const { return _client; }
Database* db() const { return _db; }
const char * ns() const { return _ns.c_str(); }
- bool equals( const string& ns , const string& path=dbpath ) const { return _ns == ns && _path == path; }
+ bool equals(const string& ns, const string& path=storageGlobalParams.dbpath) const {
+ return _ns == ns && _path == path;
+ }
/** @return if the db was created by this Context */
bool justCreated() const { return _justCreated; }
/** @return true iff the current Context is using db/path */
- bool inDB( const string& db , const string& path=dbpath ) const;
+ bool inDB(const string& db, const string& path=storageGlobalParams.dbpath) const;
void _clear() { // this is sort of an "early destruct" indication, _ns can never be uncleared
const_cast<string&>(_ns).clear();
@@ -235,7 +237,7 @@ namespace mongo {
class WriteContext : boost::noncopyable {
public:
- WriteContext(const string& ns, const std::string& path=dbpath);
+ WriteContext(const string& ns, const std::string& path=storageGlobalParams.dbpath);
Context& ctx() { return _c; }
private:
Lock::DBWrite _lk;
diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp
index c8d1c10d890..c2768559ce9 100644
--- a/src/mongo/db/clientcursor.cpp
+++ b/src/mongo/db/clientcursor.cpp
@@ -942,7 +942,7 @@ namespace mongo {
static Mem mlast;
try {
ProcessInfo p;
- if ( !cmdLine.quiet && p.supported() ) {
+ if (!serverGlobalParams.quiet && p.supported()) {
Mem m;
m.res = p.getResidentSize();
m.virt = p.getVirtualMemorySize();
@@ -951,7 +951,7 @@ namespace mongo {
if( now - last >= 300 || m.grew(mlast) ) {
log() << "mem (MB) res:" << m.res << " virt:" << m.virt;
long long totalMapped = m.mapped;
- if (cmdLine.dur) {
+ if (storageGlobalParams.dur) {
totalMapped *= 2;
log() << " mapped (incl journal view):" << totalMapped;
}
diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp
index 4b70b21e082..8fa8fbc2f6a 100644
--- a/src/mongo/db/cloner.cpp
+++ b/src/mongo/db/cloner.cpp
@@ -46,6 +46,7 @@
#include "mongo/db/repl/oplog.h"
#include "mongo/db/repl/oplogreader.h"
#include "mongo/db/pdfile.h"
+#include "mongo/db/storage_options.h"
namespace mongo {
@@ -336,11 +337,11 @@ namespace mongo {
string todb = cc().database()->name();
stringstream a,b;
- a << "localhost:" << cmdLine.port;
- b << "127.0.0.1:" << cmdLine.port;
+ a << "localhost:" << serverGlobalParams.port;
+ b << "127.0.0.1:" << serverGlobalParams.port;
bool masterSameProcess = ( a.str() == masterHost || b.str() == masterHost );
if ( masterSameProcess ) {
- if ( opts.fromDB == todb && cc().database()->path() == dbpath ) {
+ if (opts.fromDB == todb && cc().database()->path() == storageGlobalParams.dbpath) {
// guard against an "infinite" loop
/* if you are replicating, the local.sources config may be wrong if you get this */
errmsg = "can't clone from self (localhost).";
@@ -688,7 +689,7 @@ namespace mongo {
if ( fromhost.empty() ) {
/* copy from self */
stringstream ss;
- ss << "localhost:" << cmdLine.port;
+ ss << "localhost:" << serverGlobalParams.port;
fromhost = ss.str();
}
authConn_.reset( new DBClientConnection() );
@@ -744,7 +745,7 @@ namespace mongo {
if ( fromSelf ) {
/* copy from self */
stringstream ss;
- ss << "localhost:" << cmdLine.port;
+ ss << "localhost:" << serverGlobalParams.port;
fromhost = ss.str();
}
string fromdb = cmdObj.getStringField("fromdb");
diff --git a/src/mongo/db/cmdline.cpp b/src/mongo/db/cmdline.cpp
deleted file mode 100644
index 66e2212cdf5..00000000000
--- a/src/mongo/db/cmdline.cpp
+++ /dev/null
@@ -1,566 +0,0 @@
-// cmdline.cpp
-
-/**
-* Copyright (C) 2008 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/>.
-*
-* As a special exception, the copyright holders give permission to link the
-* code of portions of this program with the OpenSSL library under certain
-* conditions as described in each individual source file and distribute
-* linked combinations including the program with the OpenSSL library. You
-* must comply with the GNU Affero General Public License in all respects for
-* all of the code used other than as permitted herein. If you modify file(s)
-* with this exception, you may extend this exception to your version of the
-* file(s), but you are not obligated to do so. If you do not wish to do so,
-* delete this exception statement from your version. If you delete this
-* exception statement from all source files in the program, then also delete
-* it in the license file.
-*/
-
-#include <boost/algorithm/string.hpp>
-#include <boost/filesystem.hpp>
-
-#include "mongo/pch.h"
-
-#include "mongo/db/cmdline.h"
-
-#include "mongo/base/status.h"
-#include "mongo/bson/util/builder.h"
-#include "mongo/db/server_parameters.h"
-#include "mongo/logger/message_event_utf8_encoder.h"
-#include "mongo/util/map_util.h"
-#include "mongo/util/mongoutils/str.h"
-#include "mongo/util/net/listen.h"
-#include "mongo/util/net/ssl_options.h"
-#include "mongo/util/options_parser/environment.h"
-#include "mongo/util/options_parser/option_section.h"
-#include "mongo/util/options_parser/options_parser.h"
-#include "mongo/util/password.h"
-
-#ifdef _WIN32
-#include <direct.h>
-#endif
-
-#define MAX_LINE_LENGTH 256
-
-#include <fstream>
-
-namespace mongo {
-
- namespace moe = mongo::optionenvironment;
-
-#ifdef _WIN32
- string dbpath = "\\data\\db\\";
-#else
- string dbpath = "/data/db/";
-#endif
-
- static bool _isPasswordArgument(char const* argumentName);
- static bool _isPasswordSwitch(char const* switchName);
-
-namespace {
- BSONArray argvArray;
- BSONObj parsedOpts;
-} // namespace
-
- BSONArray CmdLine::getArgvArray() {
- return argvArray;
- }
-
- BSONObj CmdLine::getParsedOpts() {
- return parsedOpts;
- }
-
- Status CmdLine::setupBinaryName(const std::vector<std::string>& argv) {
-
- if (argv.empty()) {
- return Status(ErrorCodes::InternalError, "Cannot get binary name: argv array is empty");
- }
-
- // setup binary name
- cmdLine.binaryName = argv[0];
- size_t i = cmdLine.binaryName.rfind( '/' );
- if ( i != string::npos ) {
- cmdLine.binaryName = cmdLine.binaryName.substr( i + 1 );
- }
- return Status::OK();
- }
-
- Status CmdLine::setupCwd() {
- // setup cwd
- char buffer[1024];
-#ifdef _WIN32
- verify( _getcwd( buffer , 1000 ) );
-#else
- verify( getcwd( buffer , 1000 ) );
-#endif
- cmdLine.cwd = buffer;
- return Status::OK();
- }
-
- Status CmdLine::setArgvArray(const std::vector<std::string>& argv) {
- BSONArrayBuilder b;
- std::vector<std::string> censoredArgv = argv;
- censor(&censoredArgv);
- for (size_t i=0; i < censoredArgv.size(); i++) {
- b << censoredArgv[i];
- }
- argvArray = b.arr();
- return Status::OK();
- }
-
-namespace {
-
- // Converts a map of values with dotted key names to a BSONObj with sub objects.
- // 1. Check for dotted field names and call valueMapToBSON recursively.
- // 2. Append the actual value to our builder if we did not find a dot in our key name.
- Status valueMapToBSON(const std::map<moe::Key, moe::Value>& params,
- BSONObjBuilder* builder,
- const std::string& prefix = std::string()) {
- for (std::map<moe::Key, moe::Value>::const_iterator it(params.begin());
- it != params.end(); it++) {
- moe::Key key = it->first;
- moe::Value value = it->second;
-
- // 1. Check for dotted field names and call valueMapToBSON recursively.
- // NOTE: this code depends on the fact that std::map is sorted
- //
- // EXAMPLE:
- // The map:
- // {
- // "var1.dotted1" : false,
- // "var2" : true,
- // "var1.dotted2" : 6
- // }
- //
- // Gets sorted by keys as:
- // {
- // "var1.dotted1" : false,
- // "var1.dotted2" : 6,
- // "var2" : true
- // }
- //
- // Which means when we see the "var1" prefix, we can iterate until we see either a name
- // without a dot or without "var1" as a prefix, aggregating its fields in a new map as
- // we go. Because the map is sorted, once we see a name without a dot or a "var1"
- // prefix we know that we've seen everything with "var1" as a prefix and can recursively
- // build the entire sub object at once using our new map (which is the only way to make
- // a single coherent BSON sub object using this append only builder).
- //
- // The result of this function for this example should be a BSON object of the form:
- // {
- // "var1" : {
- // "dotted1" : false,
- // "dotted2" : 6
- // },
- // "var2" : true
- // }
-
- // Check to see if this key name is dotted
- std::string::size_type dotOffset = key.find('.');
- if (dotOffset != string::npos) {
-
- // Get the name of the "section" that we are currently iterating. This will be
- // the name of our sub object.
- std::string sectionName = key.substr(0, dotOffset);
-
- // Build a map of the "section" that we are iterating to be passed in a
- // recursive call.
- std::map<moe::Key, moe::Value> sectionMap;
-
- std::string beforeDot = key.substr(0, dotOffset);
- std::string afterDot = key.substr(dotOffset + 1, key.size() - dotOffset - 1);
- std::map<moe::Key, moe::Value>::const_iterator it_next = it;
-
- do {
- // Here we know that the key at it_next has a dot and has the prefix we are
- // currently creating a sub object for. Since that means we will definitely
- // process that element in this loop, advance the outer for loop iterator here.
- it = it_next;
-
- // Add the value to our section map with a key of whatever is after the dot
- // since the section name itself will be part of our sub object builder.
- sectionMap[afterDot] = value;
-
- // Peek at the next value for our iterator and check to see if we've finished.
- if (++it_next == params.end()) {
- break;
- }
- key = it_next->first;
- value = it_next->second;
-
- // Look for a dot for our next iteration.
- dotOffset = key.find('.');
-
- beforeDot = key.substr(0, dotOffset);
- afterDot = key.substr(dotOffset + 1, key.size() - dotOffset - 1);
- }
- while (dotOffset != string::npos && beforeDot == sectionName);
-
- // Use the section name in our object builder, and recursively call
- // valueMapToBSON with our sub map with keys that have the section name removed.
- BSONObjBuilder sectionObjBuilder(builder->subobjStart(sectionName));
- valueMapToBSON(sectionMap, &sectionObjBuilder, sectionName);
- sectionObjBuilder.done();
-
- // Our iterator is currently on the last field that matched our dot and prefix, so
- // continue to the next loop iteration.
- continue;
- }
-
- // 2. Append the actual value to our builder if we did not find a dot in our key name.
- const type_info& type = value.type();
-
- if (type == typeid(string)){
- if (value.as<string>().empty()) {
- // boost po uses empty string for flags like --quiet
- // TODO: Remove this when we remove boost::program_options
- builder->appendBool(key, true);
- }
- else {
- if ( _isPasswordArgument(key.c_str()) ) {
- builder->append( key, "<password>" );
- }
- else {
- builder->append( key, value.as<string>() );
- }
- }
- }
- else if (type == typeid(int))
- builder->append(key, value.as<int>());
- else if (type == typeid(double))
- builder->append(key, value.as<double>());
- else if (type == typeid(bool))
- builder->appendBool(key, value.as<bool>());
- else if (type == typeid(long))
- builder->appendNumber(key, (long long)value.as<long>());
- else if (type == typeid(unsigned))
- builder->appendNumber(key, (long long)value.as<unsigned>());
- else if (type == typeid(unsigned long long))
- builder->appendNumber(key, (long long)value.as<unsigned long long>());
- else if (type == typeid(vector<string>))
- builder->append(key, value.as<vector<string> >());
- else
- builder->append(key, "UNKNOWN TYPE: " + demangleName(type));
- }
- return Status::OK();
- }
-} // namespace
-
- Status CmdLine::setParsedOpts(moe::Environment& params) {
- const std::map<moe::Key, moe::Value> paramsMap = params.getExplicitlySet();
- BSONObjBuilder builder;
- Status ret = valueMapToBSON(paramsMap, &builder);
- if (!ret.isOK()) {
- return ret;
- }
- parsedOpts = builder.obj();
- return Status::OK();
- }
-
- Status CmdLine::store( const std::vector<std::string>& argv,
- moe::OptionSection& options,
- moe::Environment& params ) {
-
- Status ret = CmdLine::setupBinaryName(argv);
- if (!ret.isOK()) {
- return ret;
- }
-
- ret = CmdLine::setupCwd();
- if (!ret.isOK()) {
- return ret;
- }
-
- moe::OptionsParser parser;
-
- // XXX: env is not used in the parser at this point, so just leave it empty
- std::map<std::string, std::string> env;
-
- ret = parser.run(options, argv, env, &params);
- if (!ret.isOK()) {
- std::cerr << "Error parsing command line: " << ret.toString() << std::endl;
- std::cerr << "use --help for help" << std::endl;
- return ret;
- }
-
- ret = CmdLine::setArgvArray(argv);
- if (!ret.isOK()) {
- return ret;
- }
-
- ret = CmdLine::setParsedOpts(params);
- if (!ret.isOK()) {
- return ret;
- }
-
- if (params.count("verbose")) {
- logger::globalLogDomain()->setMinimumLoggedSeverity(logger::LogSeverity::Debug(1));
- }
-
- for (string s = "vv"; s.length() <= 12; s.append("v")) {
- if (params.count(s)) {
- logger::globalLogDomain()->setMinimumLoggedSeverity(
- logger::LogSeverity::Debug(s.length()));
- }
- }
-
- if (params.count("enableExperimentalIndexStatsCmd")) {
- cmdLine.experimental.indexStatsCmdEnabled = true;
- }
- if (params.count("enableExperimentalStorageDetailsCmd")) {
- cmdLine.experimental.storageDetailsCmdEnabled = true;
- }
-
- if (params.count("port")) {
- cmdLine.port = params["port"].as<int>();
- }
-
- if (params.count("bind_ip")) {
- cmdLine.bind_ip = params["bind_ip"].as<std::string>();
- }
-
- if (params.count("clusterAuthMode")) {
- cmdLine.clusterAuthMode = params["clusterAuthMode"].as<std::string>();
- }
-
- if (params.count("quiet")) {
- cmdLine.quiet = true;
- }
-
- if (params.count("traceExceptions")) {
- DBException::traceExceptions = true;
- }
-
- if (params.count("maxConns")) {
- cmdLine.maxConns = params["maxConns"].as<int>();
-
- if ( cmdLine.maxConns < 5 ) {
- return Status(ErrorCodes::BadValue, "maxConns has to be at least 5");
- }
- }
-
- if (params.count("objcheck")) {
- cmdLine.objcheck = true;
- }
- if (params.count("noobjcheck")) {
- if (params.count("objcheck")) {
- return Status(ErrorCodes::BadValue, "can't have both --objcheck and --noobjcheck");
- }
- cmdLine.objcheck = false;
- }
-
- if (params.count("bind_ip")) {
- // passing in wildcard is the same as default behavior; remove and warn
- if ( cmdLine.bind_ip == "0.0.0.0" ) {
- cout << "warning: bind_ip of 0.0.0.0 is unnecessary; listens on all ips by default" << endl;
- cmdLine.bind_ip = "";
- }
- }
-
-#ifndef _WIN32
- if (params.count("unixSocketPrefix")) {
- cmdLine.socket = params["unixSocketPrefix"].as<string>();
- }
-
- if (params.count("nounixsocket")) {
- cmdLine.noUnixSocket = true;
- }
-
- if (params.count("fork") && !params.count("shutdown")) {
- cmdLine.doFork = true;
- }
-#endif // _WIN32
-
- if (params.count("logTimestampFormat")) {
- using logger::MessageEventDetailsEncoder;
- std::string formatterName = params["logTimestampFormat"].as<string>();
- if (formatterName == "ctime") {
- MessageEventDetailsEncoder::setDateFormatter(dateToCtimeString);
- }
- else if (formatterName == "iso8601-utc") {
- MessageEventDetailsEncoder::setDateFormatter(dateToISOStringUTC);
- }
- else if (formatterName == "iso8601-local") {
- MessageEventDetailsEncoder::setDateFormatter(dateToISOStringLocal);
- }
- else {
- StringBuilder sb;
- sb << "Value of logTimestampFormat must be one of ctime, iso8601-utc " <<
- "or iso8601-local; not \"" << formatterName << "\".";
- return Status(ErrorCodes::BadValue, sb.str());
- }
- }
- if (params.count("logpath")) {
- cmdLine.logpath = params["logpath"].as<string>();
- if (cmdLine.logpath.empty()) {
- return Status(ErrorCodes::BadValue, "logpath cannot be empty if supplied");
- }
- }
-
- cmdLine.logWithSyslog = params.count("syslog");
- cmdLine.logAppend = params.count("logappend");
- if (!cmdLine.logpath.empty() && cmdLine.logWithSyslog) {
- return Status(ErrorCodes::BadValue, "Cant use both a logpath and syslog ");
- }
-
- if (cmdLine.doFork && cmdLine.logpath.empty() && !cmdLine.logWithSyslog) {
- return Status(ErrorCodes::BadValue, "--fork has to be used with --logpath or --syslog");
- }
-
- if (params.count("keyFile")) {
- cmdLine.keyFile = params["keyFile"].as<string>();
- }
-
- if ( params.count("pidfilepath")) {
- cmdLine.pidFile = params["pidfilepath"].as<string>();
- }
-
- if (params.count("setParameter")) {
- std::vector<std::string> parameters =
- params["setParameter"].as<std::vector<std::string> >();
- for (size_t i = 0, length = parameters.size(); i < length; ++i) {
- std::string name;
- std::string value;
- if (!mongoutils::str::splitOn(parameters[i], '=', name, value)) {
- StringBuilder sb;
- sb << "Illegal option assignment: \"" << parameters[i] << "\"";
- return Status(ErrorCodes::BadValue, sb.str());
- }
- ServerParameter* parameter = mapFindWithDefault(
- ServerParameterSet::getGlobal()->getMap(),
- name,
- static_cast<ServerParameter*>(NULL));
- if (NULL == parameter) {
- StringBuilder sb;
- sb << "Illegal --setParameter parameter: \"" << name << "\"";
- return Status(ErrorCodes::BadValue, sb.str());
- }
- if (!parameter->allowedToChangeAtStartup()) {
- StringBuilder sb;
- sb << "Cannot use --setParameter to set \"" << name << "\" at startup";
- return Status(ErrorCodes::BadValue, sb.str());
- }
- Status status = parameter->setFromString(value);
- if (!status.isOK()) {
- StringBuilder sb;
- sb << "Bad value for parameter \"" << name << "\": " << status.reason();
- return Status(ErrorCodes::BadValue, sb.str());
- }
- }
- }
- if (!params.count("clusterAuthMode") && params.count("keyFile")){
- cmdLine.clusterAuthMode = "keyfile";
- }
-
-#ifdef MONGO_SSL
- ret = storeSSLServerOptions(params);
- if (!ret.isOK()) {
- return ret;
- }
-#else // ifdef MONGO_SSL
- // Keyfile is currently the only supported value if not using SSL
- if (params.count("clusterAuthMode") && cmdLine.clusterAuthMode != "keyfile") {
- StringBuilder sb;
- sb << "unsupported value for clusterAuthMode " << cmdLine.clusterAuthMode;
- return Status(ErrorCodes::BadValue, sb.str());
- }
-#endif
-
- return Status::OK();
- }
-
- static bool _isPasswordArgument(const char* argumentName) {
- static const char* const passwordArguments[] = {
- "sslPEMKeyPassword",
- "ssl.PEMKeyPassword",
- "servicePassword",
- NULL // Last entry sentinel.
- };
- for (const char* const* current = passwordArguments; *current; ++current) {
- if (mongoutils::str::equals(argumentName, *current))
- return true;
- }
- return false;
- }
-
- static bool _isPasswordSwitch(const char* switchName) {
- if (switchName[0] != '-')
- return false;
- size_t i = 1;
- if (switchName[1] == '-')
- i = 2;
- switchName += i;
-
- return _isPasswordArgument(switchName);
- }
-
- static void _redact(char* arg) {
- for (; *arg; ++arg)
- *arg = 'x';
- }
-
- void CmdLine::censor(std::vector<std::string>* args) {
- for (size_t i = 0; i < args->size(); ++i) {
- std::string& arg = args->at(i);
- const std::string::iterator endSwitch = std::find(arg.begin(), arg.end(), '=');
- std::string switchName(arg.begin(), endSwitch);
- if (_isPasswordSwitch(switchName.c_str())) {
- if (endSwitch == arg.end()) {
- if (i + 1 < args->size()) {
- args->at(i + 1) = "<password>";
- }
- }
- else {
- arg = switchName + "=<password>";
- }
- }
- }
- }
-
- void CmdLine::censor(int argc, char** argv) {
- // Algorithm: For each arg in argv:
- // Look for an equal sign in arg; if there is one, temporarily nul it out.
- // check to see if arg is a password switch. If so, overwrite the value
- // component with xs.
- // restore the nul'd out equal sign, if any.
- for (int i = 0; i < argc; ++i) {
-
- char* const arg = argv[i];
- char* const firstEqSign = strchr(arg, '=');
- if (NULL != firstEqSign) {
- *firstEqSign = '\0';
- }
-
- if (_isPasswordSwitch(arg)) {
- if (NULL == firstEqSign) {
- if (i + 1 < argc) {
- _redact(argv[i + 1]);
- }
- }
- else {
- _redact(firstEqSign + 1);
- }
- }
-
- if (NULL != firstEqSign) {
- *firstEqSign = '=';
- }
- }
- }
-
- void printCommandLineOpts() {
- log() << "options: " << parsedOpts << endl;
- }
-}
diff --git a/src/mongo/db/cmdline.h b/src/mongo/db/cmdline.h
deleted file mode 100644
index e6a2d1f78ba..00000000000
--- a/src/mongo/db/cmdline.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
-* Copyright (C) 2008 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/>.
-*
-* As a special exception, the copyright holders give permission to link the
-* code of portions of this program with the OpenSSL library under certain
-* conditions as described in each individual source file and distribute
-* linked combinations including the program with the OpenSSL library. You
-* must comply with the GNU Affero General Public License in all respects for
-* all of the code used other than as permitted herein. If you modify file(s)
-* with this exception, you may extend this exception to your version of the
-* file(s), but you are not obligated to do so. If you do not wish to do so,
-* delete this exception statement from your version. If you delete this
-* exception statement from all source files in the program, then also delete
-* it in the license file.
-*/
-
-#pragma once
-
-#include <string>
-#include <vector>
-
-#include "mongo/base/status.h"
-#include "mongo/db/jsobj.h"
-#include "mongo/platform/process_id.h"
-#include "mongo/util/net/listen.h"
-
-namespace mongo {
-
- namespace optionenvironment {
- class OptionSection;
- class Environment;
- } // namespace optionenvironment
-
- /* command line options
- */
- /* concurrency: OK/READ */
- struct CmdLine {
-
- CmdLine();
-
- std::string binaryName; // mongod or mongos
- std::string cwd; // cwd of when process started
-
- // this is suboptimal as someone could rename a binary. todo...
- bool isMongos() const { return binaryName == "mongos"; }
-
- int port; // --port
- enum {
- DefaultDBPort = 27017,
- ConfigServerPort = 27019,
- ShardServerPort = 27018
- };
- bool isDefaultPort() const { return port == DefaultDBPort; }
-
- std::string bind_ip; // --bind_ip
- bool rest; // --rest
- bool jsonp; // --jsonp
-
- std::string _replSet; // --replSet[/<seedlist>]
- std::string ourSetName() const {
- std::string setname;
- size_t sl = _replSet.find('/');
- if( sl == std::string::npos )
- return _replSet;
- return _replSet.substr(0, sl);
- }
- bool usingReplSets() const { return !_replSet.empty(); }
-
- std::string rsIndexPrefetch;// --indexPrefetch
- bool indexBuildRetry; // --noIndexBuildRetry
-
- // for master/slave replication
- std::string source; // --source
- std::string only; // --only
-
- bool quiet; // --quiet
- bool noTableScan; // --notablescan no table scans allowed
- bool prealloc; // --noprealloc no preallocation of data files
- bool preallocj; // --nopreallocj no preallocation of journal files
- bool smallfiles; // --smallfiles allocate smaller data files
-
- bool configsvr; // --configsvr
-
- bool quota; // --quota
- int quotaFiles; // --quotaFiles
- bool cpu; // --cpu show cpu time periodically
-
- bool dur; // --dur durability (now --journal)
- unsigned journalCommitInterval; // group/batch commit interval ms
-
- /** --durOptions 7 dump journal and terminate without doing anything further
- --durOptions 4 recover and terminate without listening
- */
- enum { // bits to be ORed
- DurDumpJournal = 1, // dump diagnostics on the journal during recovery
- DurScanOnly = 2, // don't do any real work, just scan and dump if dump specified
- DurRecoverOnly = 4, // terminate after recovery step
- DurParanoid = 8, // paranoid mode enables extra checks
- DurAlwaysCommit = 16, // do a group commit every time the writelock is released
- DurAlwaysRemap = 32, // remap the private view after every group commit (may lag to the next write lock acquisition, but will do all files then)
- DurNoCheckSpace = 64 // don't check that there is enough room for journal files before startup (for diskfull tests)
- };
- int durOptions; // --durOptions <n> for debugging
-
- bool objcheck; // --objcheck
-
- long long oplogSize; // --oplogSize
- int defaultProfile; // --profile
- int slowMS; // --time in ms that is "slow"
- int defaultLocalThresholdMillis; // --localThreshold in ms to consider a node local
- int pretouch; // --pretouch for replication application (experimental)
- bool moveParanoia; // for move chunk paranoia
- double syncdelay; // seconds between fsyncs
-
- bool noUnixSocket; // --nounixsocket
- bool doFork; // --fork
- std::string socket; // UNIX domain socket directory
-
- int maxConns; // Maximum number of simultaneous open connections.
-
- std::string keyFile; // Path to keyfile, or empty if none.
- std::string pidFile; // Path to pid file, or empty if none.
-
- std::string logpath; // Path to log file, if logging to a file; otherwise, empty.
- bool logAppend; // True if logging to a file in append mode.
- bool logWithSyslog; // True if logging to syslog; must not be set if logpath is set.
- std::string clusterAuthMode; // Cluster authentication mode
-
- bool isHttpInterfaceEnabled; // True if the dbwebserver should be enabled.
-
-#ifndef _WIN32
- ProcessId parentProc; // --fork pid of initial process
- ProcessId leaderProc; // --fork pid of leader process
-#endif
-
- /**
- * Switches to enable experimental (unsupported) features.
- */
- struct ExperimentalFeatures {
- ExperimentalFeatures()
- : indexStatsCmdEnabled(false)
- , storageDetailsCmdEnabled(false)
- {}
- bool indexStatsCmdEnabled; // -- enableExperimentalIndexStatsCmd
- bool storageDetailsCmdEnabled; // -- enableExperimentalStorageDetailsCmd
- } experimental;
-
- static void launchOk();
-
- /**
- * @return true if should run program, false if should exit
- */
- static Status store( const std::vector<std::string>& argv,
- optionenvironment::OptionSection& options,
- optionenvironment::Environment& output );
-
- /**
- * Blot out sensitive fields in the argv array.
- */
- static void censor(int argc, char** argv);
- static void censor(std::vector<std::string>* args);
-
- static BSONArray getArgvArray();
- static BSONObj getParsedOpts();
-
- static Status setupBinaryName(const std::vector<std::string>& argv);
- static Status setupCwd();
- static Status setArgvArray(const std::vector<std::string>& argv);
- static Status setParsedOpts(optionenvironment::Environment& params);
-
- time_t started;
- };
-
- // todo move to cmdline.cpp?
- inline CmdLine::CmdLine() :
- port(DefaultDBPort), rest(false), jsonp(false), indexBuildRetry(true), quiet(false),
- noTableScan(false), prealloc(true), preallocj(true), smallfiles(sizeof(int*) == 4),
- configsvr(false), quota(false), quotaFiles(8), cpu(false),
- durOptions(0), objcheck(true), oplogSize(0), defaultProfile(0),
- slowMS(100), defaultLocalThresholdMillis(15), pretouch(0), moveParanoia( true ),
- syncdelay(60), noUnixSocket(false), doFork(0), socket("/tmp"), maxConns(DEFAULT_MAX_CONN),
- logAppend(false), logWithSyslog(false), isHttpInterfaceEnabled(false)
- {
- started = time(0);
-
- journalCommitInterval = 0; // 0 means use default
- dur = false;
-#if defined(_DURABLEDEFAULTON)
- dur = true;
-#endif
- if( sizeof(void*) == 8 )
- dur = true;
-#if defined(_DURABLEDEFAULTOFF)
- dur = false;
-#endif
- }
-
- extern CmdLine cmdLine;
-
- void printCommandLineOpts();
-}
-
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index 23288bab1ae..0e31f0b8851 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -242,7 +242,7 @@ namespace mongo {
void Command::logIfSlow( const Timer& timer, const string& msg ) {
int ms = timer.millis();
- if ( ms > cmdLine.slowMS ) {
+ if (ms > serverGlobalParams.slowMS) {
out() << msg << " took " << ms << " ms." << endl;
}
}
diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp
index 0d1e481ba03..0fba00753c3 100644
--- a/src/mongo/db/commands/authentication_commands.cpp
+++ b/src/mongo/db/commands/authentication_commands.cpp
@@ -165,7 +165,8 @@ namespace mongo {
Status CmdAuthenticate::_authenticateCR(const UserName& user, const BSONObj& cmdObj) {
- if (user == internalSecurity.user->getName() && cmdLine.clusterAuthMode == "x509") {
+ if (user == internalSecurity.user->getName() &&
+ serverGlobalParams.clusterAuthMode == "x509") {
return Status(ErrorCodes::AuthenticationFailed,
"Mechanism x509 is required for internal cluster authentication");
}
@@ -273,7 +274,8 @@ namespace mongo {
// Handle internal cluster member auth, only applies to server-server connections
if (srvClusterId == peerClusterId) {
- if (cmdLine.clusterAuthMode.empty() || cmdLine.clusterAuthMode == "keyfile") {
+ if (serverGlobalParams.clusterAuthMode.empty() ||
+ serverGlobalParams.clusterAuthMode == "keyfile") {
return Status(ErrorCodes::AuthenticationFailed, "The provided certificate "
"can only be used for cluster authentication, not client "
"authentication. The current configuration does not allow "
diff --git a/src/mongo/db/commands/index_stats.cpp b/src/mongo/db/commands/index_stats.cpp
index 61224d2579c..719fac8444d 100644
--- a/src/mongo/db/commands/index_stats.cpp
+++ b/src/mongo/db/commands/index_stats.cpp
@@ -500,7 +500,7 @@ namespace mongo {
string ns = dbname + "." + cmdObj.firstElement().valuestrsafe();
const NamespaceDetails* nsd = nsdetails(ns);
- if (!cmdLine.quiet) {
+ if (!serverGlobalParams.quiet) {
MONGO_TLOG(0) << "CMD: indexStats " << ns << endl;
}
if (!nsd) {
@@ -544,7 +544,7 @@ namespace mongo {
};
MONGO_INITIALIZER(IndexStatsCmd)(InitializerContext* context) {
- if (cmdLine.experimental.indexStatsCmdEnabled) {
+ if (serverGlobalParams.experimental.indexStatsCmdEnabled) {
// Leaked intentionally: a Command registers itself when constructed.
new IndexStatsCmd();
}
diff --git a/src/mongo/db/commands/isself.cpp b/src/mongo/db/commands/isself.cpp
index ee14c7df526..88352fb3742 100644
--- a/src/mongo/db/commands/isself.cpp
+++ b/src/mongo/db/commands/isself.cpp
@@ -41,6 +41,7 @@
#include "mongo/db/auth/security_key.h"
#include "mongo/db/commands.h"
#include "mongo/db/jsobj.h"
+#include "mongo/db/server_options.h"
#include "mongo/util/net/listen.h"
#include "mongo/util/net/hostandport.h"
#include "mongo/client/dbclientinterface.h"
@@ -76,8 +77,8 @@ namespace mongo {
vector<string> out;
ifaddrs * addrs;
- if ( ! cmdLine.bind_ip.empty() ) {
- boost::split( out, cmdLine.bind_ip, boost::is_any_of( ", " ) );
+ if (!serverGlobalParams.bind_ip.empty()) {
+ boost::split(out, serverGlobalParams.bind_ip, boost::is_any_of(", "));
return out;
}
@@ -129,7 +130,7 @@ namespace mongo {
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = (IPv6Enabled() ? AF_UNSPEC : AF_INET);
- static string portNum = BSONObjBuilder::numStr(cmdLine.port);
+ static string portNum = BSONObjBuilder::numStr(serverGlobalParams.port);
vector<string> out;
@@ -203,9 +204,9 @@ namespace mongo {
bool HostAndPort::isSelf() const {
int _p = port();
- int p = _p == -1 ? CmdLine::DefaultDBPort : _p;
+ int p = _p == -1 ? ServerGlobalParams::DefaultDBPort : _p;
- if( p != cmdLine.port ) {
+ if (p != serverGlobalParams.port) {
// shortcut - ports have to match at the very least
return false;
}
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index 3a5539348ed..6f92e67fd50 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -43,6 +43,7 @@
#include "mongo/db/matcher.h"
#include "mongo/db/query_optimizer.h"
#include "mongo/db/repl/is_master.h"
+#include "mongo/db/storage_options.h"
#include "mongo/scripting/engine.h"
#include "mongo/s/collection_metadata.h"
#include "mongo/s/d_logic.h"
@@ -1215,7 +1216,7 @@ namespace mongo {
Lock::DBRead lock( config.ns );
// This context does no version check, safe b/c we checked earlier and have an
// open cursor
- Client::Context ctx(config.ns, dbpath, false);
+ Client::Context ctx(config.ns, storageGlobalParams.dbpath, false);
// obtain full cursor on data to apply mr to
shared_ptr<Cursor> temp = getOptimizedCursor( config.ns.c_str(),
diff --git a/src/mongo/db/commands/parameters.cpp b/src/mongo/db/commands/parameters.cpp
index 8341d758167..1e860659ff3 100644
--- a/src/mongo/db/commands/parameters.cpp
+++ b/src/mongo/db/commands/parameters.cpp
@@ -33,8 +33,8 @@
#include "mongo/client/dbclient_rs.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/commands.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/server_parameters.h"
+#include "mongo/db/storage_options.h"
#include "mongo/util/mongoutils/str.h"
namespace mongo {
@@ -75,9 +75,10 @@ namespace mongo {
// TODO: convert to ServerParameters -- SERVER-10515
- if( cmdLine.dur && (all || cmdObj.hasElement("journalCommitInterval")) ) {
+ if (isJournalingEnabled() && (all || cmdObj.hasElement("journalCommitInterval")) &&
+ !isMongos()) {
result.append("journalCommitInterval",
- cmdLine.journalCommitInterval);
+ getJournalCommitInterval());
}
if( all || cmdObj.hasElement( "traceExceptions" ) ) {
result.append("traceExceptions",
@@ -128,13 +129,17 @@ namespace mongo {
// TODO: convert to ServerParameters -- SERVER-10515
if( cmdObj.hasElement("journalCommitInterval") ) {
- if( !cmdLine.dur ) {
+ if (isMongos()) {
+ errmsg = "cannot set journalCommitInterval on a mongos";
+ return false;
+ }
+ if(!isJournalingEnabled()) {
errmsg = "journaling is off";
return false;
}
int x = (int) cmdObj["journalCommitInterval"].Number();
verify( x > 1 && x < 500 );
- cmdLine.journalCommitInterval = x;
+ setJournalCommitInterval(x);
log() << "setParameter journalCommitInterval=" << x << endl;
s++;
}
@@ -226,23 +231,11 @@ namespace mongo {
}
} logLevelSetting;
- ExportedServerParameter<bool> NoTableScanSetting( ServerParameterSet::getGlobal(),
- "notablescan",
- &cmdLine.noTableScan,
- true,
- true );
-
ExportedServerParameter<bool> QuietSetting( ServerParameterSet::getGlobal(),
"quiet",
- &cmdLine.quiet,
+ &serverGlobalParams.quiet,
true,
true );
-
- ExportedServerParameter<double> SyncdelaySetting( ServerParameterSet::getGlobal(),
- "syncdelay",
- &cmdLine.syncdelay,
- true,
- true );
}
}
diff --git a/src/mongo/db/commands/pipeline_command.cpp b/src/mongo/db/commands/pipeline_command.cpp
index b103dba8588..e090c65fabb 100644
--- a/src/mongo/db/commands/pipeline_command.cpp
+++ b/src/mongo/db/commands/pipeline_command.cpp
@@ -43,6 +43,7 @@
#include "mongo/db/pipeline/pipeline_d.h"
#include "mongo/db/pipeline/pipeline.h"
#include "mongo/db/ops/query.h"
+#include "mongo/db/storage_options.h"
namespace mongo {
@@ -227,7 +228,7 @@ namespace mongo {
intrusive_ptr<ExpressionContext> pCtx =
new ExpressionContext(InterruptStatusMongod::status, NamespaceString(ns));
- pCtx->tempDir = dbpath + "/_tmp";
+ pCtx->tempDir = storageGlobalParams.dbpath + "/_tmp";
/* try to parse the command; if this fails, then we didn't run */
intrusive_ptr<Pipeline> pPipeline = Pipeline::parseCommand(errmsg, cmdObj, pCtx);
diff --git a/src/mongo/db/commands/server_status.cpp b/src/mongo/db/commands/server_status.cpp
index 8ca074d9f5f..a6d951d5bf6 100644
--- a/src/mongo/db/commands/server_status.cpp
+++ b/src/mongo/db/commands/server_status.cpp
@@ -36,7 +36,6 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/client_basic.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/server_status.h"
#include "mongo/db/stats/counters.h"
@@ -103,9 +102,9 @@ namespace mongo {
result.append("host", prettyHostName() );
result.append("version", versionString);
- result.append("process",cmdLine.binaryName);
+ result.append("process", serverGlobalParams.binaryName);
result.append("pid", ProcessId::getCurrent().asLongLong());
- result.append("uptime",(double) (time(0)-cmdLine.started));
+ result.append("uptime", (double) (time(0) - serverGlobalParams.started));
result.append("uptimeMillis", (long long)(curTimeMillis64()-_started));
result.append("uptimeEstimate",(double) (start/1000));
result.appendDate( "localTime" , jsTime() );
diff --git a/src/mongo/db/commands/storage_details.cpp b/src/mongo/db/commands/storage_details.cpp
index 6229dc34625..18bdf1fedb2 100644
--- a/src/mongo/db/commands/storage_details.cpp
+++ b/src/mongo/db/commands/storage_details.cpp
@@ -328,7 +328,7 @@ namespace {
};
MONGO_INITIALIZER(StorageDetailsCmd)(InitializerContext* context) {
- if (cmdLine.experimental.storageDetailsCmdEnabled) {
+ if (serverGlobalParams.experimental.storageDetailsCmdEnabled) {
// Leaked intentionally: a Command registers itself when constructed.
new StorageDetailsCmd();
}
@@ -779,7 +779,7 @@ namespace {
const string ns = dbname + "." + cmdObj.firstElement().valuestrsafe();
const NamespaceDetails* nsd = nsdetails(ns);
- if (!cmdLine.quiet) {
+ if (!serverGlobalParams.quiet) {
MONGO_TLOG(0) << "CMD: storageDetails " << ns << ", analyze " << subCommandStr << endl;
}
if (!nsd) {
diff --git a/src/mongo/db/commands/write_commands/batch_executor.cpp b/src/mongo/db/commands/write_commands/batch_executor.cpp
index 5acc6d55708..3b1094479d1 100644
--- a/src/mongo/db/commands/write_commands/batch_executor.cpp
+++ b/src/mongo/db/commands/write_commands/batch_executor.cpp
@@ -195,8 +195,9 @@ namespace mongo {
opDebug.recordStats();
// Log operation if running with at least "-v", or if exceeds slow threshold.
- if ( logger::globalLogDomain()->shouldLog( logger::LogSeverity::Debug( 1 ) )
- || opDebug.executionTime > cmdLine.slowMS + childOp.getExpectedLatencyMs() ) {
+ if (logger::globalLogDomain()->shouldLog(logger::LogSeverity::Debug(1))
+ || opDebug.executionTime >
+ serverGlobalParams.slowMS + childOp.getExpectedLatencyMs()) {
MONGO_TLOG(1) << opDebug.report( childOp ) << endl;
}
diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h
index bc21c6f7954..8df653f8ff1 100644
--- a/src/mongo/db/curop.h
+++ b/src/mongo/db/curop.h
@@ -201,7 +201,7 @@ namespace mongo {
if ( _dbprofile <= 0 )
return false;
- return _dbprofile >= 2 || ms >= cmdLine.slowMS;
+ return _dbprofile >= 2 || ms >= serverGlobalParams.slowMS;
}
AtomicUInt opNum() const { return _opNum; }
diff --git a/src/mongo/db/curop_test.cpp b/src/mongo/db/curop_test.cpp
index 1ec562181e6..392c53a6509 100644
--- a/src/mongo/db/curop_test.cpp
+++ b/src/mongo/db/curop_test.cpp
@@ -34,8 +34,6 @@
namespace mongo {
- CmdLine cmdLine; // needed to satisfy reference in curop.h (and elsewhere)
-
namespace {
const long long intervalLong = 2000 * 1000; // 2s in micros
diff --git a/src/mongo/db/database.cpp b/src/mongo/db/database.cpp
index 9bd972e04e1..75b8c14a930 100644
--- a/src/mongo/db/database.cpp
+++ b/src/mongo/db/database.cpp
@@ -46,6 +46,7 @@
#include "mongo/db/pdfile.h"
#include "mongo/db/query/internal_plans.h"
#include "mongo/db/ops/delete.h"
+#include "mongo/db/storage_options.h"
#include "mongo/db/structure/collection.h"
namespace mongo {
@@ -104,7 +105,7 @@ namespace mongo {
Database::Database(const char *nm, bool& newDb, const string& path )
: _name(nm), _path(path),
_namespaceIndex( _path, _name ),
- _extentManager( _name, _path, 0, directoryperdb /* this is a global right now */ ),
+ _extentManager(_name, _path, 0, storageGlobalParams.directoryperdb),
_profileName(_name + ".system.profile"),
_namespacesName(_name + ".system.namespaces"),
_extentFreelistName( _name + ".$freelist" ),
@@ -118,7 +119,7 @@ namespace mongo {
try {
newDb = _namespaceIndex.exists();
- _profile = cmdLine.defaultProfile;
+ _profile = serverGlobalParams.defaultProfile;
checkDuplicateUncasedNames(true);
// If already exists, open. Otherwise behave as if empty until
diff --git a/src/mongo/db/database.h b/src/mongo/db/database.h
index ef8109736eb..e642b1ed158 100644
--- a/src/mongo/db/database.h
+++ b/src/mongo/db/database.h
@@ -31,10 +31,10 @@
#pragma once
#include "mongo/db/cc_by_loc.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/namespace_details.h"
-#include "mongo/db/storage/record.h"
#include "mongo/db/storage/extent_manager.h"
+#include "mongo/db/storage/record.h"
+#include "mongo/db/storage_options.h"
namespace mongo {
@@ -50,7 +50,8 @@ namespace mongo {
class Database {
public:
// you probably need to be in dbHolderMutex when constructing this
- Database(const char *nm, /*out*/ bool& newDb, const string& path = dbpath);
+ Database(const char *nm, /*out*/ bool& newDb,
+ const string& path = storageGlobalParams.dbpath);
/* you must use this to close - there is essential code in this method that is not in the ~Database destructor.
thus the destructor is private. this could be cleaned up one day...
diff --git a/src/mongo/db/database_holder.cpp b/src/mongo/db/database_holder.cpp
index 94587943c5c..4fae75965c1 100644
--- a/src/mongo/db/database_holder.cpp
+++ b/src/mongo/db/database_holder.cpp
@@ -56,7 +56,9 @@ namespace mongo {
bool cant = !Lock::isWriteLocked(ns);
if( logger::globalLogDomain()->shouldLog(logger::LogSeverity::Debug(1)) ||
m.size() > 40 || cant || DEBUG_BUILD ) {
- log() << "opening db: " << (path==dbpath?"":path) << ' ' << dbname << endl;
+ log() << "opening db: "
+ << (path == storageGlobalParams.dbpath ? "" : path) << ' ' << dbname
+ << endl;
}
massert(15927, "can't open database in a read lock. if db was just closed, consider retrying the query. might otherwise indicate an internal error", !cant);
}
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 37be15e2f5b..5195b6ef0d8 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -42,7 +42,6 @@
#include "mongo/db/auth/authorization_manager_global.h"
#include "mongo/db/client.h"
#include "mongo/db/clientcursor.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands/server_status.h"
#include "mongo/db/d_concurrency.h"
#include "mongo/db/d_globals.h"
@@ -67,13 +66,16 @@
#include "mongo/db/repl/replication_server_status.h"
#include "mongo/db/repl/rs.h"
#include "mongo/db/restapi.h"
+#include "mongo/db/startup_warnings.h"
#include "mongo/db/stats/counters.h"
#include "mongo/db/stats/snapshots.h"
+#include "mongo/db/storage_options.h"
#include "mongo/db/ttl.h"
#include "mongo/platform/process_id.h"
#include "mongo/s/d_writeback.h"
#include "mongo/scripting/engine.h"
#include "mongo/util/background.h"
+#include "mongo/util/cmdline_utils/censor_cmdline.h"
#include "mongo/util/concurrency/task.h"
#include "mongo/util/concurrency/thread_name.h"
#include "mongo/util/exception_filter_win32.h"
@@ -83,6 +85,7 @@
#include "mongo/util/ntservice.h"
#include "mongo/util/options_parser/environment.h"
#include "mongo/util/options_parser/option_section.h"
+#include "mongo/util/options_parser/options_parser.h"
#include "mongo/util/ramlog.h"
#include "mongo/util/stacktrace.h"
#include "mongo/util/startup_test.h"
@@ -95,17 +98,11 @@
namespace mongo {
- namespace dur {
- extern unsigned long long DataLimitPerJournalFile;
- }
-
/* only off if --nohints */
extern bool useHints;
extern int diagLogging;
- extern unsigned lenForNewNsFiles;
extern int lockFile;
- extern string repairpath;
static void setupSignalHandlers();
static void startSignalProcessingThread();
@@ -119,12 +116,6 @@ namespace mongo {
};
#endif
- CmdLine cmdLine;
- moe::Environment params;
- moe::OptionSection options("Allowed options");
- static bool scriptingEnabled = true;
- bool shouldRepairDatabases = 0;
- static bool forceRepair = 0;
Timer startupSrandTimer;
const char *ourgetns() {
@@ -184,19 +175,6 @@ namespace mongo {
};
#endif
- void sysRuntimeInfo() {
- out() << "sysinfo:" << endl;
-#if defined(_SC_PAGE_SIZE)
- out() << " page size: " << (int) sysconf(_SC_PAGE_SIZE) << endl;
-#endif
-#if defined(_SC_PHYS_PAGES)
- out() << " _SC_PHYS_PAGES: " << sysconf(_SC_PHYS_PAGES) << endl;
-#endif
-#if defined(_SC_AVPHYS_PAGES)
- out() << " _SC_AVPHYS_PAGES: " << sysconf(_SC_AVPHYS_PAGES) << endl;
-#endif
- }
-
/* if server is really busy, wait a bit */
void beNice() {
sleepmicros( Client::recommendedYieldMicros() );
@@ -274,7 +252,7 @@ namespace mongo {
toLog.appendTimeT( "startTime", time(0) );
toLog.append( "startTimeLocal", dateToCtimeString(curTimeMillis64()) );
- toLog.append( "cmdLine", CmdLine::getParsedOpts() );
+ toLog.append("cmdLine", serverGlobalParams.parsedOpts);
toLog.append( "pid", ProcessId::getCurrent().asLongLong() );
@@ -296,7 +274,7 @@ namespace mongo {
//testTheDb();
MessageServer::Options options;
options.port = port;
- options.ipList = cmdLine.bind_ip;
+ options.ipList = serverGlobalParams.bind_ip;
MessageServer * server = createServer( options , new MyMessageHandler() );
server->setAsTimeTracker();
@@ -306,7 +284,7 @@ namespace mongo {
logStartup();
startReplication();
- if ( cmdLine.isHttpInterfaceEnabled )
+ if (serverGlobalParams.isHttpInterfaceEnabled)
boost::thread web( boost::bind(&webServerThread, new RestAdminAccess() /* takes ownership */));
#if(TESTEXHAUST)
@@ -345,7 +323,7 @@ namespace mongo {
}
void checkForIdIndexes(const std::string& dbName) {
- if (!cmdLine.usingReplSets()) {
+ if (!replSettings.usingReplSets()) {
// we only care about the _id index if we are in a replset
return;
}
@@ -406,7 +384,7 @@ namespace mongo {
DataFile *p = cc().database()->getFile( 0 );
DataFileHeader *h = p->getHeader();
checkForIdIndexes(dbName);
- if ( !h->isCurrentVersion() || forceRepair ) {
+ if (!h->isCurrentVersion() || mongodGlobalParams.repair) {
if( h->version <= 0 ) {
uasserted(14026,
@@ -424,7 +402,7 @@ namespace mongo {
<< endl;
}
- if ( shouldRepairDatabases ) {
+ if (mongodGlobalParams.upgrade) {
// QUESTION: Repair even if file format is higher version than code?
string errmsg;
verify( doDBUpgrade( dbName , errmsg , h ) );
@@ -434,7 +412,7 @@ namespace mongo {
log() << "\t run --upgrade to upgrade dbs, then start again" << endl;
log() << "****" << endl;
dbexit( EXIT_NEED_UPGRADE );
- shouldRepairDatabases = 1;
+ mongodGlobalParams.upgrade = 1;
return;
}
}
@@ -461,13 +439,13 @@ namespace mongo {
warning() << "Internal error while reading collection " << systemIndexes;
}
}
- Database::closeDatabase( dbName.c_str(), dbpath );
+ Database::closeDatabase(dbName.c_str(), storageGlobalParams.dbpath);
}
}
LOG(1) << "done repairDatabases" << endl;
- if ( shouldRepairDatabases ) {
+ if (mongodGlobalParams.upgrade) {
log() << "finished checking dbs" << endl;
cc().shutdown();
dbexit( EXIT_CLEAN );
@@ -475,7 +453,7 @@ namespace mongo {
}
void clearTmpFiles() {
- boost::filesystem::path path( dbpath );
+ boost::filesystem::path path(storageGlobalParams.dbpath);
for ( boost::filesystem::directory_iterator i( path );
i != boost::filesystem::directory_iterator(); ++i ) {
string fileName = boost::filesystem::path(*i).leaf().string();
@@ -494,7 +472,7 @@ namespace mongo {
*/
unsigned long long checkIfReplMissingFromCommandLine() {
Lock::GlobalWrite lk; // this is helpful for the query below to work as you can't open files when readlocked
- if( !cmdLine.usingReplSets() ) {
+ if (!replSettings.usingReplSets()) {
Client::GodScope gs;
DBDirectClient c;
return c.count("local.system.replset");
@@ -520,25 +498,25 @@ namespace mongo {
void run() {
Client::initThread( name().c_str() );
- if( cmdLine.syncdelay == 0 ) {
+ if (storageGlobalParams.syncdelay == 0) {
log() << "warning: --syncdelay 0 is not recommended and can have strange performance" << endl;
}
- else if( cmdLine.syncdelay == 1 ) {
+ else if (storageGlobalParams.syncdelay == 1) {
log() << "--syncdelay 1" << endl;
}
- else if( cmdLine.syncdelay != 60 ) {
- LOG(1) << "--syncdelay " << cmdLine.syncdelay << endl;
+ else if (storageGlobalParams.syncdelay != 60) {
+ LOG(1) << "--syncdelay " << storageGlobalParams.syncdelay << endl;
}
int time_flushing = 0;
while ( ! inShutdown() ) {
_diaglog.flush();
- if ( cmdLine.syncdelay == 0 ) {
+ if (storageGlobalParams.syncdelay == 0) {
// in case at some point we add an option to change at runtime
sleepsecs(5);
continue;
}
- sleepmillis( (long long) std::max(0.0, (cmdLine.syncdelay * 1000) - time_flushing) );
+ sleepmillis((long long) std::max(0.0, (storageGlobalParams.syncdelay * 1000) - time_flushing));
if ( inShutdown() ) {
// occasional issue trying to flush during shutdown when sleep interrupted
@@ -592,7 +570,7 @@ namespace mongo {
int m = static_cast<int>(MemoryMappedFile::totalMappedLength() / ( 1024 * 1024 ));
b.appendNumber( "mapped" , m );
- if ( cmdLine.dur ) {
+ if (storageGlobalParams.dur) {
m *= 2;
b.appendNumber( "mappedWithJournal" , m );
}
@@ -659,13 +637,15 @@ namespace mongo {
{
ProcessId pid = ProcessId::getCurrent();
LogstreamBuilder l = log();
- l << "MongoDB starting : pid=" << pid << " port=" << cmdLine.port << " dbpath=" << dbpath;
+ l << "MongoDB starting : pid=" << pid
+ << " port=" << serverGlobalParams.port
+ << " dbpath=" << storageGlobalParams.dbpath;
if( replSettings.master ) l << " master=" << replSettings.master;
if( replSettings.slave ) l << " slave=" << (int) replSettings.slave;
l << ( is32bit ? " 32" : " 64" ) << "-bit host=" << getHostNameCached() << endl;
}
DEV log() << "_DEBUG build (which is slower)" << endl;
- show_warnings();
+ logStartupWarnings();
#if defined(_WIN32)
printTargetMinOS();
#endif
@@ -674,23 +654,24 @@ namespace mongo {
stringstream ss;
ss << endl;
ss << "*********************************************************************" << endl;
- ss << " ERROR: dbpath (" << dbpath << ") does not exist." << endl;
+ ss << " ERROR: dbpath (" << storageGlobalParams.dbpath << ") does not exist." << endl;
ss << " Create this directory or give existing directory in --dbpath." << endl;
ss << " See http://dochub.mongodb.org/core/startingandstoppingmongo" << endl;
ss << "*********************************************************************" << endl;
- uassert( 10296 , ss.str().c_str(), boost::filesystem::exists( dbpath ) );
+ uassert(10296, ss.str().c_str(), boost::filesystem::exists(storageGlobalParams.dbpath));
}
{
stringstream ss;
- ss << "repairpath (" << repairpath << ") does not exist";
- uassert( 12590 , ss.str().c_str(), boost::filesystem::exists( repairpath ) );
+ ss << "repairpath (" << storageGlobalParams.repairpath << ") does not exist";
+ uassert(12590, ss.str().c_str(),
+ boost::filesystem::exists(storageGlobalParams.repairpath));
}
// TODO check non-journal subdirs if using directory-per-db
- checkReadAhead(dbpath);
+ checkReadAhead(storageGlobalParams.dbpath);
- acquirePathLock(forceRepair);
- boost::filesystem::remove_all( dbpath + "/_tmp/" );
+ acquirePathLock(mongodGlobalParams.repair);
+ boost::filesystem::remove_all(storageGlobalParams.dbpath + "/_tmp/");
FileAllocator::get()->start();
@@ -698,7 +679,7 @@ namespace mongo {
dur::startup();
- if( cmdLine.durOptions & CmdLine::DurRecoverOnly )
+ if (storageGlobalParams.durOptions & StorageGlobalParams::DurRecoverOnly)
return;
unsigned long long missingRepl = checkIfReplMissingFromCommandLine();
@@ -715,7 +696,7 @@ namespace mongo {
Module::initAll();
- if ( scriptingEnabled ) {
+ if (mongodGlobalParams.scriptingEnabled) {
ScriptEngine::setup();
globalScriptEngine->setCheckInterruptCallback( jsInterruptCallback );
globalScriptEngine->setGetCurrentOpIdCallback( jsGetCurrentOpIdCallback );
@@ -723,7 +704,7 @@ namespace mongo {
repairDatabasesAndCheckVersion();
- if ( shouldRepairDatabases )
+ if (mongodGlobalParams.upgrade)
return;
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
@@ -747,13 +728,13 @@ namespace mongo {
}
#ifndef _WIN32
- CmdLine::launchOk();
+ mongo::signalForkSuccess();
#endif
if(AuthorizationManager::isAuthEnabled()) {
// open admin db in case we need to use it later. TODO this is not the right way to
// resolve this.
- Client::WriteContext c("admin", dbpath);
+ Client::WriteContext c("admin", storageGlobalParams.dbpath);
}
getDeleter()->startWorkers();
@@ -793,7 +774,7 @@ namespace mongo {
void initService() {
ntservice::reportStatus( SERVICE_RUNNING );
log() << "Service running" << endl;
- initAndListen( cmdLine.port );
+ initAndListen(serverGlobalParams.port);
}
#endif
@@ -801,10 +782,6 @@ namespace mongo {
using namespace mongo;
-void show_help_text(const moe::OptionSection& options) {
- std::cout << options.helpString() << std::endl;
-};
-
static int mongoDbMain(int argc, char* argv[], char** envp);
#if defined(_WIN32)
@@ -825,374 +802,6 @@ int main(int argc, char* argv[], char** envp) {
}
#endif
-static Status processCommandLineOptions(const std::vector<std::string>& argv) {
- Status ret = addMongodOptions(&options);
- if (!ret.isOK()) {
- StringBuilder sb;
- sb << "Error getting mongod options descriptions: " << ret.toString();
- return Status(ErrorCodes::InternalError, sb.str());
- }
-
- {
- ret = CmdLine::store(argv, options, params);
- if (!ret.isOK()) {
- std::cerr << "Error parsing command line: " << ret.toString() << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
-
- if (params.count("help")) {
- std::cout << options.helpString() << std::endl;
- ::_exit(EXIT_SUCCESS);
- }
- if (params.count("version")) {
- cout << mongodVersion() << endl;
- printGitVersion();
- printOpenSSLVersion();
- ::_exit(EXIT_SUCCESS);
- }
- if (params.count("sysinfo")) {
- sysRuntimeInfo();
- ::_exit(EXIT_SUCCESS);
- }
-
- if ( params.count( "dbpath" ) ) {
- dbpath = params["dbpath"].as<string>();
- if ( params.count( "fork" ) && dbpath[0] != '/' ) {
- // we need to change dbpath if we fork since we change
- // cwd to "/"
- // fork only exists on *nix
- // so '/' is safe
- dbpath = cmdLine.cwd + "/" + dbpath;
- }
- }
-#ifdef _WIN32
- if (dbpath.size() > 1 && dbpath[dbpath.size()-1] == '/') {
- // size() check is for the unlikely possibility of --dbpath "/"
- dbpath = dbpath.erase(dbpath.size()-1);
- }
-#endif
- if ( params.count("slowms")) {
- cmdLine.slowMS = params["slowms"].as<int>();
- }
-
- if ( params.count("syncdelay")) {
- cmdLine.syncdelay = params["syncdelay"].as<double>();
- }
-
- if ( params.count("directoryperdb")) {
- directoryperdb = true;
- }
- if (params.count("cpu")) {
- cmdLine.cpu = true;
- }
- if (params.count("noauth")) {
- AuthorizationManager::setAuthEnabled(false);
- }
- if (params.count("auth")) {
- AuthorizationManager::setAuthEnabled(true);
- }
- if (params.count("quota")) {
- cmdLine.quota = true;
- }
- if (params.count("quotaFiles")) {
- cmdLine.quota = true;
- cmdLine.quotaFiles = params["quotaFiles"].as<int>() - 1;
- }
- bool journalExplicit = false;
- if( params.count("nodur") || params.count( "nojournal" ) ) {
- journalExplicit = true;
- cmdLine.dur = false;
- }
- if( params.count("dur") || params.count( "journal" ) ) {
- if (journalExplicit) {
- std::cerr << "Can't specify both --journal and --nojournal options." << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- journalExplicit = true;
- cmdLine.dur = true;
- }
- if (params.count("durOptions")) {
- cmdLine.durOptions = params["durOptions"].as<int>();
- }
- if( params.count("journalCommitInterval") ) {
- // 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 a dev environment.
- cmdLine.journalCommitInterval = params["journalCommitInterval"].as<unsigned>();
- if( cmdLine.journalCommitInterval <= 1 || cmdLine.journalCommitInterval > 300 ) {
- std::cerr << "--journalCommitInterval out of allowed range (0-300ms)" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- }
- if (params.count("journalOptions")) {
- cmdLine.durOptions = params["journalOptions"].as<int>();
- }
- if (params.count("repairpath")) {
- repairpath = params["repairpath"].as<string>();
- if (!repairpath.size()) {
- std::cerr << "repairpath is empty" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
-
- if (cmdLine.dur && !str::startsWith(repairpath, dbpath)) {
- std::cerr << "You must use a --repairpath that is a subdirectory of "
- << "--dbpath when using journaling" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- }
- if (params.count("nohints")) {
- useHints = false;
- }
- if (params.count("nopreallocj")) {
- cmdLine.preallocj = false;
- }
- if (params.count("httpinterface")) {
- if (params.count("nohttpinterface")) {
- std::cerr << "can't have both --httpinterface and --nohttpinterface" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- cmdLine.isHttpInterfaceEnabled = true;
- }
- // SERVER-10019 Enabling rest/jsonp without --httpinterface should break in the future
- if (params.count("rest")) {
- if (params.count("nohttpinterface")) {
- log() << "** WARNING: Should not specify both --rest and --nohttpinterface" <<
- startupWarningsLog;
- }
- else if (!params.count("httpinterface")) {
- log() << "** WARNING: --rest is specified without --httpinterface," <<
- startupWarningsLog;
- log() << "** enabling http interface" << startupWarningsLog;
- cmdLine.isHttpInterfaceEnabled = true;
- }
- cmdLine.rest = true;
- }
- if (params.count("jsonp")) {
- if (params.count("nohttpinterface")) {
- log() << "** WARNING: Should not specify both --jsonp and --nohttpinterface" <<
- startupWarningsLog;
- }
- else if (!params.count("httpinterface")) {
- log() << "** WARNING --jsonp is specified without --httpinterface," <<
- startupWarningsLog;
- log() << "** enabling http interface" << startupWarningsLog;
- cmdLine.isHttpInterfaceEnabled = true;
- }
- cmdLine.jsonp = true;
- }
- if (params.count("noscripting")) {
- scriptingEnabled = false;
- }
- if (params.count("noprealloc")) {
- cmdLine.prealloc = false;
- cout << "note: noprealloc may hurt performance in many applications" << endl;
- }
- if (params.count("smallfiles")) {
- cmdLine.smallfiles = true;
- verify( dur::DataLimitPerJournalFile >= 128 * 1024 * 1024 );
- dur::DataLimitPerJournalFile = 128 * 1024 * 1024;
- }
- if (params.count("diaglog")) {
- int x = params["diaglog"].as<int>();
- if ( x < 0 || x > 7 ) {
- std::cerr << "can't interpret --diaglog setting" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- _diaglog.setLevel(x);
- }
- if (params.count("repair")) {
- if (journalExplicit && cmdLine.dur) {
- std::cerr << "Can't specify both --journal and --repair options." << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
-
- Record::MemoryTrackingEnabled = false;
- shouldRepairDatabases = 1;
- forceRepair = 1;
- cmdLine.dur = false;
- }
- if (params.count("upgrade")) {
- Record::MemoryTrackingEnabled = false;
- shouldRepairDatabases = 1;
- }
- if (params.count("notablescan")) {
- cmdLine.noTableScan = true;
- }
- if (params.count("master")) {
- replSettings.master = true;
- }
- if (params.count("slave")) {
- replSettings.slave = SimpleSlave;
- }
- if (params.count("slavedelay")) {
- replSettings.slavedelay = params["slavedelay"].as<int>();
- }
- if (params.count("fastsync")) {
- replSettings.fastsync = true;
- }
- if (params.count("autoresync")) {
- replSettings.autoresync = true;
- if( params.count("replSet") ) {
- std::cerr << "--autoresync is not used with --replSet\nsee "
- << "http://dochub.mongodb.org/core/resyncingaverystalereplicasetmember"
- << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- }
- if (params.count("source")) {
- /* specifies what the source in local.sources should be */
- cmdLine.source = params["source"].as<string>().c_str();
- }
- if( params.count("pretouch") ) {
- cmdLine.pretouch = params["pretouch"].as<int>();
- }
- if (params.count("replSet")) {
- if (params.count("slavedelay")) {
- std::cerr << "--slavedelay cannot be used with --replSet" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- else if (params.count("only")) {
- std::cerr << "--only cannot be used with --replSet" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- /* seed list of hosts for the repl set */
- cmdLine._replSet = params["replSet"].as<string>().c_str();
- }
- if (params.count("replIndexPrefetch")) {
- cmdLine.rsIndexPrefetch = params["replIndexPrefetch"].as<std::string>();
- }
- if (params.count("noIndexBuildRetry")) {
- cmdLine.indexBuildRetry = false;
- }
- if (params.count("only")) {
- cmdLine.only = params["only"].as<string>().c_str();
- }
- if( params.count("nssize") ) {
- int x = params["nssize"].as<int>();
- if (x <= 0 || x > (0x7fffffff/1024/1024)) {
- std::cerr << "bad --nssize arg" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- lenForNewNsFiles = x * 1024 * 1024;
- verify(lenForNewNsFiles > 0);
- }
- if (params.count("oplogSize")) {
- long long x = params["oplogSize"].as<int>();
- if (x <= 0) {
- std::cerr << "bad --oplogSize arg" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- // note a small size such as x==1 is ok for an arbiter.
- if( x > 1000 && sizeof(void*) == 4 ) {
- StringBuilder sb;
- std::cerr << "--oplogSize of " << x
- << "MB is too big for 32 bit version. Use 64 bit build instead."
- << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- cmdLine.oplogSize = x * 1024 * 1024;
- verify(cmdLine.oplogSize > 0);
- }
- if (params.count("cacheSize")) {
- long x = params["cacheSize"].as<long>();
- if (x <= 0) {
- std::cerr << "bad --cacheSize arg" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- std::cerr << "--cacheSize option not currently supported" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- if (!params.count("port")) {
- if( params.count("configsvr") ) {
- cmdLine.port = CmdLine::ConfigServerPort;
- }
- if( params.count("shardsvr") ) {
- if( params.count("configsvr") ) {
- std::cerr << "can't do --shardsvr and --configsvr at the same time" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- cmdLine.port = CmdLine::ShardServerPort;
- }
- }
- else {
- if ( cmdLine.port <= 0 || cmdLine.port > 65535 ) {
- std::cerr << "bad --port number" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- }
- if ( params.count("configsvr" ) ) {
- cmdLine.configsvr = true;
- cmdLine.smallfiles = true; // config server implies small files
- dur::DataLimitPerJournalFile = 128 * 1024 * 1024;
- if (cmdLine.usingReplSets() || replSettings.master || replSettings.slave) {
- std::cerr << "replication should not be enabled on a config server" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- if (!params.count("nodur") && !params.count("nojournal"))
- cmdLine.dur = true;
- if (!params.count("dbpath"))
- dbpath = "/data/configdb";
- replSettings.master = true;
- if (!params.count("oplogSize"))
- cmdLine.oplogSize = 5 * 1024 * 1024;
- }
- if ( params.count( "profile" ) ) {
- cmdLine.defaultProfile = params["profile"].as<int>();
- }
- if (params.count("ipv6")) {
- enableIPv6();
- }
-
- if (params.count("noMoveParanoia") && params.count("moveParanoia")) {
- std::cerr << "The moveParanoia and noMoveParanoia flags cannot both be set; "
- << "please use only one of them." << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
-
- if (params.count("noMoveParanoia"))
- cmdLine.moveParanoia = false;
-
- if (params.count("moveParanoia"))
- cmdLine.moveParanoia = true;
-
- if (params.count("pairwith") || params.count("arbiter") || params.count("opIdMem")) {
- std::cerr << "****\n"
- << "Replica Pairs have been deprecated. Invalid options: --pairwith, "
- << "--arbiter, and/or --opIdMem\n"
- << "<http://dochub.mongodb.org/core/replicapairs>\n"
- << "****" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
-
- // needs to be after things like --configsvr parsing, thus here.
- if( repairpath.empty() )
- repairpath = dbpath;
-
- if( cmdLine.pretouch )
- log() << "--pretouch " << cmdLine.pretouch << endl;
-
- if (sizeof(void*) == 4 && !journalExplicit) {
- // trying to make this stand out more like startup warnings
- log() << endl;
- warning() << "32-bit servers don't have journaling enabled by default. Please use --journal if you want durability." << endl;
- log() << endl;
- }
- }
-
- return Status::OK();
-}
-
-MONGO_INITIALIZER_GENERAL(ParseStartupConfiguration,
- ("GlobalLogManager"),
- ("default", "completedStartupConfig"))(InitializerContext* context) {
-
- Status ret = processCommandLineOptions(context->args());
- if (!ret.isOK()) {
- return ret;
- }
-
- return Status::OK();
-}
-
MONGO_INITIALIZER_GENERAL(ForkServerOrDie,
("completedStartupConfig"),
("default"))(InitializerContext* context) {
@@ -1204,46 +813,46 @@ MONGO_INITIALIZER_GENERAL(ForkServerOrDie,
* This function should contain the startup "actions" that we take based on the startup config. It
* is intended to separate the actions from "storage" and "validation" of our startup configuration.
*/
-static void startupConfigActions(const std::vector<std::string>& argv) {
+static void startupConfigActions(const std::vector<std::string>& args) {
// The "command" option is deprecated. For backward compatibility, still support the "run"
// and "dbppath" command. The "run" command is the same as just running mongod, so just
// falls through.
- if (params.count("command")) {
- vector<string> command = params["command"].as< vector<string> >();
+ if (serverParsedOptions.count("command")) {
+ vector<string> command = serverParsedOptions["command"].as< vector<string> >();
if (command[0].compare("dbpath") == 0) {
- cout << dbpath << endl;
+ cout << storageGlobalParams.dbpath << endl;
::_exit(EXIT_SUCCESS);
}
if (command[0].compare("run") != 0) {
cout << "Invalid command: " << command[0] << endl;
- show_help_text(options);
+ printMongodHelp(serverOptions);
::_exit(EXIT_FAILURE);
}
if (command.size() > 1) {
cout << "Too many parameters to 'run' command" << endl;
- show_help_text(options);
+ printMongodHelp(serverOptions);
::_exit(EXIT_FAILURE);
}
}
- Module::configAll(params);
+ Module::configAll(serverParsedOptions);
#ifdef _WIN32
ntservice::configureService(initService,
- params,
+ serverParsedOptions,
defaultServiceStrings,
std::vector<std::string>(),
- argv);
+ args);
#endif // _WIN32
#ifdef __linux__
- if (params.count("shutdown")){
+ if (serverParsedOptions.count("shutdown")){
bool failed = false;
- string name = ( boost::filesystem::path( dbpath ) / "mongod.lock" ).string();
+ string name = (boost::filesystem::path(storageGlobalParams.dbpath) / "mongod.lock").string();
if ( !boost::filesystem::exists( name ) || boost::filesystem::file_size( name ) == 0 )
failed = true;
@@ -1264,7 +873,8 @@ static void startupConfigActions(const std::vector<std::string>& argv) {
}
if (failed) {
- cerr << "There doesn't seem to be a server running with dbpath: " << dbpath << endl;
+ std::cerr << "There doesn't seem to be a server running with dbpath: "
+ << storageGlobalParams.dbpath << std::endl;
::_exit(EXIT_FAILURE);
}
@@ -1330,7 +940,7 @@ static int mongoDbMain(int argc, char* argv[], char **envp) {
mongo::runGlobalInitializersOrDie(argc, argv, envp);
startupConfigActions(std::vector<std::string>(argv, argv + argc));
- CmdLine::censor(argc, argv);
+ cmdline_utils::censorArgvArray(argc, argv);
if (!initializeServerGlobalState())
::_exit(EXIT_FAILURE);
@@ -1349,7 +959,7 @@ static int mongoDbMain(int argc, char* argv[], char **envp) {
#endif
StartupTest::runTests();
- initAndListen(cmdLine.port);
+ initAndListen(serverGlobalParams.port);
dbexit(EXIT_CLEAN);
return 0;
}
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp
index 9087c598ba0..26fd3dd7951 100644
--- a/src/mongo/db/dbcommands.cpp
+++ b/src/mongo/db/dbcommands.cpp
@@ -298,7 +298,7 @@ namespace mongo {
CmdDropDatabase() : Command("dropDatabase") {}
bool run(const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
// disallow dropping the config database
- if ( cmdLine.configsvr && ( dbname == "config" ) ) {
+ if (serverGlobalParams.configsvr && (dbname == "config")) {
errmsg = "Cannot drop 'config' database if mongod started with --configsvr";
return false;
}
@@ -399,7 +399,7 @@ namespace mongo {
bool run(const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
BSONElement e = cmdObj.firstElement();
result.append("was", cc().database()->getProfilingLevel());
- result.append("slowms", cmdLine.slowMS );
+ result.append("slowms", serverGlobalParams.slowMS);
int p = (int) e.number();
bool ok = false;
@@ -412,7 +412,7 @@ namespace mongo {
BSONElement slow = cmdObj["slowms"];
if ( slow.isNumber() )
- cmdLine.slowMS = slow.numberInt();
+ serverGlobalParams.slowMS = slow.numberInt();
return ok;
}
@@ -468,7 +468,7 @@ namespace mongo {
bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) {
int was = _diaglog.setLevel( cmdObj.firstElement().numberInt() );
_diaglog.flush();
- if ( !cmdLine.quiet ) {
+ if (!serverGlobalParams.quiet) {
MONGO_TLOG(0) << "CMD: diagLogging set to " << _diaglog.getLevel() << " from: " << was << endl;
}
result.append( "was" , was );
@@ -512,7 +512,7 @@ namespace mongo {
virtual bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) {
string nsToDrop = dbname + '.' + cmdObj.firstElement().valuestr();
- if ( !cmdLine.quiet ) {
+ if (!serverGlobalParams.quiet) {
MONGO_TLOG(0) << "CMD: drop " << nsToDrop << endl;
}
@@ -700,7 +700,7 @@ namespace mongo {
BSONElement e = jsobj.firstElement();
string toDeleteNs = dbname + '.' + e.valuestr();
NamespaceDetails *d = nsdetails(toDeleteNs);
- if ( !cmdLine.quiet ) {
+ if (!serverGlobalParams.quiet) {
MONGO_TLOG(0) << "CMD: dropIndexes " << toDeleteNs << endl;
}
if ( d ) {
@@ -855,7 +855,8 @@ namespace mongo {
seen.insert( i->c_str() );
}
- // TODO: erh 1/1/2010 I think this is broken where path != dbpath ??
+ // TODO: erh 1/1/2010 I think this is broken where
+ // path != storageGlobalParams.dbpath ??
set<string> allShortNames;
{
Lock::GlobalRead lk;
@@ -907,7 +908,7 @@ namespace mongo {
bool run(const string& dbname , BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& result, bool /*fromRepl*/) {
bool ok;
try {
- ok = dbHolderW().closeAll( dbpath , result, false );
+ ok = dbHolderW().closeAll(storageGlobalParams.dbpath, result, false);
}
catch(DBException&) {
throw;
@@ -1986,7 +1987,7 @@ namespace mongo {
scoped_ptr<Lock::GlobalRead> lk;
if( c->lockGlobally() )
lk.reset( new Lock::GlobalRead() );
- Client::ReadContext ctx(ns , dbpath); // read locks
+ Client::ReadContext ctx(ns, storageGlobalParams.dbpath); // read locks
client.curop()->ensureStarted();
retval = _execCommand(c, dbname, cmdObj, queryOptions, errmsg, result, fromRepl);
}
@@ -2006,7 +2007,7 @@ namespace mongo {
static_cast<Lock::ScopedLock*>( new Lock::GlobalWrite() ) :
static_cast<Lock::ScopedLock*>( new Lock::DBWrite( dbname ) ) );
client.curop()->ensureStarted();
- Client::Context ctx(dbname, dbpath);
+ Client::Context ctx(dbname, storageGlobalParams.dbpath);
retval = _execCommand(c, dbname, cmdObj, queryOptions, errmsg, result, fromRepl);
if ( retval && c->logTheOp() && ! fromRepl ) {
logOp("c", cmdns, cmdObj);
diff --git a/src/mongo/db/dbcommands_admin.cpp b/src/mongo/db/dbcommands_admin.cpp
index 9c1c78bafa8..1a3e5a4f093 100644
--- a/src/mongo/db/dbcommands_admin.cpp
+++ b/src/mongo/db/dbcommands_admin.cpp
@@ -47,7 +47,6 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/privilege.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/curop-inl.h"
#include "mongo/db/index/catalog_hack.h"
@@ -57,6 +56,7 @@
#include "mongo/db/kill_current_op.h"
#include "mongo/db/pdfile.h"
#include "mongo/db/query/internal_plans.h"
+#include "mongo/db/storage_options.h"
#include "mongo/scripting/engine.h"
#include "mongo/util/alignedbuilder.h"
#include "mongo/util/background.h"
@@ -136,7 +136,8 @@ namespace mongo {
catch(...) { }
try {
- result.append("onSamePartition", onSamePartition(dur::getJournalDir().string(), dbpath));
+ result.append("onSamePartition", onSamePartition(dur::getJournalDir().string(),
+ storageGlobalParams.dbpath));
}
catch(...) { }
@@ -175,7 +176,7 @@ namespace mongo {
bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl ) {
string ns = dbname + "." + cmdObj.firstElement().valuestrsafe();
NamespaceDetails * d = nsdetails( ns );
- if ( !cmdLine.quiet ) {
+ if (!serverGlobalParams.quiet) {
MONGO_TLOG(0) << "CMD: validate " << ns << endl;
}
diff --git a/src/mongo/db/dbcommands_generic.cpp b/src/mongo/db/dbcommands_generic.cpp
index 07bdbf2e3cc..393511049a5 100644
--- a/src/mongo/db/dbcommands_generic.cpp
+++ b/src/mongo/db/dbcommands_generic.cpp
@@ -51,9 +51,10 @@
#include "mongo/db/pdfile.h"
#include "mongo/db/repl/multicmd.h"
#include "mongo/db/repl/write_concern.h"
-#include "mongo/server.h"
+#include "mongo/db/server_options.h"
#include "mongo/db/stats/counters.h"
#include "mongo/scripting/engine.h"
+#include "mongo/server.h"
#include "mongo/util/lruishmap.h"
#include "mongo/util/md5.hpp"
#include "mongo/util/processinfo.h"
@@ -404,8 +405,8 @@ namespace mongo {
out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
}
virtual bool run(const string&, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
- result.append("argv", CmdLine::getArgvArray());
- result.append("parsed", CmdLine::getParsedOpts());
+ result.append("argv", serverGlobalParams.argvArray);
+ result.append("parsed", serverGlobalParams.parsedOpts);
return true;
}
diff --git a/src/mongo/db/dbeval.cpp b/src/mongo/db/dbeval.cpp
index af190d082c3..c25588c8bf1 100644
--- a/src/mongo/db/dbeval.cpp
+++ b/src/mongo/db/dbeval.cpp
@@ -36,7 +36,6 @@
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_manager_global.h"
#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/introspect.h"
#include "mongo/db/jsobj.h"
@@ -100,9 +99,9 @@ namespace mongo {
int res;
{
Timer t;
- res = s->invoke(f, &args, 0, cmdLine.quota ? 10 * 60 * 1000 : 0 );
+ res = s->invoke(f, &args, 0, storageGlobalParams.quota ? 10 * 60 * 1000 : 0);
int m = t.millis();
- if ( m > cmdLine.slowMS ) {
+ if (m > serverGlobalParams.slowMS) {
out() << "dbeval slow, time: " << dec << m << "ms " << dbName << endl;
if ( m >= 1000 ) log() << code << endl;
else OCCASIONALLY log() << code << endl;
diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp
index ad3df07bc8e..ba198f503ce 100644
--- a/src/mongo/db/dbhelpers.cpp
+++ b/src/mongo/db/dbhelpers.cpp
@@ -49,6 +49,7 @@
#include "mongo/db/query/internal_plans.h"
#include "mongo/db/repl/oplog.h"
#include "mongo/db/repl/write_concern.h"
+#include "mongo/db/storage_options.h"
#include "mongo/db/structure/collection.h"
#include "mongo/s/d_logic.h"
@@ -174,7 +175,7 @@ namespace mongo {
}
bool Helpers::isEmpty(const char *ns) {
- Client::Context context(ns, dbpath);
+ Client::Context context(ns, storageGlobalParams.dbpath);
auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns));
return Runner::RUNNER_EOF == runner->getNext(NULL, NULL);
}
@@ -521,7 +522,7 @@ namespace mongo {
: _out(0) {
static int NUM = 0;
- _root = dbpath;
+ _root = storageGlobalParams.dbpath;
if ( a.size() )
_root /= a;
if ( b.size() )
diff --git a/src/mongo/db/dbmessage.h b/src/mongo/db/dbmessage.h
index a265a7eb0d7..88a34a3ecfb 100644
--- a/src/mongo/db/dbmessage.h
+++ b/src/mongo/db/dbmessage.h
@@ -209,7 +209,7 @@ namespace mongo {
"Client Error: Remaining data too small for BSON object",
theEnd - nextjsobj >= 5 );
- if ( cmdLine.objcheck ) {
+ if (serverGlobalParams.objcheck) {
Status status = validateBSON( nextjsobj, theEnd - nextjsobj );
massert( 10307,
str::stream() << "Client Error: bad object in message: " << status.reason(),
diff --git a/src/mongo/db/dbwebserver.cpp b/src/mongo/db/dbwebserver.cpp
index 6ae04510585..14163ce8de5 100644
--- a/src/mongo/db/dbwebserver.cpp
+++ b/src/mongo/db/dbwebserver.cpp
@@ -46,7 +46,6 @@
#include "mongo/db/auth/user_name.h"
#include "mongo/db/auth/user.h"
#include "mongo/db/background.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/db.h"
#include "mongo/db/instance.h"
@@ -89,7 +88,7 @@ namespace mongo {
ss << "git hash: " << gitVersion() << '\n';
ss << openSSLVersion("OpenSSL version: ", "\n");
ss << "sys info: " << sysInfo() << '\n';
- ss << "uptime: " << time(0)-cmdLine.started << " seconds\n";
+ ss << "uptime: " << time(0)-serverGlobalParams.started << " seconds\n";
ss << "</pre>";
}
@@ -199,12 +198,13 @@ namespace mongo {
DbWebHandler * handler = DbWebHandler::findHandler( url );
if ( handler ) {
- if ( handler->requiresREST( url ) && ! cmdLine.rest ) {
+ if (handler->requiresREST(url) && !serverGlobalParams.rest) {
_rejectREST( responseMsg , responseCode , headers );
}
else {
string callback = params.getStringField("jsonp");
- uassert(13453, "server not started with --jsonp", callback.empty() || cmdLine.jsonp);
+ uassert(13453, "server not started with --jsonp",
+ callback.empty() || serverGlobalParams.jsonp);
handler->handle( rq , url , params , responseMsg , responseCode , headers , from );
@@ -217,7 +217,7 @@ namespace mongo {
}
- if ( ! cmdLine.rest ) {
+ if (!serverGlobalParams.rest) {
_rejectREST( responseMsg , responseCode , headers );
return;
}
@@ -242,7 +242,7 @@ namespace mongo {
string dbname;
{
stringstream z;
- z << cmdLine.binaryName << ' ' << prettyHostName();
+ z << serverGlobalParams.binaryName << ' ' << prettyHostName();
dbname = z.str();
}
ss << start(dbname) << h2(dbname);
@@ -359,7 +359,7 @@ namespace mongo {
};
MONGO_INITIALIZER(WebStatusLogPlugin)(InitializerContext*) {
- if (cmdLine.isHttpInterfaceEnabled) {
+ if (serverGlobalParams.isHttpInterfaceEnabled) {
new LogPlugin;
}
return Status::OK();
@@ -565,8 +565,8 @@ namespace mongo {
void webServerThread(const AdminAccess* adminAccess) {
boost::scoped_ptr<const AdminAccess> adminAccessPtr(adminAccess); // adminAccess is owned here
Client::initThread("websvr");
- const int p = cmdLine.port + 1000;
- DbWebServer mini(cmdLine.bind_ip, p, adminAccessPtr.get());
+ const int p = serverGlobalParams.port + 1000;
+ DbWebServer mini(serverGlobalParams.bind_ip, p, adminAccessPtr.get());
mini.setupSockets();
mini.initAndListen();
cc().shutdown();
diff --git a/src/mongo/db/driverHelpers.cpp b/src/mongo/db/driverHelpers.cpp
index dcc688eeb10..b827aef5451 100644
--- a/src/mongo/db/driverHelpers.cpp
+++ b/src/mongo/db/driverHelpers.cpp
@@ -42,7 +42,6 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/privilege.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/curop-inl.h"
#include "mongo/db/jsobj.h"
diff --git a/src/mongo/db/dur.cpp b/src/mongo/db/dur.cpp
index c9c5bc46391..cda03eeacb1 100644
--- a/src/mongo/db/dur.cpp
+++ b/src/mongo/db/dur.cpp
@@ -72,7 +72,6 @@
#include <boost/thread/thread.hpp>
#include "mongo/db/client.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands/fsync.h"
#include "mongo/db/commands/server_status.h"
#include "mongo/db/dur.h"
@@ -80,6 +79,7 @@
#include "mongo/db/dur_journal.h"
#include "mongo/db/dur_recover.h"
#include "mongo/db/dur_stats.h"
+#include "mongo/db/storage_options.h"
#include "mongo/server.h"
#include "mongo/util/concurrency/race.h"
#include "mongo/util/mongoutils/hash.h"
@@ -162,8 +162,8 @@ namespace mongo {
"writeToDataFiles" << (unsigned) (_writeToDataFilesMicros/1000) <<
"remapPrivateView" << (unsigned) (_remapPrivateViewMicros/1000)
);
- if( cmdLine.journalCommitInterval != 0 )
- b << "journalCommitIntervalMs" << cmdLine.journalCommitInterval;
+ if (storageGlobalParams.journalCommitInterval != 0)
+ b << "journalCommitIntervalMs" << storageGlobalParams.journalCommitInterval;
return b.obj();
}
@@ -350,7 +350,7 @@ namespace mongo {
static int n;
++n;
- verify(debug && cmdLine.dur);
+ verify(debug && storageGlobalParams.dur);
if (commitJob.writes().empty())
return;
const WriteIntent &i = commitJob.lastWrite();
@@ -449,7 +449,7 @@ namespace mongo {
/** (SLOW) diagnostic to check that the private view and the non-private view are in sync.
*/
void debugValidateAllMapsMatch() {
- if( ! (cmdLine.durOptions & CmdLine::DurParanoid) )
+ if (!(storageGlobalParams.durOptions & StorageGlobalParams::DurParanoid))
return;
unsigned long long bytes = 0;
@@ -478,7 +478,7 @@ namespace mongo {
// remapping.
unsigned long long now = curTimeMicros64();
double fraction = (now-lastRemap)/2000000.0;
- if( cmdLine.durOptions & CmdLine::DurAlwaysRemap )
+ if (storageGlobalParams.durOptions & StorageGlobalParams::DurAlwaysRemap)
fraction = 1;
lastRemap = now;
@@ -746,7 +746,9 @@ namespace mongo {
const int N = 10;
static int n;
- if( privateMapBytes < UncommittedBytesLimit && ++n % N && (cmdLine.durOptions&CmdLine::DurAlwaysRemap)==0 ) {
+ if (privateMapBytes < UncommittedBytesLimit && ++n % N &&
+ (storageGlobalParams.durOptions &
+ StorageGlobalParams::DurAlwaysRemap) == 0) {
// limited locks version doesn't do any remapprivateview at all, so only try this if privateMapBytes
// is in an acceptable range. also every Nth commit, we do everything so we can do some remapping;
// remapping a lot all at once could cause jitter from a large amount of copy-on-writes all at once.
@@ -767,7 +769,7 @@ namespace mongo {
views disappear
*/
void closingFileNotification() {
- if (!cmdLine.dur)
+ if (!storageGlobalParams.dur)
return;
if( Lock::isLocked() ) {
@@ -789,7 +791,8 @@ namespace mongo {
bool samePartition = true;
try {
- const string dbpathDir = boost::filesystem::path(dbpath).string();
+ const std::string dbpathDir =
+ boost::filesystem::path(storageGlobalParams.dbpath).string();
samePartition = onSamePartition(getJournalDir().string(), dbpathDir);
}
catch(...) {
@@ -798,7 +801,7 @@ namespace mongo {
while( !inShutdown() ) {
RACECHECK
- unsigned ms = cmdLine.journalCommitInterval;
+ unsigned ms = storageGlobalParams.journalCommitInterval;
if( ms == 0 ) {
// use default
ms = samePartition ? 100 : 30;
@@ -841,17 +844,17 @@ namespace mongo {
/** at startup, recover, and then start the journal threads */
void startup() {
- if( !cmdLine.dur )
+ if (!storageGlobalParams.dur)
return;
#if defined(_DURABLEDEFAULTON)
DEV {
if( time(0) & 1 ) {
- cmdLine.durOptions |= CmdLine::DurAlwaysCommit;
+ storageGlobalParams.durOptions |= StorageGlobalParams::DurAlwaysCommit;
log() << "_DEBUG _DURABLEDEFAULTON : forcing DurAlwaysCommit mode for this run" << endl;
}
if( time(0) & 2 ) {
- cmdLine.durOptions |= CmdLine::DurAlwaysRemap;
+ storageGlobalParams.durOptions |= StorageGlobalParams::DurAlwaysRemap;
log() << "_DEBUG _DURABLEDEFAULTON : forcing DurAlwaysRemap mode for this run" << endl;
}
}
@@ -904,7 +907,7 @@ namespace mongo {
virtual bool includeByDefault() const { return true; }
BSONObj generateSection(const BSONElement& configElement) const {
- if ( ! cmdLine.dur )
+ if (!storageGlobalParams.dur)
return BSONObj();
return dur::stats.asObj();
}
diff --git a/src/mongo/db/dur.h b/src/mongo/db/dur.h
index f32551b7b30..2ae50ef62d7 100644
--- a/src/mongo/db/dur.h
+++ b/src/mongo/db/dur.h
@@ -49,7 +49,7 @@ namespace mongo {
/** Call during startup so durability module can initialize
Throws if fatal error
- Does nothing if cmdLine.dur is false
+ Does nothing if storageGlobalParams.dur is false
*/
void startup();
diff --git a/src/mongo/db/dur_commitjob.cpp b/src/mongo/db/dur_commitjob.cpp
index 91e90924692..f755f908180 100644
--- a/src/mongo/db/dur_commitjob.cpp
+++ b/src/mongo/db/dur_commitjob.cpp
@@ -179,7 +179,7 @@ namespace mongo {
/** note an operation other than a "basic write" */
void CommitJob::noteOp(shared_ptr<DurOp> p) {
- dassert( cmdLine.dur );
+ dassert(storageGlobalParams.dur);
// DurOp's are rare so it is ok to have the lock cost here
SimpleMutex::scoped_lock lk(groupCommitMutex);
cc().writeHappened();
diff --git a/src/mongo/db/dur_commitjob.h b/src/mongo/db/dur_commitjob.h
index 1bc8865dc65..6d5863e0c7d 100644
--- a/src/mongo/db/dur_commitjob.h
+++ b/src/mongo/db/dur_commitjob.h
@@ -30,7 +30,6 @@
#pragma once
-#include "mongo/db/cmdline.h"
#include "mongo/db/d_concurrency.h"
#include "mongo/db/dur.h"
#include "mongo/db/durop.h"
diff --git a/src/mongo/db/dur_journal.cpp b/src/mongo/db/dur_journal.cpp
index 0b2281b3e31..bb466139f2e 100644
--- a/src/mongo/db/dur_journal.cpp
+++ b/src/mongo/db/dur_journal.cpp
@@ -36,10 +36,12 @@
#include <boost/filesystem.hpp>
#include <boost/filesystem/operations.hpp>
+#include "mongo/base/init.h"
#include "mongo/db/client.h"
#include "mongo/db/dur_journalformat.h"
#include "mongo/db/dur_journalimpl.h"
#include "mongo/db/dur_stats.h"
+#include "mongo/db/storage_options.h"
#include "mongo/platform/random.h"
#include "mongo/server.h"
#include "mongo/util/alignedbuilder.h"
@@ -77,6 +79,14 @@ namespace mongo {
unsigned long long DataLimitPerJournalFile = (sizeof(void*)==4) ? 256 * 1024 * 1024 : 1 * 1024 * 1024 * 1024;
#endif
+ MONGO_INITIALIZER(InitializeJournalingParams)(InitializerContext* context) {
+ if (storageGlobalParams.smallfiles == true) {
+ verify(dur::DataLimitPerJournalFile >= 128 * 1024 * 1024);
+ dur::DataLimitPerJournalFile = 128 * 1024 * 1024;
+ }
+ return Status::OK();
+ }
+
BOOST_STATIC_ASSERT( sizeof(Checksum) == 16 );
BOOST_STATIC_ASSERT( sizeof(JHeader) == 8192 );
BOOST_STATIC_ASSERT( sizeof(JSectHeader) == 20 );
@@ -89,7 +99,7 @@ namespace mongo {
void removeOldJournalFile(boost::filesystem::path p);
boost::filesystem::path getJournalDir() {
- boost::filesystem::path p(dbpath);
+ boost::filesystem::path p(storageGlobalParams.dbpath);
p /= "journal";
return p;
}
@@ -405,12 +415,12 @@ namespace mongo {
}
void preallocateFiles() {
- if (! (cmdLine.durOptions & CmdLine::DurNoCheckSpace))
+ if (!(storageGlobalParams.durOptions & StorageGlobalParams::DurNoCheckSpace))
checkFreeSpace();
if( exists(preallocPath(0)) || // if enabled previously, keep using
exists(preallocPath(1)) ||
- ( cmdLine.preallocj && preallocateIsFaster() ) ) {
+ (storageGlobalParams.preallocj && preallocateIsFaster()) ) {
usingPreallocate = true;
try {
_preallocateFiles();
diff --git a/src/mongo/db/dur_preplogbuffer.cpp b/src/mongo/db/dur_preplogbuffer.cpp
index 1999602a938..1c28a358f04 100644
--- a/src/mongo/db/dur_preplogbuffer.cpp
+++ b/src/mongo/db/dur_preplogbuffer.cpp
@@ -38,7 +38,6 @@
#include "mongo/pch.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/dur.h"
#include "mongo/db/dur_commitjob.h"
#include "mongo/db/dur_journal.h"
@@ -174,7 +173,7 @@ namespace mongo {
@return partially populated sectheader and _ab set
*/
static void _PREPLOGBUFFER(JSectHeader& h, AlignedBuilder& bb) {
- verify( cmdLine.dur );
+ verify(storageGlobalParams.dur);
assertLockedForCommitting();
resetLogBuffer(h, bb); // adds JSectHeader
diff --git a/src/mongo/db/dur_recover.cpp b/src/mongo/db/dur_recover.cpp
index da886dd25ad..e6a7af033cb 100644
--- a/src/mongo/db/dur_recover.cpp
+++ b/src/mongo/db/dur_recover.cpp
@@ -36,7 +36,6 @@
#include <fcntl.h>
#include <sys/stat.h>
-#include "mongo/db/cmdline.h"
#include "mongo/db/curop.h"
#include "mongo/db/database.h"
#include "mongo/db/db.h"
@@ -49,6 +48,7 @@
#include "mongo/db/kill_current_op.h"
#include "mongo/db/storage/durable_mapped_file.h"
#include "mongo/db/pdfile.h"
+#include "mongo/db/storage_options.h"
#include "mongo/util/bufreader.h"
#include "mongo/util/checksum.h"
#include "mongo/util/compress.h"
@@ -206,7 +206,7 @@ namespace mongo {
ss << fileNo;
// relative name -> full path name
- boost::filesystem::path full(dbpath);
+ boost::filesystem::path full(storageGlobalParams.dbpath);
full /= ss.str();
return full.string();
}
@@ -349,8 +349,10 @@ namespace mongo {
}
void RecoveryJob::applyEntries(const vector<ParsedJournalEntry> &entries) {
- bool apply = (cmdLine.durOptions & CmdLine::DurScanOnly) == 0;
- bool dump = cmdLine.durOptions & CmdLine::DurDumpJournal;
+ bool apply = (storageGlobalParams.durOptions &
+ StorageGlobalParams::DurScanOnly) == 0;
+ bool dump = storageGlobalParams.durOptions &
+ StorageGlobalParams::DurDumpJournal;
if( dump )
log() << "BEGIN section" << endl;
@@ -457,7 +459,8 @@ namespace mongo {
uasserted(13536, str::stream() << "journal version number mismatch " << h._version);
}
fileId = h.fileId;
- if(cmdLine.durOptions & CmdLine::DurDumpJournal) {
+ if (storageGlobalParams.durOptions &
+ StorageGlobalParams::DurDumpJournal) {
log() << "JHeader::fileId=" << fileId << endl;
}
}
@@ -467,7 +470,8 @@ namespace mongo {
JSectHeader h;
br.peek(h);
if( h.fileId != fileId ) {
- if( debug || (cmdLine.durOptions & CmdLine::DurDumpJournal) ) {
+ if (debug || (storageGlobalParams.durOptions &
+ StorageGlobalParams::DurDumpJournal)) {
log() << "Ending processFileBuffer at differing fileId want:" << fileId << " got:" << h.fileId << endl;
log() << " sect len:" << h.sectionLen() << " seqnum:" << h.seqNumber << endl;
}
@@ -485,7 +489,7 @@ namespace mongo {
}
}
catch( BufReader::eof& ) {
- if( cmdLine.durOptions & CmdLine::DurDumpJournal )
+ if (storageGlobalParams.durOptions & StorageGlobalParams::DurDumpJournal)
log() << "ABRUPT END" << endl;
return true; // abrupt end
}
@@ -534,8 +538,10 @@ namespace mongo {
close();
- if( cmdLine.durOptions & CmdLine::DurScanOnly ) {
- uasserted(13545, str::stream() << "--durOptions " << (int) CmdLine::DurScanOnly << " (scan only) specified");
+ if (storageGlobalParams.durOptions & StorageGlobalParams::DurScanOnly) {
+ uasserted(13545, str::stream() << "--durOptions "
+ << (int) StorageGlobalParams::DurScanOnly
+ << " (scan only) specified");
}
log() << "recover cleaning up" << endl;
@@ -546,7 +552,7 @@ namespace mongo {
}
void _recover() {
- verify( cmdLine.dur );
+ verify(storageGlobalParams.dur);
boost::filesystem::path p = getJournalDir();
if( !exists(p) ) {
diff --git a/src/mongo/db/durop.cpp b/src/mongo/db/durop.cpp
index 6e113c06b0c..6f32295aed7 100644
--- a/src/mongo/db/durop.cpp
+++ b/src/mongo/db/durop.cpp
@@ -45,8 +45,6 @@ using namespace mongoutils;
namespace mongo {
- extern string dbpath; // --dbpath parm
-
void _deleteDataFiles(const char *);
namespace dur {
diff --git a/src/mongo/db/explain.cpp b/src/mongo/db/explain.cpp
index c88f1013667..b73f3081696 100644
--- a/src/mongo/db/explain.cpp
+++ b/src/mongo/db/explain.cpp
@@ -17,9 +17,9 @@
#include "mongo/db/explain.h"
-#include "mongo/db/cmdline.h"
-#include "mongo/util/net/sock.h"
+#include "mongo/db/server_options.h"
#include "mongo/util/mongoutils/str.h"
+#include "mongo/util/net/sock.h"
namespace mongo {
@@ -263,7 +263,7 @@ namespace mongo {
}
string ExplainQueryInfo::server() {
- return mongoutils::str::stream() << getHostNameCached() << ":" << cmdLine.port;
+ return mongoutils::str::stream() << getHostNameCached() << ":" << serverGlobalParams.port;
}
ExplainSinglePlanQueryInfo::ExplainSinglePlanQueryInfo() :
diff --git a/src/mongo/db/extsort.cpp b/src/mongo/db/extsort.cpp
index b4802122a0a..e4aeb5f53ca 100644
--- a/src/mongo/db/extsort.cpp
+++ b/src/mongo/db/extsort.cpp
@@ -44,6 +44,7 @@
#include <sys/types.h>
#include "mongo/db/kill_current_op.h"
+#include "mongo/db/storage_options.h"
#include "mongo/platform/posix_fadvise.h"
#include "mongo/util/file.h"
@@ -79,7 +80,7 @@ namespace mongo {
long maxFileSize)
: _mayInterrupt(boost::make_shared<bool>(false))
, _sorter(Sorter<BSONObj, DiskLoc>::make(
- SortOptions().TempDir(dbpath + "/_tmp")
+ SortOptions().TempDir(storageGlobalParams.dbpath + "/_tmp")
.ExtSortAllowed()
.MaxMemoryUsageBytes(maxFileSize),
OldExtSortComparator(comp, _mayInterrupt)))
@@ -126,8 +127,8 @@ namespace mongo {
_sorted(0) {
stringstream rootpath;
- rootpath << dbpath;
- if ( dbpath[dbpath.size()-1] != '/' )
+ rootpath << storageGlobalParams.dbpath;
+ if (storageGlobalParams.dbpath[storageGlobalParams.dbpath.size()-1] != '/')
rootpath << "/";
unsigned long long thisUniqueNumber;
diff --git a/src/mongo/db/index_rebuilder.cpp b/src/mongo/db/index_rebuilder.cpp
index ac1ae0ad350..6f3edbeae44 100644
--- a/src/mongo/db/index_rebuilder.cpp
+++ b/src/mongo/db/index_rebuilder.cpp
@@ -109,7 +109,7 @@ namespace mongo {
}
// If the indexBuildRetry flag isn't set, just clear the inProg flag
- if (!cmdLine.indexBuildRetry) {
+ if (!serverGlobalParams.indexBuildRetry) {
// If we crash between unsetting the inProg flag and cleaning up the index, the
// index space will be lost.
nsd->blowAwayInProgressIndexEntries();
diff --git a/src/mongo/db/initialize_server_global_state.cpp b/src/mongo/db/initialize_server_global_state.cpp
index d23a6ef5835..3d66d684f4f 100644
--- a/src/mongo/db/initialize_server_global_state.cpp
+++ b/src/mongo/db/initialize_server_global_state.cpp
@@ -43,7 +43,6 @@
#include "mongo/client/sasl_client_authenticate.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/security_key.h"
-#include "mongo/db/cmdline.h"
#include "mongo/logger/logger.h"
#include "mongo/logger/message_event.h"
#include "mongo/logger/message_event_utf8_encoder.h"
@@ -68,7 +67,7 @@ namespace mongo {
if ( sig == SIGUSR2 ) {
ProcessId cur = ProcessId::getCurrent();
- if ( cur == cmdLine.parentProc || cur == cmdLine.leaderProc ) {
+ if (cur == serverGlobalParams.parentProc || cur == serverGlobalParams.leaderProc) {
// signal indicates successful start allowing us to exit
_exit(0);
}
@@ -79,10 +78,10 @@ namespace mongo {
verify( signal(SIGUSR2 , launchSignal ) != SIG_ERR );
}
- void CmdLine::launchOk() {
- if ( cmdLine.doFork ) {
+ void signalForkSuccess() {
+ if (serverGlobalParams.doFork) {
// killing leader will propagate to parent
- verify( kill( cmdLine.leaderProc.toNative(), SIGUSR2 ) == 0 );
+ verify(kill(serverGlobalParams.leaderProc.toNative(), SIGUSR2) == 0);
}
}
#endif
@@ -90,13 +89,14 @@ namespace mongo {
static bool forkServer() {
#ifndef _WIN32
- if (cmdLine.doFork) {
- fassert(16447, !cmdLine.logpath.empty() || cmdLine.logWithSyslog);
+ if (serverGlobalParams.doFork) {
+ fassert(16447, !serverGlobalParams.logpath.empty() ||
+ serverGlobalParams.logWithSyslog);
cout.flush();
cerr.flush();
- cmdLine.parentProc = ProcessId::getCurrent();
+ serverGlobalParams.parentProc = ProcessId::getCurrent();
// facilitate clean exit when child starts successfully
setupLaunchSignals();
@@ -135,7 +135,7 @@ namespace mongo {
}
setsid();
- cmdLine.leaderProc = ProcessId::getCurrent();
+ serverGlobalParams.leaderProc = ProcessId::getCurrent();
pid_t child2 = fork();
if (child2 == -1) {
@@ -200,9 +200,9 @@ namespace mongo {
#ifndef _WIN32
using logger::SyslogAppender;
- if (cmdLine.logWithSyslog) {
+ if (serverGlobalParams.logWithSyslog) {
StringBuilder sb;
- sb << cmdLine.binaryName << "." << cmdLine.port;
+ sb << serverGlobalParams.binaryName << "." << serverGlobalParams.port;
openlog(strdup(sb.str().c_str()), LOG_PID | LOG_CONS, LOG_USER);
LogManager* manager = logger::globalLogManager();
manager->getGlobalDomain()->clearAppenders();
@@ -217,10 +217,10 @@ namespace mongo {
}
#endif // defined(_WIN32)
- if (!cmdLine.logpath.empty()) {
- fassert(16448, !cmdLine.logWithSyslog);
+ if (!serverGlobalParams.logpath.empty()) {
+ fassert(16448, !serverGlobalParams.logWithSyslog);
std::string absoluteLogpath = boost::filesystem::absolute(
- cmdLine.logpath, cmdLine.cwd).string();
+ serverGlobalParams.logpath, serverGlobalParams.cwd).string();
bool exists;
@@ -239,7 +239,8 @@ namespace mongo {
"\" should name a file, not a directory.");
}
- if (!cmdLine.logAppend && boost::filesystem::is_regular(absoluteLogpath)) {
+ if (!serverGlobalParams.logAppend &&
+ boost::filesystem::is_regular(absoluteLogpath)) {
std::string renameTarget = absoluteLogpath + "." + terseCurrentTime(false);
if (0 == rename(absoluteLogpath.c_str(), renameTarget.c_str())) {
log() << "log file \"" << absoluteLogpath
@@ -256,7 +257,8 @@ namespace mongo {
}
StatusWithRotatableFileWriter writer =
- logger::globalRotatableFileManager()->openFile(absoluteLogpath, cmdLine.logAppend);
+ logger::globalRotatableFileManager()->openFile(absoluteLogpath,
+ serverGlobalParams.logAppend);
if (!writer.isOK()) {
return writer.getStatus();
}
@@ -272,7 +274,7 @@ namespace mongo {
new RotatableFileAppender<MessageEventEphemeral>(
new MessageEventDetailsEncoder, writer.getValue())));
- if (cmdLine.logAppend && exists) {
+ if (serverGlobalParams.logAppend && exists) {
log() << "***** SERVER RESTARTED *****" << endl;
Status status =
logger::RotatableFileWriter::Use(writer.getValue()).status();
@@ -290,24 +292,24 @@ namespace mongo {
bool initializeServerGlobalState() {
- Listener::globalTicketHolder.resize( cmdLine.maxConns );
+ Listener::globalTicketHolder.resize(serverGlobalParams.maxConns);
#ifndef _WIN32
- if (!fs::is_directory(cmdLine.socket)) {
- cout << cmdLine.socket << " must be a directory" << endl;
+ if (!fs::is_directory(serverGlobalParams.socket)) {
+ cout << serverGlobalParams.socket << " must be a directory" << endl;
return false;
}
#endif
- if (!cmdLine.pidFile.empty()) {
- if (!writePidFile(cmdLine.pidFile)) {
+ if (!serverGlobalParams.pidFile.empty()) {
+ if (!writePidFile(serverGlobalParams.pidFile)) {
// error message logged in writePidFile
return false;
}
}
- if (!cmdLine.keyFile.empty() && cmdLine.clusterAuthMode != "x509") {
- if (!setUpSecurityKey(cmdLine.keyFile)) {
+ if (!serverGlobalParams.keyFile.empty() && serverGlobalParams.clusterAuthMode != "x509") {
+ if (!setUpSecurityKey(serverGlobalParams.keyFile)) {
// error message printed in setUpPrivateKey
return false;
}
@@ -315,12 +317,13 @@ namespace mongo {
// Auto-enable auth except if clusterAuthMode is not set.
// clusterAuthMode is automatically set if a --keyfile parameter is provided.
- if (!cmdLine.clusterAuthMode.empty()) {
+ if (!serverGlobalParams.clusterAuthMode.empty()) {
AuthorizationManager::setAuthEnabled(true);
}
#ifdef MONGO_SSL
- if (cmdLine.clusterAuthMode == "x509" || cmdLine.clusterAuthMode == "sendX509") {
+ if (serverGlobalParams.clusterAuthMode == "x509" ||
+ serverGlobalParams.clusterAuthMode == "sendX509") {
setInternalUserAuthParams(BSON(saslCommandMechanismFieldName << "MONGODB-X509" <<
saslCommandUserSourceFieldName << "$external" <<
saslCommandUserFieldName <<
diff --git a/src/mongo/db/initialize_server_global_state.h b/src/mongo/db/initialize_server_global_state.h
index e2d558e71a0..68f25f77cf2 100644
--- a/src/mongo/db/initialize_server_global_state.h
+++ b/src/mongo/db/initialize_server_global_state.h
@@ -38,12 +38,19 @@ namespace mongo {
bool initializeServerGlobalState();
/**
- * Forks and detaches the server, on platforms that support it, if cmdLine.doFork is true.
+ * Forks and detaches the server, on platforms that support it, if serverGlobalParams.doFork is
+ * true.
*
* Call after processing the command line but before running mongo initializers.
*/
void forkServerOrDie();
+ /**
+ * Notify the parent that we forked from that we have successfully completed basic
+ * initialization so it can stop waiting and exit.
+ */
+ void signalForkSuccess();
+
void setupCoreSignals();
} // namespace mongo
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index 043ebe96173..968b295c543 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -47,7 +47,6 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/background.h"
#include "mongo/db/clientcursor.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands/fsync.h"
#include "mongo/db/d_concurrency.h"
#include "mongo/db/db.h"
@@ -60,6 +59,7 @@
#include "mongo/db/json.h"
#include "mongo/db/kill_current_op.h"
#include "mongo/db/lasterror.h"
+#include "mongo/db/mongod_options.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/ops/count.h"
#include "mongo/db/ops/delete.h"
@@ -70,6 +70,7 @@
#include "mongo/db/repl/is_master.h"
#include "mongo/db/repl/oplog.h"
#include "mongo/db/stats/counters.h"
+#include "mongo/db/storage_options.h"
#include "mongo/platform/process_id.h"
#include "mongo/s/d_logic.h"
#include "mongo/s/stale_exception.h" // for SendStaleConfigException
@@ -97,8 +98,6 @@ namespace mongo {
string dbExecCommand;
- bool useHints = true;
-
KillCurrentOp killCurrentOp;
int lockFile = 0;
@@ -435,7 +434,7 @@ namespace mongo {
OpDebug& debug = currentOp.debug();
debug.op = op;
- long long logThreshold = cmdLine.slowMS;
+ long long logThreshold = serverGlobalParams.slowMS;
bool shouldLog = logger::globalLogDomain()->shouldLog(logger::LogSeverity::Debug(1));
if ( op == dbQuery ) {
@@ -961,7 +960,7 @@ namespace mongo {
boost::filesystem::path path( usePath );
for ( boost::filesystem::directory_iterator i( path );
i != boost::filesystem::directory_iterator(); ++i ) {
- if ( directoryperdb ) {
+ if (storageGlobalParams.directoryperdb) {
boost::filesystem::path p = *i;
string dbName = p.leaf().string();
p /= ( dbName + ".ns" );
@@ -1102,7 +1101,7 @@ namespace mongo {
log() << "shutdown: waiting for fs preallocator..." << endl;
FileAllocator::get()->waitUntilFinished();
- if( cmdLine.dur ) {
+ if (storageGlobalParams.dur) {
log() << "shutdown: lock for final commit..." << endl;
{
int n = 10;
@@ -1130,7 +1129,7 @@ namespace mongo {
MemoryMappedFile::closeAllFiles( ss3 );
log() << ss3.str() << endl;
- if( cmdLine.dur ) {
+ if (storageGlobalParams.dur) {
dur::journalCleanup(true);
}
@@ -1239,7 +1238,7 @@ namespace mongo {
}
void acquirePathLock(bool doingRepair) {
- string name = ( boost::filesystem::path( dbpath ) / "mongod.lock" ).string();
+ string name = (boost::filesystem::path(storageGlobalParams.dbpath) / "mongod.lock").string();
bool oldFile = false;
@@ -1288,7 +1287,7 @@ namespace mongo {
"run with --repair again.\n"
"**************";
}
- else if (cmdLine.dur) {
+ else if (storageGlobalParams.dur) {
if (!dur::haveJournalFiles(/*anyFiles=*/true)) {
// Passing anyFiles=true as we are trying to protect against starting in an
// unclean state with the journal directory unmounted. If there are any files,
@@ -1342,7 +1341,7 @@ namespace mongo {
}
// Not related to lock file, but this is where we handle unclean shutdown
- if( !cmdLine.dur && dur::haveJournalFiles() ) {
+ if (!storageGlobalParams.dur && dur::haveJournalFiles()) {
cout << "**************" << endl;
cout << "Error: journal files are present in journal directory, yet starting without journaling enabled." << endl;
cout << "It is recommended that you start with journaling enabled so that recovery may occur." << endl;
@@ -1366,7 +1365,7 @@ namespace mongo {
// TODO - this is very bad that the code above not running here.
// Not related to lock file, but this is where we handle unclean shutdown
- if( !cmdLine.dur && dur::haveJournalFiles() ) {
+ if (!storageGlobalParams.dur && dur::haveJournalFiles()) {
cout << "**************" << endl;
cout << "Error: journal files are present in journal directory, yet starting without --journal enabled." << endl;
cout << "It is recommended that you start with journaling enabled so that recovery may occur." << endl;
@@ -1384,7 +1383,7 @@ namespace mongo {
void DiagLog::openFile() {
verify( f == 0 );
stringstream ss;
- ss << dbpath << "/diaglog." << hex << time(0);
+ ss << storageGlobalParams.dbpath << "/diaglog." << hex << time(0);
string name = ss.str();
f = new ofstream(name.c_str(), ios::out | ios::binary);
if ( ! f->good() ) {
diff --git a/src/mongo/db/instance.h b/src/mongo/db/instance.h
index bb0307defcb..43f0674ce86 100644
--- a/src/mongo/db/instance.h
+++ b/src/mongo/db/instance.h
@@ -33,9 +33,9 @@
#include "mongo/client/dbclientinterface.h"
#include "mongo/db/client.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/curop-inl.h"
#include "mongo/db/dbmessage.h"
+#include "mongo/db/storage_options.h"
namespace mongo {
@@ -69,7 +69,8 @@ namespace mongo {
void assembleResponse( Message &m, DbResponse &dbresponse, const HostAndPort &client );
- void getDatabaseNames( vector< string > &names , const string& usePath = dbpath );
+ void getDatabaseNames(vector<std::string> &names,
+ const std::string& usePath = storageGlobalParams.dbpath);
/* returns true if there is no data on this server. useful when starting replication.
local database does NOT count.
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
index bee2531b37f..4642e9655d1 100644
--- a/src/mongo/db/introspect.cpp
+++ b/src/mongo/db/introspect.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/introspect.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/pdfile.h"
+#include "mongo/db/storage_options.h"
#include "mongo/util/goodies.h"
namespace {
@@ -134,8 +135,8 @@ namespace {
try {
Lock::DBWrite lk( currentOp.getNS() );
- if ( dbHolder()._isLoaded( nsToDatabase( currentOp.getNS() ) , dbpath ) ) {
- Client::Context cx(currentOp.getNS(), dbpath);
+ if (dbHolder()._isLoaded(nsToDatabase(currentOp.getNS()), storageGlobalParams.dbpath)) {
+ Client::Context cx(currentOp.getNS(), storageGlobalParams.dbpath);
_profile(c, currentOp, profileBufBuilder);
}
else {
@@ -154,7 +155,7 @@ namespace {
fassert(16372, db);
const char* profileName = db->getProfilingNS();
NamespaceDetails* details = db->namespaceIndex().details(profileName);
- if (!details && (cmdLine.defaultProfile || force)) {
+ if (!details && (serverGlobalParams.defaultProfile || force)) {
// system.profile namespace doesn't exist; create it
log() << "creating profile collection: " << profileName << endl;
string myerrmsg;
diff --git a/src/mongo/db/log_process_details.cpp b/src/mongo/db/log_process_details.cpp
index 70eaa809ea7..f8447f245e9 100644
--- a/src/mongo/db/log_process_details.cpp
+++ b/src/mongo/db/log_process_details.cpp
@@ -32,7 +32,8 @@
#include "mongo/db/log_process_details.h"
-#include "mongo/db/cmdline.h"
+#include "mongo/db/server_options.h"
+#include "mongo/util/net/sock.h"
#include "mongo/util/net/ssl_manager.h"
#include "mongo/util/processinfo.h"
#include "mongo/util/version.h"
@@ -54,7 +55,7 @@ namespace mongo {
void logProcessDetailsForLogRotate() {
log() << "pid=" << ProcessId::getCurrent()
- << " port=" << cmdLine.port
+ << " port=" << serverGlobalParams.port
<< ( is32bit() ? " 32" : " 64" ) << "-bit "
<< "host=" << getHostNameCached();
diff --git a/src/mongo/db/mongod_options.cpp b/src/mongo/db/mongod_options.cpp
index 7456a033c08..5f9a5b489f3 100644
--- a/src/mongo/db/mongod_options.cpp
+++ b/src/mongo/db/mongod_options.cpp
@@ -31,20 +31,30 @@
#include <string>
#include <vector>
+#include "mongo/base/init.h"
#include "mongo/base/status.h"
#include "mongo/bson/util/builder.h"
+#include "mongo/db/auth/authorization_manager.h"
+#include "mongo/db/instance.h"
#include "mongo/db/module.h"
+#include "mongo/db/pdfile.h"
+#include "mongo/db/repl/replication_server_status.h"
#include "mongo/db/server_options.h"
+#include "mongo/util/mongoutils/str.h"
#include "mongo/util/net/ssl_options.h"
#include "mongo/util/options_parser/option_description.h"
#include "mongo/util/options_parser/option_section.h"
+#include "mongo/util/options_parser/options_parser.h"
+#include "mongo/util/version.h"
namespace mongo {
typedef moe::OptionDescription OD;
typedef moe::PositionalOptionDescription POD;
- extern std::string dbpath;
+ MongodGlobalParams mongodGlobalParams;
+
+ extern DiagLog _diaglog;
Status addMongodOptions(moe::OptionSection* options) {
@@ -78,9 +88,6 @@ namespace mongo {
moe::OptionSection replication_options("Replication options");
moe::OptionSection sharding_options("Sharding options");
- StringBuilder dbpathBuilder;
- dbpathBuilder << "directory for datafiles - defaults to " << dbpath;
-
ret = general_options.addOption(OD("auth", "auth", moe::Switch, "run with security", true));
if (!ret.isOK()) {
return ret;
@@ -90,8 +97,15 @@ namespace mongo {
if (!ret.isOK()) {
return ret;
}
+#ifdef _WIN32
+ ret = general_options.addOption(OD("dbpath", "dbpath", moe::String,
+ "directory for datafiles - defaults to \\data\\db\\",
+ true, moe::Value(std::string("\\data\\db\\"))));
+#else
ret = general_options.addOption(OD("dbpath", "dbpath", moe::String,
- dbpathBuilder.str().c_str(), true));
+ "directory for datafiles - defaults to /data/db/",
+ true, moe::Value(std::string("/data/db"))));
+#endif
if (!ret.isOK()) {
return ret;
}
@@ -383,6 +397,426 @@ namespace mongo {
return Status::OK();
}
+ void printMongodHelp(const moe::OptionSection& options) {
+ std::cout << options.helpString() << std::endl;
+ };
+
+ namespace {
+ void sysRuntimeInfo() {
+ out() << "sysinfo:" << endl;
+#if defined(_SC_PAGE_SIZE)
+ out() << " page size: " << (int) sysconf(_SC_PAGE_SIZE) << endl;
+#endif
+#if defined(_SC_PHYS_PAGES)
+ out() << " _SC_PHYS_PAGES: " << sysconf(_SC_PHYS_PAGES) << endl;
+#endif
+#if defined(_SC_AVPHYS_PAGES)
+ out() << " _SC_AVPHYS_PAGES: " << sysconf(_SC_AVPHYS_PAGES) << endl;
+#endif
+ }
+ } // namespace
+
+ Status handlePreValidationMongodOptions(const moe::Environment& params,
+ const std::vector<std::string>& args) {
+ if (params.count("help")) {
+ printMongodHelp(serverOptions);
+ ::_exit(EXIT_SUCCESS);
+ }
+ if (params.count("version")) {
+ cout << mongodVersion() << endl;
+ printGitVersion();
+ printOpenSSLVersion();
+ ::_exit(EXIT_SUCCESS);
+ }
+ if (params.count("sysinfo")) {
+ sysRuntimeInfo();
+ ::_exit(EXIT_SUCCESS);
+ }
+
+ return Status::OK();
+ }
+
+ Status storeMongodOptions(const moe::Environment& params,
+ const std::vector<std::string>& args) {
+
+ Status ret = storeServerOptions(params, args);
+ if (!ret.isOK()) {
+ std::cerr << "Error storing command line: " << ret.toString() << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ if (params.count("dbpath")) {
+ storageGlobalParams.dbpath = params["dbpath"].as<string>();
+ if (params.count("fork") && storageGlobalParams.dbpath[0] != '/') {
+ // we need to change dbpath if we fork since we change
+ // cwd to "/"
+ // fork only exists on *nix
+ // so '/' is safe
+ storageGlobalParams.dbpath = serverGlobalParams.cwd + "/" +
+ storageGlobalParams.dbpath;
+ }
+ }
+#ifdef _WIN32
+ if (storageGlobalParams.dbpath.size() > 1 &&
+ storageGlobalParams.dbpath[storageGlobalParams.dbpath.size()-1] == '/') {
+ // size() check is for the unlikely possibility of --dbpath "/"
+ storageGlobalParams.dbpath =
+ storageGlobalParams.dbpath.erase(storageGlobalParams.dbpath.size()-1);
+ }
+#endif
+ if ( params.count("slowms")) {
+ serverGlobalParams.slowMS = params["slowms"].as<int>();
+ }
+
+ if ( params.count("syncdelay")) {
+ storageGlobalParams.syncdelay = params["syncdelay"].as<double>();
+ }
+
+ if (params.count("directoryperdb")) {
+ storageGlobalParams.directoryperdb = true;
+ }
+ if (params.count("cpu")) {
+ serverGlobalParams.cpu = true;
+ }
+ if (params.count("noauth")) {
+ AuthorizationManager::setAuthEnabled(false);
+ }
+ if (params.count("auth")) {
+ AuthorizationManager::setAuthEnabled(true);
+ }
+ if (params.count("quota")) {
+ storageGlobalParams.quota = true;
+ }
+ if (params.count("quotaFiles")) {
+ storageGlobalParams.quota = true;
+ storageGlobalParams.quotaFiles = params["quotaFiles"].as<int>() - 1;
+ }
+ if ((params.count("nodur") || params.count("nojournal")) &&
+ (params.count("dur") || params.count("journal"))) {
+ std::cerr << "Can't specify both --journal and --nojournal options." << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ 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("journalCommitInterval") ) {
+ // 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
+ // a dev environment.
+ storageGlobalParams.journalCommitInterval =
+ params["journalCommitInterval"].as<unsigned>();
+ if (storageGlobalParams.journalCommitInterval <= 1 ||
+ storageGlobalParams.journalCommitInterval > 300) {
+ std::cerr << "--journalCommitInterval out of allowed range (0-300ms)" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ }
+ if (params.count("journalOptions")) {
+ storageGlobalParams.durOptions = params["journalOptions"].as<int>();
+ }
+ if (params.count("nohints")) {
+ storageGlobalParams.useHints = false;
+ }
+ if (params.count("nopreallocj")) {
+ storageGlobalParams.preallocj = false;
+ }
+ if (params.count("httpinterface")) {
+ if (params.count("nohttpinterface")) {
+ std::cerr << "can't have both --httpinterface and --nohttpinterface" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ serverGlobalParams.isHttpInterfaceEnabled = true;
+ }
+ // SERVER-10019 Enabling rest/jsonp without --httpinterface should break in the future
+ if (params.count("rest")) {
+ if (params.count("nohttpinterface")) {
+ log() << "** WARNING: Should not specify both --rest and --nohttpinterface" <<
+ startupWarningsLog;
+ }
+ else if (!params.count("httpinterface")) {
+ log() << "** WARNING: --rest is specified without --httpinterface," <<
+ startupWarningsLog;
+ log() << "** enabling http interface" << startupWarningsLog;
+ serverGlobalParams.isHttpInterfaceEnabled = true;
+ }
+ serverGlobalParams.rest = true;
+ }
+ if (params.count("jsonp")) {
+ if (params.count("nohttpinterface")) {
+ log() << "** WARNING: Should not specify both --jsonp and --nohttpinterface" <<
+ startupWarningsLog;
+ }
+ else if (!params.count("httpinterface")) {
+ log() << "** WARNING --jsonp is specified without --httpinterface," <<
+ startupWarningsLog;
+ log() << "** enabling http interface" << startupWarningsLog;
+ serverGlobalParams.isHttpInterfaceEnabled = true;
+ }
+ serverGlobalParams.jsonp = true;
+ }
+ if (params.count("noscripting")) {
+ mongodGlobalParams.scriptingEnabled = false;
+ }
+ if (params.count("noprealloc")) {
+ storageGlobalParams.prealloc = false;
+ cout << "note: noprealloc may hurt performance in many applications" << endl;
+ }
+ if (params.count("smallfiles")) {
+ storageGlobalParams.smallfiles = true;
+ }
+ if (params.count("diaglog")) {
+ int x = params["diaglog"].as<int>();
+ if ( x < 0 || x > 7 ) {
+ std::cerr << "can't interpret --diaglog setting" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ _diaglog.setLevel(x);
+ }
+
+ if ((params.count("dur") || params.count("journal")) && params.count("repair")) {
+ std::cerr << "Can't specify both --journal and --repair options." << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ if (params.count("repair")) {
+ Record::MemoryTrackingEnabled = false;
+ mongodGlobalParams.upgrade = 1; // --repair implies --upgrade
+ mongodGlobalParams.repair = 1;
+ storageGlobalParams.dur = false;
+ }
+ if (params.count("upgrade")) {
+ Record::MemoryTrackingEnabled = false;
+ mongodGlobalParams.upgrade = 1;
+ }
+ if (params.count("notablescan")) {
+ storageGlobalParams.noTableScan = true;
+ }
+ if (params.count("master")) {
+ replSettings.master = true;
+ }
+ if (params.count("slave")) {
+ replSettings.slave = SimpleSlave;
+ }
+ if (params.count("slavedelay")) {
+ replSettings.slavedelay = params["slavedelay"].as<int>();
+ }
+ if (params.count("fastsync")) {
+ replSettings.fastsync = true;
+ }
+ if (params.count("autoresync")) {
+ replSettings.autoresync = true;
+ if( params.count("replSet") ) {
+ std::cerr << "--autoresync is not used with --replSet\nsee "
+ << "http://dochub.mongodb.org/core/resyncingaverystalereplicasetmember"
+ << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ }
+ if (params.count("source")) {
+ /* specifies what the source in local.sources should be */
+ replSettings.source = params["source"].as<string>().c_str();
+ }
+ if( params.count("pretouch") ) {
+ replSettings.pretouch = params["pretouch"].as<int>();
+ }
+ if (params.count("replSet")) {
+ if (params.count("slavedelay")) {
+ std::cerr << "--slavedelay cannot be used with --replSet" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ else if (params.count("only")) {
+ std::cerr << "--only cannot be used with --replSet" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ /* seed list of hosts for the repl set */
+ replSettings.replSet = params["replSet"].as<string>().c_str();
+ }
+ if (params.count("replIndexPrefetch")) {
+ replSettings.rsIndexPrefetch = params["replIndexPrefetch"].as<std::string>();
+ }
+ if (params.count("noIndexBuildRetry")) {
+ serverGlobalParams.indexBuildRetry = false;
+ }
+ if (params.count("only")) {
+ replSettings.only = params["only"].as<string>().c_str();
+ }
+ if( params.count("nssize") ) {
+ int x = params["nssize"].as<int>();
+ if (x <= 0 || x > (0x7fffffff/1024/1024)) {
+ std::cerr << "bad --nssize arg" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ storageGlobalParams.lenForNewNsFiles = x * 1024 * 1024;
+ verify(storageGlobalParams.lenForNewNsFiles > 0);
+ }
+ if (params.count("oplogSize")) {
+ long long x = params["oplogSize"].as<int>();
+ if (x <= 0) {
+ std::cerr << "bad --oplogSize arg" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ // note a small size such as x==1 is ok for an arbiter.
+ if( x > 1000 && sizeof(void*) == 4 ) {
+ StringBuilder sb;
+ std::cerr << "--oplogSize of " << x
+ << "MB is too big for 32 bit version. Use 64 bit build instead."
+ << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ replSettings.oplogSize = x * 1024 * 1024;
+ verify(replSettings.oplogSize > 0);
+ }
+ if (params.count("cacheSize")) {
+ long x = params["cacheSize"].as<long>();
+ if (x <= 0) {
+ std::cerr << "bad --cacheSize arg" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ std::cerr << "--cacheSize option not currently supported" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ if (!params.count("port")) {
+ if( params.count("configsvr") ) {
+ serverGlobalParams.port = ServerGlobalParams::ConfigServerPort;
+ }
+ if( params.count("shardsvr") ) {
+ if( params.count("configsvr") ) {
+ std::cerr << "can't do --shardsvr and --configsvr at the same time"
+ << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ serverGlobalParams.port = ServerGlobalParams::ShardServerPort;
+ }
+ }
+ else {
+ if (serverGlobalParams.port <= 0 || serverGlobalParams.port > 65535) {
+ std::cerr << "bad --port number" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ }
+ if ( params.count("configsvr" ) ) {
+ serverGlobalParams.configsvr = true;
+ storageGlobalParams.smallfiles = true; // config server implies small files
+ if (replSettings.usingReplSets() || replSettings.master || replSettings.slave) {
+ std::cerr << "replication should not be enabled on a config server" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ if (!params.count("nodur") && !params.count("nojournal"))
+ storageGlobalParams.dur = true;
+ if (!params.count("dbpath"))
+ storageGlobalParams.dbpath = "/data/configdb";
+ replSettings.master = true;
+ if (!params.count("oplogSize"))
+ replSettings.oplogSize = 5 * 1024 * 1024;
+ }
+ if ( params.count( "profile" ) ) {
+ serverGlobalParams.defaultProfile = params["profile"].as<int>();
+ }
+ if (params.count("ipv6")) {
+ enableIPv6();
+ }
+
+ if (params.count("noMoveParanoia") && params.count("moveParanoia")) {
+ std::cerr << "The moveParanoia and noMoveParanoia flags cannot both be set; "
+ << "please use only one of them." << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ if (params.count("noMoveParanoia"))
+ serverGlobalParams.moveParanoia = false;
+
+ if (params.count("moveParanoia"))
+ serverGlobalParams.moveParanoia = true;
+
+ if (params.count("pairwith") || params.count("arbiter") || params.count("opIdMem")) {
+ std::cerr << "****\n"
+ << "Replica Pairs have been deprecated. Invalid options: --pairwith, "
+ << "--arbiter, and/or --opIdMem\n"
+ << "<http://dochub.mongodb.org/core/replicapairs>\n"
+ << "****" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ // needs to be after things like --configsvr parsing, thus here.
+ if (params.count("repairpath")) {
+ storageGlobalParams.repairpath = params["repairpath"].as<string>();
+ if (!storageGlobalParams.repairpath.size()) {
+ std::cerr << "repairpath is empty" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ if (storageGlobalParams.dur &&
+ !str::startsWith(storageGlobalParams.repairpath,
+ storageGlobalParams.dbpath)) {
+ std::cerr << "You must use a --repairpath that is a subdirectory of "
+ << "--dbpath when using journaling" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ }
+ else {
+ storageGlobalParams.repairpath = storageGlobalParams.dbpath;
+ }
+
+ if (replSettings.pretouch)
+ log() << "--pretouch " << replSettings.pretouch << endl;
+
+ if (sizeof(void*) == 4 && !(params.count("nodur") || params.count("nojournal") ||
+ params.count("dur") || params.count("journal"))) {
+ // trying to make this stand out more like startup warnings
+ log() << endl;
+ warning() << "32-bit servers don't have journaling enabled by default. "
+ << "Please use --journal if you want durability." << endl;
+ log() << endl;
+ }
+
+ return Status::OK();
+ }
+
+ MONGO_INITIALIZER_GENERAL(ParseStartupConfiguration,
+ ("GlobalLogManager"),
+ ("default", "completedStartupConfig"))(InitializerContext* context) {
+
+ serverOptions = moe::OptionSection("Allowed options");
+ Status ret = addMongodOptions(&serverOptions);
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ moe::OptionsParser parser;
+ ret = parser.run(serverOptions, context->args(), context->env(), &serverParsedOptions);
+ if (!ret.isOK()) {
+ std::cerr << "Error parsing command line: " << ret.toString() << std::endl;
+ std::cerr << "use --help for help" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ ret = handlePreValidationMongodOptions(serverParsedOptions, context->args());
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ ret = serverParsedOptions.validate();
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ ret = storeMongodOptions(serverParsedOptions, context->args());
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ return Status::OK();
+ }
+
Status addModuleOptions(moe::OptionSection* options) {
Module::addAllOptions(options);
return Status::OK();
diff --git a/src/mongo/db/mongod_options.h b/src/mongo/db/mongod_options.h
index e507802684d..b5bab35e441 100644
--- a/src/mongo/db/mongod_options.h
+++ b/src/mongo/db/mongod_options.h
@@ -29,6 +29,8 @@
#pragma once
#include "mongo/base/status.h"
+#include "mongo/db/server_options.h"
+#include "mongo/db/storage_options.h"
namespace mongo {
@@ -38,7 +40,28 @@ namespace mongo {
namespace moe = mongo::optionenvironment;
+ struct MongodGlobalParams {
+ bool upgrade;
+ bool repair;
+ bool scriptingEnabled; // --noscripting
+
+ MongodGlobalParams() :
+ upgrade(0),
+ repair(0),
+ scriptingEnabled(true)
+ { }
+ };
+
+ extern MongodGlobalParams mongodGlobalParams;
+
Status addMongodOptions(moe::OptionSection* options);
+ void printMongodHelp(const moe::OptionSection& options);
+
+ Status handlePreValidationMongodOptions(const moe::Environment& params,
+ const std::vector<std::string>& args);
+
+ Status storeMongodOptions(const moe::Environment& params, const std::vector<std::string>& args);
+
Status addModuleOptions(moe::OptionSection* options);
}
diff --git a/src/mongo/db/namespace_details.cpp b/src/mongo/db/namespace_details.cpp
index daf308f5805..7aaf30ed940 100644
--- a/src/mongo/db/namespace_details.cpp
+++ b/src/mongo/db/namespace_details.cpp
@@ -90,7 +90,7 @@ namespace mongo {
#if defined(_DEBUG)
void NamespaceDetails::dump(const Namespace& k) {
- if( !cmdLine.dur )
+ if (!storageGlobalParams.dur)
cout << "ns offsets which follow will not display correctly with --journal disabled" << endl;
size_t ofs = 1; // 1 is sentinel that the find call below failed
diff --git a/src/mongo/db/namespace_details.h b/src/mongo/db/namespace_details.h
index 5129ba1724f..168ee241bce 100644
--- a/src/mongo/db/namespace_details.h
+++ b/src/mongo/db/namespace_details.h
@@ -645,8 +645,4 @@ namespace mongo {
}
return make_inlock(ns);
}
-
- extern string dbpath; // --dbpath parm
- extern bool directoryperdb;
-
} // namespace mongo
diff --git a/src/mongo/db/ops/query.cpp b/src/mongo/db/ops/query.cpp
index ceb86e427cc..05d9ad81f35 100644
--- a/src/mongo/db/ops/query.cpp
+++ b/src/mongo/db/ops/query.cpp
@@ -49,6 +49,7 @@
#include "mongo/db/repl/oplog.h"
#include "mongo/db/repl/repl_reads_ok.h"
#include "mongo/db/scanandorder.h"
+#include "mongo/db/storage_options.h"
#include "mongo/s/d_logic.h"
#include "mongo/s/stale_exception.h" // for SendStaleConfigException
#include "mongo/server.h"
@@ -949,7 +950,7 @@ namespace mongo {
BSONObj resObject; // put inside since we don't own the memory
- Client::ReadContext ctx( ns , dbpath ); // read locks
+ Client::ReadContext ctx(ns, storageGlobalParams.dbpath); // read locks
replVerifyReadsOk(&pq);
bool found = Helpers::findById( currentClient, ns, query, resObject, &nsFound, &indexFound );
@@ -1116,7 +1117,7 @@ namespace mongo {
}
try {
- Client::ReadContext ctx( ns , dbpath ); // read locks
+ Client::ReadContext ctx(ns, storageGlobalParams.dbpath); // read locks
const ChunkVersion shardingVersionAtStart = shardingState.getVersion( ns );
replVerifyReadsOk(&pq);
diff --git a/src/mongo/db/pdfile.cpp b/src/mongo/db/pdfile.cpp
index 3f0a684e5fe..852e0d4d76e 100644
--- a/src/mongo/db/pdfile.cpp
+++ b/src/mongo/db/pdfile.cpp
@@ -73,6 +73,7 @@ _ disallow system* manipulations from the database.
#include "mongo/db/repl/is_master.h"
#include "mongo/db/sort_phase_one.h"
#include "mongo/db/repl/oplog.h"
+#include "mongo/db/storage_options.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/file.h"
#include "mongo/util/file_allocator.h"
@@ -124,8 +125,6 @@ namespace mongo {
/* ----------------------------------------- */
const char FREELIST_NS[] = ".$freelist";
- bool directoryperdb = false;
- string repairpath;
string pidfilepath;
DataFileMgr theDataFileMgr;
@@ -180,12 +179,16 @@ namespace mongo {
virtual const char * op() const = 0;
};
- void _applyOpToDataFiles( const char *database, FileOp &fo, bool afterAllocator = false, const string& path = dbpath );
+ void _applyOpToDataFiles(const char *database, FileOp &fo, bool afterAllocator = false,
+ const string& path = storageGlobalParams.dbpath);
void _deleteDataFiles(const char *database) {
- if ( directoryperdb ) {
+ if (storageGlobalParams.directoryperdb) {
FileAllocator::get()->waitUntilFinished();
- MONGO_ASSERT_ON_EXCEPTION_WITH_MSG( boost::filesystem::remove_all( boost::filesystem::path( dbpath ) / database ), "delete data files with a directoryperdb" );
+ MONGO_ASSERT_ON_EXCEPTION_WITH_MSG(
+ boost::filesystem::remove_all(
+ boost::filesystem::path(storageGlobalParams.dbpath) / database),
+ "delete data files with a directoryperdb");
return;
}
class : public FileOp {
@@ -200,7 +203,7 @@ namespace mongo {
}
void checkConfigNS(const char *ns) {
- if ( cmdLine.configsvr &&
+ if ( serverGlobalParams.configsvr &&
!( str::startsWith( ns, "config." ) ||
str::startsWith( ns, "local." ) ||
str::startsWith( ns, "admin." ) ) ) {
@@ -1273,7 +1276,7 @@ namespace mongo {
// back up original database files to 'temp' dir
void _renameForBackup( const char *database, const Path &reservedPath ) {
Path newPath( reservedPath );
- if ( directoryperdb )
+ if (storageGlobalParams.directoryperdb)
newPath /= database;
class Renamer : public FileOp {
public:
@@ -1295,8 +1298,8 @@ namespace mongo {
// move temp files to standard data dir
void _replaceWithRecovered( const char *database, const char *reservedPathString ) {
- Path newPath( dbpath );
- if ( directoryperdb )
+ Path newPath(storageGlobalParams.dbpath);
+ if (storageGlobalParams.directoryperdb)
newPath /= database;
class Replacer : public FileOp {
public:
@@ -1318,7 +1321,7 @@ namespace mongo {
// generate a directory name for storing temp data files
Path uniqueReservedPath( const char *prefix ) {
- Path repairPath = Path( repairpath );
+ Path repairPath = Path(storageGlobalParams.repairpath);
Path reservedPath;
int i = 0;
bool exists = false;
@@ -1363,19 +1366,19 @@ namespace mongo {
const char * dbName = dbNameS.c_str();
stringstream ss;
- ss << "localhost:" << cmdLine.port;
+ ss << "localhost:" << serverGlobalParams.port;
string localhost = ss.str();
problem() << "repairDatabase " << dbName << endl;
verify( cc().database()->name() == dbName );
- verify( cc().database()->path() == dbpath );
+ verify(cc().database()->path() == storageGlobalParams.dbpath);
BackgroundOperation::assertNoBgOpInProgForDb(dbName);
getDur().syncDataAndTruncateJournal(); // Must be done before and after repair
boost::intmax_t totalSize = dbSize( dbName );
- boost::intmax_t freeSize = File::freeSpace(repairpath);
+ boost::intmax_t freeSize = File::freeSpace(storageGlobalParams.repairpath);
if ( freeSize > -1 && freeSize < totalSize ) {
stringstream ss;
ss << "Cannot repair database " << dbName << " having size: " << totalSize
@@ -1421,14 +1424,15 @@ namespace mongo {
}
Client::Context ctx( dbName );
- Database::closeDatabase( dbName, dbpath );
+ Database::closeDatabase(dbName, storageGlobalParams.dbpath);
if ( backupOriginalFiles ) {
_renameForBackup( dbName, reservedPath );
}
else {
_deleteDataFiles( dbName );
- MONGO_ASSERT_ON_EXCEPTION( boost::filesystem::create_directory( Path( dbpath ) / dbName ) );
+ MONGO_ASSERT_ON_EXCEPTION(
+ boost::filesystem::create_directory(Path(storageGlobalParams.dbpath) / dbName));
}
_replaceWithRecovered( dbName, reservedPathString.c_str() );
@@ -1445,7 +1449,7 @@ namespace mongo {
string c = database;
c += '.';
boost::filesystem::path p(path);
- if ( directoryperdb )
+ if (storageGlobalParams.directoryperdb)
p /= database;
boost::filesystem::path q;
q = p / (c+"ns");
diff --git a/src/mongo/db/pipeline/document_source_cursor.cpp b/src/mongo/db/pipeline/document_source_cursor.cpp
index 009697a58f7..e399d90e28c 100644
--- a/src/mongo/db/pipeline/document_source_cursor.cpp
+++ b/src/mongo/db/pipeline/document_source_cursor.cpp
@@ -34,6 +34,7 @@
#include "mongo/db/instance.h"
#include "mongo/db/ops/query.h"
#include "mongo/db/pipeline/document.h"
+#include "mongo/db/storage_options.h"
#include "mongo/s/d_logic.h"
#include "mongo/s/stale_exception.h" // for SendStaleConfigException
@@ -106,7 +107,7 @@ namespace mongo {
// We have already validated the sharding version when we constructed the cursor
// so we shouldn't check it again.
Lock::DBRead lk(ns);
- Client::Context ctx(ns, dbpath, /*doVersion=*/false);
+ Client::Context ctx(ns, storageGlobalParams.dbpath, /*doVersion=*/false);
ClientCursorPin pin(_cursorId);
ClientCursor* cursor = pin.c();
@@ -212,7 +213,7 @@ namespace mongo {
return Value();
Lock::DBRead lk(ns);
- Client::Context ctx(ns, dbpath, /*doVersion=*/false);
+ Client::Context ctx(ns, storageGlobalParams.dbpath, /*doVersion=*/false);
ClientCursorPin pin(_cursorId);
ClientCursor* cursor = pin.c();
diff --git a/src/mongo/db/pipeline/document_source_merge_cursors.cpp b/src/mongo/db/pipeline/document_source_merge_cursors.cpp
index 194e3c1b262..d3f4c5f1bcf 100644
--- a/src/mongo/db/pipeline/document_source_merge_cursors.cpp
+++ b/src/mongo/db/pipeline/document_source_merge_cursors.cpp
@@ -30,7 +30,6 @@
#include "mongo/db/pipeline/document_source.h"
-#include "mongo/db/cmdline.h"
namespace mongo {
diff --git a/src/mongo/db/query/new_find.cpp b/src/mongo/db/query/new_find.cpp
index 295ba4a9996..a3d6fce6afe 100644
--- a/src/mongo/db/query/new_find.cpp
+++ b/src/mongo/db/query/new_find.cpp
@@ -45,7 +45,9 @@
#include "mongo/db/query/stage_builder.h"
#include "mongo/db/query/type_explain.h"
#include "mongo/db/repl/repl_reads_ok.h"
+#include "mongo/db/server_options.h"
#include "mongo/db/server_parameters.h"
+#include "mongo/db/storage_options.h"
#include "mongo/s/chunk_version.h"
#include "mongo/s/d_logic.h"
#include "mongo/s/stale_exception.h"
@@ -166,7 +168,7 @@ namespace mongo {
vector<QuerySolution*> solutions;
size_t options = QueryPlanner::DEFAULT;
- if (cmdLine.noTableScan) {
+ if (storageGlobalParams.noTableScan) {
const string& ns = canonicalQuery->ns();
// There are certain cases where we ignore this restriction:
bool ignore = canonicalQuery->getQueryObj().isEmpty()
@@ -386,7 +388,7 @@ namespace mongo {
*/
std::string newRunQuery(Message& m, QueryMessage& q, CurOp& curop, Message &result) {
// This is a read lock.
- Client::ReadContext ctx(q.ns, dbpath);
+ Client::ReadContext ctx(q.ns, storageGlobalParams.dbpath);
// Parse, canonicalize, plan, transcribe, and get a runner.
Runner* rawRunner;
@@ -560,7 +562,7 @@ namespace mongo {
// Fill in the missing run-time fields in explain, starting with propeties of
// the process running the query.
std::string server = mongoutils::str::stream()
- << getHostNameCached() << ":" << cmdLine.port;
+ << getHostNameCached() << ":" << serverGlobalParams.port;
explain->setServer(server);
// Fill in the number of documents consummed that were involved in an ongoing
diff --git a/src/mongo/db/query_plan.cpp b/src/mongo/db/query_plan.cpp
index 6fd0d78889c..36d58c0b10b 100644
--- a/src/mongo/db/query_plan.cpp
+++ b/src/mongo/db/query_plan.cpp
@@ -29,7 +29,6 @@
#include "mongo/db/query_plan.h"
#include "mongo/db/btreecursor.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/index_selection.h"
#include "mongo/db/index/catalog_hack.h"
#include "mongo/db/index/emulated_cursor.h"
@@ -370,7 +369,7 @@ doneCheckOrder:
}
void QueryPlan::checkTableScanAllowed() const {
- if ( likely( !cmdLine.noTableScan ) )
+ if (likely(!storageGlobalParams.noTableScan))
return;
// TODO - is this desirable? See SERVER-2222.
@@ -386,7 +385,8 @@ doneCheckOrder:
if ( !nsdetails( ns() ) )
return;
- uassert( 10111, (string)"table scans not allowed:" + ns(), !cmdLine.noTableScan );
+ uassert(10111, (string)"table scans not allowed:" + ns(),
+ !storageGlobalParams.noTableScan);
}
int QueryPlan::independentRangesSingleIntervalLimit() const {
diff --git a/src/mongo/db/queryoptimizercursorimpl.cpp b/src/mongo/db/queryoptimizercursorimpl.cpp
index 76e78a276bc..0545aa7ea9f 100644
--- a/src/mongo/db/queryoptimizercursorimpl.cpp
+++ b/src/mongo/db/queryoptimizercursorimpl.cpp
@@ -38,8 +38,6 @@
namespace mongo {
- extern bool useHints;
-
QueryOptimizerCursorImpl* QueryOptimizerCursorImpl::make
( auto_ptr<MultiPlanScanner>& mps,
const QueryPlanSelectionPolicy& planPolicy,
@@ -394,7 +392,7 @@ namespace mongo {
}
void CursorGenerator::setArgumentsHint() {
- if ( useHints && _parsedQuery ) {
+ if (storageGlobalParams.useHints && _parsedQuery) {
_argumentsHint = _parsedQuery->getHint();
}
diff --git a/src/mongo/db/range_deleter_db_env.cpp b/src/mongo/db/range_deleter_db_env.cpp
index 5b76f118d22..326fdbfd825 100644
--- a/src/mongo/db/range_deleter_db_env.cpp
+++ b/src/mongo/db/range_deleter_db_env.cpp
@@ -31,7 +31,6 @@
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/clientcursor.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/dbhelpers.h"
#include "mongo/db/repl/rs.h"
#include "mongo/db/repl/write_concern.h"
@@ -85,7 +84,7 @@ namespace mongo {
keyPattern),
false, /*maxInclusive*/
replSet? secondaryThrottle : false,
- cmdLine.moveParanoia ? &removeSaver : NULL,
+ serverGlobalParams.moveParanoia ? &removeSaver : NULL,
true, /*fromMigrate*/
true); /*onlyRemoveOrphans*/
diff --git a/src/mongo/db/repl/consensus.cpp b/src/mongo/db/repl/consensus.cpp
index 68e6cb5b456..3f7c8d65822 100644
--- a/src/mongo/db/repl/consensus.cpp
+++ b/src/mongo/db/repl/consensus.cpp
@@ -28,7 +28,6 @@
#include "mongo/pch.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/repl/multicmd.h"
#include "mongo/db/repl/rs.h"
@@ -385,7 +384,7 @@ namespace mongo {
rs.sethbmsg("",9);
- if( !allUp && time(0) - cmdLine.started < 60 * 5 ) {
+ if (!allUp && time(0) - serverGlobalParams.started < 60 * 5) {
/* the idea here is that if a bunch of nodes bounce all at once, we don't want to drop data
if we don't have to -- we'd rather be offline and wait a little longer instead
todo: make this configurable.
diff --git a/src/mongo/db/repl/health.cpp b/src/mongo/db/repl/health.cpp
index 6c94a4c1762..90aa448c733 100644
--- a/src/mongo/db/repl/health.cpp
+++ b/src/mongo/db/repl/health.cpp
@@ -31,7 +31,6 @@
#include "mongo/db/repl/health.h"
#include "mongo/client/connpool.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/dbhelpers.h"
#include "mongo/db/repl/bgsync.h"
@@ -320,7 +319,7 @@ namespace mongo {
s << tr() << td(_self->fullName() + " (me)") <<
td(_self->id()) <<
td("1") << //up
- td(ago(cmdLine.started)) <<
+ td(ago(serverGlobalParams.started)) <<
td("") << // last heartbeat
td(ToString(_self->config().votes)) <<
td(ToString(_self->config().priority)) <<
@@ -433,7 +432,7 @@ namespace mongo {
bb.append("health", 1.0);
bb.append("state", (int)myState.s);
bb.append("stateStr", myState.toString());
- bb.append("uptime", (unsigned)(time(0) - cmdLine.started));
+ bb.append("uptime", (unsigned)(time(0) - serverGlobalParams.started));
if (!_self->config().arbiterOnly) {
bb.appendTimestamp("optime", lastOpTimeWritten.asDate());
bb.appendDate("optimeDate", lastOpTimeWritten.getSecs() * 1000LL);
diff --git a/src/mongo/db/repl/heartbeat.cpp b/src/mongo/db/repl/heartbeat.cpp
index a64b520eb5c..f22c2526369 100644
--- a/src/mongo/db/repl/heartbeat.cpp
+++ b/src/mongo/db/repl/heartbeat.cpp
@@ -124,9 +124,10 @@ namespace mongo {
}
{
string s = string(cmdObj.getStringField("replSetHeartbeat"));
- if( cmdLine.ourSetName() != s ) {
+ if (replSettings.ourSetName() != s) {
errmsg = "repl set names do not match";
- log() << "replSet set names do not match, our cmdline: " << cmdLine._replSet << rsLog;
+ log() << "replSet set names do not match, our cmdline: " << replSettings.replSet
+ << rsLog;
log() << "replSet s: " << s << rsLog;
result.append("mismatch", true);
return false;
diff --git a/src/mongo/db/repl/master_slave.cpp b/src/mongo/db/repl/master_slave.cpp
index e1983cbd096..0b90942e14b 100644
--- a/src/mongo/db/repl/master_slave.cpp
+++ b/src/mongo/db/repl/master_slave.cpp
@@ -52,6 +52,7 @@
#include "mongo/db/repl/replication_server_status.h" // replSettings
#include "mongo/db/repl/rs.h" // replLocalAuth()
#include "mongo/db/server_parameters.h"
+#include "mongo/db/storage_options.h"
namespace mongo {
@@ -103,7 +104,7 @@ namespace mongo {
void help(stringstream&h) const { h << "resync (from scratch) an out of date replica slave.\nhttp://dochub.mongodb.org/core/masterslave"; }
CmdResync() : Command("resync") { }
virtual bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
- if( cmdLine.usingReplSets() ) {
+ if (replSettings.usingReplSets()) {
errmsg = "resync command not currently supported with replica sets. See RS102 info in the mongodb documentations";
result.append("info", "http://dochub.mongodb.org/core/resyncingaverystalereplicasetmember");
return false;
@@ -295,7 +296,7 @@ namespace mongo {
SourceVector old = v;
v.clear();
- if ( !cmdLine.source.empty() ) {
+ if (!replSettings.source.empty()) {
// --source <host> specified.
// check that no items are in sources other than that
// add if missing
@@ -306,16 +307,18 @@ namespace mongo {
while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&obj, NULL))) {
n++;
ReplSource tmp(obj);
- if ( tmp.hostName != cmdLine.source ) {
- log() << "repl: --source " << cmdLine.source << " != " << tmp.hostName << " from local.sources collection" << endl;
+ if (tmp.hostName != replSettings.source) {
+ log() << "repl: --source " << replSettings.source << " != " << tmp.hostName
+ << " from local.sources collection" << endl;
log() << "repl: for instructions on changing this slave's source, see:" << endl;
log() << "http://dochub.mongodb.org/core/masterslave" << endl;
log() << "repl: terminating mongod after 30 seconds" << endl;
sleepsecs(30);
dbexit( EXIT_REPLICATION_ERROR );
}
- if ( tmp.only != cmdLine.only ) {
- log() << "--only " << cmdLine.only << " != " << tmp.only << " from local.sources collection" << endl;
+ if (tmp.only != replSettings.only) {
+ log() << "--only " << replSettings.only << " != " << tmp.only
+ << " from local.sources collection" << endl;
log() << "terminating after 30 seconds" << endl;
sleepsecs(30);
dbexit( EXIT_REPLICATION_ERROR );
@@ -326,14 +329,14 @@ namespace mongo {
if ( n == 0 ) {
// source missing. add.
ReplSource s;
- s.hostName = cmdLine.source;
- s.only = cmdLine.only;
+ s.hostName = replSettings.source;
+ s.only = replSettings.only;
s.save();
}
}
else {
try {
- massert( 10384 , "--only requires use of --source", cmdLine.only.empty());
+ massert(10384 , "--only requires use of --source", replSettings.only.empty());
}
catch ( ... ) {
dbexit( EXIT_BADOPTIONS );
@@ -470,7 +473,7 @@ namespace mongo {
}
bool ReplSource::handleDuplicateDbName( const BSONObj &op, const char *ns, const char *db ) {
- if ( dbHolder()._isLoaded( ns, dbpath ) ) {
+ if (dbHolder()._isLoaded(ns, storageGlobalParams.dbpath)) {
// Database is already present.
return true;
}
@@ -480,7 +483,7 @@ namespace mongo {
// missing from master after optime "ts".
return false;
}
- if ( Database::duplicateUncasedName( false, db, dbpath ).empty() ) {
+ if (Database::duplicateUncasedName(false, db, storageGlobalParams.dbpath).empty()) {
// No duplicate database names are present.
return true;
}
@@ -533,7 +536,7 @@ namespace mongo {
// Check for duplicates again, since we released the lock above.
set< string > duplicates;
- Database::duplicateUncasedName( false, db, dbpath, &duplicates );
+ Database::duplicateUncasedName(false, db, storageGlobalParams.dbpath, &duplicates);
// The database is present on the master and no conflicting databases
// are present on the master. Drop any local conflicts.
@@ -546,7 +549,7 @@ namespace mongo {
}
massert( 14034, "Duplicate database names present after attempting to delete duplicates",
- Database::duplicateUncasedName( false, db, dbpath ).empty() );
+ Database::duplicateUncasedName(false, db, storageGlobalParams.dbpath).empty() );
return true;
}
@@ -603,8 +606,9 @@ namespace mongo {
if ( !only.empty() && only != clientName )
return;
- if( cmdLine.pretouch && !alreadyLocked/*doesn't make sense if in write lock already*/ ) {
- if( cmdLine.pretouch > 1 ) {
+ if (replSettings.pretouch &&
+ !alreadyLocked/*doesn't make sense if in write lock already*/) {
+ if (replSettings.pretouch > 1) {
/* note: this is bad - should be put in ReplSource. but this is first test... */
static int countdown;
verify( countdown >= 0 );
@@ -614,12 +618,12 @@ namespace mongo {
else {
const int m = 4;
if( tp.get() == 0 ) {
- int nthr = min(8, cmdLine.pretouch);
+ int nthr = min(8, replSettings.pretouch);
nthr = max(nthr, 1);
tp.reset( new ThreadPool(nthr) );
}
vector<BSONObj> v;
- oplogReader.peek(v, cmdLine.pretouch);
+ oplogReader.peek(v, replSettings.pretouch);
unsigned a = 0;
while( 1 ) {
if( a >= v.size() ) break;
@@ -1021,7 +1025,7 @@ namespace mongo {
int ReplSource::sync(int& nApplied) {
_sleepAdviceTime = 0;
ReplInfo r("sync");
- if ( !cmdLine.quiet ) {
+ if (!serverGlobalParams.quiet) {
LogstreamBuilder l = log();
l << "repl: syncing from ";
if( sourceName() != "main" ) {
@@ -1032,7 +1036,8 @@ namespace mongo {
nClonedThisPass = 0;
// FIXME Handle cases where this db isn't on default port, or default port is spec'd in hostName.
- if ( (string("localhost") == hostName || string("127.0.0.1") == hostName) && cmdLine.port == CmdLine::DefaultDBPort ) {
+ if ((string("localhost") == hostName || string("127.0.0.1") == hostName) &&
+ serverGlobalParams.port == ServerGlobalParams::DefaultDBPort) {
log() << "repl: can't sync from self (localhost). sources configuration may be wrong." << endl;
sleepsecs(5);
return -1;
@@ -1172,7 +1177,7 @@ namespace mongo {
stringstream ss;
ss << "repl: sleep " << s << " sec before next pass";
string msg = ss.str();
- if ( ! cmdLine.quiet )
+ if (!serverGlobalParams.quiet)
log() << msg << endl;
ReplInfo r(msg.c_str());
sleepsecs(s);
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index e76e192bd34..3c677781e0a 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -50,6 +50,7 @@
#include "mongo/db/repl/rs.h"
#include "mongo/db/repl/write_concern.h"
#include "mongo/db/stats/counters.h"
+#include "mongo/db/storage_options.h"
#include "mongo/s/d_logic.h"
#include "mongo/util/elapsed_tracker.h"
#include "mongo/util/file.h"
@@ -85,7 +86,7 @@ namespace mongo {
{
const char *logns = rsoplog;
if ( rsOplogDetails == 0 ) {
- Client::Context ctx(logns , dbpath);
+ Client::Context ctx(logns, storageGlobalParams.dbpath);
localDB = ctx.db();
verify( localDB );
rsOplogDetails = nsdetails(logns);
@@ -226,7 +227,7 @@ namespace mongo {
{
const char *logns = rsoplog;
if ( rsOplogDetails == 0 ) {
- Client::Context ctx(logns , dbpath);
+ Client::Context ctx(logns, storageGlobalParams.dbpath);
localDB = ctx.db();
verify( localDB );
rsOplogDetails = nsdetails(logns);
@@ -300,7 +301,7 @@ namespace mongo {
if( logNS == 0 ) {
logNS = "local.oplog.$main";
if ( localOplogMainDetails == 0 ) {
- Client::Context ctx(logNS , dbpath);
+ Client::Context ctx(logNS, storageGlobalParams.dbpath);
localDB = ctx.db();
verify( localDB );
localOplogMainDetails = nsdetails(logNS);
@@ -310,7 +311,7 @@ namespace mongo {
r = theDataFileMgr.fast_oplog_insert(localOplogMainDetails, logNS, len);
}
else {
- Client::Context ctx(logNS, dbpath);
+ Client::Context ctx(logNS, storageGlobalParams.dbpath);
verify( nsdetails( logNS ) );
// first we allocate the space, then we fill it below.
r = theDataFileMgr.fast_oplog_insert( nsdetails( logNS ), logNS, len);
@@ -371,7 +372,7 @@ namespace mongo {
const char * ns = "local.oplog.$main";
- bool rs = !cmdLine._replSet.empty();
+ bool rs = !replSettings.replSet.empty();
if( rs )
ns = rsoplog;
@@ -381,9 +382,9 @@ namespace mongo {
if ( nsd ) {
- if ( cmdLine.oplogSize != 0 ) {
+ if (replSettings.oplogSize != 0) {
int o = (int)(nsd->storageSize() / ( 1024 * 1024 ) );
- int n = (int)(cmdLine.oplogSize / ( 1024 * 1024 ) );
+ int n = (int)(replSettings.oplogSize / (1024 * 1024));
if ( n != o ) {
stringstream ss;
ss << "cmdline oplogsize (" << n << ") different than existing (" << o << ") see: http://dochub.mongodb.org/core/increase-oplog";
@@ -405,8 +406,8 @@ namespace mongo {
/* create an oplog collection, if it doesn't yet exist. */
BSONObjBuilder b;
double sz;
- if ( cmdLine.oplogSize != 0 )
- sz = (double)cmdLine.oplogSize;
+ if (replSettings.oplogSize != 0)
+ sz = (double)replSettings.oplogSize;
else {
/* not specified. pick a default size */
sz = 50.0 * 1024 * 1024;
@@ -416,7 +417,8 @@ namespace mongo {
sz = (256-64) * 1024 * 1024;
#else
sz = 990.0 * 1024 * 1024;
- boost::intmax_t free = File::freeSpace(dbpath); //-1 if call not supported.
+ boost::intmax_t free =
+ File::freeSpace(storageGlobalParams.dbpath); //-1 if call not supported.
double fivePct = free * 0.05;
if ( fivePct > sz )
sz = fivePct;
diff --git a/src/mongo/db/repl/repl_start.cpp b/src/mongo/db/repl/repl_start.cpp
index e66c9aace7b..71e883db51c 100644
--- a/src/mongo/db/repl/repl_start.cpp
+++ b/src/mongo/db/repl/repl_start.cpp
@@ -32,7 +32,6 @@
#include <boost/thread.hpp>
#include <iostream>
-#include "mongo/db/cmdline.h"
#include "mongo/db/repl/master_slave.h"
#include "mongo/db/repl/oplog.h"
#include "mongo/db/repl/replication_server_status.h"
@@ -43,7 +42,7 @@ namespace mongo {
void startReplication() {
/* if we are going to be a replica set, we aren't doing other forms of replication. */
- if( !cmdLine._replSet.empty() ) {
+ if (!replSettings.replSet.empty()) {
if( replSettings.slave || replSettings.master ) {
log() << "***" << endl;
log() << "ERROR: can't use --slave or --master replication options with --replSet" << endl;
@@ -52,7 +51,7 @@ namespace mongo {
newRepl();
replSet = true;
- ReplSetCmdline *replSetCmdline = new ReplSetCmdline(cmdLine._replSet);
+ ReplSetCmdline *replSetCmdline = new ReplSetCmdline(replSettings.replSet);
boost::thread t( boost::bind( &startReplSets, replSetCmdline) );
return;
diff --git a/src/mongo/db/repl/replication_server_status.cpp b/src/mongo/db/repl/replication_server_status.cpp
index ddbe4d2c312..f50cd5f913e 100644
--- a/src/mongo/db/repl/replication_server_status.cpp
+++ b/src/mongo/db/repl/replication_server_status.cpp
@@ -40,6 +40,7 @@
#include "mongo/db/repl/master_slave.h"
#include "mongo/db/repl/oplogreader.h"
#include "mongo/db/repl/rs.h"
+#include "mongo/db/storage_options.h"
#include "mongo/db/wire_version.h"
namespace mongo {
@@ -84,7 +85,7 @@ namespace mongo {
int n = 0;
list<BSONObj> src;
{
- Client::ReadContext ctx("local.sources", dbpath);
+ Client::ReadContext ctx("local.sources", storageGlobalParams.dbpath);
auto_ptr<Runner> runner(InternalPlanner::collectionScan("local.sources"));
BSONObj obj;
Runner::RunnerState state;
diff --git a/src/mongo/db/repl/replication_server_status.h b/src/mongo/db/repl/replication_server_status.h
index e3e7d3b4460..3b7238b7c63 100644
--- a/src/mongo/db/repl/replication_server_status.h
+++ b/src/mongo/db/repl/replication_server_status.h
@@ -57,6 +57,25 @@ namespace mongo {
int slavedelay;
+ long long oplogSize; // --oplogSize
+
+ // for master/slave replication
+ std::string source; // --source
+ std::string only; // --only
+ int pretouch; // --pretouch for replication application (experimental)
+
+ std::string replSet; // --replSet[/<seedlist>]
+ std::string ourSetName() const {
+ std::string setname;
+ size_t sl = replSet.find('/');
+ if( sl == std::string::npos )
+ return replSet;
+ return replSet.substr(0, sl);
+ }
+ bool usingReplSets() const { return !replSet.empty(); }
+
+ std::string rsIndexPrefetch;// --indexPrefetch
+
std::set<std::string> discoveredSeeds;
mutex discoveredSeeds_mx;
@@ -68,6 +87,8 @@ namespace mongo {
fastsync(),
autoresync(false),
slavedelay(),
+ oplogSize(0),
+ pretouch(0),
discoveredSeeds(),
discoveredSeeds_mx("ReplSettings::discoveredSeeds") {
}
diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp
index 1539436b9a1..77a1149e8b4 100644
--- a/src/mongo/db/repl/replset_commands.cpp
+++ b/src/mongo/db/repl/replset_commands.cpp
@@ -33,7 +33,6 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/repl/health.h"
#include "mongo/db/repl/oplog.h"
diff --git a/src/mongo/db/repl/replset_web_handler.cpp b/src/mongo/db/repl/replset_web_handler.cpp
index 6ffdad86d3a..2bc56bd9f58 100644
--- a/src/mongo/db/repl/replset_web_handler.cpp
+++ b/src/mongo/db/repl/replset_web_handler.cpp
@@ -28,9 +28,9 @@
#include "mongo/platform/basic.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/dbwebserver.h"
#include "mongo/db/jsobj.h"
+#include "mongo/db/repl/replication_server_status.h" // replSettings
#include "mongo/db/repl/rs.h"
#include "mongo/util/mongoutils/html.h"
#include "mongo/util/mongoutils/str.h"
@@ -74,7 +74,7 @@ namespace {
s << p(t);
if( theReplSet == 0 ) {
- if( cmdLine._replSet.empty() )
+ if (replSettings.replSet.empty())
s << p("Not using --replSet");
else {
s << p("Still starting up, or else set is not yet " + a("http://dochub.mongodb.org/core/replicasetconfiguration#ReplicaSetConfiguration-InitialSetup", "", "initiated")
@@ -105,7 +105,7 @@ namespace {
);
if( theReplSet == 0 ) {
- if( cmdLine._replSet.empty() )
+ if (replSettings.replSet.empty())
s << p("Not using --replSet");
else {
s << p("Still starting up, or else set is not yet " + a("http://dochub.mongodb.org/core/replicasetconfiguration#ReplicaSetConfiguration-InitialSetup", "", "initiated")
diff --git a/src/mongo/db/repl/rs.cpp b/src/mongo/db/repl/rs.cpp
index e437245802c..02a41334784 100644
--- a/src/mongo/db/repl/rs.cpp
+++ b/src/mongo/db/repl/rs.cpp
@@ -33,7 +33,6 @@
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/client.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/dbhelpers.h"
#include "mongo/db/instance.h"
#include "mongo/db/repl/bgsync.h"
@@ -440,7 +439,7 @@ namespace mongo {
}
// Figure out indexPrefetch setting
- std::string& prefetch = cmdLine.rsIndexPrefetch;
+ std::string& prefetch = replSettings.rsIndexPrefetch;
if (!prefetch.empty()) {
IndexPrefetchConfig prefetchConfig = PREFETCH_ALL;
if (prefetch == "none")
diff --git a/src/mongo/db/repl/rs.h b/src/mongo/db/repl/rs.h
index 6d8c616c8a4..f33ec6f3798 100644
--- a/src/mongo/db/repl/rs.h
+++ b/src/mongo/db/repl/rs.h
@@ -694,7 +694,7 @@ namespace mongo {
bool check(string& errmsg, BSONObjBuilder& result) {
if( !replSet ) {
errmsg = "not running with --replSet";
- if( cmdLine.configsvr ) {
+ if (serverGlobalParams.configsvr) {
result.append("info", "configsvr"); // for shell prompt
}
return false;
diff --git a/src/mongo/db/repl/rs_config.cpp b/src/mongo/db/repl/rs_config.cpp
index fcef0ccdcf8..b21370719a6 100644
--- a/src/mongo/db/repl/rs_config.cpp
+++ b/src/mongo/db/repl/rs_config.cpp
@@ -36,6 +36,7 @@
#include "mongo/db/instance.h"
#include "mongo/db/repl/connections.h"
#include "mongo/db/repl/oplog.h"
+#include "mongo/db/repl/replication_server_status.h" // replSettings
#include "mongo/db/repl/rs.h"
#include "mongo/util/net/hostandport.h"
#include "mongo/util/text.h"
@@ -350,8 +351,9 @@ namespace mongo {
void ReplSetConfig::checkRsConfig() const {
uassert(13132,
- str::stream() << "nonmatching repl set name in _id field: " << _id << " vs. " << cmdLine.ourSetName(),
- _id == cmdLine.ourSetName());
+ str::stream() << "nonmatching repl set name in _id field: " << _id << " vs. "
+ << replSettings.ourSetName(),
+ _id == replSettings.ourSetName());
uassert(13308, "replSet bad config version #", version > 0);
uassert(13133, "replSet bad config no members", members.size() >= 1);
uassert(13309, "replSet bad config maximum number of members is 12", members.size() <= 12);
@@ -690,7 +692,7 @@ namespace mongo {
}
else {
/* first, make sure other node is configured to be a replset. just to be safe. */
- string setname = cmdLine.ourSetName();
+ string setname = replSettings.ourSetName();
BSONObj cmd = BSON( "replSetHeartbeat" << setname );
int theirVersion;
BSONObj info;
diff --git a/src/mongo/db/repl/rs_initiate.cpp b/src/mongo/db/repl/rs_initiate.cpp
index 43b8bf858cc..dc53a4bb11d 100644
--- a/src/mongo/db/repl/rs_initiate.cpp
+++ b/src/mongo/db/repl/rs_initiate.cpp
@@ -37,11 +37,11 @@
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/privilege.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/dbhelpers.h"
#include "mongo/db/repl/health.h"
#include "mongo/db/repl/oplog.h"
+#include "mongo/db/repl/replication_server_status.h" // replSettings
#include "mongo/db/repl/rs.h"
#include "mongo/db/repl/rs_config.h"
#include "mongo/util/mmap.h"
@@ -78,7 +78,7 @@ namespace mongo {
if( me != 1 ) {
stringstream ss;
ss << "can't find self in the replset config";
- if( !cmdLine.isDefaultPort() ) ss << " my port: " << cmdLine.port;
+ if (!serverGlobalParams.isDefaultPort()) ss << " my port: " << serverGlobalParams.port;
if( me != 0 ) ss << " found: " << me;
uasserted(13279, ss.str());
}
@@ -218,7 +218,7 @@ namespace mongo {
if( ReplSet::startupStatus != ReplSet::EMPTYCONFIG ) {
result.append("startupStatus", ReplSet::startupStatus);
errmsg = "all members and seeds must be reachable to initiate set";
- result.append("info", cmdLine._replSet);
+ result.append("info", replSettings.replSet);
return false;
}
@@ -231,7 +231,7 @@ namespace mongo {
string name;
vector<HostAndPort> seeds;
set<HostAndPort> seedSet;
- parseReplsetCmdLine(cmdLine._replSet, name, seeds, seedSet); // may throw...
+ parseReplsetCmdLine(replSettings.replSet, name, seeds, seedSet); // may throw...
bob b;
b.append("_id", name);
diff --git a/src/mongo/db/repl/rs_sync.cpp b/src/mongo/db/repl/rs_sync.cpp
index 259bbf70d09..bfa54421217 100644
--- a/src/mongo/db/repl/rs_sync.cpp
+++ b/src/mongo/db/repl/rs_sync.cpp
@@ -43,6 +43,7 @@
#include "mongo/db/repl/oplog.h"
#include "mongo/db/repl/rs.h"
#include "mongo/db/repl/rs_sync.h"
+#include "mongo/db/storage_options.h"
#include "mongo/util/fail_point_service.h"
#include "mongo/db/commands/server_status.h"
#include "mongo/db/stats/timer_stats.h"
@@ -116,7 +117,7 @@ namespace replset {
lk.reset(new Lock::DBWrite(ns));
}
- Client::Context ctx(ns, dbpath);
+ Client::Context ctx(ns, storageGlobalParams.dbpath);
ctx.getClient()->curop()->reset();
// For non-initial-sync, we convert updates to upserts
// to suppress errors when replaying oplog entries.
diff --git a/src/mongo/db/restapi.cpp b/src/mongo/db/restapi.cpp
index a1170c3bd4b..2585681796d 100644
--- a/src/mongo/db/restapi.cpp
+++ b/src/mongo/db/restapi.cpp
@@ -280,7 +280,7 @@ namespace mongo {
if( *replInfo )
ss << "\nreplInfo: " << replInfo << "\n\n";
if( replSet ) {
- ss << a("", "see replSetGetStatus link top of page") << "--replSet </a>" << cmdLine._replSet;
+ ss << a("", "see replSetGetStatus link top of page") << "--replSet </a>" << replSettings.replSet;
}
if ( replAllDead )
ss << "\n<b>replication replAllDead=" << replAllDead << "</b>\n";
diff --git a/src/mongo/db/server_options.cpp b/src/mongo/db/server_options.cpp
index bbc4957ee66..6c27cae17ef 100644
--- a/src/mongo/db/server_options.cpp
+++ b/src/mongo/db/server_options.cpp
@@ -28,10 +28,19 @@
#include "mongo/db/server_options.h"
+#ifdef _WIN32
+#include <direct.h>
+#endif
+
#include "mongo/base/status.h"
#include "mongo/bson/util/builder.h"
-#include "mongo/db/cmdline.h" // For CmdLine::DefaultDBPort
+#include "mongo/db/server_parameters.h"
+#include "mongo/logger/message_event_utf8_encoder.h"
+#include "mongo/util/cmdline_utils/censor_cmdline.h"
+#include "mongo/util/map_util.h"
+#include "mongo/util/mongoutils/str.h"
#include "mongo/util/net/listen.h" // For DEFAULT_MAX_CONN
+#include "mongo/util/net/ssl_options.h"
#include "mongo/util/options_parser/option_description.h"
#include "mongo/util/options_parser/option_section.h"
@@ -40,11 +49,16 @@ namespace mongo {
typedef moe::OptionDescription OD;
typedef moe::PositionalOptionDescription POD;
+ moe::OptionSection serverOptions;
+ moe::Environment serverParsedOptions;
+
+ ServerGlobalParams serverGlobalParams;
+
Status addGeneralServerOptions(moe::OptionSection* options) {
StringBuilder portInfoBuilder;
StringBuilder maxConnInfoBuilder;
- portInfoBuilder << "specify port number - " << CmdLine::DefaultDBPort << " by default";
+ portInfoBuilder << "specify port number - " << ServerGlobalParams::DefaultDBPort << " by default";
maxConnInfoBuilder << "max number of simultaneous connections - "
<< DEFAULT_MAX_CONN << " by default";
@@ -252,4 +266,259 @@ namespace mongo {
return Status::OK();
}
+ namespace {
+ // Helpers for option storage
+ Status setupBinaryName(const std::vector<std::string>& argv) {
+
+ if (argv.empty()) {
+ return Status(ErrorCodes::InternalError, "Cannot get binary name: argv array is empty");
+ }
+
+ // setup binary name
+ serverGlobalParams.binaryName = argv[0];
+ size_t i = serverGlobalParams.binaryName.rfind('/');
+ if (i != string::npos) {
+ serverGlobalParams.binaryName = serverGlobalParams.binaryName.substr(i + 1);
+ }
+ return Status::OK();
+ }
+
+ Status setupCwd() {
+ // setup cwd
+ char buffer[1024];
+#ifdef _WIN32
+ verify(_getcwd(buffer, 1000));
+#else
+ verify(getcwd(buffer, 1000));
+#endif
+ serverGlobalParams.cwd = buffer;
+ return Status::OK();
+ }
+
+ Status setArgvArray(const std::vector<std::string>& argv) {
+ BSONArrayBuilder b;
+ std::vector<std::string> censoredArgv = argv;
+ cmdline_utils::censorArgsVector(&censoredArgv);
+ for (size_t i=0; i < censoredArgv.size(); i++) {
+ b << censoredArgv[i];
+ }
+ serverGlobalParams.argvArray = b.arr();
+ return Status::OK();
+ }
+
+ Status setParsedOpts(const moe::Environment& params) {
+ serverGlobalParams.parsedOpts = params.toBSON();
+ cmdline_utils::censorBSONObj(&serverGlobalParams.parsedOpts);
+ return Status::OK();
+ }
+ } //namespace
+
+ void printCommandLineOpts() {
+ log() << "options: " << serverGlobalParams.parsedOpts << endl;
+ }
+
+ Status storeServerOptions(const moe::Environment& params,
+ const std::vector<std::string>& args) {
+
+ Status ret = setupBinaryName(args);
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ ret = setupCwd();
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ ret = setArgvArray(args);
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ ret = setParsedOpts(params);
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ if (params.count("verbose")) {
+ logger::globalLogDomain()->setMinimumLoggedSeverity(logger::LogSeverity::Debug(1));
+ }
+
+ for (string s = "vv"; s.length() <= 12; s.append("v")) {
+ if (params.count(s)) {
+ logger::globalLogDomain()->setMinimumLoggedSeverity(
+ logger::LogSeverity::Debug(s.length()));
+ }
+ }
+
+ if (params.count("enableExperimentalIndexStatsCmd")) {
+ serverGlobalParams.experimental.indexStatsCmdEnabled = true;
+ }
+ if (params.count("enableExperimentalStorageDetailsCmd")) {
+ serverGlobalParams.experimental.storageDetailsCmdEnabled = true;
+ }
+
+ if (params.count("port")) {
+ serverGlobalParams.port = params["port"].as<int>();
+ }
+
+ if (params.count("bind_ip")) {
+ serverGlobalParams.bind_ip = params["bind_ip"].as<std::string>();
+ }
+
+ if (params.count("clusterAuthMode")) {
+ serverGlobalParams.clusterAuthMode = params["clusterAuthMode"].as<std::string>();
+ }
+
+ if (params.count("quiet")) {
+ serverGlobalParams.quiet = true;
+ }
+
+ if (params.count("traceExceptions")) {
+ DBException::traceExceptions = true;
+ }
+
+ if (params.count("maxConns")) {
+ serverGlobalParams.maxConns = params["maxConns"].as<int>();
+
+ if (serverGlobalParams.maxConns < 5) {
+ return Status(ErrorCodes::BadValue, "maxConns has to be at least 5");
+ }
+ }
+
+ if (params.count("objcheck")) {
+ serverGlobalParams.objcheck = true;
+ }
+ if (params.count("noobjcheck")) {
+ if (params.count("objcheck")) {
+ return Status(ErrorCodes::BadValue, "can't have both --objcheck and --noobjcheck");
+ }
+ serverGlobalParams.objcheck = false;
+ }
+
+ if (params.count("bind_ip")) {
+ // passing in wildcard is the same as default behavior; remove and warn
+ if (serverGlobalParams.bind_ip == "0.0.0.0") {
+ std::cout << "warning: bind_ip of 0.0.0.0 is unnecessary; "
+ << "listens on all ips by default" << endl;
+ serverGlobalParams.bind_ip = "";
+ }
+ }
+
+#ifndef _WIN32
+ if (params.count("unixSocketPrefix")) {
+ serverGlobalParams.socket = params["unixSocketPrefix"].as<string>();
+ }
+
+ if (params.count("nounixsocket")) {
+ serverGlobalParams.noUnixSocket = true;
+ }
+
+ if (params.count("fork") && !params.count("shutdown")) {
+ serverGlobalParams.doFork = true;
+ }
+#endif // _WIN32
+
+ if (params.count("logTimestampFormat")) {
+ using logger::MessageEventDetailsEncoder;
+ std::string formatterName = params["logTimestampFormat"].as<string>();
+ if (formatterName == "ctime") {
+ MessageEventDetailsEncoder::setDateFormatter(dateToCtimeString);
+ }
+ else if (formatterName == "iso8601-utc") {
+ MessageEventDetailsEncoder::setDateFormatter(dateToISOStringUTC);
+ }
+ else if (formatterName == "iso8601-local") {
+ MessageEventDetailsEncoder::setDateFormatter(dateToISOStringLocal);
+ }
+ else {
+ StringBuilder sb;
+ sb << "Value of logTimestampFormat must be one of ctime, iso8601-utc " <<
+ "or iso8601-local; not \"" << formatterName << "\".";
+ return Status(ErrorCodes::BadValue, sb.str());
+ }
+ }
+ if (params.count("logpath")) {
+ serverGlobalParams.logpath = params["logpath"].as<string>();
+ if (serverGlobalParams.logpath.empty()) {
+ return Status(ErrorCodes::BadValue, "logpath cannot be empty if supplied");
+ }
+ }
+
+ serverGlobalParams.logWithSyslog = params.count("syslog");
+ serverGlobalParams.logAppend = params.count("logappend");
+ if (!serverGlobalParams.logpath.empty() && serverGlobalParams.logWithSyslog) {
+ return Status(ErrorCodes::BadValue, "Cant use both a logpath and syslog ");
+ }
+
+ if (serverGlobalParams.doFork && serverGlobalParams.logpath.empty() &&
+ !serverGlobalParams.logWithSyslog) {
+ return Status(ErrorCodes::BadValue, "--fork has to be used with --logpath or --syslog");
+ }
+
+ if (params.count("keyFile")) {
+ serverGlobalParams.keyFile = params["keyFile"].as<string>();
+ }
+
+ if ( params.count("pidfilepath")) {
+ serverGlobalParams.pidFile = params["pidfilepath"].as<string>();
+ }
+
+ if (params.count("setParameter")) {
+ std::vector<std::string> parameters =
+ params["setParameter"].as<std::vector<std::string> >();
+ for (size_t i = 0, length = parameters.size(); i < length; ++i) {
+ std::string name;
+ std::string value;
+ if (!mongoutils::str::splitOn(parameters[i], '=', name, value)) {
+ StringBuilder sb;
+ sb << "Illegal option assignment: \"" << parameters[i] << "\"";
+ return Status(ErrorCodes::BadValue, sb.str());
+ }
+ ServerParameter* parameter = mapFindWithDefault(
+ ServerParameterSet::getGlobal()->getMap(),
+ name,
+ static_cast<ServerParameter*>(NULL));
+ if (NULL == parameter) {
+ StringBuilder sb;
+ sb << "Illegal --setParameter parameter: \"" << name << "\"";
+ return Status(ErrorCodes::BadValue, sb.str());
+ }
+ if (!parameter->allowedToChangeAtStartup()) {
+ StringBuilder sb;
+ sb << "Cannot use --setParameter to set \"" << name << "\" at startup";
+ return Status(ErrorCodes::BadValue, sb.str());
+ }
+ Status status = parameter->setFromString(value);
+ if (!status.isOK()) {
+ StringBuilder sb;
+ sb << "Bad value for parameter \"" << name << "\": " << status.reason();
+ return Status(ErrorCodes::BadValue, sb.str());
+ }
+ }
+ }
+ if (!params.count("clusterAuthMode") && params.count("keyFile")){
+ serverGlobalParams.clusterAuthMode = "keyfile";
+ }
+
+#ifdef MONGO_SSL
+ ret = storeSSLServerOptions(params);
+ if (!ret.isOK()) {
+ return ret;
+ }
+#else // ifdef MONGO_SSL
+ // Keyfile is currently the only supported value if not using SSL
+ if (params.count("clusterAuthMode") && serverGlobalParams.clusterAuthMode != "keyfile") {
+ StringBuilder sb;
+ sb << "unsupported value for clusterAuthMode " << serverGlobalParams.clusterAuthMode;
+ return Status(ErrorCodes::BadValue, sb.str());
+ }
+#endif
+
+ return Status::OK();
+ }
+
+ // FIXME: This function will not return the correct value if someone renames the mongos binary
+ bool isMongos() { return serverGlobalParams.binaryName == "mongos"; }
+
} // namespace mongo
diff --git a/src/mongo/db/server_options.h b/src/mongo/db/server_options.h
index 07c6ea1a616..78f49c20db6 100644
--- a/src/mongo/db/server_options.h
+++ b/src/mongo/db/server_options.h
@@ -29,6 +29,10 @@
#pragma once
#include "mongo/base/status.h"
+#include "mongo/platform/process_id.h"
+#include "mongo/util/net/listen.h" // For DEFAULT_MAX_CONN
+#include "mongo/util/options_parser/environment.h"
+#include "mongo/util/options_parser/option_section.h"
namespace mongo {
@@ -38,9 +42,104 @@ namespace mongo {
namespace moe = mongo::optionenvironment;
+ extern moe::OptionSection serverOptions;
+ extern moe::Environment serverParsedOptions;
+
+ struct ServerGlobalParams {
+
+ ServerGlobalParams() :
+ port(DefaultDBPort), rest(false), jsonp(false), indexBuildRetry(true), quiet(false),
+ configsvr(false), cpu(false), objcheck(true), defaultProfile(0),
+ slowMS(100), defaultLocalThresholdMillis(15), moveParanoia(true),
+ noUnixSocket(false), doFork(0), socket("/tmp"), maxConns(DEFAULT_MAX_CONN),
+ logAppend(false), logWithSyslog(false), isHttpInterfaceEnabled(false)
+ {
+ started = time(0);
+ }
+
+ std::string binaryName; // mongod or mongos
+ std::string cwd; // cwd of when process started
+
+ int port; // --port
+ enum {
+ DefaultDBPort = 27017,
+ ConfigServerPort = 27019,
+ ShardServerPort = 27018
+ };
+ bool isDefaultPort() const { return port == DefaultDBPort; }
+
+ std::string bind_ip; // --bind_ip
+ bool rest; // --rest
+ bool jsonp; // --jsonp
+
+ bool indexBuildRetry; // --noIndexBuildRetry
+
+ bool quiet; // --quiet
+
+ bool configsvr; // --configsvr
+
+ bool cpu; // --cpu show cpu time periodically
+
+ bool objcheck; // --objcheck
+
+ int defaultProfile; // --profile
+ int slowMS; // --time in ms that is "slow"
+ int defaultLocalThresholdMillis; // --localThreshold in ms to consider a node local
+ bool moveParanoia; // for move chunk paranoia
+
+ bool noUnixSocket; // --nounixsocket
+ bool doFork; // --fork
+ std::string socket; // UNIX domain socket directory
+
+ int maxConns; // Maximum number of simultaneous open connections.
+
+ std::string keyFile; // Path to keyfile, or empty if none.
+ std::string pidFile; // Path to pid file, or empty if none.
+
+ std::string logpath; // Path to log file, if logging to a file; otherwise, empty.
+ bool logAppend; // True if logging to a file in append mode.
+ bool logWithSyslog; // True if logging to syslog; must not be set if logpath is set.
+ std::string clusterAuthMode; // Cluster authentication mode
+
+ bool isHttpInterfaceEnabled; // True if the dbwebserver should be enabled.
+
+#ifndef _WIN32
+ ProcessId parentProc; // --fork pid of initial process
+ ProcessId leaderProc; // --fork pid of leader process
+#endif
+
+ /**
+ * Switches to enable experimental (unsupported) features.
+ */
+ struct ExperimentalFeatures {
+ ExperimentalFeatures()
+ : indexStatsCmdEnabled(false)
+ , storageDetailsCmdEnabled(false)
+ {}
+ bool indexStatsCmdEnabled; // -- enableExperimentalIndexStatsCmd
+ bool storageDetailsCmdEnabled; // -- enableExperimentalStorageDetailsCmd
+ } experimental;
+
+ time_t started;
+
+ BSONArray argvArray;
+ BSONObj parsedOpts;
+ };
+
+ extern ServerGlobalParams serverGlobalParams;
+
Status addGeneralServerOptions(moe::OptionSection* options);
Status addWindowsServerOptions(moe::OptionSection* options);
Status addSSLServerOptions(moe::OptionSection* options);
+
+ Status storeServerOptions(const moe::Environment& params,
+ const std::vector<std::string>& args);
+
+ void printCommandLineOpts();
+
+ // This function should eventually go away, but needs to be here now because we have a lot of
+ // code that is shared between mongod and mongos that must know at runtime which binary it is in
+ bool isMongos();
}
diff --git a/src/mongo/db/sorter/sorter.cpp b/src/mongo/db/sorter/sorter.cpp
index acd2eb62594..3539e07984c 100644
--- a/src/mongo/db/sorter/sorter.cpp
+++ b/src/mongo/db/sorter/sorter.cpp
@@ -52,9 +52,11 @@
#include "mongo/base/string_data.h"
#include "mongo/bson/util/atomic_int.h"
-#include "mongo/db/cmdline.h"
+#include "mongo/db/jsobj.h"
+#include "mongo/db/storage_options.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/bufreader.h"
+#include "mongo/util/goodies.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
@@ -156,7 +158,7 @@ namespace mongo {
FileIterator(const string& fileName,
const Settings& settings,
- shared_ptr<FileDeleter> fileDeleter)
+ boost::shared_ptr<FileDeleter> fileDeleter)
: _settings(settings)
, _done(false)
, _fileName(fileName)
@@ -253,7 +255,7 @@ namespace mongo {
boost::scoped_ptr<BufReader> _reader;
string _fileName;
boost::shared_ptr<FileDeleter> _fileDeleter; // Must outlive _file
- ifstream _file;
+ std::ifstream _file;
};
/** Merge-sorts results from 0 or more FileIterators */
@@ -264,7 +266,7 @@ namespace mongo {
typedef std::pair<Key, Value> Data;
- MergeIterator(const vector<shared_ptr<Input> >& iters,
+ MergeIterator(const std::vector<boost::shared_ptr<Input> >& iters,
const SortOptions& opts,
const Comparator& comp)
: _opts(opts)
@@ -770,7 +772,7 @@ namespace mongo {
// This should be checked by consumers, but if we get here don't allow writes.
massert(16946, "Attempting to use external sort from mongos. This is not allowed.",
- !cmdLine.isMongos());
+ !isMongos());
massert(17148, "Attempting to use external sort without setting SortOptions::tempDir",
!opts.tempDir.empty());
@@ -783,7 +785,7 @@ namespace mongo {
boost::filesystem::create_directories(opts.tempDir);
- _file.open(_fileName.c_str(), ios::binary | ios::out);
+ _file.open(_fileName.c_str(), std::ios::binary | std::ios::out);
massert(16818, str::stream() << "error opening file \"" << _fileName << "\": "
<< sorter::myErrnoWithDescription(),
_file.good());
@@ -791,7 +793,7 @@ namespace mongo {
_fileDeleter = boost::make_shared<sorter::FileDeleter>(_fileName);
// throw on failure
- _file.exceptions(ios::failbit | ios::badbit | ios::eofbit);
+ _file.exceptions(std::ios::failbit | std::ios::badbit | std::ios::eofbit);
}
template <typename Key, typename Value>
@@ -860,7 +862,7 @@ namespace mongo {
// This should be checked by consumers, but if it isn't try to fail early.
massert(16947, "Attempting to use external sort from mongos. This is not allowed.",
- !(cmdLine.isMongos() && opts.extSortAllowed));
+ !(isMongos() && opts.extSortAllowed));
massert(17149, "Attempting to use external sort without setting SortOptions::tempDir",
!(opts.extSortAllowed && opts.tempDir.empty()));
diff --git a/src/mongo/db/sorter/sorter_test.cpp b/src/mongo/db/sorter/sorter_test.cpp
index 5ad6cfc08e8..7fef29ca83a 100644
--- a/src/mongo/db/sorter/sorter_test.cpp
+++ b/src/mongo/db/sorter/sorter_test.cpp
@@ -23,6 +23,7 @@
#include "mongo/unittest/temp_dir.h"
#include "mongo/unittest/unittest.h"
+#include "mongo/util/goodies.h"
#include "mongo/util/mongoutils/str.h"
// Need access to internal classes
@@ -32,7 +33,11 @@ namespace mongo {
using namespace mongo::sorter;
using boost::make_shared;
- CmdLine cmdLine;
+ // Stub to avoid including the server_options library
+ // TODO: This should go away once we can do these checks at compile time
+ bool isMongos() {
+ return false;
+ }
//
// Sorter framework testing utilities
@@ -139,7 +144,7 @@ namespace mongo {
} catch (...) {
mongo::unittest::log() <<
- "Failure from line " << line << " on iteration " << iteration << endl;
+ "Failure from line " << line << " on iteration " << iteration << std::endl;
throw;
}
}
@@ -147,7 +152,7 @@ namespace mongo {
template <int N>
boost::shared_ptr<IWIterator> makeInMemIterator(const int (&array)[N]) {
- vector<IWPair> vec;
+ std::vector<IWPair> vec;
for (int i=0; i<N; i++)
vec.push_back(IWPair(array[i], -array[i]));
return boost::make_shared<sorter::InMemIterator<IntWrapper, IntWrapper> >(vec);
@@ -157,7 +162,7 @@ namespace mongo {
boost::shared_ptr<IWIterator> mergeIterators(IteratorPtr (&array)[N],
Direction Dir=ASC,
const SortOptions& opts=SortOptions()) {
- vector<boost::shared_ptr<IWIterator> > vec;
+ std::vector<boost::shared_ptr<IWIterator> > vec;
for (int i=0; i<N; i++)
vec.push_back(boost::shared_ptr<IWIterator>(array[i]));
return boost::shared_ptr<IWIterator>(IWIterator::merge(vec, opts, IWComparator(Dir)));
@@ -235,7 +240,7 @@ namespace mongo {
public:
void run() {
{ // test empty (no inputs)
- vector<boost::shared_ptr<IWIterator> > vec;
+ std::vector<boost::shared_ptr<IWIterator> > vec;
boost::shared_ptr<IWIterator> mergeIter (IWIterator::merge(vec,
SortOptions(),
IWComparator()));
diff --git a/src/mongo/db/startup_warnings.cpp b/src/mongo/db/startup_warnings.cpp
new file mode 100644
index 00000000000..2eadc90b4d8
--- /dev/null
+++ b/src/mongo/db/startup_warnings.cpp
@@ -0,0 +1,209 @@
+/**
+* Copyright (C) 2013 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/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects
+* for all of the code used other than as permitted herein. If you modify
+* file(s) with this exception, you may extend this exception to your
+* version of the file(s), but you are not obligated to do so. If you do not
+* wish to do so, delete this exception statement from your version. If you
+* delete this exception statement from all source files in the program,
+* then also delete it in the license file.
+*/
+
+#include "mongo/db/startup_warnings.h"
+
+#include <boost/filesystem/operations.hpp>
+#include <fstream>
+
+#include "mongo/db/storage_options.h"
+#include "mongo/util/log.h"
+#include "mongo/util/processinfo.h"
+#include "mongo/util/version.h"
+
+namespace mongo {
+
+ //
+ // system warnings
+ //
+ void logStartupWarnings() {
+ // each message adds a leading and a trailing newline
+
+ bool warned = false;
+ {
+ const char * foo = strchr(versionString , '.') + 1;
+ int bar = atoi(foo);
+ if ((2 * (bar / 2)) != bar) {
+ log() << startupWarningsLog;
+ log() << "** NOTE: This is a development version (" << versionString
+ << ") of MongoDB." << startupWarningsLog;
+ log() << "** Not recommended for production." << startupWarningsLog;
+ warned = true;
+ }
+ }
+
+ if (sizeof(int*) == 4) {
+ log() << startupWarningsLog;
+ log() << "** NOTE: This is a 32 bit MongoDB binary." << startupWarningsLog;
+ log() << "** 32 bit builds are limited to less than 2GB of data "
+ << "(or less with --journal)." << startupWarningsLog;
+ if (!storageGlobalParams.dur) {
+ log() << "** Note that journaling defaults to off for 32 bit "
+ << "and is currently off." << startupWarningsLog;
+ }
+ log() << "** See http://dochub.mongodb.org/core/32bit" << startupWarningsLog;
+ warned = true;
+ }
+
+ if (!ProcessInfo::blockCheckSupported()) {
+ log() << startupWarningsLog;
+ log() << "** NOTE: your operating system version does not support the method that "
+ << "MongoDB" << startupWarningsLog;
+ log() << "** uses to detect impending page faults." << startupWarningsLog;
+ log() << "** This may result in slower performance for certain use "
+ << "cases" << startupWarningsLog;
+ warned = true;
+ }
+#ifdef __linux__
+ if (boost::filesystem::exists("/proc/vz") && !boost::filesystem::exists("/proc/bc")) {
+ log() << startupWarningsLog;
+ log() << "** WARNING: You are running in OpenVZ. This is known to be broken!!!"
+ << startupWarningsLog;
+ warned = true;
+ }
+
+ if (boost::filesystem::exists("/sys/devices/system/node/node1")){
+ // We are on a box with a NUMA enabled kernel and more than 1 numa node (they start at
+ // node0)
+ // Now we look at the first line of /proc/self/numa_maps
+ //
+ // Bad example:
+ // $ cat /proc/self/numa_maps
+ // 00400000 default file=/bin/cat mapped=6 N4=6
+ //
+ // Good example:
+ // $ numactl --interleave=all cat /proc/self/numa_maps
+ // 00400000 interleave:0-7 file=/bin/cat mapped=6 N4=6
+
+ std::ifstream f("/proc/self/numa_maps", std::ifstream::in);
+ if (f.is_open()) {
+ std::string line; //we only need the first line
+ std::getline(f, line);
+ if (f.fail()) {
+ warning() << "failed to read from /proc/self/numa_maps: "
+ << errnoWithDescription() << startupWarningsLog;
+ warned = true;
+ }
+ else {
+ // skip over pointer
+ std::string::size_type where = line.find(' ');
+ if ((where == std::string::npos) || (++where == line.size())) {
+ log() << startupWarningsLog;
+ log() << "** WARNING: cannot parse numa_maps line: '" << line << "'"
+ << startupWarningsLog;
+ warned = true;
+ }
+ // if the text following the space doesn't begin with 'interleave', then
+ // issue the warning.
+ else if (line.find("interleave", where) != where) {
+ log() << startupWarningsLog;
+ log() << "** WARNING: You are running on a NUMA machine."
+ << startupWarningsLog;
+ log() << "** We suggest launching mongod like this to avoid "
+ << "performance problems:" << startupWarningsLog;
+ log() << "** numactl --interleave=all mongod [other options]"
+ << startupWarningsLog;
+ warned = true;
+ }
+ }
+ }
+ }
+
+ if (storageGlobalParams.dur) {
+ std::fstream f("/proc/sys/vm/overcommit_memory", ios_base::in);
+ unsigned val;
+ f >> val;
+
+ if (val == 2) {
+ log() << startupWarningsLog;
+ log() << "** WARNING: /proc/sys/vm/overcommit_memory is " << val
+ << startupWarningsLog;
+ log() << "** Journaling works best with it set to 0 or 1"
+ << startupWarningsLog;
+ }
+ }
+
+ if (boost::filesystem::exists("/proc/sys/vm/zone_reclaim_mode")){
+ std::fstream f("/proc/sys/vm/zone_reclaim_mode", ios_base::in);
+ unsigned val;
+ f >> val;
+
+ if (val != 0) {
+ log() << startupWarningsLog;
+ log() << "** WARNING: /proc/sys/vm/zone_reclaim_mode is " << val
+ << startupWarningsLog;
+ log() << "** We suggest setting it to 0" << startupWarningsLog;
+ log() << "** http://www.kernel.org/doc/Documentation/sysctl/vm.txt"
+ << startupWarningsLog;
+ }
+ }
+#endif
+
+#if defined(RLIMIT_NPROC) && defined(RLIMIT_NOFILE)
+ //Check that # of files rlmit > 1000 , and # of processes > # of files/2
+ const unsigned int minNumFiles = 1000;
+ const double filesToProcsRatio = 2.0;
+ struct rlimit rlnproc;
+ struct rlimit rlnofile;
+
+ if(!getrlimit(RLIMIT_NPROC,&rlnproc) && !getrlimit(RLIMIT_NOFILE,&rlnofile)){
+ if(rlnofile.rlim_cur < minNumFiles){
+ log() << startupWarningsLog;
+ log() << "** WARNING: soft rlimits too low. Number of files is "
+ << rlnofile.rlim_cur
+ << ", should be at least " << minNumFiles << startupWarningsLog;
+ }
+
+ if(false){
+ // juse to make things cleaner
+ }
+#ifdef __APPLE__
+ else if(rlnproc.rlim_cur >= 709){
+ // os x doesn't make it easy to go higher
+ // ERH thinks its ok not to add the warning in this case 7/3/2012
+ }
+#endif
+ else if(rlnproc.rlim_cur < rlnofile.rlim_cur/filesToProcsRatio){
+ log() << startupWarningsLog;
+ log() << "** WARNING: soft rlimits too low. rlimits set to "
+ << rlnproc.rlim_cur << " processes, "
+ << rlnofile.rlim_cur << " files. Number of processes should be at least "
+ << rlnofile.rlim_cur/filesToProcsRatio << " : "
+ << 1/filesToProcsRatio << " times number of files." << startupWarningsLog;
+ }
+ } else {
+ log() << startupWarningsLog;
+ log() << "** WARNING: getrlimit failed. " << errnoWithDescription()
+ << startupWarningsLog;
+ }
+#endif
+ if (warned) {
+ log() << startupWarningsLog;
+ }
+ }
+} // namespace mongo
diff --git a/src/mongo/db/startup_warnings.h b/src/mongo/db/startup_warnings.h
new file mode 100644
index 00000000000..35a33210159
--- /dev/null
+++ b/src/mongo/db/startup_warnings.h
@@ -0,0 +1,32 @@
+/**
+* Copyright (C) 2013 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/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects
+* for all of the code used other than as permitted herein. If you modify
+* file(s) with this exception, you may extend this exception to your
+* version of the file(s), but you are not obligated to do so. If you do not
+* wish to do so, delete this exception statement from your version. If you
+* delete this exception statement from all source files in the program,
+* then also delete it in the license file.
+*/
+
+namespace mongo {
+ // Checks various startup conditions and logs any necessary warnings
+ void logStartupWarnings();
+} // namespace mongo
diff --git a/src/mongo/db/stats/snapshots.cpp b/src/mongo/db/stats/snapshots.cpp
index 74efaf81994..ecd392decea 100644
--- a/src/mongo/db/stats/snapshots.cpp
+++ b/src/mongo/db/stats/snapshots.cpp
@@ -127,7 +127,7 @@ namespace mongo {
try {
const SnapshotData* s = statsSnapshots.takeSnapshot();
- if ( prev && cmdLine.cpu ) {
+ if (prev && serverGlobalParams.cpu) {
unsigned long long elapsed = s->_created - prev->_created;
SnapshotDelta d( *prev , *s );
log() << "cpu: elapsed:" << (elapsed/1000) <<" writelock: " << (int)(100*d.percentWriteLocked()) << "%" << endl;
diff --git a/src/mongo/db/storage/data_file.cpp b/src/mongo/db/storage/data_file.cpp
index 59c95a203f2..941e3864512 100644
--- a/src/mongo/db/storage/data_file.cpp
+++ b/src/mongo/db/storage/data_file.cpp
@@ -34,7 +34,6 @@
#include <boost/filesystem/operations.hpp>
-#include "mongo/db/cmdline.h"
#include "mongo/db/d_concurrency.h"
#include "mongo/db/dur.h"
#include "mongo/db/lockstate.h"
@@ -54,7 +53,7 @@ namespace mongo {
if ( sizeof( int* ) == 4 ) {
return 512 * 1024 * 1024;
}
- else if ( cmdLine.smallfiles ) {
+ else if (storageGlobalParams.smallfiles) {
return 0x7ff00000 >> 2;
}
else {
@@ -80,7 +79,7 @@ namespace mongo {
size = (64*1024*1024) << fileNo;
else
size = 0x7ff00000;
- if ( cmdLine.smallfiles ) {
+ if (storageGlobalParams.smallfiles) {
size = size >> 2;
}
return size;
@@ -100,9 +99,10 @@ namespace mongo {
unsigned long long sz = mmf.length();
verify( sz <= 0x7fffffff );
verify( sz % 4096 == 0 );
- if( sz < 64*1024*1024 && !cmdLine.smallfiles ) {
+ if (sz < 64*1024*1024 && !storageGlobalParams.smallfiles) {
if( sz >= 16*1024*1024 && sz % (1024*1024) == 0 ) {
- log() << "info openExisting file size " << sz << " but cmdLine.smallfiles=false: "
+ log() << "info openExisting file size " << sz
+ << " but storageGlobalParams.smallfiles=false: "
<< filename << endl;
}
else {
@@ -128,11 +128,11 @@ namespace mongo {
if ( size > maxSize() )
size = maxSize();
- verify( size >= 64*1024*1024 || cmdLine.smallfiles );
+ verify(size >= 64*1024*1024 || storageGlobalParams.smallfiles);
verify( size % 4096 == 0 );
if ( preallocateOnly ) {
- if ( cmdLine.prealloc ) {
+ if (storageGlobalParams.prealloc) {
FileAllocator::get()->requestAllocation( filename, size );
}
return;
diff --git a/src/mongo/db/storage/durable_mapped_file.cpp b/src/mongo/db/storage/durable_mapped_file.cpp
index 09639986f2d..5e491fc7d97 100644
--- a/src/mongo/db/storage/durable_mapped_file.cpp
+++ b/src/mongo/db/storage/durable_mapped_file.cpp
@@ -36,7 +36,6 @@
#include "mongo/db/storage/durable_mapped_file.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/d_concurrency.h"
#include "mongo/db/dur.h"
@@ -49,7 +48,7 @@ using namespace mongoutils;
namespace mongo {
void DurableMappedFile::remapThePrivateView() {
- verify( cmdLine.dur );
+ verify(storageGlobalParams.dur);
// todo 1.9 : it turns out we require that we always remap to the same address.
// so the remove / add isn't necessary and can be removed?
@@ -125,8 +124,6 @@ namespace mongo {
PointerToDurableMappedFile privateViews;
- extern string dbpath;
-
// here so that it is precomputed...
void DurableMappedFile::setPath(const std::string& f) {
string suffix;
@@ -158,7 +155,7 @@ namespace mongo {
bool DurableMappedFile::finishOpening() {
LOG(3) << "mmf finishOpening " << (void*) _view_write << ' ' << filename() << " len:" << length() << endl;
if( _view_write ) {
- if( cmdLine.dur ) {
+ if (storageGlobalParams.dur) {
_view_private = createPrivateMap();
if( _view_private == 0 ) {
msgasserted(13636, str::stream() << "file " << filename() << " open/create failed in createPrivateMap (look in log for more information)");
@@ -192,7 +189,7 @@ namespace mongo {
LOG(3) << "mmf close " << filename() << endl;
if( view_write() /*actually was opened*/ ) {
- if( cmdLine.dur ) {
+ if (storageGlobalParams.dur) {
dur::closingFileNotification();
}
/* todo: is it ok to close files if we are not globally locked exclusively?
diff --git a/src/mongo/db/storage/extent_manager.cpp b/src/mongo/db/storage/extent_manager.cpp
index 6b067695a10..112492f50ed 100644
--- a/src/mongo/db/storage/extent_manager.cpp
+++ b/src/mongo/db/storage/extent_manager.cpp
@@ -315,8 +315,8 @@ namespace mongo {
bool fileIndexExceedsQuota( const char *ns, int fileIndex ) {
return
- cmdLine.quota &&
- fileIndex >= cmdLine.quotaFiles &&
+ storageGlobalParams.quota &&
+ fileIndex >= storageGlobalParams.quotaFiles &&
// we don't enforce the quota on "special" namespaces as that could lead to problems -- e.g.
// rejecting an index insert after inserting the main record.
!NamespaceString::special( ns ) &&
diff --git a/src/mongo/db/storage/namespace_index.cpp b/src/mongo/db/storage/namespace_index.cpp
index f56989c665c..3a99092ddc7 100644
--- a/src/mongo/db/storage/namespace_index.cpp
+++ b/src/mongo/db/storage/namespace_index.cpp
@@ -37,8 +37,6 @@
namespace mongo {
- unsigned lenForNewNsFiles = 16 * 1024 * 1024;
-
NamespaceDetails* NamespaceIndex::details(const StringData& ns) {
Namespace n(ns);
return details(n);
@@ -93,7 +91,7 @@ namespace mongo {
boost::filesystem::path NamespaceIndex::path() const {
boost::filesystem::path ret( _dir );
- if ( directoryperdb )
+ if (storageGlobalParams.directoryperdb)
ret /= _database;
ret /= ( _database + ".ns" );
return ret;
@@ -114,7 +112,7 @@ namespace mongo {
}
void NamespaceIndex::maybeMkdir() const {
- if ( !directoryperdb )
+ if (!storageGlobalParams.directoryperdb)
return;
boost::filesystem::path dir( _dir );
dir /= _database;
@@ -153,14 +151,15 @@ namespace mongo {
}
}
else {
- // use lenForNewNsFiles, we are making a new database
- massert( 10343, "bad lenForNewNsFiles", lenForNewNsFiles >= 1024*1024 );
+ // use storageGlobalParams.lenForNewNsFiles, we are making a new database
+ massert(10343, "bad storageGlobalParams.lenForNewNsFiles",
+ storageGlobalParams.lenForNewNsFiles >= 1024*1024);
maybeMkdir();
- unsigned long long l = lenForNewNsFiles;
+ unsigned long long l = storageGlobalParams.lenForNewNsFiles;
if ( _f.create(pathString, l, true) ) {
getDur().createdFile(pathString, l); // always a new file
len = l;
- verify( len == lenForNewNsFiles );
+ verify(len == storageGlobalParams.lenForNewNsFiles);
p = _f.getView();
}
}
diff --git a/src/mongo/db/storage_options.cpp b/src/mongo/db/storage_options.cpp
new file mode 100644
index 00000000000..23516baf85d
--- /dev/null
+++ b/src/mongo/db/storage_options.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2013 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/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/db/storage_options.h"
+
+#include "mongo/bson/util/builder.h"
+#include "mongo/db/server_parameters.h"
+
+namespace mongo {
+
+ StorageGlobalParams storageGlobalParams;
+
+ bool isJournalingEnabled() {
+ return storageGlobalParams.dur;
+ }
+
+ void setJournalCommitInterval(unsigned newValue) {
+ storageGlobalParams.journalCommitInterval = newValue;
+ }
+
+ unsigned getJournalCommitInterval() {
+ return storageGlobalParams.journalCommitInterval;
+ }
+
+ ExportedServerParameter<bool> NoTableScanSetting(ServerParameterSet::getGlobal(),
+ "notablescan",
+ &storageGlobalParams.noTableScan,
+ true,
+ true);
+
+ ExportedServerParameter<double> SyncdelaySetting(ServerParameterSet::getGlobal(),
+ "syncdelay",
+ &storageGlobalParams.syncdelay,
+ true,
+ true);
+
+} // namespace mongo
diff --git a/src/mongo/db/storage_options.h b/src/mongo/db/storage_options.h
new file mode 100644
index 00000000000..4b02468aa05
--- /dev/null
+++ b/src/mongo/db/storage_options.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2013 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/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+#include <string>
+
+/*
+ * This file defines the storage for options that come from the command line related to data file
+ * persistence. Many executables that can access data files directly such as mongod and certain
+ * tools use these variables, but each executable may have a different set of command line flags
+ * that allow the user to change a different subset of these options.
+ */
+
+namespace mongo {
+
+ struct StorageGlobalParams {
+
+ StorageGlobalParams() :
+#ifdef _WIN32
+ dbpath("\\data\\db\\"),
+#else
+ dbpath("/data/db/"),
+#endif
+ directoryperdb(false),
+ lenForNewNsFiles(16 * 1024 * 1024),
+ preallocj(true),
+ journalCommitInterval(0), // 0 means use default
+ quota(false), quotaFiles(8),
+ syncdelay(60),
+ useHints(true)
+ {
+ repairpath = dbpath;
+ dur = false;
+#if defined(_DURABLEDEFAULTON)
+ dur = true;
+#endif
+ if (sizeof(void*) == 8)
+ dur = true;
+#if defined(_DURABLEDEFAULTOFF)
+ dur = false;
+#endif
+ }
+
+ std::string dbpath;
+ bool directoryperdb;
+ std::string repairpath;
+ unsigned lenForNewNsFiles;
+
+ bool preallocj; // --nopreallocj no preallocation of journal files
+ bool prealloc; // --noprealloc no preallocation of data files
+ bool smallfiles; // --smallfiles allocate smaller data files
+ bool noTableScan; // --notablescan no table scans allowed
+
+ bool dur; // --dur durability (now --journal)
+ unsigned journalCommitInterval; // group/batch commit interval ms
+
+ /** --durOptions 7 dump journal and terminate without doing anything further
+ --durOptions 4 recover and terminate without listening
+ */
+ enum { // bits to be ORed
+ DurDumpJournal = 1, // dump diagnostics on the journal during recovery
+ DurScanOnly = 2, // don't do any real work, just scan and dump if dump specified
+ DurRecoverOnly = 4, // terminate after recovery step
+ DurParanoid = 8, // paranoid mode enables extra checks
+ DurAlwaysCommit = 16, // do a group commit every time the writelock is released
+ DurAlwaysRemap = 32, // remap the private view after every group commit (may lag to the
+ // next write lock acquisition, but will do all files then)
+ DurNoCheckSpace = 64 // don't check that there is enough room for journal files before
+ // startup (for diskfull tests)
+ };
+ int durOptions; // --durOptions <n> for debugging
+
+ bool quota; // --quota
+ int quotaFiles; // --quotaFiles
+
+ double syncdelay; // seconds between fsyncs
+
+ bool useHints; // only off if --nohints
+ };
+
+ extern StorageGlobalParams storageGlobalParams;
+
+ bool isJournalingEnabled();
+ void setJournalCommitInterval(unsigned newValue);
+ unsigned getJournalCommitInterval();
+
+ // This is not really related to persistence, but mongos and the other executables share code
+ // and we use this function to determine at runtime which executable we are in.
+ bool isMongos();
+
+} // namespace mongo
diff --git a/src/mongo/db/write_concern.cpp b/src/mongo/db/write_concern.cpp
index 4b9635044d8..331525e946b 100644
--- a/src/mongo/db/write_concern.cpp
+++ b/src/mongo/db/write_concern.cpp
@@ -86,7 +86,7 @@ namespace mongo {
BSONElement e = cmdObj["w"];
if ( e.ok() ) {
- if ( cmdLine.configsvr && (!e.isNumber() || e.numberInt() > 1) ) {
+ if (serverGlobalParams.configsvr && (!e.isNumber() || e.numberInt() > 1)) {
// w:1 on config servers should still work, but anything greater than that
// should not.
result->append( "wnote", "can't use w on config servers" );
diff --git a/src/mongo/dbtests/documentsourcetests.cpp b/src/mongo/dbtests/documentsourcetests.cpp
index a50663eea13..076b8bafe3f 100644
--- a/src/mongo/dbtests/documentsourcetests.cpp
+++ b/src/mongo/dbtests/documentsourcetests.cpp
@@ -23,6 +23,7 @@
#include "mongo/db/interrupt_status_mongod.h"
#include "mongo/db/pipeline/document_source.h"
#include "mongo/db/pipeline/expression_context.h"
+#include "mongo/db/storage_options.h"
#include "mongo/dbtests/dbtests.h"
namespace DocumentSourceTests {
@@ -105,7 +106,7 @@ namespace DocumentSourceTests {
public:
Base()
: _ctx(new ExpressionContext(InterruptStatusMongod::status, NamespaceString(ns)))
- { _ctx->tempDir = dbpath + "/_tmp"; }
+ { _ctx->tempDir = storageGlobalParams.dbpath + "/_tmp"; }
protected:
void createSource() {
Client::ReadContext ctx (ns);
@@ -411,7 +412,7 @@ namespace DocumentSourceTests {
intrusive_ptr<ExpressionContext> expressionContext =
new ExpressionContext(InterruptStatusMongod::status, NamespaceString(ns));
expressionContext->inShard = inShard;
- expressionContext->tempDir = dbpath + "/_tmp";
+ expressionContext->tempDir = storageGlobalParams.dbpath + "/_tmp";
_group = DocumentSourceGroup::createFromBson( &specElement, expressionContext );
assertRoundTrips( _group );
diff --git a/src/mongo/dbtests/framework.cpp b/src/mongo/dbtests/framework.cpp
index 6a0992d0c9f..f154a15e4d3 100644
--- a/src/mongo/dbtests/framework.cpp
+++ b/src/mongo/dbtests/framework.cpp
@@ -30,10 +30,11 @@
#include "mongo/base/init.h"
#include "mongo/base/status.h"
#include "mongo/db/client.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/dur.h"
#include "mongo/db/ops/update.h"
#include "mongo/db/query/new_find.h"
+#include "mongo/db/repl/replication_server_status.h" // replSettings
+#include "mongo/db/storage_options.h"
#include "mongo/dbtests/dbtests.h"
#include "mongo/util/background.h"
#include "mongo/util/concurrency/mutex.h"
@@ -47,7 +48,6 @@ namespace moe = mongo::optionenvironment;
namespace mongo {
- CmdLine cmdLine;
moe::OptionSection options;
moe::Environment params;
@@ -249,14 +249,14 @@ MONGO_INITIALIZER_GENERAL(ParseStartupConfiguration,
bool nodur = false;
if( params.count("nodur") ) {
nodur = true;
- cmdLine.dur = false;
+ storageGlobalParams.dur = false;
}
- if( params.count("dur") || cmdLine.dur ) {
- cmdLine.dur = true;
+ if (params.count("dur") || storageGlobalParams.dur) {
+ storageGlobalParams.dur = true;
}
if( params.count("nopreallocj") ) {
- cmdLine.preallocj = false;
+ storageGlobalParams.preallocj = false;
}
if (params.count("debug") || params.count("verbose") ) {
@@ -294,17 +294,17 @@ MONGO_INITIALIZER_GENERAL(ParseStartupConfiguration,
}
string dbpathString = p.string();
- dbpath = dbpathString.c_str();
+ storageGlobalParams.dbpath = dbpathString.c_str();
- cmdLine.prealloc = false;
+ storageGlobalParams.prealloc = false;
// dbtest defaults to smallfiles
- cmdLine.smallfiles = true;
+ storageGlobalParams.smallfiles = true;
if( params.count("bigfiles") ) {
- cmdLine.dur = true;
+ storageGlobalParams.dur = true;
}
- cmdLine.oplogSize = 10 * 1024 * 1024;
+ replSettings.oplogSize = 10 * 1024 * 1024;
Client::initThread("testsuite");
acquirePathLock();
@@ -319,8 +319,8 @@ MONGO_INITIALIZER_GENERAL(ParseStartupConfiguration,
log() << "random seed: " << seed << endl;
if( time(0) % 3 == 0 && !nodur ) {
- if( !cmdLine.dur ) {
- cmdLine.dur = true;
+ if (!storageGlobalParams.dur) {
+ storageGlobalParams.dur = true;
log() << "****************" << endl;
log() << "running with journaling enabled to test that. dbtests will do this occasionally even if --dur is not specified." << endl;
log() << "****************" << endl;
@@ -341,10 +341,10 @@ MONGO_INITIALIZER_GENERAL(ParseStartupConfiguration,
dur::startup();
- if( debug && cmdLine.dur ) {
- log() << "_DEBUG: automatically enabling cmdLine.durOptions=8 (DurParanoid)" << endl;
+ if (debug && storageGlobalParams.dur) {
+ log() << "_DEBUG: automatically enabling storageGlobalParams.durOptions=8 (DurParanoid)" << endl;
// this was commented out. why too slow or something? :
- cmdLine.durOptions |= 8;
+ storageGlobalParams.durOptions |= 8;
}
TestWatchDog twd;
diff --git a/src/mongo/dbtests/mmaptests.cpp b/src/mongo/dbtests/mmaptests.cpp
index 20e363c9db0..7741ccfa933 100644
--- a/src/mongo/dbtests/mmaptests.cpp
+++ b/src/mongo/dbtests/mmaptests.cpp
@@ -31,12 +31,13 @@ namespace MMapTests {
const int optOld;
public:
LeakTest() :
- fn( (boost::filesystem::path(dbpath) / "testfile.map").string() ), optOld(cmdLine.durOptions)
+ fn((boost::filesystem::path(storageGlobalParams.dbpath) / "testfile.map").string()),
+ optOld(storageGlobalParams.durOptions)
{
- cmdLine.durOptions = 0; // DurParanoid doesn't make sense with this test
+ storageGlobalParams.durOptions = 0; // DurParanoid doesn't make sense with this test
}
~LeakTest() {
- cmdLine.durOptions = optOld;
+ storageGlobalParams.durOptions = optOld;
try { boost::filesystem::remove(fn); }
catch(...) { }
}
@@ -55,11 +56,11 @@ namespace MMapTests {
char *p = (char *) f.getView();
verify(p);
// write something to the private view as a test
- if( cmdLine.dur )
+ if (storageGlobalParams.dur)
MemoryMappedFile::makeWritable(p, 6);
strcpy(p, "hello");
}
- if( cmdLine.dur ) {
+ if (storageGlobalParams.dur) {
char *w = (char *) f.view_write();
strcpy(w + 6, "world");
}
@@ -86,11 +87,11 @@ namespace MMapTests {
{
char *p = (char *) f.getView();
verify(p);
- if( cmdLine.dur )
+ if (storageGlobalParams.dur)
MemoryMappedFile::makeWritable(p, 4);
strcpy(p, "zzz");
}
- if( cmdLine.dur ) {
+ if (storageGlobalParams.dur) {
char *w = (char *) f.view_write();
if( i % 2 == 0 )
++(*w);
diff --git a/src/mongo/dbtests/pdfiletests.cpp b/src/mongo/dbtests/pdfiletests.cpp
index ef0427453fd..ed7a0e4ebf0 100644
--- a/src/mongo/dbtests/pdfiletests.cpp
+++ b/src/mongo/dbtests/pdfiletests.cpp
@@ -319,11 +319,11 @@ namespace PdfileTests {
public:
struct SmallFilesControl {
SmallFilesControl() {
- old = cmdLine.smallfiles;
- cmdLine.smallfiles = false;
+ old = storageGlobalParams.smallfiles;
+ storageGlobalParams.smallfiles = false;
}
~SmallFilesControl() {
- cmdLine.smallfiles = old;
+ storageGlobalParams.smallfiles = old;
}
bool old;
};
diff --git a/src/mongo/dbtests/perf/perftest.cpp b/src/mongo/dbtests/perf/perftest.cpp
index e3d982cf758..c74b8dbf7be 100644
--- a/src/mongo/dbtests/perf/perftest.cpp
+++ b/src/mongo/dbtests/perf/perftest.cpp
@@ -32,8 +32,6 @@
#include "mongo/unittest/unittest.h"
namespace mongo {
- extern string dbpath;
-
// This specifies default dbpath for our testing framework
const std::string default_test_dbpath = "/data/db/perftest";
} // namespace mongo
diff --git a/src/mongo/dbtests/perftests.cpp b/src/mongo/dbtests/perftests.cpp
index 321c5b945b6..904c6baeefb 100644
--- a/src/mongo/dbtests/perftests.cpp
+++ b/src/mongo/dbtests/perftests.cpp
@@ -235,7 +235,9 @@ namespace PerfTests {
Query q;
{
BSONObjBuilder b;
- b.append("host",_perfhostname).append("test",s).append("dur",cmdLine.dur);
+ b.append("host", _perfhostname);
+ b.append("test", s);
+ b.append("dur", storageGlobalParams.dur);
DEV { b.append("info.DEBUG",true); }
else b.appendNull("info.DEBUG");
if( sizeof(int*) == 4 )
@@ -270,8 +272,8 @@ namespace PerfTests {
b.append("test", s);
b.append("rps", (int) rps);
b.append("millis", ms);
- b.appendBool("dur", cmdLine.dur);
- if( showDurStats() && cmdLine.dur )
+ b.appendBool("dur", storageGlobalParams.dur);
+ if (showDurStats() && storageGlobalParams.dur)
b.append("durStats", dur::stats.curr->_asObj());
{
bob inf;
@@ -1225,7 +1227,7 @@ namespace PerfTests {
// write something to the private view as a test
strcpy(p, "hello");
}
- if( cmdLine.dur ) {
+ if (storageGlobalParams.dur) {
char *w = (char *) f.view_write();
strcpy(w + 6, "world");
}
diff --git a/src/mongo/dbtests/replsettests.cpp b/src/mongo/dbtests/replsettests.cpp
index c3008e29b42..4866c2fb917 100644
--- a/src/mongo/dbtests/replsettests.cpp
+++ b/src/mongo/dbtests/replsettests.cpp
@@ -26,6 +26,7 @@
#include "mongo/db/kill_current_op.h"
#include "mongo/db/repl/bgsync.h"
#include "mongo/db/repl/oplog.h"
+#include "mongo/db/repl/replication_server_status.h" // replSettings
#include "mongo/db/repl/rs.h"
#include "mongo/dbtests/dbtests.h"
#include "mongo/util/time_support.h"
@@ -154,8 +155,8 @@ namespace ReplSetTests {
c.ctx().db()->dropCollection( ns() );
}
static void setup() {
- cmdLine._replSet = "foo";
- cmdLine.oplogSize = 5 * 1024 * 1024;
+ replSettings.replSet = "foo";
+ replSettings.oplogSize = 5 * 1024 * 1024;
createOplog();
// setup background sync instance
diff --git a/src/mongo/dbtests/repltests.cpp b/src/mongo/dbtests/repltests.cpp
index b900461d749..dd5e67a2726 100644
--- a/src/mongo/dbtests/repltests.cpp
+++ b/src/mongo/dbtests/repltests.cpp
@@ -48,8 +48,8 @@ namespace ReplTests {
public:
Base() : _context( ns() ) {
oldRepl();
- cmdLine._replSet = "";
- cmdLine.oplogSize = 5 * 1024 * 1024;
+ replSettings.replSet = "";
+ replSettings.oplogSize = 5 * 1024 * 1024;
replSettings.master = true;
createOplog();
ensureHaveIdIndex( ns(), false );
diff --git a/src/mongo/s/balance.cpp b/src/mongo/s/balance.cpp
index d0e20da4696..3ad371474d3 100644
--- a/src/mongo/s/balance.cpp
+++ b/src/mongo/s/balance.cpp
@@ -32,7 +32,6 @@
#include "mongo/client/dbclientcursor.h"
#include "mongo/client/distlock.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/jsobj.h"
#include "mongo/s/chunk.h"
#include "mongo/s/config.h"
@@ -388,7 +387,7 @@ namespace mongo {
log() << "config servers and shards contacted successfully" << endl;
StringBuilder buf;
- buf << getHostNameCached() << ":" << cmdLine.port;
+ buf << getHostNameCached() << ":" << serverGlobalParams.port;
_myid = buf.str();
_started = time(0);
diff --git a/src/mongo/s/balancer_policy_tests.cpp b/src/mongo/s/balancer_policy_tests.cpp
index a6a5ed34c18..b9ea82a8644 100644
--- a/src/mongo/s/balancer_policy_tests.cpp
+++ b/src/mongo/s/balancer_policy_tests.cpp
@@ -22,7 +22,6 @@
namespace mongo {
// these are all crutch and hopefully will eventually go away
- CmdLine cmdLine;
bool inShutdown() { return false; }
DBClientBase *createDirectClient() { return 0; }
void dbexit( ExitCode rc, const char *why ){
@@ -32,7 +31,6 @@ namespace mongo {
bool haveLocalShardingInfo( const string& ns ) {
return false;
}
-
namespace {
TEST( BalancerPolicyTests , SizeMaxedShardTest ) {
diff --git a/src/mongo/s/commands_admin.cpp b/src/mongo/s/commands_admin.cpp
index be0d7f7ec51..6080ec54027 100644
--- a/src/mongo/s/commands_admin.cpp
+++ b/src/mongo/s/commands_admin.cpp
@@ -1145,7 +1145,7 @@ namespace mongo {
// it's fine if mongods of a set all use default port
if ( ! serverAddrs[i].hasPort() ) {
- serverAddrs[i].setPort( CmdLine::ShardServerPort );
+ serverAddrs[i].setPort(ServerGlobalParams::ShardServerPort);
}
}
diff --git a/src/mongo/s/config.cpp b/src/mongo/s/config.cpp
index e286ea357de..89ba0aec24a 100644
--- a/src/mongo/s/config.cpp
+++ b/src/mongo/s/config.cpp
@@ -34,7 +34,6 @@
#include "mongo/client/connpool.h"
#include "mongo/client/dbclientcursor.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/pdfile.h"
#include "mongo/s/chunk.h"
#include "mongo/s/chunk_version.h"
@@ -1066,7 +1065,7 @@ namespace mongo {
if ( withPort ) {
stringstream ss;
- ss << name << ":" << CmdLine::ConfigServerPort;
+ ss << name << ":" << ServerGlobalParams::ConfigServerPort;
return ss.str();
}
diff --git a/src/mongo/s/config_server_tests.cpp b/src/mongo/s/config_server_tests.cpp
index 9a4acf61059..355f0963c2f 100644
--- a/src/mongo/s/config_server_tests.cpp
+++ b/src/mongo/s/config_server_tests.cpp
@@ -34,7 +34,6 @@
namespace mongo {
// Note: these are all crutch and hopefully will eventually go away
- CmdLine cmdLine;
bool inShutdown() {
return false;
diff --git a/src/mongo/s/d_migrate.cpp b/src/mongo/s/d_migrate.cpp
index 77274df9d77..41839265f2d 100644
--- a/src/mongo/s/d_migrate.cpp
+++ b/src/mongo/s/d_migrate.cpp
@@ -51,7 +51,6 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/clientcursor.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/dbhelpers.h"
#include "mongo/db/dur.h"
@@ -1585,7 +1584,8 @@ namespace mongo {
long long num = Helpers::removeRange( range,
false, /*maxInclusive*/
secondaryThrottle, /* secondaryThrottle */
- cmdLine.moveParanoia ? &rs : 0, /*callback*/
+ /*callback*/
+ serverGlobalParams.moveParanoia ? &rs : 0,
true ); /* flag fromMigrate in oplog */
if (num < 0) {
@@ -1864,7 +1864,7 @@ namespace mongo {
Helpers::removeRange( range ,
true , /*maxInclusive*/
false , /* secondaryThrottle */
- cmdLine.moveParanoia ? &rs : 0 , /*callback*/
+ serverGlobalParams.moveParanoia ? &rs : 0 , /*callback*/
true ); /*fromMigrate*/
*lastOpApplied = cx.ctx().getClient()->getLastOp().asDate();
diff --git a/src/mongo/s/d_split.cpp b/src/mongo/s/d_split.cpp
index da7a99eddfc..0bb1c0783e4 100644
--- a/src/mongo/s/d_split.cpp
+++ b/src/mongo/s/d_split.cpp
@@ -440,7 +440,7 @@ namespace mongo {
// Remove the sentinel at the beginning before returning
splitKeys.erase( splitKeys.begin() );
- if ( timer.millis() > cmdLine.slowMS ) {
+ if (timer.millis() > serverGlobalParams.slowMS) {
warning() << "Finding the split vector for " << ns << " over "<< keyPattern
<< " keyCount: " << keyCount << " numSplits: " << splitKeys.size()
<< " lookedAt: " << currCount << " took " << timer.millis() << "ms"
diff --git a/src/mongo/s/grid.cpp b/src/mongo/s/grid.cpp
index 7f079d5b808..c0eb0b4d632 100644
--- a/src/mongo/s/grid.cpp
+++ b/src/mongo/s/grid.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/json.h"
#include "mongo/db/namespace_string.h"
#include "mongo/s/grid.h"
+#include "mongo/s/mongos_options.h"
#include "mongo/s/shard.h"
#include "mongo/s/type_collection.h"
#include "mongo/s/type_database.h"
@@ -304,7 +305,7 @@ namespace mongo {
vector<HostAndPort> hosts = servers.getServers();
for ( size_t i = 0 ; i < hosts.size() ; i++ ) {
if (!hosts[i].hasPort()) {
- hosts[i].setPort(CmdLine::DefaultDBPort);
+ hosts[i].setPort(ServerGlobalParams::DefaultDBPort);
}
string host = hosts[i].toString(); // host:port
if ( hostSet.find( host ) == hostSet.end() ) {
@@ -614,7 +615,7 @@ namespace mongo {
public:
void run() {
- if ( ! cmdLine.isMongos() )
+ if (!isMongos())
return;
// T0 < T1 < now < T2 < T3 and Error
diff --git a/src/mongo/s/mongos_options.cpp b/src/mongo/s/mongos_options.cpp
index b73e5898e15..fd0027c6551 100644
--- a/src/mongo/s/mongos_options.cpp
+++ b/src/mongo/s/mongos_options.cpp
@@ -19,19 +19,25 @@
#include <string>
#include <vector>
+#include "mongo/base/init.h"
#include "mongo/base/status.h"
#include "mongo/bson/util/builder.h"
#include "mongo/db/server_options.h"
+#include "mongo/s/chunk.h"
+#include "mongo/s/version_mongos.h"
#include "mongo/util/net/ssl_options.h"
#include "mongo/util/options_parser/option_description.h"
#include "mongo/util/options_parser/option_section.h"
+#include "mongo/util/options_parser/options_parser.h"
+#include "mongo/util/startup_test.h"
+#include "mongo/util/stringutils.h"
namespace mongo {
typedef moe::OptionDescription OD;
typedef moe::PositionalOptionDescription POD;
- extern std::string dbpath;
+ MongosGlobalParams mongosGlobalParams;
Status addMongosOptions(moe::OptionSection* options) {
@@ -124,4 +130,147 @@ namespace mongo {
return Status::OK();
}
+ void printMongosHelp(const moe::OptionSection& options) {
+ std::cout << options.helpString() << std::endl;
+ };
+
+ Status handlePreValidationMongosOptions(const moe::Environment& params,
+ const std::vector<std::string>& args) {
+ if (params.count("help")) {
+ printMongosHelp(serverOptions);
+ ::_exit(EXIT_SUCCESS);
+ }
+ if (params.count("version")) {
+ printShardingVersionInfo(true);
+ ::_exit(EXIT_SUCCESS);
+ }
+
+ return Status::OK();
+ }
+
+ Status storeMongosOptions(const moe::Environment& params,
+ const std::vector<std::string>& args) {
+
+ Status ret = storeServerOptions(params, args);
+ if (!ret.isOK()) {
+ std::cerr << "Error storing command line: " << ret.toString() << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ if ( params.count( "chunkSize" ) ) {
+ int csize = params["chunkSize"].as<int>();
+
+ // validate chunksize before proceeding
+ if ( csize == 0 ) {
+ std::cerr << "error: need a non-zero chunksize" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ if ( !Chunk::setMaxChunkSizeSizeMB( csize ) ) {
+ std::cerr << "MaxChunkSize invalid" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ }
+
+ if (params.count( "port" ) ) {
+ int port = params["port"].as<int>();
+ if ( port <= 0 || port > 65535 ) {
+ out() << "error: port number must be between 1 and 65535" << endl;
+ ::_exit(EXIT_FAILURE);
+ }
+ }
+
+ if ( params.count( "localThreshold" ) ) {
+ serverGlobalParams.defaultLocalThresholdMillis = params["localThreshold"].as<int>();
+ }
+
+ if ( params.count( "ipv6" ) ) {
+ enableIPv6();
+ }
+
+ if ( params.count( "jsonp" ) ) {
+ serverGlobalParams.jsonp = true;
+ }
+
+ if ( params.count( "test" ) ) {
+ ::mongo::logger::globalLogDomain()->setMinimumLoggedSeverity(
+ ::mongo::logger::LogSeverity::Debug(5));
+ StartupTest::runTests();
+ ::_exit(EXIT_SUCCESS);
+ }
+
+ if (params.count("noscripting")) {
+ // This option currently has no effect for mongos
+ }
+
+ if (params.count("httpinterface")) {
+ if (params.count("nohttpinterface")) {
+ std::cerr << "can't have both --httpinterface and --nohttpinterface" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+ serverGlobalParams.isHttpInterfaceEnabled = true;
+ }
+
+ if (params.count("noAutoSplit")) {
+ warning() << "running with auto-splitting disabled" << endl;
+ Chunk::ShouldAutoSplit = false;
+ }
+
+ if ( ! params.count( "configdb" ) ) {
+ std::cerr << "error: no args for --configdb" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ splitStringDelim(params["configdb"].as<std::string>(), &mongosGlobalParams.configdbs, ',');
+ if (mongosGlobalParams.configdbs.size() != 1 && mongosGlobalParams.configdbs.size() != 3) {
+ std::cerr << "need either 1 or 3 configdbs" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ if (mongosGlobalParams.configdbs.size() == 1) {
+ warning() << "running with 1 config server should be done only for testing purposes "
+ << "and is not recommended for production" << endl;
+ }
+
+ mongosGlobalParams.upgrade = params.count("upgrade");
+
+ return Status::OK();
+ }
+
+ MONGO_INITIALIZER_GENERAL(ParseStartupConfiguration,
+ ("GlobalLogManager"),
+ ("default", "completedStartupConfig"))(InitializerContext* context) {
+
+ serverOptions = moe::OptionSection("Allowed options");
+ Status ret = addMongosOptions(&serverOptions);
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ moe::OptionsParser parser;
+ ret = parser.run(serverOptions, context->args(), context->env(), &serverParsedOptions);
+ if (!ret.isOK()) {
+ std::cerr << "Error parsing command line: " << ret.toString() << std::endl;
+ std::cerr << "use --help for help" << std::endl;
+ ::_exit(EXIT_BADOPTIONS);
+ }
+
+ ret = handlePreValidationMongosOptions(serverParsedOptions, context->args());
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ ret = serverParsedOptions.validate();
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ ret = storeMongosOptions(serverParsedOptions, context->args());
+ if (!ret.isOK()) {
+ return ret;
+ }
+
+ return Status::OK();
+ }
+
} // namespace mongo
diff --git a/src/mongo/s/mongos_options.h b/src/mongo/s/mongos_options.h
index e9f266b8207..9784591f8f3 100644
--- a/src/mongo/s/mongos_options.h
+++ b/src/mongo/s/mongos_options.h
@@ -17,6 +17,7 @@
#pragma once
#include "mongo/base/status.h"
+#include "mongo/db/server_options.h"
namespace mongo {
@@ -26,5 +27,25 @@ namespace mongo {
namespace moe = mongo::optionenvironment;
+ struct MongosGlobalParams {
+ std::vector<std::string> configdbs;
+ bool upgrade;
+
+ MongosGlobalParams() :
+ upgrade(false)
+ { }
+ };
+
+ extern MongosGlobalParams mongosGlobalParams;
+
Status addMongosOptions(moe::OptionSection* options);
+
+ void printMongosHelp(const moe::OptionSection& options);
+
+ Status handlePreValidationMongosOptions(const moe::Environment& params,
+ const std::vector<std::string>& args);
+
+ Status storeMongosOptions(const moe::Environment& params, const std::vector<std::string>& args);
+
+ bool isMongos();
}
diff --git a/src/mongo/s/mongos_persistence_stubs.cpp b/src/mongo/s/mongos_persistence_stubs.cpp
new file mode 100644
index 00000000000..98508931b25
--- /dev/null
+++ b/src/mongo/s/mongos_persistence_stubs.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 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 <string>
+
+namespace mongo {
+
+ // TODO: When the following calls are removed from parameters.cpp, we can remove these.
+ // See SERVER-10515.
+
+ bool isJournalingEnabled() { return false; }
+
+ void setJournalCommitInterval(unsigned newValue) {
+ // This is only for linking and should not get called at runtime
+ }
+
+ unsigned getJournalCommitInterval() {
+ return 0;
+ }
+
+} // namespace mongo
diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp
index fec01840b6b..c8b9c494902 100644
--- a/src/mongo/s/server.cpp
+++ b/src/mongo/s/server.cpp
@@ -57,8 +57,10 @@
#include "mongo/s/grid.h"
#include "mongo/s/mongos_options.h"
#include "mongo/s/request.h"
+#include "mongo/s/version_mongos.h"
#include "mongo/scripting/engine.h"
#include "mongo/util/admin_access.h"
+#include "mongo/util/cmdline_utils/censor_cmdline.h"
#include "mongo/util/concurrency/task.h"
#include "mongo/util/concurrency/thread_name.h"
#include "mongo/util/exception_filter_win32.h"
@@ -70,19 +72,15 @@
#include "mongo/util/ntservice.h"
#include "mongo/util/options_parser/environment.h"
#include "mongo/util/options_parser/option_section.h"
+#include "mongo/util/options_parser/options_parser.h"
#include "mongo/util/processinfo.h"
#include "mongo/util/ramlog.h"
#include "mongo/util/signal_handlers.h"
#include "mongo/util/stacktrace.h"
-#include "mongo/util/startup_test.h"
#include "mongo/util/stringutils.h"
#include "mongo/util/text.h"
#include "mongo/util/version.h"
-namespace {
- bool _isUpgradeSwitchSet = false;
-}
-
namespace mongo {
#if defined(_WIN32)
@@ -94,14 +92,9 @@ namespace mongo {
static void initService();
#endif
- CmdLine cmdLine;
- moe::Environment params;
- moe::OptionSection options("Allowed options");
Database *database = 0;
string mongosCommand;
bool dbexitCalled = false;
- static bool scriptingEnabled = true;
- static vector<string> configdbs;
bool inShutdown() {
return dbexitCalled;
@@ -269,27 +262,6 @@ namespace mongo {
return 0;
}
- void printShardingVersionInfo( bool out ) {
- if ( out ) {
- cout << "MongoS version " << versionString << " starting: pid=" <<
- ProcessId::getCurrent() << " port=" << cmdLine.port <<
- ( sizeof(int*) == 4 ? " 32" : " 64" ) << "-bit host=" << getHostNameCached() <<
- " (--help for usage)" << endl;
- DEV cout << "_DEBUG build" << endl;
- cout << "git version: " << gitVersion() << endl;
- cout << openSSLVersion("OpenSSL version: ") << endl;
- cout << "build sys info: " << sysInfo() << endl;
- }
- else {
- log() << "MongoS version " << versionString << " starting: pid=" <<
- ProcessId::getCurrent() << " port=" << cmdLine.port <<
- ( sizeof( int* ) == 4 ? " 32" : " 64" ) << "-bit host=" << getHostNameCached() <<
- " (--help for usage)" << endl;
- DEV log() << "_DEBUG build" << endl;
- logProcessDetails();
- }
- }
-
} // namespace mongo
using namespace mongo;
@@ -312,7 +284,7 @@ static bool runMongosServer( bool doUpgrade ) {
ReplicaSetMonitor::setConfigChangeHook( boost::bind( &ConfigServer::replicaSetChange , &configServer , _1 ) );
- if ( ! configServer.init( configdbs ) ) {
+ if (!configServer.init(mongosGlobalParams.configdbs)) {
log() << "couldn't resolve config db address" << endl;
return false;
}
@@ -350,10 +322,10 @@ static bool runMongosServer( bool doUpgrade ) {
init();
#if !defined(_WIN32)
- CmdLine::launchOk();
+ mongo::signalForkSuccess();
#endif
- if ( cmdLine.isHttpInterfaceEnabled )
+ if (serverGlobalParams.isHttpInterfaceEnabled)
boost::thread web( boost::bind(&webServerThread, new NoAdminAccess() /* takes ownership */) );
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
@@ -366,8 +338,8 @@ static bool runMongosServer( bool doUpgrade ) {
}
MessageServer::Options opts;
- opts.port = cmdLine.port;
- opts.ipList = cmdLine.bind_ip;
+ opts.port = serverGlobalParams.port;
+ opts.ipList = serverGlobalParams.bind_ip;
start(opts);
// listen() will return when exit code closes its socket.
@@ -375,128 +347,6 @@ static bool runMongosServer( bool doUpgrade ) {
return true;
}
-static Status processCommandLineOptions(const std::vector<std::string>& argv) {
- Status ret = addMongosOptions(&options);
- if (!ret.isOK()) {
- StringBuilder sb;
- sb << "Error getting mongos options descriptions: " << ret.toString();
- return Status(ErrorCodes::InternalError, sb.str());
- }
-
- // parse options
- ret = CmdLine::store(argv, options, params);
- if (!ret.isOK()) {
- std::cerr << "Error parsing command line: " << ret.toString() << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
-
- // The default value may vary depending on compile options, but for mongos
- // we want durability to be disabled.
- cmdLine.dur = false;
-
- if ( params.count( "help" ) ) {
- std::cout << options.helpString() << std::endl;
- ::_exit(EXIT_SUCCESS);
- }
- if ( params.count( "version" ) ) {
- printShardingVersionInfo(true);
- ::_exit(EXIT_SUCCESS);
- }
-
- if ( params.count( "chunkSize" ) ) {
- int csize = params["chunkSize"].as<int>();
-
- // validate chunksize before proceeding
- if ( csize == 0 ) {
- std::cerr << "error: need a non-zero chunksize" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
-
- if ( !Chunk::setMaxChunkSizeSizeMB( csize ) ) {
- std::cerr << "MaxChunkSize invalid" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- }
-
- if (params.count( "port" ) ) {
- int port = params["port"].as<int>();
- if ( port <= 0 || port > 65535 ) {
- out() << "error: port number must be between 1 and 65535" << endl;
- ::_exit(EXIT_FAILURE);
- }
- }
-
- if ( params.count( "localThreshold" ) ) {
- cmdLine.defaultLocalThresholdMillis = params["localThreshold"].as<int>();
- }
-
- if ( params.count( "ipv6" ) ) {
- enableIPv6();
- }
-
- if ( params.count( "jsonp" ) ) {
- cmdLine.jsonp = true;
- }
-
- if ( params.count( "test" ) ) {
- ::mongo::logger::globalLogDomain()->setMinimumLoggedSeverity(
- ::mongo::logger::LogSeverity::Debug(5));
- StartupTest::runTests();
- ::_exit(EXIT_SUCCESS);
- }
-
- if (params.count("noscripting")) {
- scriptingEnabled = false;
- }
-
- if (params.count("httpinterface")) {
- if (params.count("nohttpinterface")) {
- std::cerr << "can't have both --httpinterface and --nohttpinterface" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
- cmdLine.isHttpInterfaceEnabled = true;
- }
-
- if (params.count("noAutoSplit")) {
- warning() << "running with auto-splitting disabled" << endl;
- Chunk::ShouldAutoSplit = false;
- }
-
- if ( ! params.count( "configdb" ) ) {
- std::cerr << "error: no args for --configdb" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
-
- splitStringDelim( params["configdb"].as<string>() , &configdbs , ',' );
- if ( configdbs.size() != 1 && configdbs.size() != 3 ) {
- std::cerr << "need either 1 or 3 configdbs" << std::endl;
- ::_exit(EXIT_BADOPTIONS);
- }
-
- if( configdbs.size() == 1 ) {
- warning() << "running with 1 config server should be done only for testing purposes and is not recommended for production" << endl;
- }
-
- _isUpgradeSwitchSet = params.count("upgrade");
-
- // dbpath currently must be linked in to mongos, but the directory should never be written to.
- dbpath = "";
-
- return Status::OK();
-}
-
-MONGO_INITIALIZER_GENERAL(ParseStartupConfiguration,
- ("GlobalLogManager"),
- ("default", "completedStartupConfig"))(InitializerContext* context) {
-
- Status ret = processCommandLineOptions(context->args());
- if (!ret.isOK()) {
- return ret;
- }
-
- return Status::OK();
-}
-
MONGO_INITIALIZER_GENERAL(ForkServerOrDie,
("completedStartupConfig"),
("default"))(InitializerContext* context) {
@@ -513,7 +363,7 @@ static void startupConfigActions(const std::vector<std::string>& argv) {
vector<string> disallowedOptions;
disallowedOptions.push_back( "upgrade" );
ntservice::configureService(initService,
- params,
+ serverParsedOptions,
defaultServiceStrings,
disallowedOptions,
argv);
@@ -526,12 +376,13 @@ static int _main() {
return EXIT_FAILURE;
// we either have a setting where all processes are in localhost or none are
- for ( vector<string>::const_iterator it = configdbs.begin() ; it != configdbs.end() ; ++it ) {
+ for (std::vector<std::string>::const_iterator it = mongosGlobalParams.configdbs.begin();
+ it != mongosGlobalParams.configdbs.end(); ++it) {
try {
HostAndPort configAddr( *it ); // will throw if address format is invalid
- if ( it == configdbs.begin() ) {
+ if (it == mongosGlobalParams.configdbs.begin()) {
grid.setAllowLocalHost( configAddr.isLocalHost() );
}
@@ -555,7 +406,7 @@ static int _main() {
}
#endif
- return !runMongosServer(_isUpgradeSwitchSet);
+ return !runMongosServer(mongosGlobalParams.upgrade);
}
#if defined(_WIN32)
@@ -597,7 +448,7 @@ int mongoSMain(int argc, char* argv[], char** envp) {
mongo::runGlobalInitializersOrDie(argc, argv, envp);
startupConfigActions(std::vector<std::string>(argv, argv + argc));
- CmdLine::censor(argc, argv);
+ cmdline_utils::censorArgvArray(argc, argv);
try {
int exitCode = _main();
return exitCode;
diff --git a/src/mongo/s/shard_conn_test.cpp b/src/mongo/s/shard_conn_test.cpp
index 867bf2f951b..27b77730c7b 100644
--- a/src/mongo/s/shard_conn_test.cpp
+++ b/src/mongo/s/shard_conn_test.cpp
@@ -44,7 +44,6 @@ using std::vector;
namespace mongo {
// Note: these are all crutch and hopefully will eventually go away
- CmdLine cmdLine;
bool inShutdown() {
return false;
diff --git a/src/mongo/s/shard_test.cpp b/src/mongo/s/shard_test.cpp
index de6fe4f3a6e..3bf6218f77c 100644
--- a/src/mongo/s/shard_test.cpp
+++ b/src/mongo/s/shard_test.cpp
@@ -34,7 +34,6 @@
namespace mongo {
// Note: these are all crutch and hopefully will eventually go away
- CmdLine cmdLine;
bool inShutdown() {
return false;
diff --git a/src/mongo/s/version_mongos.cpp b/src/mongo/s/version_mongos.cpp
new file mode 100644
index 00000000000..e23c8cfd92a
--- /dev/null
+++ b/src/mongo/s/version_mongos.cpp
@@ -0,0 +1,63 @@
+/**
+* Copyright (C) 2013 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/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects
+* for all of the code used other than as permitted herein. If you modify
+* file(s) with this exception, you may extend this exception to your
+* version of the file(s), but you are not obligated to do so. If you do not
+* wish to do so, delete this exception statement from your version. If you
+* delete this exception statement from all source files in the program,
+* then also delete it in the license file.
+*/
+
+#include "mongo/s/version_mongos.h"
+
+#include <iostream>
+
+#include "mongo/db/log_process_details.h"
+#include "mongo/db/server_options.h"
+#include "mongo/platform/process_id.h"
+#include "mongo/util/debug_util.h"
+#include "mongo/util/log.h"
+#include "mongo/util/net/sock.h"
+#include "mongo/util/version.h"
+
+namespace mongo {
+
+ void printShardingVersionInfo( bool out ) {
+ if ( out ) {
+ std::cout << "MongoS version " << versionString << " starting: pid=" <<
+ ProcessId::getCurrent() << " port=" << serverGlobalParams.port <<
+ ( sizeof(int*) == 4 ? " 32" : " 64" ) << "-bit host=" << getHostNameCached() <<
+ " (--help for usage)" << std::endl;
+ DEV std::cout << "_DEBUG build" << std::endl;
+ std::cout << "git version: " << gitVersion() << std::endl;
+ std::cout << openSSLVersion("OpenSSL version: ") << std::endl;
+ std::cout << "build sys info: " << sysInfo() << std::endl;
+ }
+ else {
+ log() << "MongoS version " << versionString << " starting: pid=" <<
+ ProcessId::getCurrent() << " port=" << serverGlobalParams.port <<
+ ( sizeof( int* ) == 4 ? " 32" : " 64" ) << "-bit host=" << getHostNameCached() <<
+ " (--help for usage)" << std::endl;
+ DEV log() << "_DEBUG build" << std::endl;
+ logProcessDetails();
+ }
+ }
+} // namespace mongo
diff --git a/src/mongo/s/version_mongos.h b/src/mongo/s/version_mongos.h
new file mode 100644
index 00000000000..491c36da5da
--- /dev/null
+++ b/src/mongo/s/version_mongos.h
@@ -0,0 +1,32 @@
+/**
+* Copyright (C) 2013 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/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects
+* for all of the code used other than as permitted herein. If you modify
+* file(s) with this exception, you may extend this exception to your
+* version of the file(s), but you are not obligated to do so. If you do not
+* wish to do so, delete this exception statement from your version. If you
+* delete this exception statement from all source files in the program,
+* then also delete it in the license file.
+*/
+
+namespace mongo {
+ // print mongos version info
+ void printShardingVersionInfo(bool out);
+} // namespace mongo
diff --git a/src/mongo/shell/dbshell.cpp b/src/mongo/shell/dbshell.cpp
index df530dfac35..436b383765d 100644
--- a/src/mongo/shell/dbshell.cpp
+++ b/src/mongo/shell/dbshell.cpp
@@ -27,7 +27,6 @@
#include "mongo/base/status.h"
#include "mongo/client/dbclientinterface.h"
#include "mongo/client/sasl_client_authenticate.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/repl/rs_member.h"
#include "mongo/logger/console_appender.h"
#include "mongo/logger/logger.h"
@@ -791,7 +790,7 @@ Status addMongoShellOptions(moe::OptionSection* options) {
Status storeMongoShellOptions() {
if ( params.count( "quiet" ) ) {
- mongo::cmdLine.quiet = true;
+ mongo::serverGlobalParams.quiet = true;
}
#ifdef MONGO_SSL
Status ret = storeSSLClientOptions(params);
@@ -961,7 +960,7 @@ int _main( int argc, char* argv[], char **envp ) {
return mongo::EXIT_BADOPTIONS;
}
- if ( ! mongo::cmdLine.quiet )
+ if (!mongo::serverGlobalParams.quiet)
cout << "MongoDB shell version: " << mongo::versionString << endl;
mongo::StartupTest::runTests();
@@ -972,10 +971,8 @@ int _main( int argc, char* argv[], char **envp ) {
new logger::MessageEventUnadornedEncoder)));
if ( !nodb ) { // connect to db
- //if ( ! mongo::cmdLine.quiet ) cout << "url: " << url << endl;
-
stringstream ss;
- if ( mongo::cmdLine.quiet )
+ if (mongo::serverGlobalParams.quiet)
ss << "__quiet = true;";
ss << "db = connect( \"" << fixHost( url , dbhost , port ) << "\")";
@@ -1104,7 +1101,7 @@ int _main( int argc, char* argv[], char **envp ) {
f.open(rcLocation.c_str(), false); // Create empty .mongorc.js file
}
- if ( !nodb && !mongo::cmdLine.quiet && isatty(fileno(stdin)) ) {
+ if (!nodb && !mongo::serverGlobalParams.quiet && isatty(fileno(stdin))) {
scope->exec( "shellHelper( 'show', 'startupWarnings' )", "(shellwarnings", false, true, false );
}
@@ -1146,7 +1143,7 @@ int _main( int argc, char* argv[], char **envp ) {
}
if ( ! linePtr || ( strlen( linePtr ) == 4 && strstr( linePtr , "exit" ) ) ) {
- if ( ! mongo::cmdLine.quiet )
+ if (!mongo::serverGlobalParams.quiet)
cout << "bye" << endl;
if ( line )
free( line );
diff --git a/src/mongo/tools/bridge.cpp b/src/mongo/tools/bridge.cpp
index b211dcdc5b0..2d3f86cd9de 100644
--- a/src/mongo/tools/bridge.cpp
+++ b/src/mongo/tools/bridge.cpp
@@ -34,10 +34,6 @@ int delay = 0;
string destUri;
void cleanup( int sig );
-namespace mongo {
- CmdLine cmdLine;
-}
-
class Forwarder {
public:
Forwarder( MessagingPort &mp ) : mp_( mp ) {
diff --git a/src/mongo/tools/sniffer.cpp b/src/mongo/tools/sniffer.cpp
index b32f62006dc..2d193186990 100644
--- a/src/mongo/tools/sniffer.cpp
+++ b/src/mongo/tools/sniffer.cpp
@@ -67,8 +67,6 @@ using mongo::DBClientConnection;
using mongo::QueryResult;
using mongo::MemoryMappedFile;
-mongo::CmdLine mongo::cmdLine;
-
#define SNAP_LEN 65535
int captureHeaderSize;
diff --git a/src/mongo/tools/tool.cpp b/src/mongo/tools/tool.cpp
index cd7b1117700..f6fb9e33d4d 100644
--- a/src/mongo/tools/tool.cpp
+++ b/src/mongo/tools/tool.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/auth/authz_manager_external_state_mock.h"
#include "mongo/db/json.h"
#include "mongo/db/namespace_details.h"
+#include "mongo/db/storage_options.h"
#include "mongo/platform/posix_fadvise.h"
#include "mongo/util/file_allocator.h"
#include "mongo/util/options_parser/option_section.h"
@@ -45,7 +46,6 @@ using namespace mongo;
namespace mongo {
- CmdLine cmdLine;
moe::OptionSection options("options");
moe::Environment _params;
@@ -72,11 +72,11 @@ namespace mongo {
setGlobalAuthorizationManager(new AuthorizationManager(new AuthzManagerExternalStateMock()));
- cmdLine.prealloc = false;
+ storageGlobalParams.prealloc = false;
// The default value may vary depending on compile options, but for tools
// we want durability to be disabled.
- cmdLine.dur = false;
+ storageGlobalParams.dur = false;
_name = argv[0];
@@ -152,7 +152,7 @@ namespace mongo {
bool useDirectClient = hasParam( "dbpath" );
if ( useDirectClient && _params.count("journal")){
- cmdLine.dur = true;
+ storageGlobalParams.dur = true;
}
preSetup();
@@ -191,7 +191,7 @@ namespace mongo {
}
else {
if ( _params.count( "directoryperdb" ) ) {
- directoryperdb = true;
+ storageGlobalParams.directoryperdb = true;
}
verify( lastError.get( true ) );
@@ -199,7 +199,7 @@ namespace mongo {
_conn = new DBDirectClient();
_host = "DIRECT";
static string myDbpath = getParam( "dbpath" );
- dbpath = myDbpath.c_str();
+ storageGlobalParams.dbpath = myDbpath.c_str();
try {
acquirePathLock();
}
diff --git a/src/mongo/util/assert_util.h b/src/mongo/util/assert_util.h
index ff5bc810c28..8ea5f356846 100644
--- a/src/mongo/util/assert_util.h
+++ b/src/mongo/util/assert_util.h
@@ -293,8 +293,10 @@ namespace mongo {
try { \
expression; \
} catch ( const std::exception &e ) { \
- problem() << "caught exception (" << e.what() << ") in destructor (" << __FUNCTION__ << ")" << endl; \
+ problem() << "caught exception (" << e.what() << ") in destructor (" << __FUNCTION__ \
+ << ")" << std::endl; \
} catch ( ... ) { \
- problem() << "caught unknown exception in destructor (" << __FUNCTION__ << ")" << endl; \
+ problem() << "caught unknown exception in destructor (" << __FUNCTION__ << ")" \
+ << std::endl; \
}
diff --git a/src/mongo/util/cmdline_utils/SConscript b/src/mongo/util/cmdline_utils/SConscript
new file mode 100644
index 00000000000..6cdfe310ef7
--- /dev/null
+++ b/src/mongo/util/cmdline_utils/SConscript
@@ -0,0 +1,10 @@
+# -*- mode: python -*-
+
+Import("env")
+
+env.StaticLibrary('cmdline_utils', ['censor_cmdline.cpp'],
+ LIBDEPS=['$BUILD_DIR/mongo/bson'])
+
+env.CppUnitTest('censor_cmdline_test',
+ 'censor_cmdline_test.cpp',
+ LIBDEPS=['cmdline_utils', '$BUILD_DIR/mongo/unittest/unittest'])
diff --git a/src/mongo/util/cmdline_utils/censor_cmdline.cpp b/src/mongo/util/cmdline_utils/censor_cmdline.cpp
new file mode 100644
index 00000000000..e50b7018c99
--- /dev/null
+++ b/src/mongo/util/cmdline_utils/censor_cmdline.cpp
@@ -0,0 +1,161 @@
+// cmdline.cpp
+
+/**
+* Copyright (C) 2008 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/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects for
+* all of the code used other than as permitted herein. If you modify file(s)
+* with this exception, you may extend this exception to your version of the
+* file(s), but you are not obligated to do so. If you do not wish to do so,
+* delete this exception statement from your version. If you delete this
+* exception statement from all source files in the program, then also delete
+* it in the license file.
+*/
+
+#include "mongo/util/cmdline_utils/censor_cmdline.h"
+
+#include "mongo/util/mongoutils/str.h"
+
+namespace mongo {
+
+ namespace cmdline_utils {
+
+ static bool _isPasswordArgument(char const* argumentName);
+ static bool _isPasswordSwitch(char const* switchName);
+
+ static bool _isPasswordArgument(const char* argumentName) {
+ static const char* const passwordArguments[] = {
+ "sslPEMKeyPassword",
+ "ssl.PEMKeyPassword",
+ "servicePassword",
+ NULL // Last entry sentinel.
+ };
+ for (const char* const* current = passwordArguments; *current; ++current) {
+ if (mongoutils::str::equals(argumentName, *current))
+ return true;
+ }
+ return false;
+ }
+
+ static bool _isPasswordSwitch(const char* switchName) {
+ if (switchName[0] != '-')
+ return false;
+ size_t i = 1;
+ if (switchName[1] == '-')
+ i = 2;
+ switchName += i;
+
+ return _isPasswordArgument(switchName);
+ }
+
+ static void _redact(char* arg) {
+ for (; *arg; ++arg)
+ *arg = 'x';
+ }
+
+ void censorBSONObjRecursive(const BSONObj& params, // Object we are censoring
+ const std::string& parentPath, // Set if this is a sub object
+ bool isArray,
+ BSONObjBuilder* result) {
+ BSONObjIterator paramsIterator(params);
+ while (paramsIterator.more()) {
+ BSONElement param = paramsIterator.next();
+ std::string dottedName = (parentPath.empty() ? param.fieldName()
+ : isArray ? parentPath
+ : parentPath + '.' + param.fieldName());
+ if (param.type() == Array) {
+ BSONObjBuilder subArray(result->subarrayStart(param.fieldName()));
+ censorBSONObjRecursive(param.Obj(), dottedName, true, &subArray);
+ subArray.done();
+ }
+ else if (param.type() == Object) {
+ BSONObjBuilder subObj(result->subobjStart(param.fieldName()));
+ censorBSONObjRecursive(param.Obj(), dottedName, false, &subObj);
+ subObj.done();
+ }
+ else if (param.type() == String) {
+ if (_isPasswordArgument(dottedName.c_str())) {
+ result->append(param.fieldName(), "<password>");
+ }
+ else {
+ result->append(param);
+ }
+ }
+ else {
+ result->append(param);
+ }
+ }
+ }
+
+ void censorBSONObj(BSONObj* params) {
+ BSONObjBuilder builder;
+ censorBSONObjRecursive(*params, "", false, &builder);
+ *params = builder.obj();
+ }
+
+ void censorArgsVector(std::vector<std::string>* args) {
+ for (size_t i = 0; i < args->size(); ++i) {
+ std::string& arg = args->at(i);
+ const std::string::iterator endSwitch = std::find(arg.begin(), arg.end(), '=');
+ std::string switchName(arg.begin(), endSwitch);
+ if (_isPasswordSwitch(switchName.c_str())) {
+ if (endSwitch == arg.end()) {
+ if (i + 1 < args->size()) {
+ args->at(i + 1) = "<password>";
+ }
+ }
+ else {
+ arg = switchName + "=<password>";
+ }
+ }
+ }
+ }
+
+ void censorArgvArray(int argc, char** argv) {
+ // Algorithm: For each arg in argv:
+ // Look for an equal sign in arg; if there is one, temporarily nul it out.
+ // check to see if arg is a password switch. If so, overwrite the value
+ // component with xs.
+ // restore the nul'd out equal sign, if any.
+ for (int i = 0; i < argc; ++i) {
+
+ char* const arg = argv[i];
+ char* const firstEqSign = strchr(arg, '=');
+ if (NULL != firstEqSign) {
+ *firstEqSign = '\0';
+ }
+
+ if (_isPasswordSwitch(arg)) {
+ if (NULL == firstEqSign) {
+ if (i + 1 < argc) {
+ _redact(argv[i + 1]);
+ }
+ }
+ else {
+ _redact(firstEqSign + 1);
+ }
+ }
+
+ if (NULL != firstEqSign) {
+ *firstEqSign = '=';
+ }
+ }
+ }
+ } // namespace cmdline_utils
+}
diff --git a/src/mongo/util/cmdline_utils/censor_cmdline.h b/src/mongo/util/cmdline_utils/censor_cmdline.h
new file mode 100644
index 00000000000..7ab29429697
--- /dev/null
+++ b/src/mongo/util/cmdline_utils/censor_cmdline.h
@@ -0,0 +1,49 @@
+/**
+* Copyright (C) 2008 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/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects for
+* all of the code used other than as permitted herein. If you modify file(s)
+* with this exception, you may extend this exception to your version of the
+* file(s), but you are not obligated to do so. If you do not wish to do so,
+* delete this exception statement from your version. If you delete this
+* exception statement from all source files in the program, then also delete
+* it in the license file.
+*/
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "mongo/db/jsobj.h"
+
+namespace mongo {
+
+ namespace cmdline_utils {
+
+ /**
+ * Blot out sensitive fields in the argv array.
+ */
+ void censorArgvArray(int argc, char** argv);
+ void censorArgsVector(std::vector<std::string>* args);
+ void censorBSONObj(BSONObj* params);
+
+ } // namespace cmdline_utils
+}
+
diff --git a/src/mongo/db/cmdline_test.cpp b/src/mongo/util/cmdline_utils/censor_cmdline_test.cpp
index 9fe03f309c9..7648f607ecd 100644
--- a/src/mongo/db/cmdline_test.cpp
+++ b/src/mongo/util/cmdline_utils/censor_cmdline_test.cpp
@@ -30,14 +30,13 @@
#include <string>
#include <vector>
-#include "mongo/db/cmdline.h"
#include "mongo/db/jsobj.h"
#include "mongo/unittest/unittest.h"
+#include "mongo/util/cmdline_utils/censor_cmdline.h"
#include "mongo/util/options_parser/environment.h"
namespace mongo {
- CmdLine cmdLine;
#ifdef MONGO_SSL
Status storeSSLServerOptions(const optionenvironment::Environment& params) {
@@ -61,7 +60,7 @@ namespace {
char** argv = &*arrayStandin.begin();
- CmdLine::censor(elementCount, argv);
+ cmdline_utils::censorArgvArray(elementCount, argv);
for (int i = 0; i < elementCount; ++i) {
ASSERT_EQUALS(std::string(expected[i]), std::string(argv[i]));
@@ -74,7 +73,7 @@ namespace {
std::vector<std::string> actual(toCensor, toCensor + elementCount);
- CmdLine::censor(&actual);
+ cmdline_utils::censorArgsVector(&actual);
for (int i = 0; i < elementCount; ++i) {
ASSERT_EQUALS(std::string(expected[i]), actual[i]);
@@ -243,49 +242,98 @@ namespace {
testCensoringVector(expected, argv, argc);
}
- TEST(ParsedOptsTests, NormalValues) {
- moe::Environment environment;
- ASSERT_OK(environment.set(moe::Key("val1"), moe::Value(6)));
- ASSERT_OK(environment.set(moe::Key("val2"), moe::Value(std::string("string"))));
- ASSERT_OK(CmdLine::setParsedOpts(environment));
- BSONObj obj = BSON( "val1" << 6 << "val2" << "string" );
- // TODO: Put a comparison here that doesn't depend on the field order. Right now it is
- // based on the sort order of keys in a std::map.
- ASSERT_EQUALS(obj, CmdLine::getParsedOpts());
+ TEST(BSONObjCensorTests, Strings) {
+ BSONObj obj = BSON("firstarg" << "not a password" <<
+ "sslPEMKeyPassword" << "this password should be censored" <<
+ "middlearg" << "also not a password" <<
+ "servicePassword" << "this password should also be censored" <<
+ "lastarg" << false <<
+ "servicePassword" << true);
+
+ BSONObj res = BSON("firstarg" << "not a password" <<
+ "sslPEMKeyPassword" << "<password>" <<
+ "middlearg" << "also not a password" <<
+ "servicePassword" << "<password>" <<
+ "lastarg" << false <<
+ "servicePassword" << true);
+
+ cmdline_utils::censorBSONObj(&obj);
+ ASSERT_EQUALS(res, obj);
}
- TEST(ParsedOptsTests, DottedValues) {
- moe::Environment environment;
- ASSERT_OK(environment.set(moe::Key("val1.dotted1"), moe::Value(6)));
- ASSERT_OK(environment.set(moe::Key("val2"), moe::Value(true)));
- ASSERT_OK(environment.set(moe::Key("val1.dotted2"), moe::Value(std::string("string"))));
- ASSERT_OK(CmdLine::setParsedOpts(environment));
- BSONObj obj = BSON( "val1" << BSON( "dotted1" << 6 << "dotted2" << "string" )
- << "val2" << true );
- // TODO: Put a comparison here that doesn't depend on the field order. Right now it is
- // based on the sort order of keys in a std::map.
- ASSERT_EQUALS(obj, CmdLine::getParsedOpts());
+ TEST(BSONObjCensorTests, Arrays) {
+ BSONObj obj = BSON("firstarg" << "not a password" <<
+ "sslPEMKeyPassword" << BSON_ARRAY("first censored password" <<
+ "next censored password") <<
+ "middlearg" << "also not a password" <<
+ "servicePassword" << BSON_ARRAY("first censored password" <<
+ "next censored password") <<
+ "lastarg" << false <<
+ "servicePassword" << true);
+
+ BSONObj res = BSON("firstarg" << "not a password" <<
+ "sslPEMKeyPassword" << BSON_ARRAY("<password>" <<
+ "<password>") <<
+ "middlearg" << "also not a password" <<
+ "servicePassword" << BSON_ARRAY("<password>" <<
+ "<password>") <<
+ "lastarg" << false <<
+ "servicePassword" << true);
+
+ cmdline_utils::censorBSONObj(&obj);
+ ASSERT_EQUALS(res, obj);
}
- TEST(ParsedOptsTests, DeepDottedValues) {
- moe::Environment environment;
- ASSERT_OK(environment.set(moe::Key("val1.first1.second1.third1"), moe::Value(6)));
- ASSERT_OK(environment.set(moe::Key("val1.first1.second2.third1"), moe::Value(false)));
- ASSERT_OK(environment.set(moe::Key("val1.first2"), moe::Value(std::string("string"))));
- ASSERT_OK(environment.set(moe::Key("val1.first1.second1.third2"), moe::Value(true)));
- ASSERT_OK(environment.set(moe::Key("val2"), moe::Value(6.0)));
- ASSERT_OK(CmdLine::setParsedOpts(environment));
- BSONObj obj = BSON( "val1" << BSON( "first1" <<
- BSON( "second1" <<
- BSON( "third1" << 6 << "third2" << true ) <<
- "second2" <<
- BSON( "third1" << false ) ) <<
- "first2" << "string" ) <<
- "val2" << 6.0 );
- // TODO: Put a comparison here that doesn't depend on the field order. Right now it is
- // based on the sort order of keys in a std::map.
- ASSERT_EQUALS(obj, CmdLine::getParsedOpts());
+ TEST(BSONObjCensorTests, SubObjects) {
+ BSONObj obj = BSON("firstarg" << "not a password" <<
+ "ssl" << BSON("PEMKeyPassword" << BSON_ARRAY("first censored password" <<
+ "next censored password") <<
+ "PEMKeyPassword" << "should be censored too") <<
+ "lastarg" << false <<
+ "servicePassword" << true);
+
+ BSONObj res = BSON("firstarg" << "not a password" <<
+ "ssl" << BSON("PEMKeyPassword" << BSON_ARRAY("<password>" <<
+ "<password>") <<
+ "PEMKeyPassword" << "<password>") <<
+ "lastarg" << false <<
+ "servicePassword" << true);
+
+ cmdline_utils::censorBSONObj(&obj);
+ ASSERT_EQUALS(res, obj);
}
+ TEST(BSONObjCensorTests, Full) {
+ BSONObj obj = BSON("firstarg" << "not a password" <<
+ "sslPEMKeyPassword" << "this password should be censored" <<
+ "sslPEMKeyPassword" << BSON_ARRAY("first censored password" <<
+ "next censored password") <<
+ "middlearg" << "also not a password" <<
+ "servicePassword" << "this password should also be censored" <<
+ "servicePassword" << BSON_ARRAY("first censored password" <<
+ "next censored password") <<
+ "ssl" << BSON("PEMKeyPassword" << BSON_ARRAY("first censored password" <<
+ "next censored password") <<
+ "PEMKeyPassword" << "should be censored too") <<
+ "lastarg" << false <<
+ "servicePassword" << true);
+
+ BSONObj res = BSON("firstarg" << "not a password" <<
+ "sslPEMKeyPassword" << "<password>" <<
+ "sslPEMKeyPassword" << BSON_ARRAY("<password>" <<
+ "<password>") <<
+ "middlearg" << "also not a password" <<
+ "servicePassword" << "<password>" <<
+ "servicePassword" << BSON_ARRAY("<password>" <<
+ "<password>") <<
+ "ssl" << BSON("PEMKeyPassword" << BSON_ARRAY("<password>" <<
+ "<password>") <<
+ "PEMKeyPassword" << "<password>") <<
+ "lastarg" << false <<
+ "servicePassword" << true);
+
+ cmdline_utils::censorBSONObj(&obj);
+ ASSERT_EQUALS(res, obj);
+ }
} // namespace
} // namespace mongo
diff --git a/src/mongo/util/debug_util.cpp b/src/mongo/util/debug_util.cpp
index 816b0af4a2d..a496e882c67 100644
--- a/src/mongo/util/debug_util.cpp
+++ b/src/mongo/util/debug_util.cpp
@@ -22,7 +22,6 @@
#endif
#if defined(USE_GDBSERVER)
-#include "mongo/db/cmdline.h"
#include "mongo/db/jsobj.h"
#endif // defined(USE_GDBSERVER)
@@ -53,13 +52,13 @@ namespace mongo {
* Assumptions:
* 1) gdbserver is on your path
* 2) You have run "handle SIGSTOP noprint" in gdb
- * 3) cmdLine.port + 2000 is free
+ * 3) serverGlobalParams.port + 2000 is free
*/
void launchGDB(int) {
// Don't come back here
signal(SIGTRAP, SIG_IGN);
- int newPort = cmdLine.port + 2000;
+ int newPort = serverGlobalParams.port + 2000;
string newPortStr = "localhost:" + BSONObjBuilder::numStr(newPort);
string pidToDebug = BSONObjBuilder::numStr(getpid());
diff --git a/src/mongo/util/mmap.cpp b/src/mongo/util/mmap.cpp
index 78588dd3a14..207675e75de 100644
--- a/src/mongo/util/mmap.cpp
+++ b/src/mongo/util/mmap.cpp
@@ -21,7 +21,6 @@
#include <boost/filesystem/operations.hpp>
-#include "mongo/db/cmdline.h"
#include "mongo/util/concurrency/rwlock.h"
#include "mongo/util/map_util.h"
#include "mongo/util/mongoutils/str.h"
diff --git a/src/mongo/util/net/hostandport.h b/src/mongo/util/net/hostandport.h
index ff47d7f9ef4..aa1a395643b 100644
--- a/src/mongo/util/net/hostandport.h
+++ b/src/mongo/util/net/hostandport.h
@@ -18,7 +18,7 @@
#pragma once
#include "mongo/bson/util/builder.h"
-#include "mongo/db/cmdline.h"
+#include "mongo/db/server_options.h"
#include "mongo/util/mongoutils/str.h"
#include "mongo/util/net/sock.h"
@@ -38,7 +38,7 @@ namespace mongo {
/** @param p port number. -1 is ok to use default. */
HostAndPort(const std::string& h, int p /*= -1*/) : _host(h), _port(p) {
- verify( !str::startsWith(h, '#') );
+ verify(!mongoutils::str::startsWith(h, '#'));
}
HostAndPort(const SockAddr& sock ) : _host( sock.getAddr() ) , _port( sock.getPort() ) { }
@@ -84,7 +84,7 @@ namespace mongo {
int port() const {
if (hasPort())
return _port;
- return CmdLine::DefaultDBPort;
+ return ServerGlobalParams::DefaultDBPort;
}
bool hasPort() const {
return _port >= 0;
@@ -100,7 +100,7 @@ namespace mongo {
};
inline HostAndPort HostAndPort::me() {
- const char* ips = cmdLine.bind_ip.c_str();
+ const char* ips = serverGlobalParams.bind_ip.c_str();
while(*ips) {
string ip;
const char * comma = strchr(ips, ',');
@@ -112,7 +112,7 @@ namespace mongo {
ip = string(ips);
ips = "";
}
- HostAndPort h = HostAndPort(ip, cmdLine.port);
+ HostAndPort h = HostAndPort(ip, serverGlobalParams.port);
if (!h.isLocalHost()) {
return h;
}
@@ -121,7 +121,7 @@ namespace mongo {
string h = getHostName();
verify( !h.empty() );
verify( h != "localhost" );
- return HostAndPort(h, cmdLine.port);
+ return HostAndPort(h, serverGlobalParams.port);
}
inline string HostAndPort::toString( bool includePort ) const {
@@ -142,7 +142,7 @@ namespace mongo {
ss << ':';
#if defined(_DEBUG)
if( p >= 44000 && p < 44100 ) {
- log() << "warning: special debug port 44xxx used" << endl;
+ log() << "warning: special debug port 44xxx used" << std::endl;
ss << p+1;
}
else
@@ -158,7 +158,7 @@ namespace mongo {
inline bool HostAndPort::isLocalHost() const {
string _host = host();
return ( _host == "localhost"
- || startsWith(_host.c_str(), "127.")
+ || mongoutils::str::startsWith(_host.c_str(), "127.")
|| _host == "::1"
|| _host == "anonymous unix socket"
|| _host.c_str()[0] == '/' // unix socket
diff --git a/src/mongo/util/net/listen.cpp b/src/mongo/util/net/listen.cpp
index 3492dc76b69..845681881ad 100644
--- a/src/mongo/util/net/listen.cpp
+++ b/src/mongo/util/net/listen.cpp
@@ -115,7 +115,8 @@ namespace mongo {
checkTicketNumbers();
#if !defined(_WIN32)
- _mine = ipToAddrs(_ip.c_str(), _port, (!cmdLine.noUnixSocket && useUnixSockets()));
+ _mine = ipToAddrs(_ip.c_str(), _port, (!serverGlobalParams.noUnixSocket &&
+ useUnixSockets()));
#else
_mine = ipToAddrs(_ip.c_str(), _port, false);
#endif
@@ -289,7 +290,7 @@ namespace mongo {
long long myConnectionNumber = globalConnectionNumber.addAndFetch(1);
- if ( _logConnect && ! cmdLine.quiet ){
+ if (_logConnect && !serverGlobalParams.quiet) {
int conns = globalTicketHolder.used()+1;
const char* word = (conns == 1 ? " connection" : " connections");
log() << "connection accepted from " << from.toString() << " #" << myConnectionNumber << " (" << conns << word << " now open)" << endl;
@@ -483,7 +484,7 @@ namespace mongo {
long long myConnectionNumber = globalConnectionNumber.addAndFetch(1);
- if ( _logConnect && ! cmdLine.quiet ){
+ if (_logConnect && !serverGlobalParams.quiet) {
int conns = globalTicketHolder.used()+1;
const char* word = (conns == 1 ? " connection" : " connections");
log() << "connection accepted from " << from.toString() << " #" << myConnectionNumber << " (" << conns << word << " now open)" << endl;
diff --git a/src/mongo/util/net/message.h b/src/mongo/util/net/message.h
index 738d3a34ba5..aa30bd85cfc 100644
--- a/src/mongo/util/net/message.h
+++ b/src/mongo/util/net/message.h
@@ -17,7 +17,10 @@
#pragma once
+#include <vector>
+
#include "mongo/bson/util/atomic_int.h"
+#include "mongo/util/goodies.h"
#include "mongo/util/net/hostandport.h"
#include "mongo/util/net/sock.h"
@@ -201,12 +204,14 @@ namespace mongo {
verify( _freeIt );
int totalSize = 0;
- for( vector< pair< char *, int > >::const_iterator i = _data.begin(); i != _data.end(); ++i ) {
+ for (std::vector< std::pair< char *, int > >::const_iterator i = _data.begin();
+ i != _data.end(); ++i) {
totalSize += i->second;
}
char *buf = (char*)malloc( totalSize );
char *p = buf;
- for( vector< pair< char *, int > >::const_iterator i = _data.begin(); i != _data.end(); ++i ) {
+ for (std::vector< std::pair< char *, int > >::const_iterator i = _data.begin();
+ i != _data.end(); ++i) {
memcpy( p, i->first, i->second );
p += i->second;
}
@@ -233,7 +238,8 @@ namespace mongo {
if ( _buf ) {
free( _buf );
}
- for( vector< pair< char *, int > >::const_iterator i = _data.begin(); i != _data.end(); ++i ) {
+ for (std::vector< std::pair< char *, int > >::const_iterator i = _data.begin();
+ i != _data.end(); ++i) {
free(i->first);
}
}
@@ -256,10 +262,10 @@ namespace mongo {
}
verify( _freeIt );
if ( _buf ) {
- _data.push_back( make_pair( (char*)_buf, _buf->len ) );
+ _data.push_back(std::make_pair((char*)_buf, _buf->len));
_buf = 0;
}
- _data.push_back( make_pair( d, size ) );
+ _data.push_back(std::make_pair(d, size));
header()->len += size;
}
@@ -297,7 +303,7 @@ namespace mongo {
// if just one buffer, keep it in _buf, otherwise keep a sequence of buffers in _data
MsgData * _buf;
// byte buffer(s) - the first must contain at least a full MsgData unless using _buf for storage instead
- typedef vector< pair< char*, int > > MsgVec;
+ typedef std::vector< std::pair< char*, int > > MsgVec;
MsgVec _data;
bool _freeIt;
};
diff --git a/src/mongo/util/net/message_port.cpp b/src/mongo/util/net/message_port.cpp
index 1138865c294..772eeff77e9 100644
--- a/src/mongo/util/net/message_port.cpp
+++ b/src/mongo/util/net/message_port.cpp
@@ -22,7 +22,6 @@
#include <fcntl.h>
#include <time.h>
-#include "mongo/db/cmdline.h"
#include "mongo/util/background.h"
#include "mongo/util/goodies.h"
#include "mongo/util/net/listen.h"
diff --git a/src/mongo/util/net/message_port.h b/src/mongo/util/net/message_port.h
index cf11bea8773..8949f8081fb 100644
--- a/src/mongo/util/net/message_port.h
+++ b/src/mongo/util/net/message_port.h
@@ -17,6 +17,8 @@
#pragma once
+#include <vector>
+
#include "mongo/util/net/message.h"
#include "mongo/util/net/sock.h"
@@ -112,7 +114,7 @@ namespace mongo {
void send( const char * data , int len, const char *context ) {
psock->send( data, len, context );
}
- void send( const vector< pair< char *, int > > &data, const char *context ) {
+ void send(const std::vector< std::pair< char *, int > > &data, const char *context) {
psock->send( data, context );
}
bool connect(SockAddr& farEnd) {
diff --git a/src/mongo/util/net/message_server_port.cpp b/src/mongo/util/net/message_server_port.cpp
index cdcaef2c6fa..f1fec225e49 100644
--- a/src/mongo/util/net/message_server_port.cpp
+++ b/src/mongo/util/net/message_server_port.cpp
@@ -22,7 +22,6 @@
#ifndef USE_ASIO
-#include "mongo/db/cmdline.h"
#include "mongo/db/lasterror.h"
#include "mongo/db/stats/counters.h"
#include "mongo/util/concurrency/ticketholder.h"
@@ -198,7 +197,7 @@ namespace mongo {
p->psock->clearCounters();
if ( ! p->recv(m) ) {
- if( !cmdLine.quiet ){
+ if (!serverGlobalParams.quiet) {
int conns = Listener::globalTicketHolder.used()-1;
const char* word = (conns == 1 ? " connection" : " connections");
log() << "end connection " << otherSide << " (" << conns << word << " now open)" << endl;
diff --git a/src/mongo/util/net/sock.cpp b/src/mongo/util/net/sock.cpp
index 5afd18c4c70..327296257d2 100644
--- a/src/mongo/util/net/sock.cpp
+++ b/src/mongo/util/net/sock.cpp
@@ -40,7 +40,6 @@
#include "mongo/util/mongoutils/str.h"
#include "mongo/util/net/message.h"
#include "mongo/util/net/ssl_manager.h"
-#include "mongo/db/cmdline.h"
namespace mongo {
MONGO_FP_DECLARE(throwSockExcep);
@@ -316,7 +315,8 @@ namespace mongo {
SockAddr unknownAddress( "0.0.0.0", 0 );
string makeUnixSockPath(int port) {
- return mongoutils::str::stream() << cmdLine.socket << "/mongodb-" << port << ".sock";
+ return mongoutils::str::stream() << serverGlobalParams.socket << "/mongodb-" << port
+ << ".sock";
}
@@ -357,8 +357,8 @@ namespace mongo {
string prettyHostName() {
StringBuilder s;
s << getHostNameCached();
- if( cmdLine.port != CmdLine::DefaultDBPort )
- s << ':' << mongo::cmdLine.port;
+ if (serverGlobalParams.port != ServerGlobalParams::DefaultDBPort)
+ s << ':' << mongo::serverGlobalParams.port;
return s.str();
}
diff --git a/src/mongo/util/net/sock_test.cpp b/src/mongo/util/net/sock_test.cpp
index 1bba7228e82..349e4b0903a 100644
--- a/src/mongo/util/net/sock_test.cpp
+++ b/src/mongo/util/net/sock_test.cpp
@@ -38,14 +38,14 @@
#include <sys/types.h>
#endif
-#include "mongo/db/cmdline.h"
+#include "mongo/db/server_options.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/concurrency/synchronization.h"
#include "mongo/util/fail_point_service.h"
namespace mongo {
- CmdLine cmdLine;
+ ServerGlobalParams serverGlobalParams;
bool inShutdown() {
return false;
diff --git a/src/mongo/util/net/ssl_options.cpp b/src/mongo/util/net/ssl_options.cpp
index ee1900dbb75..3251b7fd3d5 100644
--- a/src/mongo/util/net/ssl_options.cpp
+++ b/src/mongo/util/net/ssl_options.cpp
@@ -18,7 +18,7 @@
#include <boost/filesystem/operations.hpp>
#include "mongo/base/status.h"
-#include "mongo/db/cmdline.h"
+#include "mongo/db/server_options.h"
#include "mongo/util/options_parser/environment.h"
#include "mongo/util/options_parser/option_description.h"
#include "mongo/util/options_parser/option_section.h"
@@ -176,16 +176,17 @@ namespace mongo {
sslGlobalParams.sslFIPSMode) {
return Status(ErrorCodes::BadValue, "need to enable sslOnNormalPorts");
}
- if (cmdLine.clusterAuthMode == "sendKeyfile" ||
- cmdLine.clusterAuthMode == "sendX509" ||
- cmdLine.clusterAuthMode == "x509") {
+ if (serverGlobalParams.clusterAuthMode == "sendKeyfile" ||
+ serverGlobalParams.clusterAuthMode == "sendX509" ||
+ serverGlobalParams.clusterAuthMode == "x509") {
if (!sslGlobalParams.sslOnNormalPorts){
return Status(ErrorCodes::BadValue, "need to enable sslOnNormalPorts");
}
}
- else if (params.count("clusterAuthMode") && cmdLine.clusterAuthMode != "keyfile") {
+ else if (params.count("clusterAuthMode") &&
+ serverGlobalParams.clusterAuthMode != "keyfile") {
StringBuilder sb;
- sb << "unsupported value for clusterAuthMode " << cmdLine.clusterAuthMode;
+ sb << "unsupported value for clusterAuthMode " << serverGlobalParams.clusterAuthMode;
return Status(ErrorCodes::BadValue, sb.str());
}
diff --git a/src/mongo/util/options_parser/environment.cpp b/src/mongo/util/options_parser/environment.cpp
index 41e94d90d40..cc4ad2a71aa 100644
--- a/src/mongo/util/options_parser/environment.cpp
+++ b/src/mongo/util/options_parser/environment.cpp
@@ -19,6 +19,8 @@
#include <iostream>
#include "mongo/bson/util/builder.h"
+#include "mongo/bson/bsonobjiterator.h"
+#include "mongo/db/jsobj.h"
#include "mongo/util/options_parser/constraints.h"
namespace mongo {
@@ -191,5 +193,147 @@ namespace optionenvironment {
}
}
+namespace {
+
+ // Converts a map of values with dotted key names to a BSONObj with sub objects.
+ // 1. Check for dotted field names and call valueMapToBSON recursively.
+ // 2. Append the actual value to our builder if we did not find a dot in our key name.
+ Status valueMapToBSON(const std::map<Key, Value>& params,
+ BSONObjBuilder* builder,
+ const std::string& prefix = std::string()) {
+ for (std::map<Key, Value>::const_iterator it(params.begin());
+ it != params.end(); it++) {
+ Key key = it->first;
+ Value value = it->second;
+
+ // 1. Check for dotted field names and call valueMapToBSON recursively.
+ // NOTE: this code depends on the fact that std::map is sorted
+ //
+ // EXAMPLE:
+ // The map:
+ // {
+ // "var1.dotted1" : false,
+ // "var2" : true,
+ // "var1.dotted2" : 6
+ // }
+ //
+ // Gets sorted by keys as:
+ // {
+ // "var1.dotted1" : false,
+ // "var1.dotted2" : 6,
+ // "var2" : true
+ // }
+ //
+ // Which means when we see the "var1" prefix, we can iterate until we see either a name
+ // without a dot or without "var1" as a prefix, aggregating its fields in a new map as
+ // we go. Because the map is sorted, once we see a name without a dot or a "var1"
+ // prefix we know that we've seen everything with "var1" as a prefix and can recursively
+ // build the entire sub object at once using our new map (which is the only way to make
+ // a single coherent BSON sub object using this append only builder).
+ //
+ // The result of this function for this example should be a BSON object of the form:
+ // {
+ // "var1" : {
+ // "dotted1" : false,
+ // "dotted2" : 6
+ // },
+ // "var2" : true
+ // }
+
+ // Check to see if this key name is dotted
+ std::string::size_type dotOffset = key.find('.');
+ if (dotOffset != string::npos) {
+
+ // Get the name of the "section" that we are currently iterating. This will be
+ // the name of our sub object.
+ std::string sectionName = key.substr(0, dotOffset);
+
+ // Build a map of the "section" that we are iterating to be passed in a
+ // recursive call.
+ std::map<Key, Value> sectionMap;
+
+ std::string beforeDot = key.substr(0, dotOffset);
+ std::string afterDot = key.substr(dotOffset + 1, key.size() - dotOffset - 1);
+ std::map<Key, Value>::const_iterator it_next = it;
+
+ do {
+ // Here we know that the key at it_next has a dot and has the prefix we are
+ // currently creating a sub object for. Since that means we will definitely
+ // process that element in this loop, advance the outer for loop iterator here.
+ it = it_next;
+
+ // Add the value to our section map with a key of whatever is after the dot
+ // since the section name itself will be part of our sub object builder.
+ sectionMap[afterDot] = value;
+
+ // Peek at the next value for our iterator and check to see if we've finished.
+ if (++it_next == params.end()) {
+ break;
+ }
+ key = it_next->first;
+ value = it_next->second;
+
+ // Look for a dot for our next iteration.
+ dotOffset = key.find('.');
+
+ beforeDot = key.substr(0, dotOffset);
+ afterDot = key.substr(dotOffset + 1, key.size() - dotOffset - 1);
+ }
+ while (dotOffset != string::npos && beforeDot == sectionName);
+
+ // Use the section name in our object builder, and recursively call
+ // valueMapToBSON with our sub map with keys that have the section name removed.
+ BSONObjBuilder sectionObjBuilder(builder->subobjStart(sectionName));
+ valueMapToBSON(sectionMap, &sectionObjBuilder, sectionName);
+ sectionObjBuilder.done();
+
+ // Our iterator is currently on the last field that matched our dot and prefix, so
+ // continue to the next loop iteration.
+ continue;
+ }
+
+ // 2. Append the actual value to our builder if we did not find a dot in our key name.
+ const type_info& type = value.type();
+
+ if (type == typeid(string)){
+ if (value.as<string>().empty()) {
+ // boost po uses empty string for flags like --quiet
+ // TODO: Remove this when we remove boost::program_options
+ builder->appendBool(key, true);
+ }
+ else {
+ builder->append(key, value.as<string>());
+ }
+ }
+ else if (type == typeid(int))
+ builder->append(key, value.as<int>());
+ else if (type == typeid(double))
+ builder->append(key, value.as<double>());
+ else if (type == typeid(bool))
+ builder->appendBool(key, value.as<bool>());
+ else if (type == typeid(long))
+ builder->appendNumber(key, (long long)value.as<long>());
+ else if (type == typeid(unsigned))
+ builder->appendNumber(key, (long long)value.as<unsigned>());
+ else if (type == typeid(unsigned long long))
+ builder->appendNumber(key, (long long)value.as<unsigned long long>());
+ else if (type == typeid(vector<string>))
+ builder->append(key, value.as<vector<string> >());
+ else
+ builder->append(key, "UNKNOWN TYPE: " + demangleName(type));
+ }
+ return Status::OK();
+ }
+} // namespace
+
+ BSONObj Environment::toBSON() const {
+ BSONObjBuilder builder;
+ Status ret = valueMapToBSON(values, &builder);
+ if (!ret.isOK()) {
+ return BSONObj();
+ }
+ return builder.obj();
+ }
+
} // namespace optionenvironment
} // namespace mongo
diff --git a/src/mongo/util/options_parser/environment.h b/src/mongo/util/options_parser/environment.h
index e2163ca5ecf..f7c8929814d 100644
--- a/src/mongo/util/options_parser/environment.h
+++ b/src/mongo/util/options_parser/environment.h
@@ -20,6 +20,7 @@
#include <vector>
#include "mongo/base/status.h"
+#include "mongo/db/jsobj.h"
#include "mongo/util/options_parser/value.h"
namespace mongo {
@@ -161,13 +162,36 @@ namespace optionenvironment {
Value operator[](const Key& key) const;
/**
- * Get all values that we have set explicitly as a map in case we need to iterate or
- * move to another structure, as is currently the use case for the parsed command line
- * options structure that we present to the user.
+ * Gets the BSON representation of this Environment. This will collapse dotted fields
+ * into sub objects.
+ *
+ * Example:
+ *
+ * The following Environment values map:
+ * "a.b.c" -> true
+ * "a.b.d" -> false
+ * "a.e.f" -> 0
+ * "a.e.g" -> 1
+ * "a.h" -> "foo"
+ *
+ * Has a BSON represation of (shown as JSON):
+ * { "a" : {
+ * "b" : {
+ * "c" : true,
+ * "d" : false
+ * },
+ * "e" : {
+ * "f" : 0,
+ * "g" : 1
+ * },
+ * "h" : "foo"
+ * }
+ * }
+ *
+ * Note that the BSON representation only includes fields that were explicitly set using
+ * setAll or set, and not defaults that were specified using setDefault.
*/
- const std::map<Key, Value>& getExplicitlySet() const {
- return values;
- }
+ BSONObj toBSON() const;
/* Debugging */
void dump();
diff --git a/src/mongo/util/options_parser/environment_test.cpp b/src/mongo/util/options_parser/environment_test.cpp
index 8893ea9db9f..959d1d08f7b 100644
--- a/src/mongo/util/options_parser/environment_test.cpp
+++ b/src/mongo/util/options_parser/environment_test.cpp
@@ -78,29 +78,44 @@ namespace {
ASSERT_EQUALS(number, 5);
}
- TEST(Environment, DefaultValueIterateExplicit) {
+ TEST(ToBSONTests, NormalValues) {
moe::Environment environment;
- ASSERT_OK(environment.setDefault(moe::Key("val1"), moe::Value(5)));
- ASSERT_OK(environment.setDefault(moe::Key("val2"), moe::Value(5)));
ASSERT_OK(environment.set(moe::Key("val1"), moe::Value(6)));
- int val1;
- ASSERT_OK(environment.get(moe::Key("val1"), &val1));
- ASSERT_EQUALS(val1, 6);
- int val2;
- ASSERT_OK(environment.get(moe::Key("val2"), &val2));
- ASSERT_EQUALS(val2, 5);
-
- const std::map<moe::Key, moe::Value> values = environment.getExplicitlySet();
- ASSERT_EQUALS((static_cast<std::map<moe::Key, moe::Value>::size_type>(1)), values.size());
+ ASSERT_OK(environment.set(moe::Key("val2"), moe::Value(std::string("string"))));
+ mongo::BSONObj obj = BSON( "val1" << 6 << "val2" << "string" );
+ // TODO: Put a comparison here that doesn't depend on the field order. Right now it is
+ // based on the sort order of keys in a std::map.
+ ASSERT_EQUALS(obj, environment.toBSON());
+ }
- typedef std::map<moe::Key, moe::Value>::const_iterator it_type;
- for(it_type iterator = values.begin();
- iterator != values.end(); iterator++) {
- ASSERT_EQUALS(moe::Key("val1"), iterator->first);
- int val1;
- ASSERT_OK(iterator->second.get(&val1));
- ASSERT_EQUALS(6, val1);
- }
+ TEST(ToBSONTests, DottedValues) {
+ moe::Environment environment;
+ ASSERT_OK(environment.set(moe::Key("val1.dotted1"), moe::Value(6)));
+ ASSERT_OK(environment.set(moe::Key("val2"), moe::Value(true)));
+ ASSERT_OK(environment.set(moe::Key("val1.dotted2"), moe::Value(std::string("string"))));
+ mongo::BSONObj obj = BSON("val1" << BSON( "dotted1" << 6 << "dotted2" << "string") <<
+ "val2" << true );
+ // TODO: Put a comparison here that doesn't depend on the field order. Right now it is
+ // based on the sort order of keys in a std::map.
+ ASSERT_EQUALS(obj, environment.toBSON());
}
+ TEST(ToBSONTests, DeepDottedValues) {
+ moe::Environment environment;
+ ASSERT_OK(environment.set(moe::Key("val1.first1.second1.third1"), moe::Value(6)));
+ ASSERT_OK(environment.set(moe::Key("val1.first1.second2.third1"), moe::Value(false)));
+ ASSERT_OK(environment.set(moe::Key("val1.first2"), moe::Value(std::string("string"))));
+ ASSERT_OK(environment.set(moe::Key("val1.first1.second1.third2"), moe::Value(true)));
+ ASSERT_OK(environment.set(moe::Key("val2"), moe::Value(6.0)));
+ mongo::BSONObj obj = BSON("val1" << BSON("first1" <<
+ BSON("second1" <<
+ BSON("third1" << 6 << "third2" << true) <<
+ "second2" <<
+ BSON("third1" << false)) <<
+ "first2" << "string") <<
+ "val2" << 6.0);
+ // TODO: Put a comparison here that doesn't depend on the field order. Right now it is
+ // based on the sort order of keys in a std::map.
+ ASSERT_EQUALS(obj, environment.toBSON());
+ }
} // unnamed namespace
diff --git a/src/mongo/util/options_parser/options_parser_test.cpp b/src/mongo/util/options_parser/options_parser_test.cpp
index 9a97892fce8..33de98fb731 100644
--- a/src/mongo/util/options_parser/options_parser_test.cpp
+++ b/src/mongo/util/options_parser/options_parser_test.cpp
@@ -461,7 +461,7 @@ namespace {
ASSERT_EQUALS(port, 6);
}
- TEST(Parsing, DefaultValueIterateExplicit) {
+ TEST(Parsing, DefaultValuesNotInBSON) {
moe::OptionsParser parser;
moe::Environment environment;
@@ -480,23 +480,8 @@ namespace {
ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
- const std::map<moe::Key, moe::Value> values = environment.getExplicitlySet();
- ASSERT_EQUALS((static_cast<std::map<moe::Key, moe::Value>::size_type>(1)), values.size());
-
- typedef std::map<moe::Key, moe::Value>::const_iterator it_type;
- for(it_type iterator = values.begin();
- iterator != values.end(); iterator++) {
- ASSERT_EQUALS(moe::Key("val1"), iterator->first);
- int val1;
- ASSERT_OK(iterator->second.get(&val1));
- ASSERT_EQUALS(6, val1);
- }
-
- moe::Value value;
- ASSERT_OK(environment.get(moe::Key("val2"), &value));
- int val2;
- ASSERT_OK(value.get(&val2));
- ASSERT_EQUALS(val2, 5);
+ mongo::BSONObj expected = BSON("val1" << 6);
+ ASSERT_EQUALS(expected, environment.toBSON());
}
TEST(Parsing, ImplicitValue) {
diff --git a/src/mongo/util/paths.h b/src/mongo/util/paths.h
index 9b59291e53a..c103ae22635 100644
--- a/src/mongo/util/paths.h
+++ b/src/mongo/util/paths.h
@@ -26,12 +26,12 @@
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
+#include "mongo/db/storage_options.h"
+
namespace mongo {
using namespace mongoutils;
- extern string dbpath;
-
/** this is very much like a boost::path. however, we define a new type to get some type
checking. if you want to say 'my param MUST be a relative path", use this.
*/
@@ -48,7 +48,7 @@ namespace mongo {
/** from a full path */
static RelativePath fromFullPath(boost::filesystem::path f) {
- boost::filesystem::path dbp(dbpath); // normalizes / and backslash
+ boost::filesystem::path dbp(storageGlobalParams.dbpath); // normalizes / and backslash
string fullpath = f.string();
string relative = str::after(fullpath, dbp.string());
if( relative.empty() ) {
@@ -57,9 +57,6 @@ namespace mongo {
rp._p = fullpath;
return rp;
}
- /*uassert(13600,
- str::stream() << "file path is not under the db path? " << fullpath << ' ' << dbpath,
- relative != fullpath);*/
if( str::startsWith(relative, "/") || str::startsWith(relative, "\\") ) {
relative.erase(0, 1);
}
@@ -75,7 +72,7 @@ namespace mongo {
bool operator<(const RelativePath& r) const { return _p < r._p; }
string asFullPath() const {
- boost::filesystem::path x(dbpath);
+ boost::filesystem::path x(storageGlobalParams.dbpath);
x /= _p;
return x.string();
}
diff --git a/src/mongo/util/version.cpp b/src/mongo/util/version.cpp
index 5fcbe599bf6..e5c2af0a309 100644
--- a/src/mongo/util/version.cpp
+++ b/src/mongo/util/version.cpp
@@ -23,12 +23,10 @@
#include <string>
#include <fstream>
-#include <boost/filesystem/operations.hpp>
-
#include "mongo/base/parse_number.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/pdfile_version.h"
+#include "mongo/db/storage_options.h"
#include "mongo/util/file.h"
#include "mongo/util/net/ssl_manager.h"
#include "mongo/util/processinfo.h"
@@ -201,158 +199,6 @@ namespace mongo {
result.appendNumber("maxBsonObjectSize", BSONObjMaxUserSize);
}
- //
- // system warnings
- //
- void show_warnings() {
- // each message adds a leading and a trailing newline
-
- bool warned = false;
- {
- const char * foo = strchr( versionString , '.' ) + 1;
- int bar = atoi( foo );
- if ( ( 2 * ( bar / 2 ) ) != bar ) {
- log() << startupWarningsLog;
- log() << "** NOTE: This is a development version (" << versionString << ") of MongoDB." << startupWarningsLog;
- log() << "** Not recommended for production." << startupWarningsLog;
- warned = true;
- }
- }
-
- if ( sizeof(int*) == 4 ) {
- log() << startupWarningsLog;
- log() << "** NOTE: This is a 32 bit MongoDB binary." << startupWarningsLog;
- log() << "** 32 bit builds are limited to less than 2GB of data (or less with --journal)." << startupWarningsLog;
- if( !cmdLine.dur ) {
- log() << "** Note that journaling defaults to off for 32 bit and is currently off." << startupWarningsLog;
- }
- log() << "** See http://dochub.mongodb.org/core/32bit" << startupWarningsLog;
- warned = true;
- }
-
- if ( !ProcessInfo::blockCheckSupported() ) {
- log() << startupWarningsLog;
- log() << "** NOTE: your operating system version does not support the method that MongoDB" << startupWarningsLog;
- log() << "** uses to detect impending page faults." << startupWarningsLog;
- log() << "** This may result in slower performance for certain use cases" << startupWarningsLog;
- warned = true;
- }
-#ifdef __linux__
- if (boost::filesystem::exists("/proc/vz") && !boost::filesystem::exists("/proc/bc")) {
- log() << startupWarningsLog;
- log() << "** WARNING: You are running in OpenVZ. This is known to be broken!!!" << startupWarningsLog;
- warned = true;
- }
-
- if (boost::filesystem::exists("/sys/devices/system/node/node1")){
- // We are on a box with a NUMA enabled kernel and more than 1 numa node (they start at node0)
- // Now we look at the first line of /proc/self/numa_maps
- //
- // Bad example:
- // $ cat /proc/self/numa_maps
- // 00400000 default file=/bin/cat mapped=6 N4=6
- //
- // Good example:
- // $ numactl --interleave=all cat /proc/self/numa_maps
- // 00400000 interleave:0-7 file=/bin/cat mapped=6 N4=6
-
- std::ifstream f("/proc/self/numa_maps", std::ifstream::in);
- if (f.is_open()) {
- std::string line; //we only need the first line
- std::getline(f, line);
- if (f.fail()) {
- warning() << "failed to read from /proc/self/numa_maps: "
- << errnoWithDescription() << startupWarningsLog;
- warned = true;
- }
- else {
- // skip over pointer
- std::string::size_type where = line.find(' ');
- if ( (where == std::string::npos) || (++where == line.size()) ) {
- log() << startupWarningsLog;
- log() << "** WARNING: cannot parse numa_maps line: '" << line << "'" << startupWarningsLog;
- warned = true;
- }
- // if the text following the space doesn't begin with 'interleave', then
- // issue the warning.
- else if ( line.find("interleave", where) != where ) {
- log() << startupWarningsLog;
- log() << "** WARNING: You are running on a NUMA machine." << startupWarningsLog;
- log() << "** We suggest launching mongod like this to avoid performance problems:" << startupWarningsLog;
- log() << "** numactl --interleave=all mongod [other options]" << startupWarningsLog;
- warned = true;
- }
- }
- }
- }
-
- if (cmdLine.dur){
- fstream f ("/proc/sys/vm/overcommit_memory", ios_base::in);
- unsigned val;
- f >> val;
-
- if (val == 2) {
- log() << startupWarningsLog;
- log() << "** WARNING: /proc/sys/vm/overcommit_memory is " << val << startupWarningsLog;
- log() << "** Journaling works best with it set to 0 or 1" << startupWarningsLog;
- }
- }
-
- if (boost::filesystem::exists("/proc/sys/vm/zone_reclaim_mode")){
- fstream f ("/proc/sys/vm/zone_reclaim_mode", ios_base::in);
- unsigned val;
- f >> val;
-
- if (val != 0) {
- log() << startupWarningsLog;
- log() << "** WARNING: /proc/sys/vm/zone_reclaim_mode is " << val << startupWarningsLog;
- log() << "** We suggest setting it to 0" << startupWarningsLog;
- log() << "** http://www.kernel.org/doc/Documentation/sysctl/vm.txt" << startupWarningsLog;
- }
- }
-#endif
-
-#if defined(RLIMIT_NPROC) && defined(RLIMIT_NOFILE)
- //Check that # of files rlmit > 1000 , and # of processes > # of files/2
- const unsigned int minNumFiles = 1000;
- const double filesToProcsRatio = 2.0;
- struct rlimit rlnproc;
- struct rlimit rlnofile;
-
- if(!getrlimit(RLIMIT_NPROC,&rlnproc) && !getrlimit(RLIMIT_NOFILE,&rlnofile)){
- if(rlnofile.rlim_cur < minNumFiles){
- log() << startupWarningsLog;
- log() << "** WARNING: soft rlimits too low. Number of files is "
- << rlnofile.rlim_cur
- << ", should be at least " << minNumFiles << startupWarningsLog;
- }
-
- if(false){
- // juse to make things cleaner
- }
-#ifdef __APPLE__
- else if(rlnproc.rlim_cur >= 709){
- // os x doesn't make it easy to go higher
- // ERH thinks its ok not to add the warning in this case 7/3/2012
- }
-#endif
- else if(rlnproc.rlim_cur < rlnofile.rlim_cur/filesToProcsRatio){
- log() << startupWarningsLog;
- log() << "** WARNING: soft rlimits too low. rlimits set to " << rlnproc.rlim_cur << " processes, "
- << rlnofile.rlim_cur << " files. Number of processes should be at least "
- << rlnofile.rlim_cur/filesToProcsRatio << " : "
- << 1/filesToProcsRatio << " times number of files." << startupWarningsLog;
- }
- } else {
- log() << startupWarningsLog;
- log() << "** WARNING: getrlimit failed. " << errnoWithDescription() << startupWarningsLog;
- }
-#endif
- if (warned) {
- log() << startupWarningsLog;
- }
- }
-
class VersionArrayTest : public StartupTest {
public:
void run() {