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-01-26 16:55:16 +0000
commitaae909d4cfba1621ccaf5d6168b89a0577d4e0ca (patch)
treed141f4ec2fee63d5ababbc2bca4363da0bbb37e0
parent5ff2fd561d48c390a03e0d27239e3e378203634b (diff)
downloadmongo-aae909d4cfba1621ccaf5d6168b89a0577d4e0ca.tar.gz
SERVER-58506 Expose Server-Parameter Settability
-rw-r--r--etc/backports_required_for_multiversion_tests.yml4
-rw-r--r--jstests/noPassthrough/getParameterWithDetails.js119
-rw-r--r--src/mongo/db/commands/parameters.cpp44
-rw-r--r--src/mongo/idl/SConscript2
-rw-r--r--src/mongo/idl/server_parameter.idl49
5 files changed, 210 insertions, 8 deletions
diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml
index a6ab07267b6..da2cbbb6aa2 100644
--- a/etc/backports_required_for_multiversion_tests.yml
+++ b/etc/backports_required_for_multiversion_tests.yml
@@ -124,6 +124,8 @@ last-continuous:
test_file: jstests/sharding/coordinate_txn_commit_with_tickets_exhausted.js
- ticket: SERVER-60685
test_file: jstests/sharding/cancel_coordinate_txn_commit_with_tickets_exhausted.js
+ - ticket: SERVER-58506
+ test_file: jstests/noPassthrough/getParameterWithDetails.js
- ticket: SERVER-57766
test_file: jstests/sharding/resharding_metrics.js
- ticket: SERVER-61757
@@ -411,6 +413,8 @@ last-lts:
test_file: jstests/sharding/coordinate_txn_commit_with_tickets_exhausted.js
- ticket: SERVER-60685
test_file: jstests/sharding/cancel_coordinate_txn_commit_with_tickets_exhausted.js
+ - ticket: SERVER-58506
+ test_file: jstests/noPassthrough/getParameterWithDetails.js
- ticket: SERVER-57766
test_file: jstests/sharding/resharding_metrics.js
- ticket: SERVER-61757
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 b08a9ec2003..ea32db50df2 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"
@@ -44,6 +45,7 @@
#include "mongo/db/storage/kv/kv_engine.h"
#include "mongo/db/storage/storage_options.h"
#include "mongo/idl/command_generic_argument.h"
+#include "mongo/idl/server_parameter_gen.h"
#include "mongo/logv2/log.h"
#include "mongo/util/str.h"
@@ -186,6 +188,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;
@@ -213,26 +228,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().str() == "*";
+ BSONObjBuilder& result) override {
+ const auto options = parseGetParameterOptions(cmdObj.firstElement());
+ const bool all = options.getAllParameters();
int before = result.len();
- for (const auto& param : ServerParameterSet::getNodeParameterSet()->getMap()) {
- if (all || cmdObj.hasElement(param.first.c_str())) {
- param.second->append(opCtx, result, param.second->name());
+ const ServerParameter::Map& m = ServerParameterSet::getNodeParameterSet()->getMap();
+ for (ServerParameter::Map::const_iterator i = m.begin(); i != m.end(); ++i) {
+ if (all || cmdObj.hasElement(i->first.c_str())) {
+ 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 32815fc5a26..9f05ee0f7f0 100644
--- a/src/mongo/idl/SConscript
+++ b/src/mongo/idl/SConscript
@@ -37,10 +37,12 @@ env.Library(
target='server_parameter',
source=[
'server_parameter.cpp',
+ 'server_parameter.idl',
'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