summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/audit.cpp16
-rw-r--r--src/mongo/db/audit.h21
-rw-r--r--src/mongo/db/commands/SConscript1
-rw-r--r--src/mongo/db/commands/get_cluster_parameter_command.cpp3
-rw-r--r--src/mongo/db/commands/set_cluster_parameter_invocation.cpp15
-rw-r--r--src/mongo/db/commands/set_cluster_parameter_invocation.h4
-rw-r--r--src/mongo/db/commands/set_cluster_parameter_invocation_test.cpp15
-rw-r--r--src/mongo/db/mongod_main.cpp5
-rw-r--r--src/mongo/db/s/config/configsvr_set_cluster_parameter_command.cpp6
-rw-r--r--src/mongo/idl/SConscript2
-rw-r--r--src/mongo/idl/cluster_server_parameter_initializer.cpp44
-rw-r--r--src/mongo/idl/cluster_server_parameter_initializer.h10
-rw-r--r--src/mongo/idl/cluster_server_parameter_op_observer.cpp12
-rw-r--r--src/mongo/idl/cluster_server_parameter_test.idl2
-rw-r--r--src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp3
-rw-r--r--src/mongo/s/mongos_main.cpp5
16 files changed, 117 insertions, 47 deletions
diff --git a/src/mongo/db/audit.cpp b/src/mongo/db/audit.cpp
index c741b8c4e4c..23a56d48d53 100644
--- a/src/mongo/db/audit.cpp
+++ b/src/mongo/db/audit.cpp
@@ -257,6 +257,22 @@ void logRemoveOperation(Client* client, const NamespaceString& nss, const BSONOb
invariant(client);
}
+void logGetClusterParameter(
+ Client* client,
+ const stdx::variant<std::string, std::vector<std::string>>& requestedParameters) {
+ invariant(client);
+}
+
+void logSetClusterParameter(Client* client, const BSONObj& oldValue, const BSONObj& newValue) {
+ invariant(client);
+}
+
+void logUpdateCachedClusterParameter(Client* client,
+ const BSONObj& oldValue,
+ const BSONObj& newValue) {
+ invariant(client);
+}
+
#endif
} // namespace audit
diff --git a/src/mongo/db/audit.h b/src/mongo/db/audit.h
index 418c73e408c..ccd1022b268 100644
--- a/src/mongo/db/audit.h
+++ b/src/mongo/db/audit.h
@@ -416,6 +416,27 @@ void logUpdateOperation(Client* client, const NamespaceString& nss, const BSONOb
*/
void logRemoveOperation(Client* client, const NamespaceString& nss, const BSONObj& doc);
+/**
+ * Logs values of cluster server parameters requested via getClusterParameter.
+ */
+void logGetClusterParameter(
+ Client* client,
+ const stdx::variant<std::string, std::vector<std::string>>& requestedParameters);
+
+/**
+ * Logs old and new value of cluster server parameter when it is updated via setClusterParameter.
+ */
+void logSetClusterParameter(Client* client, const BSONObj& oldValue, const BSONObj& newValue);
+
+/**
+ * Logs old and new value of cluster server parameter when it gets updated in-memory in response to
+ * some on-disk change. This may be due to setClusterParameter or a replication event such as
+ * rollback.
+ */
+void logUpdateCachedClusterParameter(Client* client,
+ const BSONObj& oldValue,
+ const BSONObj& newValue);
+
} // namespace audit
} // namespace mongo
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript
index ff5f93e048a..ceaa29595f8 100644
--- a/src/mongo/db/commands/SConscript
+++ b/src/mongo/db/commands/SConscript
@@ -617,6 +617,7 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/audit',
'$BUILD_DIR/mongo/s/write_ops/cluster_write_ops',
'cluster_server_parameter_cmds_idl',
],
diff --git a/src/mongo/db/commands/get_cluster_parameter_command.cpp b/src/mongo/db/commands/get_cluster_parameter_command.cpp
index 63ef032980b..d20ba275743 100644
--- a/src/mongo/db/commands/get_cluster_parameter_command.cpp
+++ b/src/mongo/db/commands/get_cluster_parameter_command.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/audit.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/cluster_server_parameter_cmds_gen.h"
@@ -85,6 +86,8 @@ public:
std::vector<BSONObj> parameterValues;
std::vector<std::string> parameterNames;
+ audit::logGetClusterParameter(opCtx->getClient(), cmdBody);
+
// For each parameter, generate a BSON representation of it and retrieve its name.
auto makeBSON = [&](ServerParameter* requestedParameter) {
// Skip any disabled cluster parameters.
diff --git a/src/mongo/db/commands/set_cluster_parameter_invocation.cpp b/src/mongo/db/commands/set_cluster_parameter_invocation.cpp
index c422f16562d..548c5e8d448 100644
--- a/src/mongo/db/commands/set_cluster_parameter_invocation.cpp
+++ b/src/mongo/db/commands/set_cluster_parameter_invocation.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/commands/set_cluster_parameter_invocation.h"
+#include "mongo/db/audit.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/vector_clock.h"
@@ -53,11 +54,7 @@ bool SetClusterParameterInvocation::invoke(OperationContext* opCtx,
BSONElement commandElement = cmdParamObj.firstElement();
StringData parameterName = commandElement.fieldName();
- const ServerParameter* serverParameter = _sps->getIfExists(parameterName);
-
- uassert(ErrorCodes::IllegalOperation,
- str::stream() << "Unknown Cluster Parameter " << parameterName,
- serverParameter != nullptr);
+ ServerParameter* serverParameter = _sps->get(parameterName);
uassert(ErrorCodes::IllegalOperation,
"Cluster parameter value must be an object",
@@ -74,6 +71,10 @@ bool SetClusterParameterInvocation::invoke(OperationContext* opCtx,
uassertStatusOK(serverParameter->validate(update));
+ BSONObjBuilder oldValueBob;
+ serverParameter->append(opCtx, oldValueBob, parameterName.toString());
+ audit::logSetClusterParameter(opCtx->getClient(), oldValueBob.obj(), update);
+
LOGV2_DEBUG(
6432603, 2, "Updating cluster parameter on-disk", "clusterParameter"_attr = parameterName);
@@ -131,7 +132,7 @@ StatusWith<bool> ClusterParameterDBClientService::updateParameterOnDisk(
return response.getNModified() > 0 || response.getN() > 0;
}
-const ServerParameter* ClusterParameterService::getIfExists(StringData name) {
- return ServerParameterSet::getClusterParameterSet()->getIfExists(name);
+ServerParameter* ClusterParameterService::get(StringData name) {
+ return ServerParameterSet::getClusterParameterSet()->get(name);
}
} // namespace mongo
diff --git a/src/mongo/db/commands/set_cluster_parameter_invocation.h b/src/mongo/db/commands/set_cluster_parameter_invocation.h
index aeb9cc1fde7..72181fdf1fa 100644
--- a/src/mongo/db/commands/set_cluster_parameter_invocation.h
+++ b/src/mongo/db/commands/set_cluster_parameter_invocation.h
@@ -37,13 +37,13 @@ namespace mongo {
class ServerParameterService {
public:
- virtual const ServerParameter* getIfExists(StringData parameterName) = 0;
+ virtual ServerParameter* get(StringData parameterName) = 0;
virtual ~ServerParameterService() = default;
};
class ClusterParameterService final : public ServerParameterService {
public:
- const ServerParameter* getIfExists(StringData parameterName) override;
+ ServerParameter* get(StringData parameterName) override;
};
class DBClientService {
diff --git a/src/mongo/db/commands/set_cluster_parameter_invocation_test.cpp b/src/mongo/db/commands/set_cluster_parameter_invocation_test.cpp
index 960e4aebe54..a2de6514420 100644
--- a/src/mongo/db/commands/set_cluster_parameter_invocation_test.cpp
+++ b/src/mongo/db/commands/set_cluster_parameter_invocation_test.cpp
@@ -53,15 +53,14 @@ const WriteConcernOptions kMajorityWriteConcern{WriteConcernOptions::kMajority,
// Mocks
class MockParameterService : public ServerParameterService {
public:
- MockParameterService(std::function<ServerParameter*(StringData)> getIfExists)
- : getIfExistsMock(getIfExists){};
+ MockParameterService(std::function<ServerParameter*(StringData)> get) : _getMock(get){};
- const ServerParameter* getIfExists(StringData parameterName) {
- return getIfExistsMock(parameterName);
+ ServerParameter* get(StringData parameterName) {
+ return _getMock(parameterName);
}
private:
- std::function<ServerParameter*(StringData)> getIfExistsMock;
+ std::function<ServerParameter*(StringData)> _getMock;
};
class MockServerParameter : public ServerParameter {
@@ -272,7 +271,9 @@ TEST(SetClusterParameterCommand, ThrowsWhenParameterNotPresent) {
auto serviceCtx = ServiceContext::make();
auto client = serviceCtx->makeClient("SomeTest");
- auto mpsPtr = std::make_unique<MockParameterService>([&](StringData s) { return nullptr; });
+ auto mpsPtr = std::make_unique<MockParameterService>([&](StringData s) {
+ return ServerParameterSet::getClusterParameterSet()->get("doesNotExistParam"_sd);
+ });
Client* clientPtr = client.get();
@@ -291,7 +292,7 @@ TEST(SetClusterParameterCommand, ThrowsWhenParameterNotPresent) {
ASSERT_THROWS_CODE(fixture.invoke(&spyCtx, testCmd, boost::none, kMajorityWriteConcern),
DBException,
- ErrorCodes::IllegalOperation);
+ ErrorCodes::NoSuchKey);
}
} // namespace
} // namespace mongo
diff --git a/src/mongo/db/mongod_main.cpp b/src/mongo/db/mongod_main.cpp
index be1bd6fc294..8242c351a6a 100644
--- a/src/mongo/db/mongod_main.cpp
+++ b/src/mongo/db/mongod_main.cpp
@@ -382,7 +382,6 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) {
#endif
logProcessDetails(nullptr);
- audit::logStartupOptions(Client::getCurrent(), serverGlobalParams.parsedOpts);
serviceContext->setServiceEntryPoint(std::make_unique<ServiceEntryPointMongod>(serviceContext));
@@ -832,6 +831,10 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) {
}
}
+ // Startup options are written to the audit log at the end of startup so that cluster server
+ // parameters are guaranteed to have been initialized from disk at this point.
+ audit::logStartupOptions(Client::getCurrent(), serverGlobalParams.parsedOpts);
+
serviceContext->notifyStartupComplete();
#ifndef _WIN32
diff --git a/src/mongo/db/s/config/configsvr_set_cluster_parameter_command.cpp b/src/mongo/db/s/config/configsvr_set_cluster_parameter_command.cpp
index a7e6b1740b3..31a20120586 100644
--- a/src/mongo/db/s/config/configsvr_set_cluster_parameter_command.cpp
+++ b/src/mongo/db/s/config/configsvr_set_cluster_parameter_command.cpp
@@ -75,11 +75,7 @@ public:
StringData parameterName = commandElement.fieldName();
std::unique_ptr<ServerParameterService> sps =
std::make_unique<ClusterParameterService>();
- const ServerParameter* serverParameter = sps->getIfExists(parameterName);
-
- uassert(ErrorCodes::IllegalOperation,
- str::stream() << "Unknown Cluster Parameter " << parameterName,
- serverParameter != nullptr);
+ const ServerParameter* serverParameter = sps->get(parameterName);
uassert(ErrorCodes::IllegalOperation,
"Cluster parameter value must be an object",
diff --git a/src/mongo/idl/SConscript b/src/mongo/idl/SConscript
index 6861fd9821a..6ac300aaae0 100644
--- a/src/mongo/idl/SConscript
+++ b/src/mongo/idl/SConscript
@@ -70,6 +70,7 @@ env.Library(
'$BUILD_DIR/mongo/base',
],
LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/audit',
'$BUILD_DIR/mongo/db/dbdirectclient',
'$BUILD_DIR/mongo/db/repl/replica_set_aware_service',
],
@@ -126,6 +127,7 @@ env.CppUnitTest(
'cluster_server_parameter_initializer_test.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/audit',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/change_stream_options_manager',
'$BUILD_DIR/mongo/db/repl/oplog',
diff --git a/src/mongo/idl/cluster_server_parameter_initializer.cpp b/src/mongo/idl/cluster_server_parameter_initializer.cpp
index 2da3a63bbdd..0874926546d 100644
--- a/src/mongo/idl/cluster_server_parameter_initializer.cpp
+++ b/src/mongo/idl/cluster_server_parameter_initializer.cpp
@@ -30,6 +30,7 @@
#include "mongo/idl/cluster_server_parameter_initializer.h"
#include "mongo/base/string_data.h"
+#include "mongo/db/audit.h"
#include "mongo/db/repl/replica_set_aware_service.h"
#include "mongo/db/service_context.h"
#include "mongo/logv2/log.h"
@@ -58,7 +59,9 @@ ClusterServerParameterInitializer* ClusterServerParameterInitializer::get(
return &getInstance(serviceContext);
}
-void ClusterServerParameterInitializer::updateParameter(BSONObj doc, StringData mode) {
+void ClusterServerParameterInitializer::updateParameter(OperationContext* opCtx,
+ BSONObj doc,
+ StringData mode) {
auto nameElem = doc[kIdField];
if (nameElem.type() != String) {
LOGV2_DEBUG(6226301,
@@ -91,19 +94,33 @@ void ClusterServerParameterInitializer::updateParameter(BSONObj doc, StringData
return;
}
+ BSONObjBuilder oldValueBob;
+ sp->append(opCtx, oldValueBob, name.toString());
+ audit::logUpdateCachedClusterParameter(opCtx->getClient(), oldValueBob.obj(), doc);
+
uassertStatusOK(sp->set(doc));
}
-void ClusterServerParameterInitializer::clearParameter(ServerParameter* sp) {
+void ClusterServerParameterInitializer::clearParameter(OperationContext* opCtx,
+ ServerParameter* sp) {
if (sp->getClusterParameterTime() == LogicalTime::kUninitialized) {
// Nothing to clear.
return;
}
+ BSONObjBuilder oldValueBob;
+ sp->append(opCtx, oldValueBob, sp->name());
+
uassertStatusOK(sp->reset());
+
+ BSONObjBuilder newValueBob;
+ sp->append(opCtx, newValueBob, sp->name());
+
+ audit::logUpdateCachedClusterParameter(
+ opCtx->getClient(), oldValueBob.obj(), newValueBob.obj());
}
-void ClusterServerParameterInitializer::clearParameter(StringData id) {
+void ClusterServerParameterInitializer::clearParameter(OperationContext* opCtx, StringData id) {
auto* sp = ServerParameterSet::getClusterParameterSet()->getIfExists(id);
if (!sp) {
LOGV2_DEBUG(6226303,
@@ -113,20 +130,21 @@ void ClusterServerParameterInitializer::clearParameter(StringData id) {
return;
}
- clearParameter(sp);
+ clearParameter(opCtx, sp);
}
-void ClusterServerParameterInitializer::clearAllParameters() {
+void ClusterServerParameterInitializer::clearAllParameters(OperationContext* opCtx) {
const auto& params = ServerParameterSet::getClusterParameterSet()->getMap();
for (const auto& it : params) {
- clearParameter(it.second);
+ clearParameter(opCtx, it.second);
}
}
void ClusterServerParameterInitializer::initializeAllParametersFromDisk(OperationContext* opCtx) {
- doLoadAllParametersFromDisk(opCtx, "initializing"_sd, [this](BSONObj doc, StringData mode) {
- updateParameter(doc, mode);
- });
+ doLoadAllParametersFromDisk(
+ opCtx, "initializing"_sd, [this](OperationContext* opCtx, BSONObj doc, StringData mode) {
+ updateParameter(opCtx, doc, mode);
+ });
}
void ClusterServerParameterInitializer::resynchronizeAllParametersFromDisk(
@@ -138,15 +156,17 @@ void ClusterServerParameterInitializer::resynchronizeAllParametersFromDisk(
}
doLoadAllParametersFromDisk(
- opCtx, "resynchronizing"_sd, [this, &unsetSettings](BSONObj doc, StringData mode) {
+ opCtx,
+ "resynchronizing"_sd,
+ [this, &unsetSettings](OperationContext* opCtx, BSONObj doc, StringData mode) {
unsetSettings.erase(doc[kIdField].str());
- updateParameter(doc, mode);
+ updateParameter(opCtx, doc, mode);
});
// For all known settings which were not present in this resync,
// explicitly clear any value which may be present in-memory.
for (const auto& setting : unsetSettings) {
- clearParameter(setting);
+ clearParameter(opCtx, setting);
}
}
diff --git a/src/mongo/idl/cluster_server_parameter_initializer.h b/src/mongo/idl/cluster_server_parameter_initializer.h
index 0eb02bb058c..f40e48548ab 100644
--- a/src/mongo/idl/cluster_server_parameter_initializer.h
+++ b/src/mongo/idl/cluster_server_parameter_initializer.h
@@ -52,10 +52,10 @@ public:
static ClusterServerParameterInitializer* get(OperationContext* opCtx);
static ClusterServerParameterInitializer* get(ServiceContext* serviceContext);
- void updateParameter(BSONObj doc, StringData mode);
- void clearParameter(ServerParameter* sp);
- void clearParameter(StringData id);
- void clearAllParameters();
+ void updateParameter(OperationContext* opCtx, BSONObj doc, StringData mode);
+ void clearParameter(OperationContext* opCtx, ServerParameter* sp);
+ void clearParameter(OperationContext* opCtx, StringData id);
+ void clearAllParameters(OperationContext* opCtx);
/**
* Used to initialize in-memory cluster parameter state based on the on-disk contents after
@@ -94,7 +94,7 @@ private:
FindCommandRequest findRequest{NamespaceString::kClusterParametersNamespace};
client.find(std::move(findRequest), ReadPreferenceSetting{}, [&](BSONObj doc) {
try {
- onEntry(doc, mode);
+ onEntry(opCtx, doc, mode);
} catch (const DBException& ex) {
failures.push_back(ex.toStatus());
}
diff --git a/src/mongo/idl/cluster_server_parameter_op_observer.cpp b/src/mongo/idl/cluster_server_parameter_op_observer.cpp
index 27090f27e38..d8eefdfe777 100644
--- a/src/mongo/idl/cluster_server_parameter_op_observer.cpp
+++ b/src/mongo/idl/cluster_server_parameter_op_observer.cpp
@@ -69,7 +69,7 @@ void ClusterServerParameterOpObserver::onInserts(OperationContext* opCtx,
}
for (auto it = first; it != last; ++it) {
- ClusterServerParameterInitializer::get(opCtx)->updateParameter(it->doc, kOplog);
+ ClusterServerParameterInitializer::get(opCtx)->updateParameter(opCtx, it->doc, kOplog);
}
}
@@ -80,7 +80,7 @@ void ClusterServerParameterOpObserver::onUpdate(OperationContext* opCtx,
return;
}
- ClusterServerParameterInitializer::get(opCtx)->updateParameter(updatedDoc, kOplog);
+ ClusterServerParameterInitializer::get(opCtx)->updateParameter(opCtx, updatedDoc, kOplog);
}
void ClusterServerParameterOpObserver::aboutToDelete(OperationContext* opCtx,
@@ -117,7 +117,7 @@ void ClusterServerParameterOpObserver::onDelete(OperationContext* opCtx,
const OplogDeleteEntryArgs& args) {
const auto& docName = aboutToDeleteDoc(opCtx);
if (!docName.empty()) {
- ClusterServerParameterInitializer::get(opCtx)->clearParameter(docName);
+ ClusterServerParameterInitializer::get(opCtx)->clearParameter(opCtx, docName);
}
}
@@ -125,7 +125,7 @@ void ClusterServerParameterOpObserver::onDropDatabase(OperationContext* opCtx,
const std::string& dbName) {
if (dbName == NamespaceString::kConfigDb) {
// Entire config DB deleted, reset to default state.
- ClusterServerParameterInitializer::get(opCtx)->clearAllParameters();
+ ClusterServerParameterInitializer::get(opCtx)->clearAllParameters(opCtx);
}
}
@@ -137,7 +137,7 @@ repl::OpTime ClusterServerParameterOpObserver::onDropCollection(
CollectionDropType dropType) {
if (isConfigNamespace(collectionName)) {
// Entire collection deleted, reset to default state.
- ClusterServerParameterInitializer::get(opCtx)->clearAllParameters();
+ ClusterServerParameterInitializer::get(opCtx)->clearAllParameters(opCtx);
}
return {};
@@ -152,7 +152,7 @@ void ClusterServerParameterOpObserver::postRenameCollection(
bool stayTemp) {
if (isConfigNamespace(fromCollection)) {
// Same as collection dropped from a config point of view.
- ClusterServerParameterInitializer::get(opCtx)->clearAllParameters();
+ ClusterServerParameterInitializer::get(opCtx)->clearAllParameters(opCtx);
}
if (isConfigNamespace(toCollection)) {
diff --git a/src/mongo/idl/cluster_server_parameter_test.idl b/src/mongo/idl/cluster_server_parameter_test.idl
index 564d628bac5..9b19cfc03bd 100644
--- a/src/mongo/idl/cluster_server_parameter_test.idl
+++ b/src/mongo/idl/cluster_server_parameter_test.idl
@@ -49,7 +49,7 @@ structs:
strValue:
description: String value
type: string
- default: ""
+ default: '""'
server_parameters:
cspTest:
diff --git a/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp b/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp
index f67b90c765b..a86e662c947 100644
--- a/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp
+++ b/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/audit.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/cluster_server_parameter_cmds_gen.h"
@@ -85,6 +86,8 @@ public:
request().getCommandParameter();
ServerParameterSet* clusterParameters = ServerParameterSet::getClusterParameterSet();
+ audit::logGetClusterParameter(opCtx->getClient(), cmdBody);
+
std::vector<std::string> requestedParameterNames;
BSONObjBuilder queryDocBuilder;
BSONObjBuilder inObjBuilder = queryDocBuilder.subobjStart("_id"_sd);
diff --git a/src/mongo/s/mongos_main.cpp b/src/mongo/s/mongos_main.cpp
index 39aca129b84..8927a858ee0 100644
--- a/src/mongo/s/mongos_main.cpp
+++ b/src/mongo/s/mongos_main.cpp
@@ -650,7 +650,6 @@ ExitCode runMongosServer(ServiceContext* serviceContext) {
ThreadClient tc("mongosMain", serviceContext);
logMongosVersionInfo(nullptr);
- audit::logStartupOptions(tc.get(), serverGlobalParams.parsedOpts);
// Set up the periodic runner for background job execution
{
@@ -808,6 +807,10 @@ ExitCode runMongosServer(ServiceContext* serviceContext) {
return EXIT_NET_ERROR;
}
+ // Startup options are written to the audit log at the end of startup so that cluster server
+ // parameters are guaranteed to have been initialized from disk at this point.
+ audit::logStartupOptions(tc.get(), serverGlobalParams.parsedOpts);
+
serviceContext->notifyStartupComplete();
#if !defined(_WIN32)