diff options
author | Benety Goh <benety@mongodb.com> | 2014-12-30 18:31:26 -0500 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2015-01-05 15:52:48 -0500 |
commit | d602ceb25e996962298ab45864aad4eb80262485 (patch) | |
tree | 0d8f006a3a6db56cd689a5a87b3805e06cc49d3a /src/mongo | |
parent | 2f881f7f2a00bb4b5f7af868033b89b1246e8bc8 (diff) | |
download | mongo-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.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp | 117 |
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 } } |