summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands/parameters.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/commands/parameters.cpp')
-rw-r--r--src/mongo/db/commands/parameters.cpp1007
1 files changed, 500 insertions, 507 deletions
diff --git a/src/mongo/db/commands/parameters.cpp b/src/mongo/db/commands/parameters.cpp
index c9048ee54c2..7ff531bb8a1 100644
--- a/src/mongo/db/commands/parameters.cpp
+++ b/src/mongo/db/commands/parameters.cpp
@@ -51,556 +51,549 @@ using std::stringstream;
namespace mongo {
- namespace {
- void appendParameterNames( stringstream& help ) {
- help << "supported:\n";
- const ServerParameter::Map& m = ServerParameterSet::getGlobal()->getMap();
- for ( ServerParameter::Map::const_iterator i = m.begin(); i != m.end(); ++i ) {
- help << " " << i->first << "\n";
- }
- }
+namespace {
+void appendParameterNames(stringstream& help) {
+ help << "supported:\n";
+ const ServerParameter::Map& m = ServerParameterSet::getGlobal()->getMap();
+ for (ServerParameter::Map::const_iterator i = m.begin(); i != m.end(); ++i) {
+ help << " " << i->first << "\n";
}
+}
+}
- class CmdGet : public Command {
- public:
- CmdGet() : Command( "getParameter" ) { }
- virtual bool slaveOk() const { return true; }
- virtual bool adminOnly() const { return true; }
- virtual bool isWriteCommandForConfigServer() const { return false; }
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) {
- ActionSet actions;
- actions.addAction(ActionType::getParameter);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+class CmdGet : public Command {
+public:
+ CmdGet() : Command("getParameter") {}
+ virtual bool slaveOk() const {
+ return true;
+ }
+ virtual bool adminOnly() const {
+ return true;
+ }
+ virtual bool isWriteCommandForConfigServer() const {
+ return false;
+ }
+ virtual void addRequiredPrivileges(const std::string& dbname,
+ const BSONObj& cmdObj,
+ std::vector<Privilege>* out) {
+ ActionSet actions;
+ actions.addAction(ActionType::getParameter);
+ out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ }
+ virtual void help(stringstream& help) const {
+ help << "get administrative option(s)\nexample:\n";
+ help << "{ getParameter:1, notablescan:1 }\n";
+ appendParameterNames(help);
+ help << "{ getParameter:'*' } to get everything\n";
+ }
+ bool run(OperationContext* txn,
+ const string& dbname,
+ BSONObj& cmdObj,
+ int,
+ string& errmsg,
+ BSONObjBuilder& result) {
+ bool all = *cmdObj.firstElement().valuestrsafe() == '*';
+
+ int before = result.len();
+
+ const ServerParameter::Map& m = ServerParameterSet::getGlobal()->getMap();
+ for (ServerParameter::Map::const_iterator i = m.begin(); i != m.end(); ++i) {
+ if (all || cmdObj.hasElement(i->first.c_str())) {
+ i->second->append(txn, result, i->second->name());
+ }
}
- virtual void help( stringstream &help ) const {
- help << "get administrative option(s)\nexample:\n";
- help << "{ getParameter:1, notablescan:1 }\n";
- appendParameterNames( help );
- help << "{ getParameter:'*' } to get everything\n";
+
+ if (before == result.len()) {
+ errmsg = "no option found to get";
+ return false;
}
- bool run(OperationContext* txn,
- const string& dbname,
- BSONObj& cmdObj,
- int,
- string& errmsg,
- BSONObjBuilder& result) {
- bool all = *cmdObj.firstElement().valuestrsafe() == '*';
-
- int before = result.len();
-
- const ServerParameter::Map& m = ServerParameterSet::getGlobal()->getMap();
- for ( ServerParameter::Map::const_iterator i = m.begin(); i != m.end(); ++i ) {
- if ( all || cmdObj.hasElement( i->first.c_str() ) ) {
- i->second->append(txn, result, i->second->name() );
- }
- }
+ return true;
+ }
+} cmdGet;
- if ( before == result.len() ) {
- errmsg = "no option found to get";
+class CmdSet : public Command {
+public:
+ CmdSet() : Command("setParameter") {}
+ virtual bool slaveOk() const {
+ return true;
+ }
+ virtual bool adminOnly() const {
+ return true;
+ }
+ virtual bool isWriteCommandForConfigServer() const {
+ return false;
+ }
+ virtual void addRequiredPrivileges(const std::string& dbname,
+ const BSONObj& cmdObj,
+ std::vector<Privilege>* out) {
+ ActionSet actions;
+ actions.addAction(ActionType::setParameter);
+ out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ }
+ virtual void help(stringstream& help) const {
+ help << "set administrative option(s)\n";
+ help << "{ setParameter:1, <param>:<value> }\n";
+ appendParameterNames(help);
+ }
+ bool run(OperationContext* txn,
+ const string& dbname,
+ BSONObj& cmdObj,
+ int,
+ string& errmsg,
+ BSONObjBuilder& result) {
+ int numSet = 0;
+ bool found = false;
+
+ const ServerParameter::Map& parameterMap = ServerParameterSet::getGlobal()->getMap();
+
+ // First check that we aren't setting the same parameter twice and that we actually are
+ // setting parameters that we have registered and can change at runtime
+ BSONObjIterator parameterCheckIterator(cmdObj);
+
+ // We already know that "setParameter" will be the first element in this object, so skip
+ // past that
+ parameterCheckIterator.next();
+
+ // Set of all the parameters the user is attempting to change
+ std::map<std::string, BSONElement> parametersToSet;
+
+ // Iterate all parameters the user passed in to do the initial validation checks,
+ // including verifying that we are not setting the same parameter twice.
+ while (parameterCheckIterator.more()) {
+ BSONElement parameter = parameterCheckIterator.next();
+ std::string parameterName = parameter.fieldName();
+
+ ServerParameter::Map::const_iterator foundParameter = parameterMap.find(parameterName);
+
+ // Check to see if this is actually a valid parameter
+ if (foundParameter == parameterMap.end()) {
+ errmsg = str::stream() << "attempted to set unrecognized parameter ["
+ << parameterName << "], use help:true to see options ";
return false;
}
- return true;
- }
- } cmdGet;
-
- class CmdSet : public Command {
- public:
- CmdSet() : Command( "setParameter" ) { }
- virtual bool slaveOk() const { return true; }
- virtual bool adminOnly() const { return true; }
- virtual bool isWriteCommandForConfigServer() const { return false; }
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) {
- ActionSet actions;
- actions.addAction(ActionType::setParameter);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
- }
- virtual void help( stringstream &help ) const {
- help << "set administrative option(s)\n";
- help << "{ setParameter:1, <param>:<value> }\n";
- appendParameterNames( help );
- }
- bool run(OperationContext* txn,
- const string& dbname,
- BSONObj& cmdObj,
- int,
- string& errmsg,
- BSONObjBuilder& result) {
- int numSet = 0;
- bool found = false;
-
- const ServerParameter::Map& parameterMap = ServerParameterSet::getGlobal()->getMap();
-
- // First check that we aren't setting the same parameter twice and that we actually are
- // setting parameters that we have registered and can change at runtime
- BSONObjIterator parameterCheckIterator(cmdObj);
-
- // We already know that "setParameter" will be the first element in this object, so skip
- // past that
- parameterCheckIterator.next();
-
- // Set of all the parameters the user is attempting to change
- std::map<std::string, BSONElement> parametersToSet;
-
- // Iterate all parameters the user passed in to do the initial validation checks,
- // including verifying that we are not setting the same parameter twice.
- while (parameterCheckIterator.more()) {
- BSONElement parameter = parameterCheckIterator.next();
- std::string parameterName = parameter.fieldName();
-
- ServerParameter::Map::const_iterator foundParameter =
- parameterMap.find(parameterName);
-
- // Check to see if this is actually a valid parameter
- if (foundParameter == parameterMap.end()) {
- errmsg = str::stream() << "attempted to set unrecognized parameter ["
- << parameterName
- << "], use help:true to see options ";
- return false;
- }
-
- // Make sure we are allowed to change this parameter
- if (!foundParameter->second->allowedToChangeAtRuntime()) {
- errmsg = str::stream() << "not allowed to change [" << parameterName
- << "] at runtime";
- return false;
- }
-
- // Make sure we are only setting this parameter once
- if (parametersToSet.count(parameterName)) {
- errmsg = str::stream() << "attempted to set parameter ["
- << parameterName
- << "] twice in the same setParameter command, "
- << "once to value: ["
- << parametersToSet[parameterName].toString(false)
- << "], and once to value: [" << parameter.toString(false)
- << "]";
- return false;
- }
-
- parametersToSet[parameterName] = parameter;
- }
- // Iterate the parameters that we have confirmed we are setting and actually set them.
- // Not that if setting any one parameter fails, the command will fail, but the user
- // won't see what has been set and what hasn't. See SERVER-8552.
- for (std::map<std::string, BSONElement>::iterator it = parametersToSet.begin();
- it != parametersToSet.end(); ++it) {
- BSONElement parameter = it->second;
- std::string parameterName = it->first;
-
- ServerParameter::Map::const_iterator foundParameter =
- parameterMap.find(parameterName);
-
- if (foundParameter == parameterMap.end()) {
- errmsg = str::stream() << "Parameter: " << parameterName << " that was "
- << "avaliable during our first lookup in the registered "
- << "parameters map is no longer available.";
- return false;
- }
-
- if (numSet == 0) {
- foundParameter->second->append(txn, result, "was");
- }
-
- Status status = foundParameter->second->set(parameter);
- if (status.isOK()) {
- numSet++;
- continue;
- }
-
- errmsg = status.reason();
- result.append("code", status.code());
+ // Make sure we are allowed to change this parameter
+ if (!foundParameter->second->allowedToChangeAtRuntime()) {
+ errmsg = str::stream() << "not allowed to change [" << parameterName
+ << "] at runtime";
return false;
}
- if (numSet == 0 && !found) {
- errmsg = "no option found to set, use help:true to see options ";
+ // Make sure we are only setting this parameter once
+ if (parametersToSet.count(parameterName)) {
+ errmsg = str::stream()
+ << "attempted to set parameter [" << parameterName
+ << "] twice in the same setParameter command, "
+ << "once to value: [" << parametersToSet[parameterName].toString(false)
+ << "], and once to value: [" << parameter.toString(false) << "]";
return false;
}
- return true;
+ parametersToSet[parameterName] = parameter;
}
- } cmdSet;
- namespace {
- using logger::globalLogDomain;
- using logger::LogComponent;
- using logger::LogComponentSetting;
- using logger::LogSeverity;
- using logger::parseLogComponentSettings;
-
- class LogLevelSetting : public ServerParameter {
- public:
- LogLevelSetting() : ServerParameter(ServerParameterSet::getGlobal(), "logLevel") {}
-
- virtual void append(OperationContext* txn, BSONObjBuilder& b, const std::string& name) {
- b << name << globalLogDomain()->getMinimumLogSeverity().toInt();
+ // Iterate the parameters that we have confirmed we are setting and actually set them.
+ // Not that if setting any one parameter fails, the command will fail, but the user
+ // won't see what has been set and what hasn't. See SERVER-8552.
+ for (std::map<std::string, BSONElement>::iterator it = parametersToSet.begin();
+ it != parametersToSet.end();
+ ++it) {
+ BSONElement parameter = it->second;
+ std::string parameterName = it->first;
+
+ ServerParameter::Map::const_iterator foundParameter = parameterMap.find(parameterName);
+
+ if (foundParameter == parameterMap.end()) {
+ errmsg = str::stream() << "Parameter: " << parameterName << " that was "
+ << "avaliable during our first lookup in the registered "
+ << "parameters map is no longer available.";
+ return false;
}
- virtual Status set(const BSONElement& newValueElement) {
- int newValue;
- if (!newValueElement.coerce(&newValue) || newValue < 0)
- return Status(ErrorCodes::BadValue, mongoutils::str::stream() <<
- "Invalid value for logLevel: " << newValueElement);
- LogSeverity newSeverity = (newValue > 0) ? LogSeverity::Debug(newValue) :
- LogSeverity::Log();
- globalLogDomain()->setMinimumLoggedSeverity(newSeverity);
- return Status::OK();
+ if (numSet == 0) {
+ foundParameter->second->append(txn, result, "was");
}
- virtual Status setFromString(const std::string& str) {
- int newValue;
- Status status = parseNumberFromString(str, &newValue);
- if (!status.isOK())
- return status;
- if (newValue < 0)
- return Status(ErrorCodes::BadValue, mongoutils::str::stream() <<
- "Invalid value for logLevel: " << newValue);
- LogSeverity newSeverity = (newValue > 0) ? LogSeverity::Debug(newValue) :
- LogSeverity::Log();
- globalLogDomain()->setMinimumLoggedSeverity(newSeverity);
- return Status::OK();
- }
- } logLevelSetting;
-
- /**
- * Log component verbosity.
- * Log levels of log component hierarchy.
- * Negative value for a log component means the default log level will be used.
- */
- class LogComponentVerbositySetting : public ServerParameter {
- MONGO_DISALLOW_COPYING(LogComponentVerbositySetting);
- public:
- LogComponentVerbositySetting()
- : ServerParameter(ServerParameterSet::getGlobal(), "logComponentVerbosity") {}
-
- virtual void append(OperationContext* txn, BSONObjBuilder& b,
- const std::string& name) {
- BSONObj currentSettings;
- _get(&currentSettings);
- b << name << currentSettings;
+ Status status = foundParameter->second->set(parameter);
+ if (status.isOK()) {
+ numSet++;
+ continue;
}
- virtual Status set(const BSONElement& newValueElement) {
- if (!newValueElement.isABSONObj()) {
- return Status(ErrorCodes::TypeMismatch, mongoutils::str::stream() <<
- "log component verbosity is not a BSON object: " <<
- newValueElement);
- }
- return _set(newValueElement.Obj());
- }
+ errmsg = status.reason();
+ result.append("code", status.code());
+ return false;
+ }
- virtual Status setFromString(const std::string& str) {
- try {
- return _set(mongo::fromjson(str));
- }
- catch (const DBException& ex) {
- return ex.toStatus();
- }
- }
+ if (numSet == 0 && !found) {
+ errmsg = "no option found to set, use help:true to see options ";
+ return false;
+ }
- private:
- /**
- * Returns current settings as a BSON document.
- * The "default" log component is an implementation detail. Don't expose this to users.
- */
- void _get(BSONObj* output) const {
- static const string defaultLogComponentName =
- LogComponent(LogComponent::kDefault).getShortName();
-
- mutablebson::Document doc;
-
- for (int i = 0; i < int(LogComponent::kNumLogComponents); ++i) {
- LogComponent component = static_cast<LogComponent::Value>(i);
-
- int severity = -1;
- if (globalLogDomain()->hasMinimumLogSeverity(component)) {
- severity = globalLogDomain()->getMinimumLogSeverity(component).toInt();
- }
-
- // Save LogComponent::kDefault LogSeverity at root
- if (component == LogComponent::kDefault) {
- doc.root().appendInt("verbosity", severity);
- continue;
- }
-
- mutablebson::Element element = doc.makeElementObject(component.getShortName());
- element.appendInt("verbosity", severity);
-
- mutablebson::Element parentElement = _getParentElement(doc, component);
- parentElement.pushBack(element);
- }
-
- BSONObj result = doc.getObject();
- output->swap(result);
- invariant(!output->hasField(defaultLogComponentName));
- }
+ return true;
+ }
+} cmdSet;
- /**
- * Updates component hierarchy log levels.
- *
- * BSON Format:
- * {
- * verbosity: 4, <-- maps to 'default' log component.
- * componentA: {
- * verbosity: 2, <-- sets componentA's log level to 2.
- * componentB: {
- * verbosity: 1, <-- sets componentA.componentB's log level to 1.
- * }
- * componentC: {
- * verbosity: -1, <-- clears componentA.componentC's log level so that
- * its final loglevel will be inherited from componentA.
- * }
- * },
- * componentD : 3 <-- sets componentD's log level to 3 (alternative to
- * subdocument with 'verbosity' field).
- * }
- *
- * For the default component, the log level is read from the top-level
- * "verbosity" field.
- * For non-default components, we look up the element using the component's
- * dotted name. If the "<dotted component name>" field is a number, the log
- * level will be read from the field's value.
- * Otherwise, we assume that the "<dotted component name>" field is an
- * object with a "verbosity" field that holds the log level for the component.
- * The more verbose format with the "verbosity" field is intended to support
- * setting of log levels of both parent and child log components in the same
- * BSON document.
- *
- * Ignore elements in BSON object that do not map to a log component's dotted
- * name.
- */
- Status _set(const BSONObj& bsonSettings) const {
- StatusWith< std::vector<LogComponentSetting> > parseStatus =
- parseLogComponentSettings(bsonSettings);
-
- if (!parseStatus.isOK()) {
- return parseStatus.getStatus();
- }
-
- std::vector<LogComponentSetting> settings = parseStatus.getValue();
- std::vector<LogComponentSetting>::iterator it = settings.begin();
- for (; it < settings.end(); ++it) {
- LogComponentSetting newSetting = *it;
-
- // Negative value means to clear log level of component.
- if (newSetting.level < 0) {
- globalLogDomain()->clearMinimumLoggedSeverity(newSetting.component);
- continue;
- }
- // Convert non-negative value to Log()/Debug(N).
- LogSeverity newSeverity = (newSetting.level > 0) ?
- LogSeverity::Debug(newSetting.level) : LogSeverity::Log();
- globalLogDomain()->setMinimumLoggedSeverity(newSetting.component,
- newSeverity);
- }
-
- return Status::OK();
- }
+namespace {
+using logger::globalLogDomain;
+using logger::LogComponent;
+using logger::LogComponentSetting;
+using logger::LogSeverity;
+using logger::parseLogComponentSettings;
- /**
- * Search document for element corresponding to log component's parent.
- */
- static mutablebson::Element _getParentElement(mutablebson::Document& doc,
- LogComponent component) {
- // Hide LogComponent::kDefault
- if (component == LogComponent::kDefault) {
- return doc.end();
- }
- LogComponent parentComponent = component.parent();
-
- // Attach LogComponent::kDefault children to root
- if (parentComponent == LogComponent::kDefault) {
- return doc.root();
- }
- mutablebson::Element grandParentElement = _getParentElement(doc, parentComponent);
- return grandParentElement.findFirstChildNamed(parentComponent.getShortName());
- }
- } logComponentVerbositySetting;
-
- } // namespace
-
- namespace {
- class SSLModeSetting : public ServerParameter {
- public:
- SSLModeSetting() : ServerParameter(ServerParameterSet::getGlobal(), "sslMode",
- false, // allowedToChangeAtStartup
- true // allowedToChangeAtRuntime
- ) {}
-
- std::string sslModeStr() {
- switch (sslGlobalParams.sslMode.load()) {
- case SSLParams::SSLMode_disabled:
- return "disabled";
- case SSLParams::SSLMode_allowSSL:
- return "allowSSL";
- case SSLParams::SSLMode_preferSSL:
- return "preferSSL";
- case SSLParams::SSLMode_requireSSL:
- return "requireSSL";
- default:
- return "undefined";
- }
- }
+class LogLevelSetting : public ServerParameter {
+public:
+ LogLevelSetting() : ServerParameter(ServerParameterSet::getGlobal(), "logLevel") {}
- virtual void append(
- OperationContext* txn, BSONObjBuilder& b, const std::string& name) {
- b << name << sslModeStr();
- }
+ virtual void append(OperationContext* txn, BSONObjBuilder& b, const std::string& name) {
+ b << name << globalLogDomain()->getMinimumLogSeverity().toInt();
+ }
- virtual Status set(const BSONElement& newValueElement) {
- try {
- return setFromString(newValueElement.String());
- }
- catch (MsgAssertionException msg) {
- return Status(ErrorCodes::BadValue, mongoutils::str::stream() <<
- "Invalid value for sslMode via setParameter command: "
- << newValueElement);
- }
+ virtual Status set(const BSONElement& newValueElement) {
+ int newValue;
+ if (!newValueElement.coerce(&newValue) || newValue < 0)
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream()
+ << "Invalid value for logLevel: " << newValueElement);
+ LogSeverity newSeverity =
+ (newValue > 0) ? LogSeverity::Debug(newValue) : LogSeverity::Log();
+ globalLogDomain()->setMinimumLoggedSeverity(newSeverity);
+ return Status::OK();
+ }
- }
+ virtual Status setFromString(const std::string& str) {
+ int newValue;
+ Status status = parseNumberFromString(str, &newValue);
+ if (!status.isOK())
+ return status;
+ if (newValue < 0)
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream() << "Invalid value for logLevel: " << newValue);
+ LogSeverity newSeverity =
+ (newValue > 0) ? LogSeverity::Debug(newValue) : LogSeverity::Log();
+ globalLogDomain()->setMinimumLoggedSeverity(newSeverity);
+ return Status::OK();
+ }
+} logLevelSetting;
- virtual Status setFromString(const std::string& str) {
-#ifndef MONGO_CONFIG_SSL
- return Status(ErrorCodes::IllegalOperation, mongoutils::str::stream() <<
- "Unable to set sslMode, SSL support is not compiled into server");
-#endif
- if (str != "disabled" && str != "allowSSL" &&
- str != "preferSSL" && str != "requireSSL") {
- return Status(ErrorCodes::BadValue, mongoutils::str::stream() <<
- "Invalid value for sslMode via setParameter command: "
- << str);
- }
-
- int oldMode = sslGlobalParams.sslMode.load();
- if (str == "preferSSL" && oldMode == SSLParams::SSLMode_allowSSL) {
- sslGlobalParams.sslMode.store(SSLParams::SSLMode_preferSSL);
- }
- else if (str == "requireSSL" && oldMode == SSLParams::SSLMode_preferSSL) {
- sslGlobalParams.sslMode.store(SSLParams::SSLMode_requireSSL);
- }
- else {
- return Status(ErrorCodes::BadValue, mongoutils::str::stream() <<
- "Illegal state transition for sslMode, attempt to change from "
- << sslModeStr() << " to " << str);
- }
- return Status::OK();
- }
- } sslModeSetting;
-
- class ClusterAuthModeSetting : public ServerParameter {
- public:
- ClusterAuthModeSetting() :
- ServerParameter(ServerParameterSet::getGlobal(), "clusterAuthMode",
- false, // allowedToChangeAtStartup
- true // allowedToChangeAtRuntime
- ) {}
-
- std::string clusterAuthModeStr() {
- switch (serverGlobalParams.clusterAuthMode.load()) {
- case ServerGlobalParams::ClusterAuthMode_keyFile:
- return "keyFile";
- case ServerGlobalParams::ClusterAuthMode_sendKeyFile:
- return "sendKeyFile";
- case ServerGlobalParams::ClusterAuthMode_sendX509:
- return "sendX509";
- case ServerGlobalParams::ClusterAuthMode_x509:
- return "x509";
- default:
- return "undefined";
- }
+/**
+ * Log component verbosity.
+ * Log levels of log component hierarchy.
+ * Negative value for a log component means the default log level will be used.
+ */
+class LogComponentVerbositySetting : public ServerParameter {
+ MONGO_DISALLOW_COPYING(LogComponentVerbositySetting);
+
+public:
+ LogComponentVerbositySetting()
+ : ServerParameter(ServerParameterSet::getGlobal(), "logComponentVerbosity") {}
+
+ virtual void append(OperationContext* txn, BSONObjBuilder& b, const std::string& name) {
+ BSONObj currentSettings;
+ _get(&currentSettings);
+ b << name << currentSettings;
+ }
+
+ virtual Status set(const BSONElement& newValueElement) {
+ if (!newValueElement.isABSONObj()) {
+ return Status(ErrorCodes::TypeMismatch,
+ mongoutils::str::stream()
+ << "log component verbosity is not a BSON object: "
+ << newValueElement);
+ }
+ return _set(newValueElement.Obj());
+ }
+
+ virtual Status setFromString(const std::string& str) {
+ try {
+ return _set(mongo::fromjson(str));
+ } catch (const DBException& ex) {
+ return ex.toStatus();
+ }
+ }
+
+private:
+ /**
+ * Returns current settings as a BSON document.
+ * The "default" log component is an implementation detail. Don't expose this to users.
+ */
+ void _get(BSONObj* output) const {
+ static const string defaultLogComponentName =
+ LogComponent(LogComponent::kDefault).getShortName();
+
+ mutablebson::Document doc;
+
+ for (int i = 0; i < int(LogComponent::kNumLogComponents); ++i) {
+ LogComponent component = static_cast<LogComponent::Value>(i);
+
+ int severity = -1;
+ if (globalLogDomain()->hasMinimumLogSeverity(component)) {
+ severity = globalLogDomain()->getMinimumLogSeverity(component).toInt();
}
- virtual void append(
- OperationContext* txn, BSONObjBuilder& b, const std::string& name) {
- b << name << clusterAuthModeStr();
+ // Save LogComponent::kDefault LogSeverity at root
+ if (component == LogComponent::kDefault) {
+ doc.root().appendInt("verbosity", severity);
+ continue;
}
- virtual Status set(const BSONElement& newValueElement) {
- try {
- return setFromString(newValueElement.String());
- }
- catch (MsgAssertionException msg) {
- return Status(ErrorCodes::BadValue, mongoutils::str::stream() <<
- "Invalid value for clusterAuthMode via setParameter command: "
- << newValueElement);
- }
+ mutablebson::Element element = doc.makeElementObject(component.getShortName());
+ element.appendInt("verbosity", severity);
+
+ mutablebson::Element parentElement = _getParentElement(doc, component);
+ parentElement.pushBack(element);
+ }
+
+ BSONObj result = doc.getObject();
+ output->swap(result);
+ invariant(!output->hasField(defaultLogComponentName));
+ }
+
+ /**
+ * Updates component hierarchy log levels.
+ *
+ * BSON Format:
+ * {
+ * verbosity: 4, <-- maps to 'default' log component.
+ * componentA: {
+ * verbosity: 2, <-- sets componentA's log level to 2.
+ * componentB: {
+ * verbosity: 1, <-- sets componentA.componentB's log level to 1.
+ * }
+ * componentC: {
+ * verbosity: -1, <-- clears componentA.componentC's log level so that
+ * its final loglevel will be inherited from componentA.
+ * }
+ * },
+ * componentD : 3 <-- sets componentD's log level to 3 (alternative to
+ * subdocument with 'verbosity' field).
+ * }
+ *
+ * For the default component, the log level is read from the top-level
+ * "verbosity" field.
+ * For non-default components, we look up the element using the component's
+ * dotted name. If the "<dotted component name>" field is a number, the log
+ * level will be read from the field's value.
+ * Otherwise, we assume that the "<dotted component name>" field is an
+ * object with a "verbosity" field that holds the log level for the component.
+ * The more verbose format with the "verbosity" field is intended to support
+ * setting of log levels of both parent and child log components in the same
+ * BSON document.
+ *
+ * Ignore elements in BSON object that do not map to a log component's dotted
+ * name.
+ */
+ Status _set(const BSONObj& bsonSettings) const {
+ StatusWith<std::vector<LogComponentSetting>> parseStatus =
+ parseLogComponentSettings(bsonSettings);
+
+ if (!parseStatus.isOK()) {
+ return parseStatus.getStatus();
+ }
+
+ std::vector<LogComponentSetting> settings = parseStatus.getValue();
+ std::vector<LogComponentSetting>::iterator it = settings.begin();
+ for (; it < settings.end(); ++it) {
+ LogComponentSetting newSetting = *it;
+ // Negative value means to clear log level of component.
+ if (newSetting.level < 0) {
+ globalLogDomain()->clearMinimumLoggedSeverity(newSetting.component);
+ continue;
}
+ // Convert non-negative value to Log()/Debug(N).
+ LogSeverity newSeverity =
+ (newSetting.level > 0) ? LogSeverity::Debug(newSetting.level) : LogSeverity::Log();
+ globalLogDomain()->setMinimumLoggedSeverity(newSetting.component, newSeverity);
+ }
+
+ return Status::OK();
+ }
+
+ /**
+ * Search document for element corresponding to log component's parent.
+ */
+ static mutablebson::Element _getParentElement(mutablebson::Document& doc,
+ LogComponent component) {
+ // Hide LogComponent::kDefault
+ if (component == LogComponent::kDefault) {
+ return doc.end();
+ }
+ LogComponent parentComponent = component.parent();
+
+ // Attach LogComponent::kDefault children to root
+ if (parentComponent == LogComponent::kDefault) {
+ return doc.root();
+ }
+ mutablebson::Element grandParentElement = _getParentElement(doc, parentComponent);
+ return grandParentElement.findFirstChildNamed(parentComponent.getShortName());
+ }
+} logComponentVerbositySetting;
+
+} // namespace
+
+namespace {
+class SSLModeSetting : public ServerParameter {
+public:
+ SSLModeSetting()
+ : ServerParameter(ServerParameterSet::getGlobal(),
+ "sslMode",
+ false, // allowedToChangeAtStartup
+ true // allowedToChangeAtRuntime
+ ) {}
+
+ std::string sslModeStr() {
+ switch (sslGlobalParams.sslMode.load()) {
+ case SSLParams::SSLMode_disabled:
+ return "disabled";
+ case SSLParams::SSLMode_allowSSL:
+ return "allowSSL";
+ case SSLParams::SSLMode_preferSSL:
+ return "preferSSL";
+ case SSLParams::SSLMode_requireSSL:
+ return "requireSSL";
+ default:
+ return "undefined";
+ }
+ }
+
+ virtual void append(OperationContext* txn, BSONObjBuilder& b, const std::string& name) {
+ b << name << sslModeStr();
+ }
+
+ virtual Status set(const BSONElement& newValueElement) {
+ try {
+ return setFromString(newValueElement.String());
+ } catch (MsgAssertionException msg) {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream()
+ << "Invalid value for sslMode via setParameter command: "
+ << newValueElement);
+ }
+ }
- virtual Status setFromString(const std::string& str) {
+ virtual Status setFromString(const std::string& str) {
#ifndef MONGO_CONFIG_SSL
- return Status(ErrorCodes::IllegalOperation, mongoutils::str::stream() <<
- "Unable to set clusterAuthMode, " <<
- "SSL support is not compiled into server");
+ return Status(ErrorCodes::IllegalOperation,
+ mongoutils::str::stream()
+ << "Unable to set sslMode, SSL support is not compiled into server");
#endif
- if (str != "keyFile" && str != "sendKeyFile" &&
- str != "sendX509" && str != "x509") {
- return Status(ErrorCodes::BadValue, mongoutils::str::stream() <<
- "Invalid value for clusterAuthMode via setParameter command: "
- << str);
- }
-
- int oldMode = serverGlobalParams.clusterAuthMode.load();
- int sslMode = sslGlobalParams.sslMode.load();
- if (str == "sendX509" &&
- oldMode == ServerGlobalParams::ClusterAuthMode_sendKeyFile) {
- if (sslMode == SSLParams::SSLMode_disabled ||
- sslMode == SSLParams::SSLMode_allowSSL) {
- return Status(ErrorCodes::BadValue, mongoutils::str::stream() <<
- "Illegal state transition for clusterAuthMode, " <<
- "need to enable SSL for outgoing connections");
- }
- serverGlobalParams.clusterAuthMode.store
- (ServerGlobalParams::ClusterAuthMode_sendX509);
-#ifdef MONGO_CONFIG_SSL
- setInternalUserAuthParams(BSON(saslCommandMechanismFieldName <<
- "MONGODB-X509" <<
- saslCommandUserDBFieldName << "$external" <<
- saslCommandUserFieldName <<
- getSSLManager()->getSSLConfiguration()
- .clientSubjectName));
-#endif
- }
- else if (str == "x509" &&
- oldMode == ServerGlobalParams::ClusterAuthMode_sendX509) {
- serverGlobalParams.clusterAuthMode.store
- (ServerGlobalParams::ClusterAuthMode_x509);
- }
- else {
- return Status(ErrorCodes::BadValue, mongoutils::str::stream() <<
- "Illegal state transition for clusterAuthMode, change from "
- << clusterAuthModeStr() << " to " << str);
- }
- return Status::OK();
- }
- } clusterAuthModeSetting;
+ if (str != "disabled" && str != "allowSSL" && str != "preferSSL" && str != "requireSSL") {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream()
+ << "Invalid value for sslMode via setParameter command: " << str);
+ }
- ExportedServerParameter<bool> QuietSetting( ServerParameterSet::getGlobal(),
- "quiet",
- &serverGlobalParams.quiet,
- true,
- true );
+ int oldMode = sslGlobalParams.sslMode.load();
+ if (str == "preferSSL" && oldMode == SSLParams::SSLMode_allowSSL) {
+ sslGlobalParams.sslMode.store(SSLParams::SSLMode_preferSSL);
+ } else if (str == "requireSSL" && oldMode == SSLParams::SSLMode_preferSSL) {
+ sslGlobalParams.sslMode.store(SSLParams::SSLMode_requireSSL);
+ } else {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream()
+ << "Illegal state transition for sslMode, attempt to change from "
+ << sslModeStr() << " to " << str);
+ }
+ return Status::OK();
+ }
+} sslModeSetting;
+
+class ClusterAuthModeSetting : public ServerParameter {
+public:
+ ClusterAuthModeSetting()
+ : ServerParameter(ServerParameterSet::getGlobal(),
+ "clusterAuthMode",
+ false, // allowedToChangeAtStartup
+ true // allowedToChangeAtRuntime
+ ) {}
+
+ std::string clusterAuthModeStr() {
+ switch (serverGlobalParams.clusterAuthMode.load()) {
+ case ServerGlobalParams::ClusterAuthMode_keyFile:
+ return "keyFile";
+ case ServerGlobalParams::ClusterAuthMode_sendKeyFile:
+ return "sendKeyFile";
+ case ServerGlobalParams::ClusterAuthMode_sendX509:
+ return "sendX509";
+ case ServerGlobalParams::ClusterAuthMode_x509:
+ return "x509";
+ default:
+ return "undefined";
+ }
+ }
- ExportedServerParameter<int> MaxConsecutiveFailedChecksSetting(
- ServerParameterSet::getGlobal(),
- "replMonitorMaxFailedChecks",
- &ReplicaSetMonitor::maxConsecutiveFailedChecks,
- false, // allowedToChangeAtStartup
- true); // allowedToChangeAtRuntime
+ virtual void append(OperationContext* txn, BSONObjBuilder& b, const std::string& name) {
+ b << name << clusterAuthModeStr();
+ }
- ExportedServerParameter<bool> TraceExceptionsSetting(ServerParameterSet::getGlobal(),
- "traceExceptions",
- &DBException::traceExceptions,
- false, // allowedToChangeAtStartup
- true); // allowedToChangeAtRuntime
+ virtual Status set(const BSONElement& newValueElement) {
+ try {
+ return setFromString(newValueElement.String());
+ } catch (MsgAssertionException msg) {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream()
+ << "Invalid value for clusterAuthMode via setParameter command: "
+ << newValueElement);
+ }
+ }
+ virtual Status setFromString(const std::string& str) {
+#ifndef MONGO_CONFIG_SSL
+ return Status(ErrorCodes::IllegalOperation,
+ mongoutils::str::stream() << "Unable to set clusterAuthMode, "
+ << "SSL support is not compiled into server");
+#endif
+ if (str != "keyFile" && str != "sendKeyFile" && str != "sendX509" && str != "x509") {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream()
+ << "Invalid value for clusterAuthMode via setParameter command: "
+ << str);
+ }
+ int oldMode = serverGlobalParams.clusterAuthMode.load();
+ int sslMode = sslGlobalParams.sslMode.load();
+ if (str == "sendX509" && oldMode == ServerGlobalParams::ClusterAuthMode_sendKeyFile) {
+ if (sslMode == SSLParams::SSLMode_disabled || sslMode == SSLParams::SSLMode_allowSSL) {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream()
+ << "Illegal state transition for clusterAuthMode, "
+ << "need to enable SSL for outgoing connections");
+ }
+ serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_sendX509);
+#ifdef MONGO_CONFIG_SSL
+ setInternalUserAuthParams(
+ BSON(saslCommandMechanismFieldName
+ << "MONGODB-X509" << saslCommandUserDBFieldName << "$external"
+ << saslCommandUserFieldName
+ << getSSLManager()->getSSLConfiguration().clientSubjectName));
+#endif
+ } else if (str == "x509" && oldMode == ServerGlobalParams::ClusterAuthMode_sendX509) {
+ serverGlobalParams.clusterAuthMode.store(ServerGlobalParams::ClusterAuthMode_x509);
+ } else {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream()
+ << "Illegal state transition for clusterAuthMode, change from "
+ << clusterAuthModeStr() << " to " << str);
+ }
+ return Status::OK();
}
-
+} clusterAuthModeSetting;
+
+ExportedServerParameter<bool> QuietSetting(
+ ServerParameterSet::getGlobal(), "quiet", &serverGlobalParams.quiet, true, true);
+
+ExportedServerParameter<int> MaxConsecutiveFailedChecksSetting(
+ ServerParameterSet::getGlobal(),
+ "replMonitorMaxFailedChecks",
+ &ReplicaSetMonitor::maxConsecutiveFailedChecks,
+ false, // allowedToChangeAtStartup
+ true); // allowedToChangeAtRuntime
+
+ExportedServerParameter<bool> TraceExceptionsSetting(ServerParameterSet::getGlobal(),
+ "traceExceptions",
+ &DBException::traceExceptions,
+ false, // allowedToChangeAtStartup
+ true); // allowedToChangeAtRuntime
+}
}
-