1
0
Fork 0

factored out lock-file handling into LockFileFeature

This commit is contained in:
jsteemann 2016-07-15 14:44:06 +02:00
parent 87a96ece67
commit 30d32bb70e
8 changed files with 152 additions and 73 deletions

View File

@ -247,6 +247,7 @@ add_executable(${BIN_ARANGOD}
RestServer/FileDescriptorsFeature.cpp
RestServer/FrontendFeature.cpp
RestServer/InitDatabaseFeature.cpp
RestServer/LockfileFeature.cpp
RestServer/QueryRegistryFeature.cpp
RestServer/RestServerFeature.cpp
RestServer/ScriptFeature.cpp

View File

@ -43,7 +43,7 @@ class DatabaseFeature final : public application_features::ApplicationFeature {
public:
TRI_vocbase_t* vocbase() const { return _vocbase; }
std::string databasePath() const { return _databasePath; }
bool ignoreDatafileErrors() const { return _ignoreDatafileErrors; }
bool isInitiallyEmpty() const { return _isInitiallyEmpty; }

View File

@ -0,0 +1,82 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////
#include "LockfileFeature.h"
#include "Basics/Exceptions.h"
#include "Basics/FileUtils.h"
#include "Basics/files.h"
#include "RestServer/DatabaseFeature.h"
using namespace arangodb;
using namespace arangodb::basics;
LockfileFeature::LockfileFeature(
application_features::ApplicationServer* server)
: ApplicationFeature(server, "Lockfile") {
setOptional(false);
requiresElevatedPrivileges(false);
startsAfter("Logger");
}
void LockfileFeature::prepare() {
// build lockfile name
DatabaseFeature* database = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
std::string databasePath = database->databasePath();
TRI_ASSERT(!databasePath.empty());
_lockFilename = basics::FileUtils::buildFilename(databasePath, "LOCK");
TRI_ASSERT(!_lockFilename.empty());
int res = TRI_VerifyLockFile(_lockFilename.c_str());
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "database is locked, please check the lock file '" << _lockFilename << "'";
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATADIR_LOCKED);
}
if (TRI_ExistsFile(_lockFilename.c_str())) {
TRI_UnlinkFile(_lockFilename.c_str());
}
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR)
<< "cannot lock the database directory, please check the lock file '"
<< _lockFilename << "': " << TRI_errno_string(res);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATADIR_UNLOCKABLE);
}
res = TRI_CreateLockFile(_lockFilename.c_str());
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR)
<< "cannot lock the database directory, please check the lock file '"
<< _lockFilename << "': " << TRI_errno_string(res);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATADIR_UNLOCKABLE);
}
}
void LockfileFeature::unprepare() {
TRI_DestroyLockFile(_lockFilename.c_str());
}

View File

@ -0,0 +1,42 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_APPLICATION_FEATURES_LOCK_FILE_FEATURE_H
#define ARANGODB_APPLICATION_FEATURES_LOCL_FILE_FEATURE_H 1
#include "ApplicationFeatures/ApplicationFeature.h"
namespace arangodb {
class LockfileFeature final : public application_features::ApplicationFeature {
public:
explicit LockfileFeature(application_features::ApplicationServer* server);
public:
void prepare() override final;
void unprepare() override final;
private:
std::string _lockFilename;
};
}
#endif

View File

