summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Wangensteen <george.wangensteen@mongodb.com>2022-01-26 16:15:16 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-22 19:50:59 +0000
commit202bb249a89ff323bea395a82974f99addefc431 (patch)
treebf42f73319d46a9986876b6b7c9d67e75682c638
parentf4f4f60996502bce2bdc707aff2de6f9597f2036 (diff)
downloadmongo-202bb249a89ff323bea395a82974f99addefc431.tar.gz
SERVER-58506 Expose Server-Parameter Settability
(cherry picked from commit aae909d4cfba1621ccaf5d6168b89a0577d4e0ca)
-rw-r--r--etc/backports_required_for_multiversion_tests.yml2
-rw-r--r--jstests/noPassthrough/getParameterWithDetails.js119
-rw-r--r--src/mongo/db/commands/parameters.cpp39
-rw-r--r--src/mongo/idl/SConscript2
-rw-r--r--src/mongo/idl/server_parameter.idl49
5 files changed, 205 insertions, 6 deletions
diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml
index c62d42aab5f..fdd3987f44d 100644
--- a/etc/backports_required_for_multiversion_tests.yml
+++ b/etc/backports_required_for_multiversion_tests.yml
@@ -124,6 +124,8 @@ all:
test_file: jstests/sharding/collation_shard_targeting_hashed_shard_key.js
- ticket: SERVER-57588
test_file: jstests/core/match_numeric_components.js
+ - ticket: SERVER-58506
+ test_file: jstests/noPassthrough/getParameterWithDetails.js
- ticket: SERVER-60682
test_file: jstests/sharding/coordinate_txn_commit_with_tickets_exhausted.js
- ticket: SERVER-60685
diff --git a/jstests/noPassthrough/getParameterWithDetails.js b/jstests/noPassthrough/getParameterWithDetails.js
new file mode 100644
index 00000000000..519970e9030
--- /dev/null
+++ b/jstests/noPassthrough/getParameterWithDetails.js
@@ -0,0 +1,119 @@
+// Test getParameter on mongod and mongos, including the with-detail syntax.
+//
+// @tags: [requires_replication, requires_sharding]
+
+(() => {
+ 'use strict';
+ const st = new ShardingTest({shards: 1, mongos: 1});
+ const mongosDB = st.s0.getDB("admin");
+ const shardDB = st.shard0.getDB("admin");
+
+ function checkSpecificParameters(dbConn, parameters) {
+ const plainCommand = {getParameter: 1};
+ const detailCommand = {getParameter: {showDetails: true}};
+
+ // Append requests to retrieve specific parameters.
+ parameters.forEach((parameter) => {
+ plainCommand[parameter["name"]] = 1;
+ detailCommand[parameter["name"]] = 1;
+ });
+
+ // Fetch results
+ const resultsPlain = assert.commandWorked(dbConn.adminCommand(plainCommand));
+ const resultsWithDetail = assert.commandWorked(dbConn.adminCommand(detailCommand));
+
+ // Ensure requested parameters had expected values and detail information.
+ parameters.forEach((parameter) => {
+ const expectedDetailedResultObj = parameter["result"];
+ const expectedValue = expectedDetailedResultObj["value"];
+ const plainErrMsg = "Expecting plain result to contain: " + tojson(parameter) +
+ "but found: " + tojson(resultsPlain);
+ const detailErrMsg = "Expecting detail result to contain: " + tojson(parameter) +
+ "but found: " + tojson(resultsWithDetail);
+
+ assert.eq(resultsPlain[parameter["name"]], expectedValue, plainErrMsg);
+ assert.docEq(
+ resultsWithDetail[parameter["name"]], expectedDetailedResultObj, detailErrMsg);
+ });
+ }
+
+ function checkAllParameters(dbConn) {
+ const plainCommand = {getParameter: '*'};
+ const detailCommand = {getParameter: {showDetails: true, allParameters: true}};
+
+ // Fetch results
+ let resultsPlain = assert.commandWorked(dbConn.adminCommand(plainCommand));
+ let resultsWithDetail = assert.commandWorked(dbConn.adminCommand(detailCommand));
+
+ // Ensure results are consistent between syntaxes. We don't check for explicit expected
+ // values here to avoid the need to specify them for every parameter and update this file
+ // every time one is added or changes in value.
+ Object.keys(resultsWithDetail).forEach((k) => {
+ if (resultsWithDetail[k].hasOwnProperty("value")) {
+ assert.eq(resultsWithDetail[k]["value"],
+ resultsPlain[k],
+ "In all parameters, mismatch for parameter " + k + ":" +
+ tojson(resultsWithDetail[k]) + " vs " + tojson(resultsPlain[k]));
+ }
+ });
+ Object.keys(resultsPlain).forEach((k) => {
+ assert(resultsWithDetail.hasOwnProperty(k));
+ if (resultsWithDetail[k].hasOwnProperty("value")) {
+ assert.eq(resultsPlain[k], resultsWithDetail[k]["value"]);
+ }
+ });
+ }
+
+ // Each of the entries in the following array is an object with two keys, "name" and "result".
+ // "name" is the name of a server parameter, and "result" is the expected object
+ // getParameter should return for that parameter, when details are requested.
+ const specificParametersBothProcesses = [
+ {
+ name: "ShardingTaskExecutorPoolMinSize",
+ result: {value: 1, settableAtRuntime: true, settableAtStartup: true}
+ },
+ {
+ name: "maxLogSizeKB",
+ result: {value: 10, settableAtRuntime: true, settableAtStartup: true}
+ },
+ {
+ name: "cursorTimeoutMillis",
+ result: {value: NumberLong(600000), settableAtRuntime: true, settableAtStartup: true}
+ }
+ ];
+ const specificParametersMongodOnly = [
+ {
+ name: "ttlMonitorEnabled",
+ result: {value: true, settableAtRuntime: true, settableAtStartup: true}
+ },
+ {
+ name: "wiredTigerMaxCacheOverflowSizeGB",
+ result: {value: 0, settableAtRuntime: true, settableAtStartup: false}
+ },
+ {
+ name: "shardedIndexConsistencyCheckIntervalMS",
+ result: {value: 600000, settableAtRuntime: false, settableAtStartup: true}
+ },
+ ];
+ const specificParametersMongosOnly = [
+ {
+ name: "taskExecutorPoolSize",
+ result: {value: 1, settableAtRuntime: true, settableAtStartup: true}
+ },
+ {
+ name: "userCacheInvalidationIntervalSecs",
+ result: {value: 30, settableAtRuntime: true, settableAtStartup: true}
+ },
+ ];
+
+ checkSpecificParameters(mongosDB, specificParametersBothProcesses);
+ checkSpecificParameters(shardDB, specificParametersBothProcesses);
+
+ checkSpecificParameters(shardDB, specificParametersMongodOnly);
+ checkSpecificParameters(mongosDB, specificParametersMongosOnly);
+
+ checkAllParameters(mongosDB);
+ checkAllParameters(shardDB);
+
+ st.stop();
+})();
diff --git a/src/mongo/db/commands/parameters.cpp b/src/mongo/db/commands/parameters.cpp
index 8e0802b0c15..33f7e323e32 100644
--- a/src/mongo/db/commands/parameters.cpp
+++ b/src/mongo/db/commands/parameters.cpp
@@ -33,6 +33,7 @@
#include <set>
+#include "mongo/bson/bsontypes.h"
#include "mongo/bson/json.h"
#include "mongo/bson/mutable/document.h"
#include "mongo/client/replica_set_monitor.h"
@@ -42,6 +43,7 @@
#include "mongo/db/commands.h"
#include "mongo/db/commands/parameters_gen.h"
#include "mongo/db/storage/storage_options.h"
+#include "mongo/idl/server_parameter_gen.h"
#include "mongo/logger/logger.h"
#include "mongo/logger/parse_log_component_settings.h"
#include "mongo/util/log.h"
@@ -184,6 +186,19 @@ Status setLogComponentVerbosity(const BSONObj& bsonSettings) {
return Status::OK();
}
+
+GetParameterOptions parseGetParameterOptions(BSONElement elem) {
+ if (elem.type() == BSONType::Object) {
+ return GetParameterOptions::parse({"getParameter"}, elem.Obj());
+ }
+ if ((elem.type() == BSONType::String) && (elem.valueStringDataSafe() == "*"_sd)) {
+ GetParameterOptions ret;
+ ret.setAllParameters(true);
+ return ret;
+ }
+ return GetParameterOptions{};
+}
+
// for automationServiceDescription
Mutex autoServiceDescriptorMutex;
std::string autoServiceDescriptorValue;
@@ -211,27 +226,39 @@ public:
std::string help() const override {
std::string h =
"get administrative option(s)\nexample:\n"
- "{ getParameter:1, notablescan:1 }\n";
+ "{ getParameter:1, notablescan:1 }\n"
+ "pass a document as the value for getParameter to request options\nexample:\n"
+ "{ getParameter:{showDetails: true}, notablescan:1}\n";
appendParameterNames(&h);
- h += "{ getParameter:'*' } to get everything\n";
+ h += "{ getParameter:'*' } or { getParameter:{allParameters: true} } to get everything\n";
return h;
}
bool errmsgRun(OperationContext* opCtx,
const string& dbname,
const BSONObj& cmdObj,
string& errmsg,
- BSONObjBuilder& result) {
- bool all = *cmdObj.firstElement().valuestrsafe() == '*';
+ BSONObjBuilder& result) override {
+ const auto options = parseGetParameterOptions(cmdObj.firstElement());
+ const bool all = options.getAllParameters();
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(opCtx, result, i->second->name());
+ if (options.getShowDetails()) {
+ BSONObjBuilder detailBob(result.subobjStart(i->second->name()));
+ i->second->append(opCtx, detailBob, "value");
+ detailBob.appendBool("settableAtRuntime",
+ i->second->allowedToChangeAtRuntime());
+ detailBob.appendBool("settableAtStartup",
+ i->second->allowedToChangeAtStartup());
+ detailBob.doneFast();
+ } else {
+ i->second->append(opCtx, result, i->second->name());
+ }
}
}
-
if (before == result.len()) {
errmsg = "no option found to get";
return false;
diff --git a/src/mongo/idl/SConscript b/src/mongo/idl/SConscript
index 0ce5bf975dc..e72dd9ed71e 100644
--- a/src/mongo/idl/SConscript
+++ b/src/mongo/idl/SConscript
@@ -32,10 +32,12 @@ env.Library(
target='server_parameter',
source=[
'server_parameter.cpp',
+ env.Idlc('server_parameter.idl')[0],
'server_parameter_with_storage.cpp',
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
+ 'idl_parser',
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/util/options_parser/options_parser',
diff --git a/src/mongo/idl/server_parameter.idl b/src/mongo/idl/server_parameter.idl
new file mode 100644
index 00000000000..2fb39ad0815
--- /dev/null
+++ b/src/mongo/idl/server_parameter.idl
@@ -0,0 +1,49 @@
+# Copyright (C) 2022-present MongoDB, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the Server Side Public License, version 1,
+# as published by MongoDB, Inc.
+#
+# 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
+# Server Side Public License for more details.
+#
+# You should have received a copy of the Server Side Public License
+# along with this program. If not, see
+# <http://www.mongodb.com/licensing/server-side-public-license>.
+#
+# 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 Server Side 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.
+#
+# IDL constructs useful for all server parameters.
+
+global:
+ cpp_namespace: "mongo"
+
+imports:
+ - "mongo/idl/basic_types.idl"
+
+# Options for the getParameter command. Describes the object "options" when the command is run as
+# {getParameter: <options>}
+structs:
+ GetParameterOptions:
+ description: 'Optional flags to pass to {getParameter: options, ...}'
+ fields:
+ showDetails:
+ description: 'Return metadata about the server parameter along with its current value'
+ type: safeBool
+ default: false
+ allParameters:
+ description: 'Return all server parameters, not just the ones specified'
+ type: safeBool
+ default: false