summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2018-10-26 12:06:36 -0400
committerLouis Williams <louis.williams@mongodb.com>2018-10-29 16:54:43 -0400
commitd5ca994f52d77b0277aa328f0adadaf1e06cb881 (patch)
tree2ce4165856bef7620feeac529fdfa8f1cc3ac24d
parentda568a8d2216b3d4b4b2c5bb0c6211a196ed395f (diff)
downloadmongo-d5ca994f52d77b0277aa328f0adadaf1e06cb881.tar.gz
SERVER-37749 replSetResizeOplog command does not validate argument correctly
(cherry picked from commit 83328dadb7aba72fc9202c91d5715ab4a2d04fcb)
-rw-r--r--jstests/noPassthrough/repl_set_resize_oplog.js47
-rw-r--r--src/mongo/db/commands/resize_oplog.cpp10
2 files changed, 55 insertions, 2 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..23682467f9d
--- /dev/null
+++ b/jstests/noPassthrough/repl_set_resize_oplog.js
@@ -0,0 +1,47 @@
+/**
+ * Tests that resizing the oplog works as expected and validates input arguments.
+ *
+ * @tags: [requires_replication, requires_wiredtiger]
+ */
+(function() {
+ "use strict";
+
+ 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 097fcdd9448..c3aa2bbd424 100644
--- a/src/mongo/db/commands/resize_oplog.cpp
+++ b/src/mongo/db/commands/resize_oplog.cpp
@@ -1,4 +1,3 @@
-
/**
* Copyright (C) 2018-present MongoDB, Inc.
*
@@ -105,10 +104,17 @@ public:
}
long long sizeMb = jsobj["size"].numberLong();
- long long size = sizeMb * 1024 * 1024;
if (sizeMb < 990L) {
uasserted(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);
uassertStatusOK(status);