summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2018-10-26 12:06:36 -0400
committerEric Milkie <milkie@10gen.com>2018-12-07 08:26:28 -0500
commitbdcf088d3c90a4fe6e9c4f23559a22e73117af45 (patch)
treec8001eaec29c1612f6528a0797866f77d639397e
parent79607f92debdeb3841387ff368f37764c23b913f (diff)
downloadmongo-bdcf088d3c90a4fe6e9c4f23559a22e73117af45.tar.gz
SERVER-37749 replSetResizeOplog command does not validate argument correctly
(cherry picked from commit 83328dadb7aba72fc9202c91d5715ab4a2d04fcb) (cherry picked from commit 8b07e3e7242c5048eb847105fe30a9e3ef2bb88c)
-rw-r--r--jstests/noPassthrough/repl_set_resize_oplog.js53
-rw-r--r--src/mongo/db/commands/resize_oplog.cpp9
2 files changed, 61 insertions, 1 deletions
diff --git a/jstests/noPassthrough/repl_set_resize_oplog.js b/jstests/noPassthrough/repl_set_resize_oplog.js
new file mode 100644
index 00000000000..7c164175685
--- /dev/null
+++ b/jstests/noPassthrough/repl_set_resize_oplog.js
@@ -0,0 +1,53 @@
+/**
+ * Tests that resizing the oplog works as expected and validates input arguments.
+ *
+ * @tags: [requires_replication, requires_wiredtiger]
+ */
+(function() {
+ "use strict";
+
+ // Skip this test if not running with the "wiredTiger" storage engine.
+ if (jsTest.options().storageEngine && jsTest.options().storageEngine !== 'wiredTiger') {
+ jsTest.log('Skipping test because storageEngine is not "wiredTiger"');
+ return;
+ }
+
+ let replSet = new ReplSetTest({nodes: 2, oplogSize: 50});
+ replSet.startSet();
+ replSet.initiate();
+
+ let primary = replSet.getPrimary();
+
+ const MB = 1024 * 1024;
+ const GB = 1024 * MB;
+ const PB = 1024 * GB;
+ const EB = 1024 * PB;
+
+ assert.eq(primary.getDB('local').oplog.rs.stats().maxSize, 50 * MB);
+
+ // Too small: 990MB
+ assert.commandFailedWithCode(
+ primary.getDB('admin').runCommand({replSetResizeOplog: 1, size: 900}),
+ ErrorCodes.InvalidOptions,
+ "Expected replSetResizeOplog to fail because the size was too small");
+
+ // Way too small: -1GB
+ assert.commandFailedWithCode(
+ primary.getDB('admin').runCommand({replSetResizeOplog: 1, size: -1 * GB / MB}),
+ ErrorCodes.InvalidOptions,
+ "Expected replSetResizeOplog to fail because the size was too small");
+
+ // Too big: 8EB
+ assert.commandFailedWithCode(
+ primary.getDB('admin').runCommand({replSetResizeOplog: 1, size: 8 * EB / MB}),
+ ErrorCodes.InvalidOptions,
+ "Expected replSetResizeOplog to fail because the size was too big");
+
+ // The maximum: 1PB
+ assert.commandWorked(
+ primary.getDB('admin').runCommand({replSetResizeOplog: 1, size: 1 * PB / MB}));
+
+ assert.eq(primary.getDB('local').oplog.rs.stats().maxSize, 1 * PB);
+
+ replSet.stopSet();
+})();
diff --git a/src/mongo/db/commands/resize_oplog.cpp b/src/mongo/db/commands/resize_oplog.cpp
index ea2899ed62a..c2a8c05c619 100644
--- a/src/mongo/db/commands/resize_oplog.cpp
+++ b/src/mongo/db/commands/resize_oplog.cpp
@@ -110,11 +110,18 @@ public:
}
long long sizeMb = jsobj["size"].numberLong();
- long long size = sizeMb * 1024 * 1024;
if (sizeMb < 990L) {
return appendCommandStatus(
result, Status(ErrorCodes::InvalidOptions, "oplog size should be 990MB at least"));
}
+
+ const long long kMB = 1024 * 1024;
+ const long long kPB = kMB * 1024 * 1024 * 1024;
+ if (sizeMb > kPB / kMB) {
+ uasserted(ErrorCodes::InvalidOptions, "oplog size in MB cannot exceed maximum of 1PB");
+ }
+ long long size = sizeMb * kMB;
+
WriteUnitOfWork wunit(opCtx);
Status status = coll->getRecordStore()->updateCappedSize(opCtx, size);
if (!status.isOK()) {