diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/audit.cpp | 16 | ||||
-rw-r--r-- | src/mongo/db/audit.h | 21 | ||||
-rw-r--r-- | src/mongo/db/commands/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/commands/get_cluster_parameter_command.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/commands/set_cluster_parameter_invocation.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/commands/set_cluster_parameter_invocation.h | 4 | ||||
-rw-r--r-- | src/mongo/db/commands/set_cluster_parameter_invocation_test.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/mongod_main.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/s/config/configsvr_set_cluster_parameter_command.cpp | 6 | ||||
-rw-r--r-- | src/mongo/idl/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/idl/cluster_server_parameter_initializer.cpp | 44 | ||||
-rw-r--r-- | src/mongo/idl/cluster_server_parameter_initializer.h | 10 | ||||
-rw-r--r-- | src/mongo/idl/cluster_server_parameter_op_observer.cpp | 12 | ||||
-rw-r--r-- | src/mongo/idl/cluster_server_parameter_test.idl | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp | 3 | ||||
-rw-r--r-- | src/mongo/s/mongos_main.cpp | 5 |
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) |