@ -57,6 +57,7 @@
#include "RestServer/FileDescriptorsFeature.h"
#include "RestServer/FrontendFeature.h"
#include "RestServer/InitDatabaseFeature.h"
#include "RestServer/LockfileFeature.h"
#include "RestServer/QueryRegistryFeature.h"
#include "RestServer/RestServerFeature.h"
#include "RestServer/ScriptFeature.h"
@ -125,6 +126,7 @@ static int runServer(int argc, char** argv) {
server.addFeature(new FrontendFeature(&server));
server.addFeature(new InitDatabaseFeature(&server, nonServerFeatures));
server.addFeature(new LanguageFeature(&server));
server.addFeature(new LockfileFeature(&server));
server.addFeature(new LogfileManager(&server));
server.addFeature(new LoggerBufferFeature(&server));
server.addFeature(new LoggerFeature(&server, true));

View File

@ -38,7 +38,8 @@ EngineSelectorFeature::EngineSelectorFeature(
: ApplicationFeature(server, "EngineSelector"), _engine(MMFilesEngine::EngineName) {
setOptional(false);
requiresElevatedPrivileges(false);
startsAfter("Logger");
startsAfter("Database");
startsAfter("LogfileManager");
}
void EngineSelectorFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {

View File

@ -306,19 +306,18 @@ static int CreateBaseApplicationDirectory(char const* basePath,
/// @brief create app subdirectory for a database
////////////////////////////////////////////////////////////////////////////////
static int CreateApplicationDirectory(char const* name, char const* basePath) {
if (basePath == nullptr || strlen(basePath) == 0) {
static int CreateApplicationDirectory(std::string const& name, std::string const& basePath) {
if (basePath.empty()) {
return TRI_ERROR_NO_ERROR;
}
std::string const path = basics::FileUtils::buildFilename(basics::FileUtils::buildFilename(basePath, "db"), name);
int res = TRI_ERROR_NO_ERROR;
char* path = TRI_Concatenate3File(basePath, "_db", name);
if (path != nullptr) {
if (!TRI_IsDirectory(path)) {
if (!TRI_IsDirectory(path.c_str())) {
long systemError;
std::string errorMessage;
res = TRI_CreateRecursiveDirectory(path, systemError, errorMessage);
res = TRI_CreateRecursiveDirectory(path.c_str(), systemError, errorMessage);
if (res == TRI_ERROR_NO_ERROR) {
if (arangodb::wal::LogfileManager::instance()->isInRecovery()) {
@ -338,9 +337,6 @@ static int CreateApplicationDirectory(char const* name, char const* basePath) {
}
}
TRI_Free(TRI_CORE_MEM_ZONE, path);
}
return res;
}
@ -520,7 +516,7 @@ static int OpenDatabases(TRI_server_t* server, bool isUpgrade) {
ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
auto appPath = dealer->appPath();
res = CreateApplicationDirectory(databaseName.c_str(), appPath.c_str());
res = CreateApplicationDirectory(databaseName, appPath);
if (res != TRI_ERROR_NO_ERROR) {
break;
@ -1149,19 +1145,9 @@ int TRI_InitServer(TRI_server_t* server,
return TRI_ERROR_OUT_OF_MEMORY;
}
server->_lockFilename = TRI_Concatenate2File(server->_basePath, "LOCK");
if (server->_lockFilename == nullptr) {
TRI_Free(TRI_CORE_MEM_ZONE, server->_databasePath);
TRI_Free(TRI_CORE_MEM_ZONE, server->_basePath);
return TRI_ERROR_OUT_OF_MEMORY;
}
server->_serverIdFilename = TRI_Concatenate2File(server->_basePath, "SERVER");
if (server->_serverIdFilename == nullptr) {
TRI_Free(TRI_CORE_MEM_ZONE, server->_lockFilename);
TRI_Free(TRI_CORE_MEM_ZONE, server->_databasePath);
TRI_Free(TRI_CORE_MEM_ZONE, server->_basePath);
@ -1208,11 +1194,8 @@ TRI_server_id_t TRI_GetIdServer() { return ServerId; }
int TRI_StartServer(TRI_server_t* server, bool checkVersion,
bool performUpgrade) {
int res;
if (!TRI_IsDirectory(server->_basePath)) {
LOG(ERR) << "database path '" << server->_basePath
<< "' is not a directory";
LOG(ERR) << "database path '" << server->_basePath << "' is not a directory";
return TRI_ERROR_ARANGO_DATADIR_INVALID;
}
@ -1225,33 +1208,6 @@ int TRI_StartServer(TRI_server_t* server, bool checkVersion,
return TRI_ERROR_ARANGO_DATADIR_NOT_WRITABLE;
}
// ...........................................................................
// check that the database is not locked and lock it
// ...........................................................................
res = TRI_VerifyLockFile(server->_lockFilename);
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "database is locked, please check the lock file '"
<< server->_lockFilename << "'";
return TRI_ERROR_ARANGO_DATADIR_LOCKED;
}
if (TRI_ExistsFile(server->_lockFilename)) {
TRI_UnlinkFile(server->_lockFilename);
}
res = TRI_CreateLockFile(server->_lockFilename);
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR)
<< "cannot lock the database directory, please check the lock file '"
<< server->_lockFilename << "': " << TRI_errno_string(res);
return TRI_ERROR_ARANGO_DATADIR_UNLOCKABLE;
}
// ...........................................................................
// read the server id
// ...........................................................................
@ -1421,8 +1377,6 @@ int TRI_StopServer(TRI_server_t* server) {
CloseDatabases(server);
TRI_DestroyLockFile(server->_lockFilename);
return res;
}
@ -1628,7 +1582,7 @@ int TRI_CreateDatabaseServer(TRI_server_t* server, TRI_voc_tick_t databaseId,
ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
auto appPath = dealer->appPath();
CreateApplicationDirectory(vocbase->_name, appPath.c_str());
CreateApplicationDirectory(vocbase->_name, appPath);
if (!arangodb::wal::LogfileManager::instance()->isInRecovery()) {
TRI_StartCompactorVocBase(vocbase);
@ -2155,7 +2109,6 @@ TRI_server_t::TRI_server_t()
_queryRegistry(nullptr),
_basePath(nullptr),
_databasePath(nullptr),
_lockFilename(nullptr),
_serverIdFilename(nullptr),
_disableReplicationAppliers(false),
_disableCompactor(false),
@ -2171,7 +2124,6 @@ TRI_server_t::~TRI_server_t() {
delete p;
TRI_Free(TRI_CORE_MEM_ZONE, _serverIdFilename);
TRI_Free(TRI_CORE_MEM_ZONE, _lockFilename);
TRI_Free(TRI_CORE_MEM_ZONE, _databasePath);
TRI_Free(TRI_CORE_MEM_ZONE, _basePath);
}

View File

@ -75,7 +75,6 @@ struct TRI_server_t {
char* _basePath;
char* _databasePath;
char* _lockFilename;
char* _serverIdFilename;
bool _disableReplicationAppliers;