summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/replsets/uninitialized_fcv_access.js32
-rw-r--r--src/mongo/base/error_codes.err1
-rw-r--r--src/mongo/db/commands/feature_compatibility_version.cpp4
3 files changed, 37 insertions, 0 deletions
diff --git a/jstests/replsets/uninitialized_fcv_access.js b/jstests/replsets/uninitialized_fcv_access.js
new file mode 100644
index 00000000000..f4cdfae7674
--- /dev/null
+++ b/jstests/replsets/uninitialized_fcv_access.js
@@ -0,0 +1,32 @@
+/**
+ * Test that attempting to call getParameter on the featureCompatibilityVersion before the fCV is
+ * initialized does not crash the server (see SERVER-34600).
+ */
+(function() {
+ 'use strict';
+ load('jstests/libs/feature_compatibility_version.js');
+
+ let rst = new ReplSetTest({nodes: 2});
+ rst.startSet();
+ let node = rst.nodes[0];
+
+ // The featureCompatibilityVersion parameter is initialized during rst.initiate(), so calling
+ // getParameter on the fCV before then will attempt to access an uninitialized fCV.
+
+ const getParamCmd = {getParameter: 1, featureCompatibilityVersion: 1};
+ assert.commandFailedWithCode(node.getDB('admin').runCommand(getParamCmd),
+ ErrorCodes.UnknownFeatureCompatibilityVersion,
+ 'expected ' + tojson(getParamCmd) +
+ ' to fail with code UnknownFeatureCompatibilityVersion');
+
+ rst.initiate();
+
+ // After the replica set is initialized, getParameter should successfully return the fCV.
+
+ const primary = rst.getPrimary();
+ const res = primary.adminCommand(getParamCmd);
+ assert.commandWorked(res);
+ assert.eq(res.featureCompatibilityVersion.version, latestFCV, tojson(res));
+
+ rst.stopSet();
+})();
diff --git a/src/mongo/base/error_codes.err b/src/mongo/base/error_codes.err
index 023bd887318..dceb57de618 100644
--- a/src/mongo/base/error_codes.err
+++ b/src/mongo/base/error_codes.err
@@ -255,6 +255,7 @@ error_code("FreeMonHttpTemporaryFailure", 254)
error_code("FreeMonHttpPermanentFailure", 255)
error_code("TransactionCommitted", 256)
error_code("TransactionTooLarge", 257)
+error_code("UnknownFeatureCompatibilityVersion", 258);
# Error codes 4000-8999 are reserved.
diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp
index 20935c0a4f2..a387b69d2a0 100644
--- a/src/mongo/db/commands/feature_compatibility_version.cpp
+++ b/src/mongo/db/commands/feature_compatibility_version.cpp
@@ -289,6 +289,10 @@ public:
virtual void append(OperationContext* opCtx, BSONObjBuilder& b, const std::string& name) {
BSONObjBuilder featureCompatibilityVersionBuilder(b.subobjStart(name));
+ uassert(ErrorCodes::UnknownFeatureCompatibilityVersion,
+ str::stream() << FeatureCompatibilityVersionParser::kParameterName
+ << " is not yet known.",
+ serverGlobalParams.featureCompatibility.isVersionInitialized());
switch (serverGlobalParams.featureCompatibility.getVersion()) {
case ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo40:
featureCompatibilityVersionBuilder.append(