summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2014-12-30 18:31:26 -0500
committerBenety Goh <benety@mongodb.com>2015-01-05 15:52:48 -0500
commitd602ceb25e996962298ab45864aad4eb80262485 (patch)
tree0d8f006a3a6db56cd689a5a87b3805e06cc49d3a /src/mongo
parent2f881f7f2a00bb4b5f7af868033b89b1246e8bc8 (diff)
downloadmongo-d602ceb25e996962298ab45864aad4eb80262485.tar.gz
SERVER-16677 moved management of mongod.lock from mmapv1 engine to global environment
added test to ensure that mongod.lock is created for all storage engines/platforms.
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/global_environment_d.cpp3
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp117
2 files changed, 14 insertions, 106 deletions
diff --git a/src/mongo/db/global_environment_d.cpp b/src/mongo/db/global_environment_d.cpp
index 182811c7edd..eb85f6f78d4 100644
--- a/src/mongo/db/global_environment_d.cpp
+++ b/src/mongo/db/global_environment_d.cpp
@@ -95,10 +95,12 @@ namespace mongo {
<< "This may prevent the current storage engine "
<< name << " from starting up.";
}
+ uassertStatusOK(_lockFile->open());
ScopeGuard guard = MakeGuard(&StorageEngineLockFile::close, _lockFile.get());
_storageEngine = factory->create(storageGlobalParams, *_lockFile);
_storageEngine->finishInit();
+ uassertStatusOK(_lockFile->writePid());
// Write a new metadata file if it is not present.
StorageEngineMetadata::updateIfMissing(storageGlobalParams.dbpath, canonicalName);
@@ -110,6 +112,7 @@ namespace mongo {
invariant(_storageEngine);
invariant(_lockFile.get());
_storageEngine->cleanShutdown();
+ _lockFile->clearPidAndUnlock();
}
void GlobalEnvironmentMongoD::registerStorageEngine(const std::string& name,
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp
index 5883ee7d902..926e65b4740 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp
@@ -36,12 +36,6 @@
#include <boost/filesystem/operations.hpp>
#include <fstream>
-#if defined(_WIN32)
-#include <io.h>
-#else
-#include <sys/file.h>
-#endif
-
#include "mongo/db/mongod_options.h"
#include "mongo/db/storage/mmap_v1/data_file_sync.h"
#include "mongo/db/storage/mmap_v1/dur.h"
@@ -50,8 +44,8 @@
#include "mongo/db/storage/mmap_v1/dur_recovery_unit.h"
#include "mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.h"
#include "mongo/db/storage/mmap_v1/mmap_v1_options.h"
+#include "mongo/db/storage/storage_engine_lock_file.h"
#include "mongo/db/storage_options.h"
-#include "mongo/platform/process_id.h"
#include "mongo/util/file_allocator.h"
#include "mongo/util/log.h"
#include "mongo/util/mmap.h"
@@ -60,70 +54,14 @@
namespace mongo {
namespace {
-#ifdef _WIN32
- HANDLE lockFileHandle;
-#endif
-
- // This is used by everyone, including windows.
- int lockFile = 0;
#if !defined(__sunos__)
- void writePid(int fd) {
- stringstream ss;
- ss << ProcessId::getCurrent() << endl;
- string s = ss.str();
- const char * data = s.c_str();
-#ifdef _WIN32
- verify( _write( fd, data, strlen( data ) ) );
-#else
- verify( write( fd, data, strlen( data ) ) );
-#endif
- }
-
// if doingRepair is true don't consider unclean shutdown an error
- void acquirePathLock(MMAPV1Engine* storageEngine, bool doingRepair) {
- string name = (boost::filesystem::path(storageGlobalParams.dbpath) / "mongod.lock").string();
-
- bool oldFile = false;
-
- if ( boost::filesystem::exists( name ) && boost::filesystem::file_size( name ) > 0 ) {
- oldFile = true;
- }
-
-#ifdef _WIN32
- lockFileHandle = CreateFileA( name.c_str(), GENERIC_READ | GENERIC_WRITE,
- 0 /* do not allow anyone else access */, NULL,
- OPEN_ALWAYS /* success if fh can open */, 0, NULL );
-
- if (lockFileHandle == INVALID_HANDLE_VALUE) {
- DWORD code = GetLastError();
- char *msg;
- FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR)&msg, 0, NULL);
- string m = msg;
- str::stripTrailing(m, "\r\n");
- uasserted(ErrorCodes::DBPathInUse,
- str::stream() << "Unable to create/open lock file: "
- << name << ' ' << m
- << ". Is a mongod instance already running?");
- }
- lockFile = _open_osfhandle((intptr_t)lockFileHandle, 0);
-#else
- lockFile = open( name.c_str(), O_RDWR | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
- if( lockFile <= 0 ) {
- uasserted( ErrorCodes::DBPathInUse,
- str::stream() << "Unable to create/open lock file: "
- << name << ' ' << errnoWithDescription()
- << " Is a mongod instance already running?" );
- }
- if (flock( lockFile, LOCK_EX | LOCK_NB ) != 0) {
- close ( lockFile );
- lockFile = 0;
- uasserted(ErrorCodes::DBPathInUse,
- "Unable to lock file: " + name + ". Is a mongod instance already running?");
- }
-#endif
+ void acquirePathLock(MMAPV1Engine* storageEngine,
+ bool doingRepair,
+ const StorageEngineLockFile& lockFile) {
+ string name = lockFile.getFilespec();
+ bool oldFile = lockFile.createdByUncleanShutdown();
if ( oldFile ) {
// we check this here because we want to see if we can get the lock
@@ -180,12 +118,6 @@ namespace {
if (!errmsg.empty()) {
log() << errmsg << endl;
-#ifdef _WIN32
- CloseHandle( lockFileHandle );
-#else
- close ( lockFile );
-#endif
- lockFile = 0;
uassert( 12596 , "old lock file" , 0 );
}
}
@@ -198,20 +130,11 @@ namespace {
log() << "**************" << endl;
uasserted(13597, "can't start without --journal enabled when journal/ files are present");
}
-
-#ifdef _WIN32
- uassert( 13625, "Unable to truncate lock file", _chsize(lockFile, 0) == 0);
- writePid( lockFile );
- _commit( lockFile );
-#else
- uassert( 13342, "Unable to truncate lock file", ftruncate(lockFile, 0) == 0);
- writePid( lockFile );
- fsync( lockFile );
- flushMyDirectory(name);
-#endif
}
#else
- void acquirePathLock(MMAPV1Engine* storageEngine, bool) {
+ void acquirePathLock(MMAPV1Engine* storageEngine,
+ bool doingRepair,
+ const StorageEngineLockFile& lockFile) {
// TODO - this is very bad that the code above not running here.
// Not related to lock file, but this is where we handle unclean shutdown
@@ -224,7 +147,7 @@ namespace {
uasserted(13618, "can't start without --journal enabled when journal/ files are present");
}
}
-#endif
+#endif // !defined(__sunos__)
/// warn if readahead > 256KB (gridfs chunk size)
@@ -291,7 +214,7 @@ namespace {
// TODO check non-journal subdirs if using directory-per-db
checkReadAhead(storageGlobalParams.dbpath);
- acquirePathLock(this, storageGlobalParams.repair);
+ acquirePathLock(this, storageGlobalParams.repair, lockFile);
FileAllocator::get()->start();
@@ -428,23 +351,5 @@ namespace {
if (storageGlobalParams.dur) {
dur::journalCleanup(true);
}
-
-#if !defined(__sunos__)
- if ( lockFile ) {
- log() << "shutdown: removing fs lock..." << endl;
- /* This ought to be an unlink(), but Eliot says the last
- time that was attempted, there was a race condition
- with acquirePathLock(). */
-#ifdef _WIN32
- if( _chsize( lockFile , 0 ) )
- log() << "couldn't remove fs lock " << errnoWithDescription(_doserrno) << endl;
- CloseHandle(lockFileHandle);
-#else
- if( ftruncate( lockFile , 0 ) )
- log() << "couldn't remove fs lock " << errnoWithDescription() << endl;
- flock( lockFile, LOCK_UN );
-#endif
- }
-#endif
}
}