diff options
Diffstat (limited to 'src/mongo/db/storage/storage_engine_lock_file_posix.cpp')
-rw-r--r-- | src/mongo/db/storage/storage_engine_lock_file_posix.cpp | 247 |
1 files changed, 125 insertions, 122 deletions
diff --git a/src/mongo/db/storage/storage_engine_lock_file_posix.cpp b/src/mongo/db/storage/storage_engine_lock_file_posix.cpp index f7f12871053..66f477232d2 100644 --- a/src/mongo/db/storage/storage_engine_lock_file_posix.cpp +++ b/src/mongo/db/storage/storage_engine_lock_file_posix.cpp @@ -50,150 +50,153 @@ namespace mongo { namespace { - const std::string kLockFileBasename = "mongod.lock"; +const std::string kLockFileBasename = "mongod.lock"; } // namespace - class StorageEngineLockFile::LockFileHandle { - public: - static const int kInvalidFd = -1; - LockFileHandle() : _fd(kInvalidFd) { } - bool isValid() const { return _fd != kInvalidFd; } - void clear() { _fd = kInvalidFd; } - int _fd; - }; - - StorageEngineLockFile::StorageEngineLockFile(const std::string& dbpath) - : _dbpath(dbpath), - _filespec((boost::filesystem::path(_dbpath) / kLockFileBasename).string()), - _uncleanShutdown(boost::filesystem::exists(_filespec) && - boost::filesystem::file_size(_filespec) > 0), - _lockFileHandle(new LockFileHandle()) { +class StorageEngineLockFile::LockFileHandle { +public: + static const int kInvalidFd = -1; + LockFileHandle() : _fd(kInvalidFd) {} + bool isValid() const { + return _fd != kInvalidFd; } - - StorageEngineLockFile::~StorageEngineLockFile() { } - - std::string StorageEngineLockFile::getFilespec() const { - return _filespec; - } - - bool StorageEngineLockFile::createdByUncleanShutdown() const { - return _uncleanShutdown; + void clear() { + _fd = kInvalidFd; } - - Status StorageEngineLockFile::open() { - try { - if (!boost::filesystem::exists(_dbpath)) { - return Status(ErrorCodes::NonExistentPath, str::stream() - << "Data directory " << _dbpath << " not found."); - } - } - catch (const std::exception& ex) { - return Status(ErrorCodes::UnknownError, str::stream() - << "Unable to check existence of data directory " - << _dbpath << ": " << ex.what()); + int _fd; +}; + +StorageEngineLockFile::StorageEngineLockFile(const std::string& dbpath) + : _dbpath(dbpath), + _filespec((boost::filesystem::path(_dbpath) / kLockFileBasename).string()), + _uncleanShutdown(boost::filesystem::exists(_filespec) && + boost::filesystem::file_size(_filespec) > 0), + _lockFileHandle(new LockFileHandle()) {} + +StorageEngineLockFile::~StorageEngineLockFile() {} + +std::string StorageEngineLockFile::getFilespec() const { + return _filespec; +} + +bool StorageEngineLockFile::createdByUncleanShutdown() const { + return _uncleanShutdown; +} + +Status StorageEngineLockFile::open() { + try { + if (!boost::filesystem::exists(_dbpath)) { + return Status(ErrorCodes::NonExistentPath, + str::stream() << "Data directory " << _dbpath << " not found."); } + } catch (const std::exception& ex) { + return Status(ErrorCodes::UnknownError, + str::stream() << "Unable to check existence of data directory " << _dbpath + << ": " << ex.what()); + } - int lockFile = ::open(_filespec.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO); - if (lockFile < 0) { - int errorcode = errno; - return Status(ErrorCodes::DBPathInUse, str::stream() - << "Unable to create/open lock file: " - << _filespec << ' ' << errnoWithDescription(errorcode) - << " Is a mongod instance already running?"); - } + int lockFile = ::open(_filespec.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO); + if (lockFile < 0) { + int errorcode = errno; + return Status(ErrorCodes::DBPathInUse, + str::stream() << "Unable to create/open lock file: " << _filespec << ' ' + << errnoWithDescription(errorcode) + << " Is a mongod instance already running?"); + } #if !defined(__sun) - int ret = ::flock(lockFile, LOCK_EX | LOCK_NB); + int ret = ::flock(lockFile, LOCK_EX | LOCK_NB); #else - struct flock fileLockInfo = {0}; - fileLockInfo.l_type = F_WRLCK; - fileLockInfo.l_whence = SEEK_SET; - int ret = ::fcntl(lockFile, F_SETLK, &fileLockInfo); + struct flock fileLockInfo = {0}; + fileLockInfo.l_type = F_WRLCK; + fileLockInfo.l_whence = SEEK_SET; + int ret = ::fcntl(lockFile, F_SETLK, &fileLockInfo); #endif // !defined(__sun) - if (ret != 0) { - int errorcode = errno; - ::close(lockFile); - return Status(ErrorCodes::DBPathInUse, str::stream() - << "Unable to lock file: " - << _filespec << ' ' << errnoWithDescription(errorcode) - << ". Is a mongod instance already running?"); - } - _lockFileHandle->_fd = lockFile; - return Status::OK(); + if (ret != 0) { + int errorcode = errno; + ::close(lockFile); + return Status(ErrorCodes::DBPathInUse, + str::stream() << "Unable to lock file: " << _filespec << ' ' + << errnoWithDescription(errorcode) + << ". Is a mongod instance already running?"); } + _lockFileHandle->_fd = lockFile; + return Status::OK(); +} - void StorageEngineLockFile::close() { - if (!_lockFileHandle->isValid()) { - return; - } - ::close(_lockFileHandle->_fd); - _lockFileHandle->clear(); +void StorageEngineLockFile::close() { + if (!_lockFileHandle->isValid()) { + return; + } + ::close(_lockFileHandle->_fd); + _lockFileHandle->clear(); +} + +Status StorageEngineLockFile::writePid() { + if (!_lockFileHandle->isValid()) { + return Status(ErrorCodes::FileNotOpen, + str::stream() << "Unable to write process ID to " << _filespec + << " because file has not been opened."); } - Status StorageEngineLockFile::writePid() { - if (!_lockFileHandle->isValid()) { - return Status(ErrorCodes::FileNotOpen, str::stream() - << "Unable to write process ID to " << _filespec - << " because file has not been opened."); - } - - if (::ftruncate(_lockFileHandle->_fd, 0)) { - int errorcode = errno; - return Status(ErrorCodes::FileStreamFailed, str::stream() - << "Unable to write process id to file (ftruncate failed): " - << _filespec << ' ' << errnoWithDescription(errorcode)); - } + if (::ftruncate(_lockFileHandle->_fd, 0)) { + int errorcode = errno; + return Status(ErrorCodes::FileStreamFailed, + str::stream() << "Unable to write process id to file (ftruncate failed): " + << _filespec << ' ' << errnoWithDescription(errorcode)); + } - ProcessId pid = ProcessId::getCurrent(); - std::stringstream ss; - ss << pid << std::endl; - std::string pidStr = ss.str(); - int bytesWritten = ::write(_lockFileHandle->_fd, pidStr.c_str(), pidStr.size()); - if (bytesWritten < 0) { - int errorcode = errno; - return Status(ErrorCodes::FileStreamFailed, str::stream() - << "Unable to write process id " << pid.toString() << " to file: " - << _filespec << ' ' << errnoWithDescription(errorcode)); + ProcessId pid = ProcessId::getCurrent(); + std::stringstream ss; + ss << pid << std::endl; + std::string pidStr = ss.str(); + int bytesWritten = ::write(_lockFileHandle->_fd, pidStr.c_str(), pidStr.size()); + if (bytesWritten < 0) { + int errorcode = errno; + return Status(ErrorCodes::FileStreamFailed, + str::stream() << "Unable to write process id " << pid.toString() + << " to file: " << _filespec << ' ' + << errnoWithDescription(errorcode)); + + } else if (bytesWritten == 0) { + return Status(ErrorCodes::FileStreamFailed, + str::stream() << "Unable to write process id " << pid.toString() + << " to file: " << _filespec << " no data written."); + } - } - else if (bytesWritten == 0) { - return Status(ErrorCodes::FileStreamFailed, str::stream() - << "Unable to write process id " << pid.toString() << " to file: " - << _filespec << " no data written."); - } + if (::fsync(_lockFileHandle->_fd)) { + int errorcode = errno; + return Status(ErrorCodes::FileStreamFailed, + str::stream() << "Unable to write process id " << pid.toString() + << " to file (fsync failed): " << _filespec << ' ' + << errnoWithDescription(errorcode)); + } - if (::fsync(_lockFileHandle->_fd)) { - int errorcode = errno; - return Status(ErrorCodes::FileStreamFailed, str::stream() - << "Unable to write process id " << pid.toString() << " to file (fsync failed): " - << _filespec << ' ' << errnoWithDescription(errorcode)); - } + flushMyDirectory(_filespec); - flushMyDirectory(_filespec); + return Status::OK(); +} - return Status::OK(); +void StorageEngineLockFile::clearPidAndUnlock() { + if (!_lockFileHandle->isValid()) { + return; + } + log() << "shutdown: removing fs lock..."; + // This ought to be an unlink(), but Eliot says the last + // time that was attempted, there was a race condition + // with acquirePathLock(). + if (::ftruncate(_lockFileHandle->_fd, 0)) { + int errorcode = errno; + log() << "couldn't remove fs lock " << errnoWithDescription(errorcode); } - - void StorageEngineLockFile::clearPidAndUnlock() { - if (!_lockFileHandle->isValid()) { - return; - } - log() << "shutdown: removing fs lock..."; - // This ought to be an unlink(), but Eliot says the last - // time that was attempted, there was a race condition - // with acquirePathLock(). - if(::ftruncate(_lockFileHandle->_fd, 0)) { - int errorcode = errno; - log() << "couldn't remove fs lock " << errnoWithDescription(errorcode); - } #if !defined(__sun) - ::flock(_lockFileHandle->_fd, LOCK_UN); + ::flock(_lockFileHandle->_fd, LOCK_UN); #else - struct flock fileLockInfo = {0}; - fileLockInfo.l_type = F_UNLCK; - fileLockInfo.l_whence = SEEK_SET; - ::fcntl(_lockFileHandle->_fd, F_SETLK, &fileLockInfo); + struct flock fileLockInfo = {0}; + fileLockInfo.l_type = F_UNLCK; + fileLockInfo.l_whence = SEEK_SET; + ::fcntl(_lockFileHandle->_fd, F_SETLK, &fileLockInfo); #endif // !defined(__sun) - } +} } // namespace mongo |