summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Midvidy <amidvidy@gmail.com>2015-03-25 19:06:49 -0400
committerAdam Midvidy <amidvidy@gmail.com>2015-03-25 19:06:49 -0400
commit5e7aa5c9efdea28cc82ff8d0ea0e3a76cf5c94f8 (patch)
tree0abe6da15dc5e696e17530fb3e76e86742e9190d
parent3ee2c5c5c2c4ad0534138d567ccc7b053defff4a (diff)
downloadmongo-5e7aa5c9efdea28cc82ff8d0ea0e3a76cf5c94f8.tar.gz
Revert "SERVER-7775 refactor fsyncUnlock to execute through standard command path"
This reverts commit 5c48ea0d3fd6556eb0ba7686a9da6159f0814d08.
-rw-r--r--jstests/auth/lib/commands_lib.js16
-rw-r--r--jstests/core/fsync.js11
-rw-r--r--jstests/noPassthroughWithMongod/fsync2.js2
-rw-r--r--jstests/repl/snapshot1.js4
-rw-r--r--jstests/replsets/fsync_lock_read_secondaries.js2
-rw-r--r--jstests/replsets/maxSyncSourceLagSecs.js2
-rw-r--r--jstests/replsets/stepdown.js2
-rw-r--r--jstests/replsets/stepdown3.js2
-rw-r--r--src/mongo/db/commands/fsync.cpp163
-rw-r--r--src/mongo/db/commands/fsync.h2
-rw-r--r--src/mongo/db/instance.cpp66
-rw-r--r--src/mongo/shell/db.js9
12 files changed, 80 insertions, 201 deletions
diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js
index e4d5fbed16e..c73439d2494 100644
--- a/jstests/auth/lib/commands_lib.js
+++ b/jstests/auth/lib/commands_lib.js
@@ -1144,22 +1144,6 @@ var authCommandsLib = {
]
},
{
- testname: "fsyncUnlock",
- command: {fsyncUnlock: 1},
- testcases: [
- {
- runOnDb: adminDbName,
- roles: roles_hostManager,
- privileges: [
- { resource: {cluster: true}, actions: ["fsync"] }
- ],
- expectFail: true
- },
- { runOnDb: firstDbName, roles: {} },
- { runOnDb: secondDbName, roles: {} }
- ]
- },
- {
testname: "geoNear",
command: {geoNear: "x", near: [50, 50], num: 1},
setup: function (db) {
diff --git a/jstests/core/fsync.js b/jstests/core/fsync.js
index 14c5d323591..53ebef0f97d 100644
--- a/jstests/core/fsync.js
+++ b/jstests/core/fsync.js
@@ -36,14 +36,3 @@ assert.eq(2, fsyncLockDB.coll.count({}));
// Ensure eval is not allowed to invoke fsyncLock
assert(!db.eval('db.fsyncLock()').ok, "eval('db.fsyncLock()') should fail.");
-
-// Check that the fsyncUnlock pseudo-command (a lookup on cmd.$sys.unlock)
-// still has the same effect as a legitimate 'fsyncUnlock' command
-// TODO: remove this in in the release following MongoDB 3.2 when pseudo-commands
-// are removed
-var fsyncCommandRes = db.fsyncLock();
-assert(fsyncLockRes.ok, "fsyncLock command failed against admin DB");
-assert(db.currentOp().fsyncLock, "Value in db.currentOp incorrect for fsyncLocked server");
-var fsyncPseudoCommandRes = db.getSiblingDB("admin").$cmd.sys.unlock.findOne();
-assert(fsyncPseudoCommandRes.ok, "fsyncUnlock pseudo-command failed");
-assert(db.currentOp().fsyncLock == null, "fsyncUnlock is not null in db.currentOp");
diff --git a/jstests/noPassthroughWithMongod/fsync2.js b/jstests/noPassthroughWithMongod/fsync2.js
index fcf4da08533..7080837a99b 100644
--- a/jstests/noPassthroughWithMongod/fsync2.js
+++ b/jstests/noPassthroughWithMongod/fsync2.js
@@ -40,7 +40,7 @@ function doTest() {
// Uncomment once SERVER-4243 is fixed
//assert.eq(1, m.getDB(db.getName()).fsync2.count());
- assert( m.getDB("admin").fsyncUnlock().ok );
+ assert( m.getDB("admin").$cmd.sys.unlock.findOne().ok );
assert.eq( 2, db.fsync2.count() );
diff --git a/jstests/repl/snapshot1.js b/jstests/repl/snapshot1.js
index 076ec2403f9..3be37aa125b 100644
--- a/jstests/repl/snapshot1.js
+++ b/jstests/repl/snapshot1.js
@@ -14,7 +14,7 @@ for( i = 0; i < 1000; ++i )
m.getDB( "admin" ).runCommand( {fsync:1,lock:1} );
copyDbpath( rt1.getPath( true ), rt1.getPath( false ) );
-m.getDB( "admin" ).fsyncUnlock();
+m.getDB( "admin" ).$cmd.sys.unlock.findOne();
s1 = rt1.start( false, null, true );
assert.eq( 1000, s1.getDB( baseName )[ baseName ].count() );
@@ -23,7 +23,7 @@ assert.soon( function() { return 1001 == s1.getDB( baseName )[ baseName ].count(
s1.getDB( "admin" ).runCommand( {fsync:1,lock:1} );
copyDbpath( rt1.getPath( false ), rt2.getPath( false ) );
-s1.getDB( "admin" ).fsyncUnlock();
+s1.getDB( "admin" ).$cmd.sys.unlock.findOne();
s2 = rt2.start( false, null, true );
assert.eq( 1001, s2.getDB( baseName )[ baseName ].count() );
diff --git a/jstests/replsets/fsync_lock_read_secondaries.js b/jstests/replsets/fsync_lock_read_secondaries.js
index d217e85241f..7aab61fd4b2 100644
--- a/jstests/replsets/fsync_lock_read_secondaries.js
+++ b/jstests/replsets/fsync_lock_read_secondaries.js
@@ -53,7 +53,7 @@ for (var i=0; i<docNum; i++) {
// this should work just fine.
var slave0count = slaves[0].getDB("foo").bar.count();
assert.eq(slave0count, 100, "Doc count in fsync lock wrong. Expected (=100), found " + slave0count);
-assert(slaves[0].getDB("admin").fsyncUnlock().ok);
+assert(slaves[0].getDB("admin").$cmd.sys.unlock.findOne().ok);
// The secondary should have equal or more documents than what it had before.
assert.soon(function() {
diff --git a/jstests/replsets/maxSyncSourceLagSecs.js b/jstests/replsets/maxSyncSourceLagSecs.js
index 1a7348c2e64..8d4702510e1 100644
--- a/jstests/replsets/maxSyncSourceLagSecs.js
+++ b/jstests/replsets/maxSyncSourceLagSecs.js
@@ -44,6 +44,6 @@
return (slaves[1].getDB("foo").bar.count() === 2);
}, "slave should have caught up after syncing to primary.");
- assert.commandWorked(slaves[0].getDB("admin").fsyncUnlock());
+ assert.commandWorked(slaves[0].getDB("admin").$cmd.sys.unlock.findOne());
replTest.stopSet();
}());
diff --git a/jstests/replsets/stepdown.js b/jstests/replsets/stepdown.js
index 275d7726d40..474154ae6ef 100644
--- a/jstests/replsets/stepdown.js
+++ b/jstests/replsets/stepdown.js
@@ -53,7 +53,7 @@ assert.eq(r2.ismaster, false);
assert.eq(r2.secondary, true);
print("\nunlock");
-printjson(locked.getDB("admin").fsyncUnlock());
+printjson(locked.getDB("admin").$cmd.sys.unlock.findOne());
print("\nreset stepped down time");
master.getDB("admin").runCommand({replSetFreeze:0});
diff --git a/jstests/replsets/stepdown3.js b/jstests/replsets/stepdown3.js
index 05ce573c883..af7f84607b7 100644
--- a/jstests/replsets/stepdown3.js
+++ b/jstests/replsets/stepdown3.js
@@ -46,5 +46,5 @@ print("result of gle:");
printjson(result);
// unlock and shut down
-printjson(locked.getDB("admin").fsyncUnlock());
+printjson(locked.getDB("admin").$cmd.sys.unlock.findOne());
replTest.stopSet();
diff --git a/src/mongo/db/commands/fsync.cpp b/src/mongo/db/commands/fsync.cpp
index b6fde72e309..f9f829df3b7 100644
--- a/src/mongo/db/commands/fsync.cpp
+++ b/src/mongo/db/commands/fsync.cpp
@@ -26,24 +26,16 @@
* it in the license file.
*/
-#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kCommand
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kStorage
#include "mongo/db/commands/fsync.h"
-#include <iostream>
-#include <memory>
-#include <sstream>
#include <string>
#include <vector>
-#include "mongo/base/init.h"
-#include "mongo/bson/bsonobj.h"
-#include "mongo/bson/bsonobjbuilder.h"
-#include "mongo/db/audit.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
-#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/commands.h"
@@ -51,11 +43,12 @@
#include "mongo/db/storage/mmap_v1/dur.h"
#include "mongo/db/storage/storage_engine.h"
#include "mongo/db/client.h"
+#include "mongo/db/jsobj.h"
#include "mongo/db/operation_context_impl.h"
-#include "mongo/stdx/memory.h"
#include "mongo/util/background.h"
#include "mongo/util/log.h"
+
namespace mongo {
using std::endl;
@@ -159,73 +152,7 @@ namespace mongo {
}
return 1;
}
- };
-
- namespace {
- bool unlockFsync();
- } // namespace
-
- class FSyncUnlockCommand : public Command {
- public:
-
- FSyncUnlockCommand() : Command("fsyncUnlock") {}
-
- bool isWriteCommandForConfigServer() const override { return false; }
-
- bool slaveOk() const override { return true; }
-
- bool adminOnly() const override { return true; }
-
- Status checkAuthForCommand(ClientBasic* client,
- const std::string& dbname,
- const BSONObj& cmdObj) override {
-
- bool isAuthorized = client->getAuthorizationSession()->isAuthorizedForActionsOnResource(
- ResourcePattern::forClusterResource(),
- ActionType::unlock);
-
- if (isAuthorized) {
- audit::logFsyncUnlockAuthzCheck(client, ErrorCodes::OK);
- return Status::OK();
- }
- else {
- audit::logFsyncUnlockAuthzCheck(client, ErrorCodes::Unauthorized);
- return Status(ErrorCodes::Unauthorized, "Unauthorized");
- }
- }
-
- bool run(OperationContext* txn,
- const std::string& db,
- BSONObj& cmdObj,
- int options,
- std::string& errmsg,
- BSONObjBuilder& result,
- bool fromRepl) override {
-
- log() << "command: unlock requested";
-
- if (unlockFsync()) {
- result.append("info", "unlock completed");
- return true;
- }
- else {
- errmsg = "not locked";
- return false;
- }
- }
-
- };
-
- namespace {
- std::unique_ptr<FSyncCommand> fsyncCmd;
- std::unique_ptr<FSyncUnlockCommand> fsyncUnlockCmd;
- } // namespace
-
- MONGO_INITIALIZER(FSyncAndFsyncUnlock)(InitializerContext*) {
- fsyncCmd = stdx::make_unique<FSyncCommand>();
- fsyncUnlockCmd = stdx::make_unique<FSyncUnlockCommand>();
- return Status::OK();
- }
+ } fsyncCmd;
SimpleMutex filesLockedFsync("filesLockedFsync");
@@ -236,17 +163,17 @@ namespace mongo {
ScopedTransaction transaction(&txn, MODE_X);
Lock::GlobalWrite global(txn.lockState()); // No WriteUnitOfWork needed
- SimpleMutex::scoped_lock lk(fsyncCmd->m);
-
- invariant(!fsyncCmd->locked); // impossible to get here if locked is true
- try {
+ SimpleMutex::scoped_lock lk(fsyncCmd.m);
+
+ invariant(!fsyncCmd.locked); // impossible to get here if locked is true
+ try {
getDur().syncDataAndTruncateJournal(&txn);
- }
- catch( std::exception& e ) {
+ }
+ catch( std::exception& e ) {
error() << "error doing syncDataAndTruncateJournal: " << e.what() << endl;
- fsyncCmd->err = e.what();
- fsyncCmd->_threadSync.notify_one();
- fsyncCmd->locked = false;
+ fsyncCmd.err = e.what();
+ fsyncCmd._threadSync.notify_one();
+ fsyncCmd.locked = false;
return;
}
@@ -256,49 +183,47 @@ namespace mongo {
StorageEngine* storageEngine = getGlobalEnvironment()->getGlobalStorageEngine();
storageEngine->flushAllFiles(true);
}
- catch( std::exception& e ) {
+ catch( std::exception& e ) {
error() << "error doing flushAll: " << e.what() << endl;
- fsyncCmd->err = e.what();
- fsyncCmd->_threadSync.notify_one();
- fsyncCmd->locked = false;
+ fsyncCmd.err = e.what();
+ fsyncCmd._threadSync.notify_one();
+ fsyncCmd.locked = false;
return;
}
- invariant(!fsyncCmd->locked);
- fsyncCmd->locked = true;
-
- fsyncCmd->_threadSync.notify_one();
+ invariant(!fsyncCmd.locked);
+ fsyncCmd.locked = true;
+
+ fsyncCmd._threadSync.notify_one();
- while ( ! fsyncCmd->pendingUnlock ) {
- fsyncCmd->_unlockSync.wait(fsyncCmd->m);
+ while ( ! fsyncCmd.pendingUnlock ) {
+ fsyncCmd._unlockSync.wait(fsyncCmd.m);
}
- fsyncCmd->pendingUnlock = false;
+ fsyncCmd.pendingUnlock = false;
+
+ fsyncCmd.locked = false;
+ fsyncCmd.err = "unlocked";
- fsyncCmd->locked = false;
- fsyncCmd->err = "unlocked";
-
- fsyncCmd->_unlockSync.notify_one();
+ fsyncCmd._unlockSync.notify_one();
}
- bool lockedForWriting() {
- return fsyncCmd->locked;
+ bool lockedForWriting() {
+ return fsyncCmd.locked;
}
- namespace {
- // @return true if unlocked
- bool unlockFsync() {
- SimpleMutex::scoped_lock lk( fsyncCmd->m );
- if( !fsyncCmd->locked ) {
- return false;
- }
- fsyncCmd->pendingUnlock = true;
- fsyncCmd->_unlockSync.notify_one();
- fsyncCmd->_threadSync.notify_one();
-
- while ( fsyncCmd->locked ) {
- fsyncCmd->_unlockSync.wait( fsyncCmd->m );
- }
- return true;
+ // @return true if unlocked
+ bool _unlockFsync() {
+ SimpleMutex::scoped_lock lk( fsyncCmd.m );
+ if( !fsyncCmd.locked ) {
+ return false;
}
- } // namespace
+ fsyncCmd.pendingUnlock = true;
+ fsyncCmd._unlockSync.notify_one();
+ fsyncCmd._threadSync.notify_one();
+
+ while ( fsyncCmd.locked ) {
+ fsyncCmd._unlockSync.wait( fsyncCmd.m );
+ }
+ return true;
+ }
}
diff --git a/src/mongo/db/commands/fsync.h b/src/mongo/db/commands/fsync.h
index 4072a1f6e50..f3fa2adb993 100644
--- a/src/mongo/db/commands/fsync.h
+++ b/src/mongo/db/commands/fsync.h
@@ -34,4 +34,4 @@ namespace mongo {
// Use this for blocking during an fsync-and-lock
extern SimpleMutex filesLockedFsync;
bool lockedForWriting();
-} // namespace mongo
+}
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index 242a81db415..46e0edd4b13 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -180,6 +180,32 @@ namespace mongo {
replyToQuery(0, m, dbresponse, obj);
}
+ bool _unlockFsync();
+ static void unlockFsync(OperationContext* txn, const char *ns, Message& m, DbResponse &dbresponse) {
+ BSONObj obj;
+
+ const bool isAuthorized = txn->getClient()->getAuthorizationSession()->isAuthorizedForActionsOnResource(
+ ResourcePattern::forClusterResource(), ActionType::unlock);
+ audit::logFsyncUnlockAuthzCheck(
+ txn->getClient(), isAuthorized ? ErrorCodes::OK : ErrorCodes::Unauthorized);
+ if (!isAuthorized) {
+ obj = fromjson("{\"err\":\"unauthorized\"}");
+ }
+ else if (strncmp(ns, "admin.", 6) != 0 ) {
+ obj = fromjson("{\"err\":\"unauthorized - this command must be run against the admin DB\"}");
+ }
+ else {
+ log() << "command: unlock requested" << endl;
+ if( _unlockFsync() ) {
+ obj = fromjson("{ok:1,\"info\":\"unlock completed\"}");
+ }
+ else {
+ obj = fromjson("{ok:0,\"errmsg\":\"not locked\"}");
+ }
+ }
+ replyToQuery(0, m, dbresponse, obj);
+ }
+
namespace {
void generateErrorResponse(const AssertionException* exception,
@@ -298,44 +324,6 @@ namespace {
dbResponse.responseTo = responseTo;
}
-namespace {
-
- // In SERVER-7775 we reimplemented the pseudo-commands fsyncUnlock, inProg, and killOp
- // as ordinary commands. To support old clients for another release, this helper serves
- // to execute the real command from the legacy pseudo-command codepath.
- // TODO: remove after MongoDB 3.2 is released
- void receivedPseudoCommand(OperationContext* txn,
- const NamespaceString& nss,
- Client& client,
- DbResponse& dbResponse,
- Message& message,
- StringData realCommandName) {
- Message interposed;
-
- NamespaceString interposedNss(nss.db(), "$cmd");
-
- BSONObjBuilder cmdBob;
- cmdBob.append(realCommandName, 1);
- auto cmd = cmdBob.done();
-
- // TODO: use OP_COMMAND here instead of constructing
- // a legacy OP_QUERY style command
- BufBuilder cmdMsgBuf;
- cmdMsgBuf.appendNum(DataView(message.header().data()).readLE<int32_t>()); // flags
- cmdMsgBuf.appendStr(interposedNss.db(), false); // not including null byte
- cmdMsgBuf.appendStr(".$cmd");
- cmdMsgBuf.appendNum(0); // ntoskip
- cmdMsgBuf.appendNum(1); // ntoreturn
- cmdMsgBuf.appendBuf(cmd.objdata(), cmd.objsize());
-
- interposed.setData(dbQuery, cmdMsgBuf.buf(), cmdMsgBuf.len());
- interposed.header().setId(message.header().getId());
-
- receivedCommand(txn, interposedNss, client, dbResponse, interposed);
- }
-
-} // namespace
-
static void receivedQuery(OperationContext* txn,
const NamespaceString& nss,
Client& c,
@@ -420,7 +408,7 @@ namespace {
return;
}
if (nsString.coll() == "$cmd.sys.unlock") {
- receivedPseudoCommand(txn, nsString, c, dbresponse, m, "fsyncUnlock");
+ unlockFsync(txn, ns, m, dbresponse);
return;
}
}
diff --git a/src/mongo/shell/db.js b/src/mongo/shell/db.js
index 9a6c5399067..48e086ad9f6 100644
--- a/src/mongo/shell/db.js
+++ b/src/mongo/shell/db.js
@@ -975,14 +975,7 @@ DB.prototype.fsyncLock = function() {
}
DB.prototype.fsyncUnlock = function() {
- var res = this.adminCommand({fsyncUnlock: 1});
- if (!res.ok &&
- // handle both error messages for nonexistent command...
- (res.errmsg.startsWith("no such cmd") || res.errmsg.startsWith("no such command"))) {
- // fallback for old servers
- res = this.getSiblingDB("admin").$cmd.sys.unlock.findOne();
- }
- return res;
+ return this.getSiblingDB("admin").$cmd.sys.unlock.findOne()
}
DB.autocomplete = function(obj){