diff options
author | Nick Zolnierz <nicholas.zolnierz@mongodb.com> | 2019-01-11 18:22:37 -0500 |
---|---|---|
committer | Nick Zolnierz <nicholas.zolnierz@mongodb.com> | 2019-01-11 18:27:35 -0500 |
commit | 587ad0e175cb501e378f4aeaf37199dbb28dd011 (patch) | |
tree | f3ffab15d358d9ef9559e570ce26e9da14ea376f | |
parent | 1006d88b7522a11ed34ba1a751678ea7f7637754 (diff) | |
download | mongo-587ad0e175cb501e378f4aeaf37199dbb28dd011.tar.gz |
SERVER-38191 Enforce restriction on namespace for failpoints in write_ops
-rw-r--r-- | jstests/noPassthrough/out_max_time_ms.js | 17 | ||||
-rw-r--r-- | jstests/sharding/out_stale_unique_key.js | 6 | ||||
-rw-r--r-- | src/mongo/db/curop_failpoint_helpers.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/curop_failpoint_helpers.h | 3 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.cpp | 25 |
5 files changed, 45 insertions, 17 deletions
diff --git a/jstests/noPassthrough/out_max_time_ms.js b/jstests/noPassthrough/out_max_time_ms.js index b4d2b6f41b2..dcad3c5c071 100644 --- a/jstests/noPassthrough/out_max_time_ms.js +++ b/jstests/noPassthrough/out_max_time_ms.js @@ -45,11 +45,20 @@ // use the 'maxTimeNeverTimeOut' failpoint to ensure that the operation does not // prematurely time out. const maxTimeMS = 1000 * 2; - const kFailPointName = - mode == "replaceDocuments" ? "hangDuringBatchUpdate" : "hangDuringBatchInsert"; + // Enable a failPoint so that the write will hang. - assert.commandWorked(connToHang.getDB("admin").runCommand( - {configureFailPoint: failPointName, mode: "alwaysOn"})); + let failpointCommand = { + configureFailPoint: failPointName, + mode: "alwaysOn", + data: {nss: kDBName + "." + kDestCollName} + }; + + // For mode "replaceCollection", the namespace of the writes will be to a temp namespace so + // remove the restriction on nss. + if (mode == "replaceCollection") + delete failpointCommand.data; + + assert.commandWorked(connToHang.getDB("admin").runCommand(failpointCommand)); // Make sure we don't run out of time before the failpoint is hit. assert.commandWorked(connToHang.getDB("admin").runCommand( diff --git a/jstests/sharding/out_stale_unique_key.js b/jstests/sharding/out_stale_unique_key.js index d42fffa0b51..02e4e36e0c5 100644 --- a/jstests/sharding/out_stale_unique_key.js +++ b/jstests/sharding/out_stale_unique_key.js @@ -159,11 +159,13 @@ // the inserts or updates. testEpochChangeDuringAgg({ outSpec: {to: target.getName(), mode: "insertDocuments"}, - failpoint: "hangDuringBatchInsert" + failpoint: "hangDuringBatchInsert", + failpointData: {nss: target.getFullName()} }); testEpochChangeDuringAgg({ outSpec: {to: target.getName(), mode: "replaceDocuments"}, - failpoint: "hangDuringBatchUpdate" + failpoint: "hangDuringBatchUpdate", + failpointData: {nss: target.getFullName()} }); st.stop(); diff --git a/src/mongo/db/curop_failpoint_helpers.cpp b/src/mongo/db/curop_failpoint_helpers.cpp index 4df9311cc6d..fb78284f6f8 100644 --- a/src/mongo/db/curop_failpoint_helpers.cpp +++ b/src/mongo/db/curop_failpoint_helpers.cpp @@ -49,12 +49,19 @@ void CurOpFailpointHelpers::waitWhileFailPointEnabled(FailPoint* failPoint, OperationContext* opCtx, const std::string& curOpMsg, const std::function<void(void)>& whileWaiting, - bool checkForInterrupt) { + bool checkForInterrupt, + boost::optional<NamespaceString> nss) { + invariant(failPoint); MONGO_FAIL_POINT_BLOCK((*failPoint), options) { + const BSONObj& data = options.getData(); + StringData fpNss = data.getStringField("nss"); + if (nss && !fpNss.empty() && fpNss != nss.get().toString()) { + return; + } + auto origCurOpMsg = updateCurOpMsg(opCtx, curOpMsg); - const BSONObj& data = options.getData(); const bool shouldCheckForInterrupt = checkForInterrupt || data["shouldCheckForInterrupt"].booleanSafe(); while (MONGO_FAIL_POINT((*failPoint))) { diff --git a/src/mongo/db/curop_failpoint_helpers.h b/src/mongo/db/curop_failpoint_helpers.h index acdf01b9889..84f15caecb1 100644 --- a/src/mongo/db/curop_failpoint_helpers.h +++ b/src/mongo/db/curop_failpoint_helpers.h @@ -55,6 +55,7 @@ public: OperationContext* opCtx, const std::string& curOpMsg, const std::function<void(void)>& whileWaiting = nullptr, - bool checkForInterrupt = false); + bool checkForInterrupt = false, + boost::optional<NamespaceString> nss = boost::none); }; } diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index 23072437272..bf46d4fe3eb 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -355,12 +355,14 @@ bool insertBatchAndHandleErrors(OperationContext* opCtx, &hangDuringBatchInsert, opCtx, "hangDuringBatchInsert", - []() { - log() << "batch insert - hangDuringBatchInsert fail point enabled. Blocking " - "until fail point is disabled."; + [wholeOp]() { + log() + << "batch insert - hangDuringBatchInsert fail point enabled for namespace " + << wholeOp.getNamespace() << ". Blocking " + "until fail point is disabled."; }, - true // Check for interrupt periodically. - ); + true, // Check for interrupt periodically. + wholeOp.getNamespace()); if (MONGO_FAIL_POINT(failAllInserts)) { uasserted(ErrorCodes::InternalError, "failAllInserts failpoint active!"); @@ -568,11 +570,18 @@ static SingleWriteResult performSingleUpdateOp(OperationContext* opCtx, boost::optional<AutoGetCollection> collection; while (true) { + const auto checkForInterrupt = false; CurOpFailpointHelpers::waitWhileFailPointEnabled( - &hangDuringBatchUpdate, opCtx, "hangDuringBatchUpdate", [opCtx]() { - log() << "batch update - hangDuringBatchUpdate fail point enabled. Blocking until " + &hangDuringBatchUpdate, + opCtx, + "hangDuringBatchUpdate", + [ns]() { + log() << "batch update - hangDuringBatchUpdate fail point enabled for nss " << ns + << ". Blocking until " "fail point is disabled."; - }); + }, + checkForInterrupt, + ns); if (MONGO_FAIL_POINT(failAllUpdates)) { uasserted(ErrorCodes::InternalError, "failAllUpdates failpoint active!"); |