diff options
author | Henrik Edin <henrik.edin@mongodb.com> | 2018-05-31 10:57:22 -0400 |
---|---|---|
committer | Henrik Edin <henrik.edin@mongodb.com> | 2018-06-07 12:06:59 -0400 |
commit | c145be9589b0b25084cd674450a32289d511a166 (patch) | |
tree | a15dd07b0f823094bde27edf0d57a56b70bec4c5 /src | |
parent | da63637defad5975040f8eac0e98c86c8d8e2533 (diff) | |
download | mongo-c145be9589b0b25084cd674450a32289d511a166.tar.gz |
SERVER-35297 Split server_options and server_status into two pieces.
Similarly to how commands are setup, so embedded can depend on a smaller library with fewer dependencies.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/SConscript | 22 | ||||
-rw-r--r-- | src/mongo/db/commands/SConscript | 18 | ||||
-rw-r--r-- | src/mongo/db/commands/server_status.cpp | 95 | ||||
-rw-r--r-- | src/mongo/db/commands/server_status_servers.cpp | 131 | ||||
-rw-r--r-- | src/mongo/db/log_process_details.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/mongod_options.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/server_options_helpers.cpp | 558 | ||||
-rw-r--r-- | src/mongo/db/server_options_helpers.h | 46 | ||||
-rw-r--r-- | src/mongo/db/server_options_init.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/server_options_server_helpers.cpp | 674 | ||||
-rw-r--r-- | src/mongo/db/server_options_server_helpers.h | 86 | ||||
-rw-r--r-- | src/mongo/db/server_options_test.cpp | 2 | ||||
-rw-r--r-- | src/mongo/embedded/embedded_options.cpp | 34 | ||||
-rw-r--r-- | src/mongo/s/mongos_options.cpp | 2 | ||||
-rw-r--r-- | src/mongo/tools/SConscript | 1 |
16 files changed, 959 insertions, 718 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index a7c2d5a8b66..08fdf4b80a8 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -298,6 +298,7 @@ env.Library( 'db/catalog/health_log', 'db/commands/mongod', 'db/commands/mongod_fcv', + 'db/commands/server_status_servers', 'db/dbdirectclient', 'db/ftdc/ftdc_mongod', 'db/free_mon/free_mon_mongod', @@ -411,6 +412,7 @@ mongos = env.Program( 'db/auth/authmongos', 'db/commands/server_status', 'db/commands/server_status_core', + 'db/commands/server_status_servers', 'db/curop', 'db/ftdc/ftdc_mongos', 'db/logical_time_metadata_hook', diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index 6653e4ebbc6..007d1bb413f 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -390,14 +390,24 @@ env.Clone().InjectModule("enterprise").Library( '$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/util/cmdline_utils/cmdline_utils', '$BUILD_DIR/mongo/util/fail_point', + '$BUILD_DIR/mongo/util/options_parser/options_parser', + 'server_options_core', + 'server_parameters', + ], +) + +env.Library( + target="server_options_servers", + source=[ + "server_options_server_helpers.cpp", + ], + LIBDEPS=[ '$BUILD_DIR/mongo/transport/message_compressor', '$BUILD_DIR/mongo/util/net/network', # The dependency on net/ssl_manager is a temporary crutch that should go away once the # networking library has separate options '$BUILD_DIR/mongo/util/net/ssl_manager', - '$BUILD_DIR/mongo/util/options_parser/options_parser', - 'server_options_core', - 'server_parameters', + 'server_options', ], ) @@ -407,7 +417,7 @@ env.CppUnitTest( 'server_options_test.cpp', ], LIBDEPS=[ - 'server_options', + 'server_options_servers', ], ) @@ -454,7 +464,7 @@ env.Library( '$BUILD_DIR/mongo/db/storage/mmap_v1/mmap_v1_options', 'repl/repl_settings', 'repl/replica_set_messages', - 'server_options', + 'server_options_servers', 'storage/storage_options', ], LIBDEPS_PRIVATE=[ @@ -1770,7 +1780,7 @@ env.Library( LIBDEPS=[ 'repl/repl_coordinator_interface', 'repl/replica_set_messages', - 'server_options', + 'server_options_servers', '$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/util/net/network', ], diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index 4d37def529b..6efa6d3e148 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -40,11 +40,22 @@ env.Library( '$BUILD_DIR/mongo/db/auth/authprivilege', '$BUILD_DIR/mongo/db/server_options_core', '$BUILD_DIR/mongo/db/stats/counters', + '$BUILD_DIR/mongo/util/processinfo', + 'server_status_core', + ], +) + +env.Library( + target='server_status_servers', + source=[ + 'server_status_servers.cpp', + ], + LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/stats/counters', '$BUILD_DIR/mongo/transport/message_compressor', '$BUILD_DIR/mongo/transport/service_executor', - '$BUILD_DIR/mongo/util/net/network', '$BUILD_DIR/mongo/util/net/ssl_manager', - '$BUILD_DIR/mongo/util/processinfo', + 'server_status', 'server_status_core', ], ) @@ -95,8 +106,8 @@ env.Library( '$BUILD_DIR/mongo/db/commands', '$BUILD_DIR/mongo/db/commands/test_commands_enabled', '$BUILD_DIR/mongo/db/common', - '$BUILD_DIR/mongo/db/log_process_details', '$BUILD_DIR/mongo/db/mongohasher', + '$BUILD_DIR/mongo/db/server_options_core', '$BUILD_DIR/mongo/logger/parse_log_component_settings', ], ) @@ -132,6 +143,7 @@ env.Library( '$BUILD_DIR/mongo/db/common', '$BUILD_DIR/mongo/client/clientdriver_minimal', '$BUILD_DIR/mongo/db/kill_sessions', + '$BUILD_DIR/mongo/db/log_process_details', '$BUILD_DIR/mongo/db/logical_session_cache', '$BUILD_DIR/mongo/db/logical_session_cache_impl', '$BUILD_DIR/mongo/db/logical_session_id', diff --git a/src/mongo/db/commands/server_status.cpp b/src/mongo/db/commands/server_status.cpp index 65c653fc089..0bf49ea4864 100644 --- a/src/mongo/db/commands/server_status.cpp +++ b/src/mongo/db/commands/server_status.cpp @@ -1,5 +1,3 @@ -// server_status.cpp - /** * Copyright (C) 2012 10gen Inc. * @@ -32,30 +30,15 @@ #include "mongo/platform/basic.h" -#include "mongo/config.h" -#include "mongo/db/auth/action_set.h" -#include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/authorization_session.h" -#include "mongo/db/auth/privilege.h" -#include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/commands/server_status.h" #include "mongo/db/commands/server_status_internal.h" -#include "mongo/db/commands/server_status_metric.h" -#include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/db/stats/counters.h" -#include "mongo/platform/process_id.h" -#include "mongo/transport/message_compressor_registry.h" -#include "mongo/transport/service_entry_point.h" #include "mongo/util/log.h" -#include "mongo/util/net/hostname_canonicalization.h" #include "mongo/util/net/socket_utils.h" -#include "mongo/util/net/ssl_manager.h" -#include "mongo/util/processinfo.h" #include "mongo/util/ramlog.h" -#include "mongo/util/time_support.h" #include "mongo/util/version.h" namespace mongo { @@ -226,28 +209,6 @@ namespace { // some universal sections -class Connections : public ServerStatusSection { -public: - Connections() : ServerStatusSection("connections") {} - virtual bool includeByDefault() const { - return true; - } - - BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElement) const { - BSONObjBuilder bb; - - auto serviceEntryPoint = opCtx->getServiceContext()->getServiceEntryPoint(); - invariant(serviceEntryPoint); - - auto stats = serviceEntryPoint->sessionStats(); - bb.append("current", static_cast<int>(stats.numOpenSessions)); - bb.append("available", static_cast<int>(stats.numAvailableSessions)); - bb.append("totalCreated", static_cast<int>(stats.numCreatedSessions)); - return bb.obj(); - } - -} connections; - class ExtraInfo : public ServerStatusSection { public: ExtraInfo() : ServerStatusSection("extra_info") {} @@ -287,46 +248,6 @@ public: } asserts; - -class Network : public ServerStatusSection { -public: - Network() : ServerStatusSection("network") {} - virtual bool includeByDefault() const { - return true; - } - - BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElement) const { - BSONObjBuilder b; - networkCounter.append(b); - appendMessageCompressionStats(&b); - auto executor = opCtx->getServiceContext()->getServiceExecutor(); - if (executor) - executor->appendStats(&b); - - return b.obj(); - } - -} network; - -#ifdef MONGO_CONFIG_SSL -class Security : public ServerStatusSection { -public: - Security() : ServerStatusSection("security") {} - virtual bool includeByDefault() const { - return true; - } - - BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElement) const { - BSONObj result; - if (getSSLManager()) { - result = getSSLManager()->getSSLConfiguration().getServerStatusBSON(); - } - - return result; - } -} security; -#endif - class MemBase : public ServerStatusMetric { public: MemBase() : ServerStatusMetric(".mem.bits") {} @@ -347,22 +268,6 @@ public: } } memBase; -class AdvisoryHostFQDNs final : public ServerStatusSection { -public: - AdvisoryHostFQDNs() : ServerStatusSection("advisoryHostFQDNs") {} - - bool includeByDefault() const override { - return false; - } - - void appendSection(OperationContext* opCtx, - const BSONElement& configElement, - BSONObjBuilder* out) const override { - out->append( - "advisoryHostFQDNs", - getHostFQDNs(getHostNameCached(), HostnameCanonicalizationMode::kForwardAndReverse)); - } -} advisoryHostFQDNs; } // namespace } // namespace mongo diff --git a/src/mongo/db/commands/server_status_servers.cpp b/src/mongo/db/commands/server_status_servers.cpp new file mode 100644 index 00000000000..96007301142 --- /dev/null +++ b/src/mongo/db/commands/server_status_servers.cpp @@ -0,0 +1,131 @@ +/** +* Copyright (C) 2012 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* 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. +*/ + +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kCommand + +#include "mongo/platform/basic.h" + +#include "mongo/config.h" +#include "mongo/db/commands/server_status.h" +#include "mongo/transport/message_compressor_registry.h" +#include "mongo/transport/service_entry_point.h" +#include "mongo/util/net/hostname_canonicalization.h" +#include "mongo/util/net/socket_utils.h" +#include "mongo/util/net/ssl_manager.h" + +namespace mongo { + +using std::endl; +using std::map; +using std::string; +using std::stringstream; + +namespace { + +// some universal sections + +class Connections : public ServerStatusSection { +public: + Connections() : ServerStatusSection("connections") {} + virtual bool includeByDefault() const { + return true; + } + + BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElement) const { + BSONObjBuilder bb; + + auto serviceEntryPoint = opCtx->getServiceContext()->getServiceEntryPoint(); + invariant(serviceEntryPoint); + + auto stats = serviceEntryPoint->sessionStats(); + bb.append("current", static_cast<int>(stats.numOpenSessions)); + bb.append("available", static_cast<int>(stats.numAvailableSessions)); + bb.append("totalCreated", static_cast<int>(stats.numCreatedSessions)); + return bb.obj(); + } + +} connections; + +class Network : public ServerStatusSection { +public: + Network() : ServerStatusSection("network") {} + virtual bool includeByDefault() const { + return true; + } + + BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElement) const { + BSONObjBuilder b; + networkCounter.append(b); + appendMessageCompressionStats(&b); + auto executor = opCtx->getServiceContext()->getServiceExecutor(); + if (executor) + executor->appendStats(&b); + + return b.obj(); + } + +} network; + +#ifdef MONGO_CONFIG_SSL +class Security : public ServerStatusSection { +public: + Security() : ServerStatusSection("security") {} + virtual bool includeByDefault() const { + return true; + } + + BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElement) const { + BSONObj result; + if (getSSLManager()) { + result = getSSLManager()->getSSLConfiguration().getServerStatusBSON(); + } + + return result; + } +} security; +#endif + +class AdvisoryHostFQDNs final : public ServerStatusSection { +public: + AdvisoryHostFQDNs() : ServerStatusSection("advisoryHostFQDNs") {} + + bool includeByDefault() const override { + return false; + } + + void appendSection(OperationContext* opCtx, + const BSONElement& configElement, + BSONObjBuilder* out) const override { + out->append( + "advisoryHostFQDNs", + getHostFQDNs(getHostNameCached(), HostnameCanonicalizationMode::kForwardAndReverse)); + } +} advisoryHostFQDNs; +} // namespace + +} // namespace mongo diff --git a/src/mongo/db/log_process_details.cpp b/src/mongo/db/log_process_details.cpp index 3719699aaa5..66582ddceb5 100644 --- a/src/mongo/db/log_process_details.cpp +++ b/src/mongo/db/log_process_details.cpp @@ -37,7 +37,7 @@ #include "mongo/db/repl/repl_set_config.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/server_options.h" -#include "mongo/db/server_options_helpers.h" +#include "mongo/db/server_options_server_helpers.h" #include "mongo/util/log.h" #include "mongo/util/net/socket_utils.h" #include "mongo/util/processinfo.h" diff --git a/src/mongo/db/mongod_options.cpp b/src/mongo/db/mongod_options.cpp index 137a5cb5771..b497c71ed7c 100644 --- a/src/mongo/db/mongod_options.cpp +++ b/src/mongo/db/mongod_options.cpp @@ -43,7 +43,7 @@ #include "mongo/db/global_settings.h" #include "mongo/db/repl/repl_settings.h" #include "mongo/db/server_options.h" -#include "mongo/db/server_options_helpers.h" +#include "mongo/db/server_options_server_helpers.h" #include "mongo/db/storage/mmap_v1/mmap_v1_options.h" #include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" diff --git a/src/mongo/db/server_options_helpers.cpp b/src/mongo/db/server_options_helpers.cpp index 578bcd6855c..48c400d0b47 100644 --- a/src/mongo/db/server_options_helpers.cpp +++ b/src/mongo/db/server_options_helpers.cpp @@ -248,276 +248,7 @@ Status addBaseServerOptions(moe::OptionSection* options) { return Status::OK(); } -Status addGeneralServerOptions(moe::OptionSection* options) { - auto baseResult = addBaseServerOptions(options); - if (!baseResult.isOK()) { - return baseResult; - } - - StringBuilder maxConnInfoBuilder; - std::stringstream unixSockPermsBuilder; - - maxConnInfoBuilder << "max number of simultaneous connections - " << DEFAULT_MAX_CONN - << " by default"; - unixSockPermsBuilder << "permissions to set on UNIX domain socket file - " - << "0" << std::oct << DEFAULT_UNIX_PERMS << " by default"; - - options->addOptionChaining("help", "help,h", moe::Switch, "show this usage information") - .setSources(moe::SourceAllLegacy); - - options->addOptionChaining("version", "version", moe::Switch, "show version information") - .setSources(moe::SourceAllLegacy); - - options - ->addOptionChaining( - "config", "config,f", moe::String, "configuration file specifying additional options") - .setSources(moe::SourceAllLegacy); - - - options - ->addOptionChaining( - "net.bindIp", - "bind_ip", - moe::String, - "comma separated list of ip addresses to listen on - localhost by default") - .incompatibleWith("bind_ip_all"); - - options - ->addOptionChaining("net.bindIpAll", "bind_ip_all", moe::Switch, "bind to all ip addresses") - .incompatibleWith("bind_ip"); - - options->addOptionChaining( - "net.ipv6", "ipv6", moe::Switch, "enable IPv6 support (disabled by default)"); - - options - ->addOptionChaining( - "net.listenBacklog", "listenBacklog", moe::Int, "set socket listen backlog size") - .setDefault(moe::Value(SOMAXCONN)); - - options->addOptionChaining( - "net.maxIncomingConnections", "maxConns", moe::Int, maxConnInfoBuilder.str().c_str()); - - options - ->addOptionChaining("net.transportLayer", - "transportLayer", - moe::String, - "sets the ingress transport layer implementation") - .hidden() - .setDefault(moe::Value("asio")); - - options - ->addOptionChaining("net.serviceExecutor", - "serviceExecutor", - moe::String, - "sets the service executor implementation") - .hidden() - .setDefault(moe::Value("synchronous")); - -#if MONGO_ENTERPRISE_VERSION - options->addOptionChaining("security.redactClientLogData", - "redactClientLogData", - moe::Switch, - "Redact client data written to the diagnostics log"); -#endif - - options->addOptionChaining("processManagement.pidFilePath", - "pidfilepath", - moe::String, - "full path to pidfile (if not set, no pidfile is created)"); - - options->addOptionChaining("processManagement.timeZoneInfo", - "timeZoneInfo", - moe::String, - "full path to time zone info directory, e.g. /usr/share/zoneinfo"); - - options - ->addOptionChaining( - "security.keyFile", "keyFile", moe::String, "private key for cluster authentication") - .incompatibleWith("noauth"); - - options->addOptionChaining("noauth", "noauth", moe::Switch, "run without security") - .setSources(moe::SourceAllLegacy) - .incompatibleWith("auth") - .incompatibleWith("keyFile") - .incompatibleWith("transitionToAuth") - .incompatibleWith("clusterAuthMode"); - - options - ->addOptionChaining( - "security.transitionToAuth", - "transitionToAuth", - moe::Switch, - "For rolling access control upgrade. Attempt to authenticate over outgoing " - "connections and proceed regardless of success. Accept incoming connections " - "with or without authentication.") - .incompatibleWith("noauth"); - - options - ->addOptionChaining("security.clusterAuthMode", - "clusterAuthMode", - moe::String, - "Authentication mode used for cluster authentication. Alternatives are " - "(keyFile|sendKeyFile|sendX509|x509)") - .format("(:?keyFile)|(:?sendKeyFile)|(:?sendX509)|(:?x509)", - "(keyFile/sendKeyFile/sendX509/x509)"); - -#ifndef _WIN32 - options - ->addOptionChaining( - "nounixsocket", "nounixsocket", moe::Switch, "disable listening on unix sockets") - .setSources(moe::SourceAllLegacy); - - options - ->addOptionChaining( - "net.unixDomainSocket.enabled", "", moe::Bool, "disable listening on unix sockets") - .setSources(moe::SourceYAMLConfig); - - options->addOptionChaining("net.unixDomainSocket.pathPrefix", - "unixSocketPrefix", - moe::String, - "alternative directory for UNIX domain sockets (defaults to /tmp)"); - - options->addOptionChaining("net.unixDomainSocket.filePermissions", - "filePermissions", - moe::Int, - unixSockPermsBuilder.str()); - - options->addOptionChaining( - "processManagement.fork", "fork", moe::Switch, "fork server process"); - -#endif - - options - ->addOptionChaining("objcheck", - "objcheck", - moe::Switch, - "inspect client data for validity on receipt (DEFAULT)") - .hidden() - .setSources(moe::SourceAllLegacy) - .incompatibleWith("noobjcheck"); - - options - ->addOptionChaining("noobjcheck", - "noobjcheck", - moe::Switch, - "do NOT inspect client data for validity on receipt") - .hidden() - .setSources(moe::SourceAllLegacy) - .incompatibleWith("objcheck"); - - options - ->addOptionChaining("net.wireObjectCheck", - "", - moe::Bool, - "inspect client data for validity on receipt (DEFAULT)") - .hidden() - .setSources(moe::SourceYAMLConfig); - - options - ->addOptionChaining("enableExperimentalStorageDetailsCmd", - "enableExperimentalStorageDetailsCmd", - moe::Switch, - "EXPERIMENTAL (UNSUPPORTED). " - "Enable command computing aggregate statistics on storage.") - .hidden() - .setSources(moe::SourceAllLegacy); - - options - ->addOptionChaining("operationProfiling.slowOpThresholdMs", - "slowms", - moe::Int, - "value of slow for profile and console log") - .setDefault(moe::Value(100)); - - options - ->addOptionChaining("operationProfiling.slowOpSampleRate", - "slowOpSampleRate", - moe::Double, - "fraction of slow ops to include in the profile and console log") - .setDefault(moe::Value(1.0)); - - auto ret = addMessageCompressionOptions(options, false); - if (!ret.isOK()) { - return ret; - } - - return Status::OK(); -} - -Status addWindowsServerOptions(moe::OptionSection* options) { - options->addOptionChaining("install", "install", moe::Switch, "install Windows service") - .setSources(moe::SourceAllLegacy); - - options->addOptionChaining("remove", "remove", moe::Switch, "remove Windows service") - .setSources(moe::SourceAllLegacy); - - options - ->addOptionChaining( - "reinstall", - "reinstall", - moe::Switch, - "reinstall Windows service (equivalent to --remove followed by --install)") - .setSources(moe::SourceAllLegacy); - - options->addOptionChaining("processManagement.windowsService.serviceName", - "serviceName", - moe::String, - "Windows service name"); - - options->addOptionChaining("processManagement.windowsService.displayName", - "serviceDisplayName", - moe::String, - "Windows service display name"); - - options->addOptionChaining("processManagement.windowsService.description", - "serviceDescription", - moe::String, - "Windows service description"); - - options->addOptionChaining("processManagement.windowsService.serviceUser", - "serviceUser", - moe::String, - "account for service execution"); - - options->addOptionChaining("processManagement.windowsService.servicePassword", - "servicePassword", - moe::String, - "password used to authenticate serviceUser"); - - options->addOptionChaining("service", "service", moe::Switch, "start mongodb service") - .hidden() - .setSources(moe::SourceAllLegacy); - - return Status::OK(); -} - namespace { -// Helpers for option storage -Status setupBinaryName(const std::vector<std::string>& argv) { - if (argv.empty()) { - return Status(ErrorCodes::UnknownError, "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 - boost::system::error_code ec; - boost::filesystem::path cwd = boost::filesystem::current_path(ec); - if (ec) { - return Status(ErrorCodes::UnknownError, - "Cannot get current working directory: " + ec.message()); - } - serverGlobalParams.cwd = cwd.string(); - return Status::OK(); -} Status setArgvArray(const std::vector<std::string>& argv) { BSONArrayBuilder b; @@ -537,11 +268,7 @@ Status setParsedOpts(const moe::Environment& params) { } } // namespace -void printCommandLineOpts() { - log() << "options: " << serverGlobalParams.parsedOpts << endl; -} - -Status validateServerOptions(const moe::Environment& params) { +Status validateBaseOptions(const moe::Environment& params) { if (params.count("verbose")) { std::string verbosity = params["verbose"].as<std::string>(); @@ -558,55 +285,9 @@ Status validateServerOptions(const moe::Environment& params) { } } -#ifdef _WIN32 - if (params.count("install") || params.count("reinstall")) { - if (params.count("logpath") && - !boost::filesystem::path(params["logpath"].as<string>()).is_absolute()) { - return Status(ErrorCodes::BadValue, - "logpath requires an absolute file path with Windows services"); - } - - if (params.count("config") && - !boost::filesystem::path(params["config"].as<string>()).is_absolute()) { - return Status(ErrorCodes::BadValue, - "config requires an absolute file path with Windows services"); - } - - if (params.count("processManagement.pidFilePath") && - !boost::filesystem::path(params["processManagement.pidFilePath"].as<string>()) - .is_absolute()) { - return Status(ErrorCodes::BadValue, - "pidFilePath requires an absolute file path with Windows services"); - } - - if (params.count("security.keyFile") && - !boost::filesystem::path(params["security.keyFile"].as<string>()).is_absolute()) { - return Status(ErrorCodes::BadValue, - "keyFile requires an absolute file path with Windows services"); - } - } -#endif - -#ifdef MONGO_CONFIG_SSL - Status ret = validateSSLServerOptions(params); - if (!ret.isOK()) { - return ret; - } -#endif - - bool haveAuthenticationMechanisms = true; - bool hasAuthorizationEnabled = false; - if (params.count("security.authenticationMechanisms") && - params["security.authenticationMechanisms"].as<std::vector<std::string>>().empty()) { - haveAuthenticationMechanisms = false; - } if (params.count("setParameter")) { std::map<std::string, std::string> parameters = params["setParameter"].as<std::map<std::string, std::string>>(); - auto authMechParameter = parameters.find("authenticationMechanisms"); - if (authMechParameter != parameters.end() && authMechParameter->second.empty()) { - haveAuthenticationMechanisms = false; - } // Only register failpoint server parameters if enableTestCommands=1. auto enableTestCommandsParameter = parameters.find("enableTestCommands"); @@ -614,73 +295,12 @@ Status validateServerOptions(const moe::Environment& params) { enableTestCommandsParameter->second.compare("1") == 0) { getGlobalFailPointRegistry()->registerAllFailPointsAsServerParameters(); } - - if (parameters.find("internalValidateFeaturesAsMaster") != parameters.end()) { - // Command line options that are disallowed when internalValidateFeaturesAsMaster is - // specified. - if (params.count("replication.replSet")) { - return Status(ErrorCodes::BadValue, - str::stream() << // - "Cannot specify both internalValidateFeaturesAsMaster and " - "replication.replSet"); - } - } - } - if ((params.count("security.authorization") && - params["security.authorization"].as<std::string>() == "enabled") || - params.count("security.clusterAuthMode") || params.count("security.keyFile") || - params.count("auth")) { - hasAuthorizationEnabled = true; - } - if (hasAuthorizationEnabled && !haveAuthenticationMechanisms) { - return Status(ErrorCodes::BadValue, - "Authorization is enabled but no authentication mechanisms are present."); } return Status::OK(); } -Status canonicalizeServerOptions(moe::Environment* params) { - // "net.wireObjectCheck" comes from the config file, so override it if either "objcheck" or - // "noobjcheck" are set, since those come from the command line. - if (params->count("objcheck")) { - Status ret = - params->set("net.wireObjectCheck", moe::Value((*params)["objcheck"].as<bool>())); - if (!ret.isOK()) { - return ret; - } - ret = params->remove("objcheck"); - if (!ret.isOK()) { - return ret; - } - } - - if (params->count("noobjcheck")) { - Status ret = - params->set("net.wireObjectCheck", moe::Value(!(*params)["noobjcheck"].as<bool>())); - if (!ret.isOK()) { - return ret; - } - ret = params->remove("noobjcheck"); - if (!ret.isOK()) { - return ret; - } - } - - // "net.unixDomainSocket.enabled" comes from the config file, so override it if - // "nounixsocket" is set since that comes from the command line. - if (params->count("nounixsocket")) { - Status ret = params->set("net.unixDomainSocket.enabled", - moe::Value(!(*params)["nounixsocket"].as<bool>())); - if (!ret.isOK()) { - return ret; - } - ret = params->remove("nounixsocket"); - if (!ret.isOK()) { - return ret; - } - } - +Status canonicalizeBaseOptions(moe::Environment* params) { // Handle both the "--verbose" string argument and the "-vvvv" arguments at the same time so // that we ensure that we set the log level to the maximum of the options provided int logLevel = -1; @@ -753,34 +373,11 @@ Status canonicalizeServerOptions(moe::Environment* params) { } } - if (params->count("noauth")) { - Status ret = - params->set("security.authorization", - (*params)["noauth"].as<bool>() ? moe::Value(std::string("disabled")) - : moe::Value(std::string("enabled"))); - if (!ret.isOK()) { - return ret; - } - ret = params->remove("noauth"); - if (!ret.isOK()) { - return ret; - } - } return Status::OK(); } -Status setupServerOptions(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); +Status setupBaseOptions(const std::vector<std::string>& args) { + Status ret = setArgvArray(args); if (!ret.isOK()) { return ret; } @@ -788,7 +385,7 @@ Status setupServerOptions(const std::vector<std::string>& args) { return Status::OK(); } -Status storeServerOptions(const moe::Environment& params) { +Status storeBaseOptions(const moe::Environment& params) { Status ret = setParsedOpts(params); if (!ret.isOK()) { return ret; @@ -828,62 +425,6 @@ Status storeServerOptions(const moe::Environment& params) { params["enableExperimentalStorageDetailsCmd"].as<bool>(); } - if (params.count("net.port")) { - serverGlobalParams.port = params["net.port"].as<int>(); - } - - if (params.count("net.ipv6") && params["net.ipv6"].as<bool>() == true) { - serverGlobalParams.enableIPv6 = true; - enableIPv6(); - } - - if (params.count("net.listenBacklog")) { - serverGlobalParams.listenBacklog = params["net.listenBacklog"].as<int>(); - } - - if (params.count("net.transportLayer")) { - serverGlobalParams.transportLayer = params["net.transportLayer"].as<std::string>(); - if (serverGlobalParams.transportLayer != "asio") { - return {ErrorCodes::BadValue, "Unsupported value for transportLayer. Must be \"asio\""}; - } - } - - if (params.count("net.serviceExecutor")) { - auto value = params["net.serviceExecutor"].as<std::string>(); - const auto valid = {"synchronous"_sd, "adaptive"_sd}; - if (std::find(valid.begin(), valid.end(), value) == valid.end()) { - return {ErrorCodes::BadValue, "Unsupported value for serviceExecutor"}; - } - serverGlobalParams.serviceExecutor = value; - } else { - serverGlobalParams.serviceExecutor = "synchronous"; - } - - if (params.count("security.transitionToAuth")) { - serverGlobalParams.transitionToAuth = params["security.transitionToAuth"].as<bool>(); - } - - if (params.count("security.clusterAuthMode")) { - std::string clusterAuthMode = params["security.clusterAuthMode"].as<std::string>(); - - if (clusterAuthMode == "keyFile") { - serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_keyFile); - } else if (clusterAuthMode == "sendKeyFile") { - serverGlobalParams.clusterAuthMode.store( - ServerGlobalParams::ClusterAuthMode_sendKeyFile); - } else if (clusterAuthMode == "sendX509") { - serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_sendX509); - } else if (clusterAuthMode == "x509") { - serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_x509); - } else { - return Status(ErrorCodes::BadValue, - "unsupported value for clusterAuthMode " + clusterAuthMode); - } - serverGlobalParams.authState = ServerGlobalParams::AuthState::kEnabled; - } else { - serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_undefined); - } - if (params.count("systemLog.quiet")) { serverGlobalParams.quiet.store(params["systemLog.quiet"].as<bool>()); } @@ -892,52 +433,6 @@ Status storeServerOptions(const moe::Environment& params) { DBException::traceExceptions.store(params["systemLog.traceAllExceptions"].as<bool>()); } - if (params.count("net.maxIncomingConnections")) { - serverGlobalParams.maxConns = params["net.maxIncomingConnections"].as<int>(); - - if (serverGlobalParams.maxConns < 5) { - return Status(ErrorCodes::BadValue, "maxConns has to be at least 5"); - } - } - - if (params.count("net.wireObjectCheck")) { - serverGlobalParams.objcheck = params["net.wireObjectCheck"].as<bool>(); - } - - if (params.count("net.bindIpAll") && params["net.bindIpAll"].as<bool>()) { - // Bind to all IP addresses - serverGlobalParams.bind_ip = "0.0.0.0"; - if (params.count("net.ipv6") && params["net.ipv6"].as<bool>()) { - serverGlobalParams.bind_ip += ",::"; - } - } else if (params.count("net.bindIp")) { - // Bind to enumerated IP addresses - serverGlobalParams.bind_ip = params["net.bindIp"].as<std::string>(); - } else { - // Bind to localhost - serverGlobalParams.bind_ip = ""; - } - -#ifndef _WIN32 - if (params.count("net.unixDomainSocket.pathPrefix")) { - serverGlobalParams.socket = params["net.unixDomainSocket.pathPrefix"].as<string>(); - } - - if (params.count("net.unixDomainSocket.enabled")) { - serverGlobalParams.noUnixSocket = !params["net.unixDomainSocket.enabled"].as<bool>(); - } - if (params.count("net.unixDomainSocket.filePermissions")) { - serverGlobalParams.unixSocketPermissions = - params["net.unixDomainSocket.filePermissions"].as<int>(); - } - - if ((params.count("processManagement.fork") && - params["processManagement.fork"].as<bool>() == true) && - (!params.count("shutdown") || params["shutdown"].as<bool>() == false)) { - serverGlobalParams.doFork = true; - } -#endif // _WIN32 - if (params.count("systemLog.timeStampFormat")) { using logger::MessageEventDetailsEncoder; std::string formatterName = params["systemLog.timeStampFormat"].as<string>(); @@ -1032,26 +527,6 @@ Status storeServerOptions(const moe::Environment& params) { 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("security.keyFile")) { - serverGlobalParams.keyFile = - boost::filesystem::absolute(params["security.keyFile"].as<string>()).generic_string(); - serverGlobalParams.authState = ServerGlobalParams::AuthState::kEnabled; - } - - if (serverGlobalParams.transitionToAuth || - (params.count("security.authorization") && - params["security.authorization"].as<std::string>() == "disabled")) { - serverGlobalParams.authState = ServerGlobalParams::AuthState::kDisabled; - } else if (params.count("security.authorization") && - params["security.authorization"].as<std::string>() == "enabled") { - serverGlobalParams.authState = ServerGlobalParams::AuthState::kEnabled; - } - if (params.count("processManagement.pidFilePath")) { serverGlobalParams.pidFile = params["processManagement.pidFilePath"].as<string>(); } @@ -1091,17 +566,6 @@ Status storeServerOptions(const moe::Environment& params) { } } - if (!params.count("security.clusterAuthMode") && params.count("security.keyFile")) { - serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_keyFile); - } - int clusterAuthMode = serverGlobalParams.clusterAuthMode.load(); - if (serverGlobalParams.transitionToAuth && - (clusterAuthMode != ServerGlobalParams::ClusterAuthMode_keyFile && - clusterAuthMode != ServerGlobalParams::ClusterAuthMode_x509)) { - return Status(ErrorCodes::BadValue, - "--transitionToAuth must be used with keyFile or x509 authentication"); - } - if (params.count("operationProfiling.slowOpThresholdMs")) { serverGlobalParams.slowMS = params["operationProfiling.slowOpThresholdMs"].as<int>(); } @@ -1110,18 +574,6 @@ Status storeServerOptions(const moe::Environment& params) { serverGlobalParams.sampleRate = params["operationProfiling.slowOpSampleRate"].as<double>(); } -#ifdef MONGO_CONFIG_SSL - ret = storeSSLServerOptions(params); - if (!ret.isOK()) { - return ret; - } -#endif - - ret = storeMessageCompressionOptions(params); - if (!ret.isOK()) { - return ret; - } - return Status::OK(); } diff --git a/src/mongo/db/server_options_helpers.h b/src/mongo/db/server_options_helpers.h index 0c8fa5f0e9c..6ea77b3e84f 100644 --- a/src/mongo/db/server_options_helpers.h +++ b/src/mongo/db/server_options_helpers.h @@ -49,28 +49,19 @@ namespace moe = mongo::optionenvironment; Status addBaseServerOptions(moe::OptionSection* options); /** - * General server options for most standalone applications. Includes addBaseServerOptions. - */ -Status addGeneralServerOptions(moe::OptionSection* options); - -Status addWindowsServerOptions(moe::OptionSection* options); - -Status addSSLServerOptions(moe::OptionSection* options); +* Handle custom validation of base options that can not currently be done by using +* Constraints in the Environment. See the "validate" function in the Environment class for +* more details. +*/ +Status validateBaseOptions(const moe::Environment& params); /** - * Handle custom validation of server options that can not currently be done by using - * Constraints in the Environment. See the "validate" function in the Environment class for - * more details. - */ -Status validateServerOptions(const moe::Environment& params); - -/** - * Canonicalize server options for the given environment. - * - * For example, the options "objcheck", "noobjcheck", and "net.wireObjectCheck" should all be - * merged into "net.wireObjectCheck". - */ -Status canonicalizeServerOptions(moe::Environment* params); +* Canonicalize base options for the given environment. +* +* For example, the options "objcheck", "noobjcheck", and "net.wireObjectCheck" should all be +* merged into "net.wireObjectCheck". +*/ +Status canonicalizeBaseOptions(moe::Environment* params); /** * Sets up the global server state necessary to be able to store the server options, based on how @@ -79,15 +70,14 @@ Status canonicalizeServerOptions(moe::Environment* params); * For example, saves the current working directory in serverGlobalParams.cwd so that relative paths * in server options can be interpreted correctly. */ -Status setupServerOptions(const std::vector<std::string>& args); +Status setupBaseOptions(const std::vector<std::string>& args); /** - * Store the given parsed params in global server state. - * - * For example, sets the serverGlobalParams.port variable based on the net.port config parameter. - */ -Status storeServerOptions(const moe::Environment& params); - -void printCommandLineOpts(); +* Store the given parsed params in global server state. +* +* For example, sets the serverGlobalParams.quiet variable based on the systemLog.quiet config +* parameter. +*/ +Status storeBaseOptions(const moe::Environment& params); } // namespace mongo diff --git a/src/mongo/db/server_options_init.cpp b/src/mongo/db/server_options_init.cpp index e0f747c62c5..59c4f5cc27b 100644 --- a/src/mongo/db/server_options_init.cpp +++ b/src/mongo/db/server_options_init.cpp @@ -27,7 +27,7 @@ */ #include "mongo/base/init.h" -#include "mongo/db/server_options_helpers.h" +#include "mongo/db/server_options_server_helpers.h" namespace mongo { diff --git a/src/mongo/db/server_options_server_helpers.cpp b/src/mongo/db/server_options_server_helpers.cpp new file mode 100644 index 00000000000..c3b71a07d10 --- /dev/null +++ b/src/mongo/db/server_options_server_helpers.cpp @@ -0,0 +1,674 @@ +/* + * Copyright (C) 2013 MongoDB 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. + */ + +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kControl + +#include "mongo/db/server_options_server_helpers.h" + +#include <boost/filesystem.hpp> +#include <boost/filesystem/operations.hpp> +#include <ios> +#include <iostream> + +#include "mongo/base/status.h" +#include "mongo/bson/util/builder.h" +#include "mongo/config.h" +#include "mongo/db/server_options.h" +#include "mongo/db/server_options_helpers.h" +#include "mongo/db/server_parameters.h" +#include "mongo/logger/log_component.h" +#include "mongo/logger/message_event_utf8_encoder.h" +#include "mongo/transport/message_compressor_registry.h" +#include "mongo/util/cmdline_utils/censor_cmdline.h" +#include "mongo/util/fail_point_service.h" +#include "mongo/util/log.h" +#include "mongo/util/map_util.h" +#include "mongo/util/mongoutils/str.h" +#include "mongo/util/net/sock.h" +#include "mongo/util/net/socket_utils.h" +#include "mongo/util/net/ssl_options.h" +#include "mongo/util/options_parser/startup_options.h" + +using std::endl; +using std::string; + +namespace mongo { + +Status addGeneralServerOptions(moe::OptionSection* options) { + auto baseResult = addBaseServerOptions(options); + if (!baseResult.isOK()) { + return baseResult; + } + + StringBuilder maxConnInfoBuilder; + std::stringstream unixSockPermsBuilder; + + maxConnInfoBuilder << "max number of simultaneous connections - " << DEFAULT_MAX_CONN + << " by default"; + unixSockPermsBuilder << "permissions to set on UNIX domain socket file - " + << "0" << std::oct << DEFAULT_UNIX_PERMS << " by default"; + + options->addOptionChaining("help", "help,h", moe::Switch, "show this usage information") + .setSources(moe::SourceAllLegacy); + + options->addOptionChaining("version", "version", moe::Switch, "show version information") + .setSources(moe::SourceAllLegacy); + + options + ->addOptionChaining( + "config", "config,f", moe::String, "configuration file specifying additional options") + .setSources(moe::SourceAllLegacy); + + + options + ->addOptionChaining( + "net.bindIp", + "bind_ip", + moe::String, + "comma separated list of ip addresses to listen on - localhost by default") + .incompatibleWith("bind_ip_all"); + + options + ->addOptionChaining("net.bindIpAll", "bind_ip_all", moe::Switch, "bind to all ip addresses") + .incompatibleWith("bind_ip"); + + options->addOptionChaining( + "net.ipv6", "ipv6", moe::Switch, "enable IPv6 support (disabled by default)"); + + options + ->addOptionChaining( + "net.listenBacklog", "listenBacklog", moe::Int, "set socket listen backlog size") + .setDefault(moe::Value(SOMAXCONN)); + + options->addOptionChaining( + "net.maxIncomingConnections", "maxConns", moe::Int, maxConnInfoBuilder.str().c_str()); + + options + ->addOptionChaining("net.transportLayer", + "transportLayer", + moe::String, + "sets the ingress transport layer implementation") + .hidden() + .setDefault(moe::Value("asio")); + + options + ->addOptionChaining("net.serviceExecutor", + "serviceExecutor", + moe::String, + "sets the service executor implementation") + .hidden() + .setDefault(moe::Value("synchronous")); + +#if MONGO_ENTERPRISE_VERSION + options->addOptionChaining("security.redactClientLogData", + "redactClientLogData", + moe::Switch, + "Redact client data written to the diagnostics log"); +#endif + + options->addOptionChaining("processManagement.pidFilePath", + "pidfilepath", + moe::String, + "full path to pidfile (if not set, no pidfile is created)"); + + options->addOptionChaining("processManagement.timeZoneInfo", + "timeZoneInfo", + moe::String, + "full path to time zone info directory, e.g. /usr/share/zoneinfo"); + + options + ->addOptionChaining( + "security.keyFile", "keyFile", moe::String, "private key for cluster authentication") + .incompatibleWith("noauth"); + + options->addOptionChaining("noauth", "noauth", moe::Switch, "run without security") + .setSources(moe::SourceAllLegacy) + .incompatibleWith("auth") + .incompatibleWith("keyFile") + .incompatibleWith("transitionToAuth") + .incompatibleWith("clusterAuthMode"); + + options + ->addOptionChaining( + "security.transitionToAuth", + "transitionToAuth", + moe::Switch, + "For rolling access control upgrade. Attempt to authenticate over outgoing " + "connections and proceed regardless of success. Accept incoming connections " + "with or without authentication.") + .incompatibleWith("noauth"); + + options + ->addOptionChaining("security.clusterAuthMode", + "clusterAuthMode", + moe::String, + "Authentication mode used for cluster authentication. Alternatives are " + "(keyFile|sendKeyFile|sendX509|x509)") + .format("(:?keyFile)|(:?sendKeyFile)|(:?sendX509)|(:?x509)", + "(keyFile/sendKeyFile/sendX509/x509)"); + +#ifndef _WIN32 + options + ->addOptionChaining( + "nounixsocket", "nounixsocket", moe::Switch, "disable listening on unix sockets") + .setSources(moe::SourceAllLegacy); + + options + ->addOptionChaining( + "net.unixDomainSocket.enabled", "", moe::Bool, "disable listening on unix sockets") + .setSources(moe::SourceYAMLConfig); + + options->addOptionChaining("net.unixDomainSocket.pathPrefix", + "unixSocketPrefix", + moe::String, + "alternative directory for UNIX domain sockets (defaults to /tmp)"); + + options->addOptionChaining("net.unixDomainSocket.filePermissions", + "filePermissions", + moe::Int, + unixSockPermsBuilder.str()); + + options->addOptionChaining( + "processManagement.fork", "fork", moe::Switch, "fork server process"); + +#endif + + options + ->addOptionChaining("objcheck", + "objcheck", + moe::Switch, + "inspect client data for validity on receipt (DEFAULT)") + .hidden() + .setSources(moe::SourceAllLegacy) + .incompatibleWith("noobjcheck"); + + options + ->addOptionChaining("noobjcheck", + "noobjcheck", + moe::Switch, + "do NOT inspect client data for validity on receipt") + .hidden() + .setSources(moe::SourceAllLegacy) + .incompatibleWith("objcheck"); + + options + ->addOptionChaining("net.wireObjectCheck", + "", + moe::Bool, + "inspect client data for validity on receipt (DEFAULT)") + .hidden() + .setSources(moe::SourceYAMLConfig); + + options + ->addOptionChaining("enableExperimentalStorageDetailsCmd", + "enableExperimentalStorageDetailsCmd", + moe::Switch, + "EXPERIMENTAL (UNSUPPORTED). " + "Enable command computing aggregate statistics on storage.") + .hidden() + .setSources(moe::SourceAllLegacy); + + options + ->addOptionChaining("operationProfiling.slowOpThresholdMs", + "slowms", + moe::Int, + "value of slow for profile and console log") + .setDefault(moe::Value(100)); + + options + ->addOptionChaining("operationProfiling.slowOpSampleRate", + "slowOpSampleRate", + moe::Double, + "fraction of slow ops to include in the profile and console log") + .setDefault(moe::Value(1.0)); + + auto ret = addMessageCompressionOptions(options, false); + if (!ret.isOK()) { + return ret; + } + + return Status::OK(); +} + +Status addWindowsServerOptions(moe::OptionSection* options) { + options->addOptionChaining("install", "install", moe::Switch, "install Windows service") + .setSources(moe::SourceAllLegacy); + + options->addOptionChaining("remove", "remove", moe::Switch, "remove Windows service") + .setSources(moe::SourceAllLegacy); + + options + ->addOptionChaining( + "reinstall", + "reinstall", + moe::Switch, + "reinstall Windows service (equivalent to --remove followed by --install)") + .setSources(moe::SourceAllLegacy); + + options->addOptionChaining("processManagement.windowsService.serviceName", + "serviceName", + moe::String, + "Windows service name"); + + options->addOptionChaining("processManagement.windowsService.displayName", + "serviceDisplayName", + moe::String, + "Windows service display name"); + + options->addOptionChaining("processManagement.windowsService.description", + "serviceDescription", + moe::String, + "Windows service description"); + + options->addOptionChaining("processManagement.windowsService.serviceUser", + "serviceUser", + moe::String, + "account for service execution"); + + options->addOptionChaining("processManagement.windowsService.servicePassword", + "servicePassword", + moe::String, + "password used to authenticate serviceUser"); + + options->addOptionChaining("service", "service", moe::Switch, "start mongodb service") + .hidden() + .setSources(moe::SourceAllLegacy); + + return Status::OK(); +} + +namespace { +// Helpers for option storage +Status setupBinaryName(const std::vector<std::string>& argv) { + if (argv.empty()) { + return Status(ErrorCodes::UnknownError, "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 + boost::system::error_code ec; + boost::filesystem::path cwd = boost::filesystem::current_path(ec); + if (ec) { + return Status(ErrorCodes::UnknownError, + "Cannot get current working directory: " + ec.message()); + } + serverGlobalParams.cwd = cwd.string(); + 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 validateServerOptions(const moe::Environment& params) { + Status ret = validateBaseOptions(params); + if (!ret.isOK()) + return ret; + +#ifdef _WIN32 + if (params.count("install") || params.count("reinstall")) { + if (params.count("logpath") && + !boost::filesystem::path(params["logpath"].as<string>()).is_absolute()) { + return Status(ErrorCodes::BadValue, + "logpath requires an absolute file path with Windows services"); + } + + if (params.count("config") && + !boost::filesystem::path(params["config"].as<string>()).is_absolute()) { + return Status(ErrorCodes::BadValue, + "config requires an absolute file path with Windows services"); + } + + if (params.count("processManagement.pidFilePath") && + !boost::filesystem::path(params["processManagement.pidFilePath"].as<string>()) + .is_absolute()) { + return Status(ErrorCodes::BadValue, + "pidFilePath requires an absolute file path with Windows services"); + } + + if (params.count("security.keyFile") && + !boost::filesystem::path(params["security.keyFile"].as<string>()).is_absolute()) { + return Status(ErrorCodes::BadValue, + "keyFile requires an absolute file path with Windows services"); + } + } +#endif + +#ifdef MONGO_CONFIG_SSL + ret = validateSSLServerOptions(params); + if (!ret.isOK()) { + return ret; + } +#endif + + bool haveAuthenticationMechanisms = true; + bool hasAuthorizationEnabled = false; + if (params.count("security.authenticationMechanisms") && + params["security.authenticationMechanisms"].as<std::vector<std::string>>().empty()) { + haveAuthenticationMechanisms = false; + } + if (params.count("setParameter")) { + std::map<std::string, std::string> parameters = + params["setParameter"].as<std::map<std::string, std::string>>(); + auto authMechParameter = parameters.find("authenticationMechanisms"); + if (authMechParameter != parameters.end() && authMechParameter->second.empty()) { + haveAuthenticationMechanisms = false; + } + + if (parameters.find("internalValidateFeaturesAsMaster") != parameters.end()) { + // Command line options that are disallowed when internalValidateFeaturesAsMaster is + // specified. + if (params.count("replication.replSet")) { + return Status(ErrorCodes::BadValue, + str::stream() << // + "Cannot specify both internalValidateFeaturesAsMaster and " + "replication.replSet"); + } + } + } + if ((params.count("security.authorization") && + params["security.authorization"].as<std::string>() == "enabled") || + params.count("security.clusterAuthMode") || params.count("security.keyFile") || + params.count("auth")) { + hasAuthorizationEnabled = true; + } + if (hasAuthorizationEnabled && !haveAuthenticationMechanisms) { + return Status(ErrorCodes::BadValue, + "Authorization is enabled but no authentication mechanisms are present."); + } + + return Status::OK(); +} + +Status canonicalizeServerOptions(moe::Environment* params) { + Status ret = canonicalizeBaseOptions(params); + if (!ret.isOK()) + return ret; + + // "net.wireObjectCheck" comes from the config file, so override it if either "objcheck" or + // "noobjcheck" are set, since those come from the command line. + if (params->count("objcheck")) { + ret = params->set("net.wireObjectCheck", moe::Value((*params)["objcheck"].as<bool>())); + if (!ret.isOK()) { + return ret; + } + ret = params->remove("objcheck"); + if (!ret.isOK()) { + return ret; + } + } + + if (params->count("noobjcheck")) { + ret = params->set("net.wireObjectCheck", moe::Value(!(*params)["noobjcheck"].as<bool>())); + if (!ret.isOK()) { + return ret; + } + ret = params->remove("noobjcheck"); + if (!ret.isOK()) { + return ret; + } + } + + // "net.unixDomainSocket.enabled" comes from the config file, so override it if + // "nounixsocket" is set since that comes from the command line. + if (params->count("nounixsocket")) { + ret = params->set("net.unixDomainSocket.enabled", + moe::Value(!(*params)["nounixsocket"].as<bool>())); + if (!ret.isOK()) { + return ret; + } + ret = params->remove("nounixsocket"); + if (!ret.isOK()) { + return ret; + } + } + + if (params->count("noauth")) { + ret = params->set("security.authorization", + (*params)["noauth"].as<bool>() ? moe::Value(std::string("disabled")) + : moe::Value(std::string("enabled"))); + if (!ret.isOK()) { + return ret; + } + ret = params->remove("noauth"); + if (!ret.isOK()) { + return ret; + } + } + return Status::OK(); +} + +Status setupServerOptions(const std::vector<std::string>& args) { + Status ret = setupBinaryName(args); + if (!ret.isOK()) { + return ret; + } + + ret = setupCwd(); + if (!ret.isOK()) { + return ret; + } + + ret = setupBaseOptions(args); + if (!ret.isOK()) { + return ret; + } + + return Status::OK(); +} + +Status storeServerOptions(const moe::Environment& params) { + Status ret = storeBaseOptions(params); + if (!ret.isOK()) { + return ret; + } + + if (params.count("net.port")) { + serverGlobalParams.port = params["net.port"].as<int>(); + } + + if (params.count("net.ipv6") && params["net.ipv6"].as<bool>() == true) { + serverGlobalParams.enableIPv6 = true; + enableIPv6(); + } + + if (params.count("net.listenBacklog")) { + serverGlobalParams.listenBacklog = params["net.listenBacklog"].as<int>(); + } + + if (params.count("net.transportLayer")) { + serverGlobalParams.transportLayer = params["net.transportLayer"].as<std::string>(); + if (serverGlobalParams.transportLayer != "asio") { + return {ErrorCodes::BadValue, "Unsupported value for transportLayer. Must be \"asio\""}; + } + } + + if (params.count("net.serviceExecutor")) { + auto value = params["net.serviceExecutor"].as<std::string>(); + const auto valid = {"synchronous"_sd, "adaptive"_sd}; + if (std::find(valid.begin(), valid.end(), value) == valid.end()) { + return {ErrorCodes::BadValue, "Unsupported value for serviceExecutor"}; + } + serverGlobalParams.serviceExecutor = value; + } else { + serverGlobalParams.serviceExecutor = "synchronous"; + } + + if (params.count("security.transitionToAuth")) { + serverGlobalParams.transitionToAuth = params["security.transitionToAuth"].as<bool>(); + } + + if (params.count("security.clusterAuthMode")) { + std::string clusterAuthMode = params["security.clusterAuthMode"].as<std::string>(); + + if (clusterAuthMode == "keyFile") { + serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_keyFile); + } else if (clusterAuthMode == "sendKeyFile") { + serverGlobalParams.clusterAuthMode.store( + ServerGlobalParams::ClusterAuthMode_sendKeyFile); + } else if (clusterAuthMode == "sendX509") { + serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_sendX509); + } else if (clusterAuthMode == "x509") { + serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_x509); + } else { + return Status(ErrorCodes::BadValue, + "unsupported value for clusterAuthMode " + clusterAuthMode); + } + serverGlobalParams.authState = ServerGlobalParams::AuthState::kEnabled; + } else { + serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_undefined); + } + + if (params.count("net.maxIncomingConnections")) { + serverGlobalParams.maxConns = params["net.maxIncomingConnections"].as<int>(); + + if (serverGlobalParams.maxConns < 5) { + return Status(ErrorCodes::BadValue, "maxConns has to be at least 5"); + } + } + + if (params.count("net.wireObjectCheck")) { + serverGlobalParams.objcheck = params["net.wireObjectCheck"].as<bool>(); + } + + if (params.count("net.bindIpAll") && params["net.bindIpAll"].as<bool>()) { + // Bind to all IP addresses + serverGlobalParams.bind_ip = "0.0.0.0"; + if (params.count("net.ipv6") && params["net.ipv6"].as<bool>()) { + serverGlobalParams.bind_ip += ",::"; + } + } else if (params.count("net.bindIp")) { + // Bind to enumerated IP addresses + serverGlobalParams.bind_ip = params["net.bindIp"].as<std::string>(); + } else { + // Bind to localhost + serverGlobalParams.bind_ip = ""; + } + +#ifndef _WIN32 + if (params.count("net.unixDomainSocket.pathPrefix")) { + serverGlobalParams.socket = params["net.unixDomainSocket.pathPrefix"].as<string>(); + } + + if (params.count("net.unixDomainSocket.enabled")) { + serverGlobalParams.noUnixSocket = !params["net.unixDomainSocket.enabled"].as<bool>(); + } + if (params.count("net.unixDomainSocket.filePermissions")) { + serverGlobalParams.unixSocketPermissions = + params["net.unixDomainSocket.filePermissions"].as<int>(); + } + + if ((params.count("processManagement.fork") && + params["processManagement.fork"].as<bool>() == true) && + (!params.count("shutdown") || params["shutdown"].as<bool>() == false)) { + serverGlobalParams.doFork = true; + } +#endif // _WIN32 + + if (serverGlobalParams.doFork && serverGlobalParams.logpath.empty() && + !serverGlobalParams.logWithSyslog) { + return Status(ErrorCodes::BadValue, "--fork has to be used with --logpath or --syslog"); + } + + if (params.count("security.keyFile")) { + serverGlobalParams.keyFile = + boost::filesystem::absolute(params["security.keyFile"].as<string>()).generic_string(); + serverGlobalParams.authState = ServerGlobalParams::AuthState::kEnabled; + } + + if (serverGlobalParams.transitionToAuth || + (params.count("security.authorization") && + params["security.authorization"].as<std::string>() == "disabled")) { + serverGlobalParams.authState = ServerGlobalParams::AuthState::kDisabled; + } else if (params.count("security.authorization") && + params["security.authorization"].as<std::string>() == "enabled") { + serverGlobalParams.authState = ServerGlobalParams::AuthState::kEnabled; + } + + if (params.count("processManagement.pidFilePath")) { + serverGlobalParams.pidFile = params["processManagement.pidFilePath"].as<string>(); + } + + if (params.count("processManagement.timeZoneInfo")) { + serverGlobalParams.timeZoneInfoPath = params["processManagement.timeZoneInfo"].as<string>(); + } + + if (!params.count("security.clusterAuthMode") && params.count("security.keyFile")) { + serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_keyFile); + } + int clusterAuthMode = serverGlobalParams.clusterAuthMode.load(); + if (serverGlobalParams.transitionToAuth && + (clusterAuthMode != ServerGlobalParams::ClusterAuthMode_keyFile && + clusterAuthMode != ServerGlobalParams::ClusterAuthMode_x509)) { + return Status(ErrorCodes::BadValue, + "--transitionToAuth must be used with keyFile or x509 authentication"); + } + +#ifdef MONGO_CONFIG_SSL + ret = storeSSLServerOptions(params); + if (!ret.isOK()) { + return ret; + } +#endif + + ret = storeMessageCompressionOptions(params); + if (!ret.isOK()) { + return ret; + } + + return Status::OK(); +} + +} // namespace mongo diff --git a/src/mongo/db/server_options_server_helpers.h b/src/mongo/db/server_options_server_helpers.h new file mode 100644 index 00000000000..a22ff251edb --- /dev/null +++ b/src/mongo/db/server_options_server_helpers.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2013 MongoDB 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 "mongo/base/status.h" +#include "mongo/util/options_parser/environment.h" +#include "mongo/util/options_parser/option_section.h" + +namespace mongo { + +namespace optionenvironment { +class OptionSection; +class Environment; +} // namespace optionenvironment + +namespace moe = mongo::optionenvironment; + +/** + * General server options for most standalone applications. Includes addBaseServerOptions. + */ +Status addGeneralServerOptions(moe::OptionSection* options); + +Status addWindowsServerOptions(moe::OptionSection* options); + +Status addSSLServerOptions(moe::OptionSection* options); + +/** + * Handle custom validation of server options that can not currently be done by using + * Constraints in the Environment. See the "validate" function in the Environment class for + * more details. + */ +Status validateServerOptions(const moe::Environment& params); + +/** + * Canonicalize server options for the given environment. + * + * For example, the options "objcheck", "noobjcheck", and "net.wireObjectCheck" should all be + * merged into "net.wireObjectCheck". + */ +Status canonicalizeServerOptions(moe::Environment* params); + +/** + * Sets up the global server state necessary to be able to store the server options, based on how + * the server was started. + * + * For example, saves the current working directory in serverGlobalParams.cwd so that relative paths + * in server options can be interpreted correctly. + */ +Status setupServerOptions(const std::vector<std::string>& args); + +/** + * Store the given parsed params in global server state. + * + * For example, sets the serverGlobalParams.port variable based on the net.port config parameter. + */ +Status storeServerOptions(const moe::Environment& params); + +void printCommandLineOpts(); + +} // namespace mongo diff --git a/src/mongo/db/server_options_test.cpp b/src/mongo/db/server_options_test.cpp index be4eff361d2..8eddeb88dfc 100644 --- a/src/mongo/db/server_options_test.cpp +++ b/src/mongo/db/server_options_test.cpp @@ -47,7 +47,7 @@ #include "mongo/bson/util/builder.h" #include "mongo/db/server_options.h" -#include "mongo/db/server_options_helpers.h" +#include "mongo/db/server_options_server_helpers.h" #include "mongo/logger/logger.h" #include "mongo/unittest/unittest.h" #include "mongo/util/log.h" diff --git a/src/mongo/embedded/embedded_options.cpp b/src/mongo/embedded/embedded_options.cpp index afa610bad64..949e31ce07b 100644 --- a/src/mongo/embedded/embedded_options.cpp +++ b/src/mongo/embedded/embedded_options.cpp @@ -90,7 +90,7 @@ Status addOptions(optionenvironment::OptionSection* options) { Status canonicalizeOptions(optionenvironment::Environment* params) { - Status ret = canonicalizeServerOptions(params); + Status ret = canonicalizeBaseOptions(params); if (!ret.isOK()) { return ret; } @@ -99,6 +99,11 @@ Status canonicalizeOptions(optionenvironment::Environment* params) { } Status storeOptions(const moe::Environment& params) { + Status ret = storeBaseOptions(params); + if (!ret.isOK()) { + return ret; + } + if (params.count("storage.engine")) { storageGlobalParams.engine = params["storage.engine"].as<std::string>(); storageGlobalParams.engineSetByUser = true; @@ -106,13 +111,6 @@ Status storeOptions(const moe::Environment& params) { if (params.count("storage.dbPath")) { storageGlobalParams.dbpath = params["storage.dbPath"].as<string>(); - if (params.count("processManagement.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 && @@ -123,26 +121,6 @@ Status storeOptions(const moe::Environment& params) { } #endif - if (!params.count("net.port")) { - if (params.count("sharding.clusterRole")) { - std::string clusterRole = params["sharding.clusterRole"].as<std::string>(); - if (clusterRole == "configsvr") { - serverGlobalParams.port = ServerGlobalParams::ConfigServerPort; - } else if (clusterRole == "shardsvr") { - serverGlobalParams.port = ServerGlobalParams::ShardServerPort; - } else { - StringBuilder sb; - sb << "Bad value for sharding.clusterRole: " << clusterRole - << ". Supported modes are: (configsvr|shardsvr)"; - return Status(ErrorCodes::BadValue, sb.str()); - } - } - } else { - if (serverGlobalParams.port < 0 || serverGlobalParams.port > 65535) { - return Status(ErrorCodes::BadValue, "bad --port number"); - } - } - #ifdef _WIN32 // If dbPath is a default value, prepend with drive name so log entries are explicit // We must resolve the dbpath before it stored in repairPath in the default case. diff --git a/src/mongo/s/mongos_options.cpp b/src/mongo/s/mongos_options.cpp index 5b1a5230037..32dccbf6f4c 100644 --- a/src/mongo/s/mongos_options.cpp +++ b/src/mongo/s/mongos_options.cpp @@ -41,7 +41,7 @@ #include "mongo/bson/util/builder.h" #include "mongo/config.h" #include "mongo/db/server_options.h" -#include "mongo/db/server_options_helpers.h" +#include "mongo/db/server_options_server_helpers.h" #include "mongo/s/version_mongos.h" #include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" diff --git a/src/mongo/tools/SConscript b/src/mongo/tools/SConscript index 7c4ce83c43b..dc4bfe408c7 100644 --- a/src/mongo/tools/SConscript +++ b/src/mongo/tools/SConscript @@ -16,6 +16,7 @@ mongobridge = env.Program( LIBDEPS=[ '$BUILD_DIR/mongo/db/dbmessage', '$BUILD_DIR/mongo/rpc/rpc', + '$BUILD_DIR/mongo/transport/message_compressor', '$BUILD_DIR/mongo/transport/service_entry_point', '$BUILD_DIR/mongo/transport/service_executor', '$BUILD_DIR/mongo/transport/transport_layer', |