diff options
author | Louis Williams <louis.williams@mongodb.com> | 2018-10-26 12:06:36 -0400 |
---|---|---|
committer | Louis Williams <louis.williams@mongodb.com> | 2018-10-29 16:54:43 -0400 |
commit | d5ca994f52d77b0277aa328f0adadaf1e06cb881 (patch) | |
tree | 2ce4165856bef7620feeac529fdfa8f1cc3ac24d | |
parent | da568a8d2216b3d4b4b2c5bb0c6211a196ed395f (diff) | |
download | mongo-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.js | 47 | ||||
-rw-r--r-- | src/mongo/db/commands/resize_oplog.cpp | 10 |
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); |