summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/base/shim.h66
-rw-r--r--src/mongo/db/auth/authorization_manager_global.cpp5
-rw-r--r--src/mongo/db/catalog/SConscript7
3 files changed, 70 insertions, 8 deletions
diff --git a/src/mongo/base/shim.h b/src/mongo/base/shim.h
index a782109d24d..14de94df7c8 100644
--- a/src/mongo/base/shim.h
+++ b/src/mongo/base/shim.h
@@ -193,6 +193,15 @@ const bool checkShimsViaTUHook = false;
} \
}
+
+/**
+ * Evaluates to a string which represents the `MONGO_INITIALIZER` step name in which this specific
+ * shim is registered. This can be useful to make sure that some initializers depend upon a shim's
+ * execution and presence in a binary.
+ */
+#define MONGO_SHIM_DEPENDENCY(...) MONGO_SHIM_EVIL_STRINGIFY_(__VA_ARGS__)
+#define MONGO_SHIM_EVIL_STRINGIFY_(args) #args
+
/**
* Define a shimmable function with name `SHIM_NAME`, returning a value of type `RETURN_TYPE`, with
* any arguments. This shim definition macro should go in the associated C++ file to the header
@@ -205,20 +214,25 @@ const bool checkShimsViaTUHook = false;
namespace { \
namespace shim_namespace##LN { \
using ShimType = decltype(__VA_ARGS__); \
+ ::mongo::Status initializerGroupStartup(::mongo::InitializerContext*) { \
+ return Status::OK(); \
+ } \
+ ::mongo::GlobalInitializerRegisterer _mongoInitializerRegisterer( \
+ std::string(MONGO_SHIM_DEPENDENCY(__VA_ARGS__)), \
+ {}, \
+ {MONGO_SHIM_DEPENDENTS}, \
+ mongo::InitializerFunction(initializerGroupStartup)); \
} /*namespace shim_namespace*/ \
} /*namespace*/ \
shim_namespace##LN::ShimType::MongoShimImplGuts::LibTUHookTypeBase::LibTUHookTypeBase() = \
default; \
shim_namespace##LN::ShimType __VA_ARGS__{};
-#define MONGO_SHIM_EVIL_STRINGIFY_(args) #args
-
-
/**
* Define an implementation of a shimmable function with name `SHIM_NAME`. The compiler will check
* supplied parameters for correctness. This shim registration macro should go in the associated
* C++ implementation file to the header where a SHIM was defined. Such a file would be a mock
- * implementation or a real implementation, for example
+ * implementation or a real implementation, for example.
*/
#define MONGO_REGISTER_SHIM(/*SHIM_NAME*/...) MONGO_REGISTER_SHIM_1(__LINE__, __VA_ARGS__)
#define MONGO_REGISTER_SHIM_1(LN, ...) MONGO_REGISTER_SHIM_2(LN, __VA_ARGS__)
@@ -240,9 +254,9 @@ const bool checkShimsViaTUHook = false;
} \
\
const ::mongo::GlobalInitializerRegisterer registrationHook{ \
- std::string(MONGO_SHIM_EVIL_STRINGIFY_(__VA_ARGS__)), \
+ std::string(MONGO_SHIM_DEPENDENCY(__VA_ARGS__) "_registration"), \
{}, \
- {MONGO_SHIM_DEPENDENTS}, \
+ {MONGO_SHIM_DEPENDENCY(__VA_ARGS__), MONGO_SHIM_DEPENDENTS}, \
mongo::InitializerFunction(createInitializerRegistration)}; \
} /*namespace shim_namespace*/ \
} /*namespace*/ \
@@ -255,3 +269,43 @@ const bool checkShimsViaTUHook = false;
and return value (using arrow \
notation). Then they write the \
body. */
+
+/**
+ * Define an overriding implementation of a shimmable function with `SHIM_NAME`. The compiler will
+ * check the supplied parameters for correctness. This shim override macro should go in the
+ * associated C++ implementation file to the header where a SHIM was defined. Such a file
+ * specifying an override would be a C++ implementation used by a mongodb extension module.
+ * This creates a runtime dependency upon the original registration being linked in.
+ */
+#define MONGO_OVERRIDE_SHIM(/*SHIM_NAME*/...) MONGO_OVERRIDE_SHIM_1(__LINE__, __VA_ARGS__)
+#define MONGO_OVERRIDE_SHIM_1(LN, ...) MONGO_OVERRIDE_SHIM_2(LN, __VA_ARGS__)
+#define MONGO_OVERRIDE_SHIM_2(LN, ...) \
+ namespace { \
+ namespace shim_namespace##LN { \
+ using ShimType = decltype(__VA_ARGS__); \
+ \
+ class OverrideImplementation final : public ShimType::MongoShimImplGuts { \
+ /* Some compilers don't work well with the trailing `override` in this kind of \
+ * function declaration. */ \
+ ShimType::MongoShimImplGuts::function_type implementation; /* override */ \
+ }; \
+ \
+ ::mongo::Status createInitializerOverride(::mongo::InitializerContext* const) { \
+ static OverrideImplementation overrideImpl; \
+ ShimType::storage::data = &overrideImpl; \
+ return Status::OK(); \
+ } \
+ \
+ const ::mongo::GlobalInitializerRegisterer overrideHook{ \
+ std::string(MONGO_SHIM_DEPENDENCY(__VA_ARGS__) "_override"), \
+ {MONGO_SHIM_DEPENDENCY( \
+ __VA_ARGS__) "_registration"}, /* Override happens after first registration */ \
+ {MONGO_SHIM_DEPENDENCY(__VA_ARGS__), /* Provides impl for this shim */ \
+ MONGO_SHIM_DEPENDENTS}, /* Still a shim registration */ \
+ mongo::InitializerFunction(createInitializerOverride)}; \
+ } /*namespace shim_namespace*/ \
+ } /*namespace*/ \
+ \
+ auto shim_namespace##LN::OverrideImplementation:: \
+ implementation /* After this point someone just writes the signature's arguments and \
+ return value (using arrow notation). Then they write the body. */
diff --git a/src/mongo/db/auth/authorization_manager_global.cpp b/src/mongo/db/auth/authorization_manager_global.cpp
index b626c3b5573..3f8a8808d04 100644
--- a/src/mongo/db/auth/authorization_manager_global.cpp
+++ b/src/mongo/db/auth/authorization_manager_global.cpp
@@ -93,7 +93,10 @@ MONGO_EXPORT_STARTUP_SERVER_PARAMETER(startupAuthSchemaValidation, bool, true);
GlobalInitializerRegisterer authorizationManagerInitializer(
"CreateAuthorizationManager",
- {"OIDGeneration", "EndStartupOptionStorage", "ServiceContext"},
+ {MONGO_SHIM_DEPENDENCY(AuthorizationManager::create),
+ "OIDGeneration",
+ "EndStartupOptionStorage",
+ "ServiceContext"},
[](InitializerContext* context) {
auto authzManager = AuthorizationManager::create();
authzManager->setAuthEnabled(serverGlobalParams.authState ==
diff --git a/src/mongo/db/catalog/SConscript b/src/mongo/db/catalog/SConscript
index 259ea12ab77..5ced8ff384b 100644
--- a/src/mongo/db/catalog/SConscript
+++ b/src/mongo/db/catalog/SConscript
@@ -103,6 +103,7 @@ env.Library(
"index_catalog.cpp",
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/base',
],
)
@@ -112,6 +113,7 @@ env.Library(
"index_catalog_entry.cpp",
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/base',
],
)
@@ -158,9 +160,10 @@ env.CppUnitTest(
env.Library(
target='database_holder',
source=[
- "database_holder.cpp",
+ 'database_holder.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/base',
],
)
@@ -170,6 +173,7 @@ env.Library(
'collection_info_cache.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/base',
],
)
@@ -179,6 +183,7 @@ env.Library(
'index_create.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/base',
],
)