mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'master' of https://github.com/fceller/ArangoDB into devel
This commit is contained in:
commit
9c92948872
23
CHANGELOG
23
CHANGELOG
|
@ -1,19 +1,30 @@
|
|||
v1.x.x (2012-XX-XX)
|
||||
-------------------
|
||||
|
||||
* fixed issue #122: arangod doesn't start if <log.file> cannot be created
|
||||
|
||||
* fixed issue #121: wrong collection size reported
|
||||
|
||||
* fixed escaping of document data in HTML admin front end
|
||||
|
||||
* added server startup option --server.disable-admin-interface to turn off the HTML admin interface
|
||||
* added server startup option --server.disable-admin-interface to turn off the
|
||||
HTML admin interface
|
||||
|
||||
* honor server startup option --database.maximal-journal-size when creating new collections without specific journalsize setting. Previously, these collections were always created with journal file sizes of 32 MB and the --database.maximal-journal-size setting was ignored
|
||||
* honor server startup option --database.maximal-journal-size when creating new
|
||||
collections without specific journalsize setting. Previously, these
|
||||
collections were always created with journal file sizes of 32 MB and the
|
||||
--database.maximal-journal-size setting was ignored
|
||||
|
||||
* added server startup option --database.wait-for-sync to control the default
|
||||
behavior
|
||||
|
||||
v1.0.alpha3 (2012-06-30)
|
||||
------------------------
|
||||
|
||||
* fixed issue #116: createCollection=create option doesn't work
|
||||
|
||||
* fixed issue #115: Compilation issue under OSX 10.7 Lion & 10.8 Mountain Lion (homebrew)
|
||||
* fixed issue #115: Compilation issue under OSX 10.7 Lion & 10.8 Mountain Lion
|
||||
(homebrew)
|
||||
|
||||
* fixed issue #114: image not found
|
||||
|
||||
|
@ -29,7 +40,8 @@ v1.0.alpha2 (2012-06-24)
|
|||
|
||||
* fixed issue #103: Should we cleanup the directory structure
|
||||
|
||||
* fixed issue #100: "count" attribute exists in cursor response with "count: false"
|
||||
* fixed issue #100: "count" attribute exists in cursor response with "count:
|
||||
false"
|
||||
|
||||
* fixed issue #84 explain command
|
||||
|
||||
|
@ -53,7 +65,8 @@ v1.0.alpha2 (2012-06-24)
|
|||
|
||||
* fixed several range-related assertion failures in the AQL query optimiser
|
||||
|
||||
* fixed AQL query optimisations for some edge cases (e.g. nested subqueries with invalid constant filter expressions)
|
||||
* fixed AQL query optimisations for some edge cases (e.g. nested subqueries with
|
||||
invalid constant filter expressions)
|
||||
|
||||
|
||||
v1.0.alpha1 (2012-05-28)
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
/// <li>@ref CommandLineArangoDisableAdminInterface "server.disable-admin-interface"</li>
|
||||
/// <li>@ref CommandLineArangoDirectory "database.directory"</li>
|
||||
/// <li>@ref CommandLineArangoMaximalJournalSize "database.maximal-journal-size"</li>
|
||||
/// <li>@ref CommandLineArangoWaitForSync "database.wait-for-sync"</li>
|
||||
/// <li>@ref CommandLineArangoRemoveOnDrop "database.remove-on-drop"</li>
|
||||
/// </ul>
|
||||
/// </li>
|
||||
|
@ -175,6 +176,9 @@
|
|||
/// @anchor CommandLineArangoMaximalJournalSize
|
||||
/// @copydetails triagens::arango::ArangoServer::_defaultMaximalSize
|
||||
///
|
||||
/// @anchor CommandLineArangoWaitForSync
|
||||
/// @copydetails triagens::arango::ArangoServer::_defaultWaitForSync
|
||||
///
|
||||
/// @anchor CommandLineArangoRemoveOnDrop
|
||||
/// @copydetails triagens::arango::ArangoServer::_removeOnDrop
|
||||
///
|
||||
|
|
|
@ -195,6 +195,7 @@ ArangoServer::ArangoServer (int argc, char** argv)
|
|||
_removeOnDrop(true),
|
||||
_removeOnCompacted(true),
|
||||
_defaultMaximalSize(TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE),
|
||||
_defaultWaitForSync(false),
|
||||
_vocbase(0) {
|
||||
char* p;
|
||||
|
||||
|
@ -361,7 +362,7 @@ void ArangoServer::buildApplicationServer () {
|
|||
// a http server
|
||||
// .............................................................................
|
||||
|
||||
_applicationHttpServer = new ApplicationHttpServer(_applicationScheduler, _applicationDispatcher);
|
||||
_applicationHttpServer = new ApplicationHttpServer(_applicationServer, _applicationScheduler, _applicationDispatcher);
|
||||
_applicationServer->addFeature(_applicationHttpServer);
|
||||
|
||||
// .............................................................................
|
||||
|
@ -414,6 +415,7 @@ void ArangoServer::buildApplicationServer () {
|
|||
additional["DATABASE Options:help-admin"]
|
||||
("database.remove-on-drop", &_removeOnDrop, "wipe a collection from disk after dropping")
|
||||
("database.maximal-journal-size", &_defaultMaximalSize, "default maximal journal size, can be overwritten when creating a collection")
|
||||
("database.wait-for-sync", &_defaultWaitForSync, "default wait-for-sync behavior, can be overwritten when creating a collection")
|
||||
;
|
||||
|
||||
additional["DATABASE Options:help-devel"]
|
||||
|
@ -1102,6 +1104,7 @@ void ArangoServer::openDatabase () {
|
|||
_vocbase->_removeOnDrop = _removeOnDrop;
|
||||
_vocbase->_removeOnCompacted = _removeOnCompacted;
|
||||
_vocbase->_defaultMaximalSize = _defaultMaximalSize;
|
||||
_vocbase->_defaultWaitForSync = _defaultWaitForSync;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -392,6 +392,19 @@ namespace triagens {
|
|||
|
||||
uint64_t _defaultMaximalSize;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief default journal size
|
||||
///
|
||||
/// @CMDOPT{--database.wait-for-size @CA{boolean}}
|
||||
///
|
||||
/// Default wait-for-sync value. Can be overwritten when creating a new
|
||||
/// collection.
|
||||
///
|
||||
/// The default is @LIT{false}.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _defaultWaitForSync;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief unit tests
|
||||
///
|
||||
|
|
|
@ -752,10 +752,10 @@ static v8::Handle<v8::Value> CreateVocBase (v8::Arguments const& argv, bool edge
|
|||
"<properties>.journalSize too small")));
|
||||
}
|
||||
|
||||
TRI_InitParameterCollection(¶meter, name.c_str(), (TRI_voc_size_t) s);
|
||||
TRI_InitParameterCollection(vocbase, ¶meter, name.c_str(), (TRI_voc_size_t) s);
|
||||
}
|
||||
else {
|
||||
TRI_InitParameterCollection(¶meter, name.c_str(), vocbase->_defaultMaximalSize);
|
||||
TRI_InitParameterCollection(vocbase, ¶meter, name.c_str(), vocbase->_defaultMaximalSize);
|
||||
}
|
||||
|
||||
if (p->Has(waitForSyncKey)) {
|
||||
|
@ -767,7 +767,7 @@ static v8::Handle<v8::Value> CreateVocBase (v8::Arguments const& argv, bool edge
|
|||
}
|
||||
}
|
||||
else {
|
||||
TRI_InitParameterCollection(¶meter, name.c_str(), vocbase->_defaultMaximalSize);
|
||||
TRI_InitParameterCollection(vocbase, ¶meter, name.c_str(), vocbase->_defaultMaximalSize);
|
||||
}
|
||||
|
||||
TRI_voc_cid_t cid = 0;
|
||||
|
@ -775,10 +775,12 @@ static v8::Handle<v8::Value> CreateVocBase (v8::Arguments const& argv, bool edge
|
|||
// extract collection id
|
||||
if (3 <= argv.Length()) {
|
||||
v8::Handle<v8::Value> val = argv[2];
|
||||
if (!val->IsNull() && !val->IsUndefined()) {
|
||||
// a pre-defined collection is passed when data is re-imported from a dump etc.
|
||||
// this allows reproduction of data from different servers
|
||||
|
||||
// a pre-defined collection is passed when data is re-imported from a dump etc.
|
||||
// this allows reproduction of data from different servers
|
||||
if (! val->IsNull() && ! val->IsUndefined()) {
|
||||
cid = TRI_ObjectToUInt64(argv[2]);
|
||||
|
||||
if (cid <= 0) {
|
||||
return scope.Close(v8::ThrowException(
|
||||
TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER,
|
||||
|
|
|
@ -366,7 +366,8 @@ static bool CloseDataFiles (const TRI_vector_pointer_t* const files) {
|
|||
/// @brief initializes a collection parameter block
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitParameterCollection (TRI_col_parameter_t* parameter,
|
||||
void TRI_InitParameterCollection (TRI_vocbase_t* vocbase,
|
||||
TRI_col_parameter_t* parameter,
|
||||
char const* name,
|
||||
TRI_voc_size_t maximalSize) {
|
||||
assert(parameter);
|
||||
|
@ -374,7 +375,7 @@ void TRI_InitParameterCollection (TRI_col_parameter_t* parameter,
|
|||
|
||||
parameter->_type = TRI_COL_TYPE_SIMPLE_DOCUMENT;
|
||||
|
||||
parameter->_waitForSync = false;
|
||||
parameter->_waitForSync = vocbase->_defaultWaitForSync;
|
||||
parameter->_maximalSize = (maximalSize / PageSize) * PageSize;
|
||||
|
||||
parameter->_isSystem = false;
|
||||
|
|
|
@ -230,7 +230,8 @@ TRI_collection_t;
|
|||
/// @brief initializes a collection parameter block
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitParameterCollection (TRI_col_parameter_t*,
|
||||
void TRI_InitParameterCollection (TRI_vocbase_t* vocbase,
|
||||
TRI_col_parameter_t*,
|
||||
char const* name,
|
||||
TRI_voc_size_t maximalSize);
|
||||
|
||||
|
|
|
@ -910,7 +910,7 @@ TRI_shaper_t* TRI_CreateVocShaper (TRI_vocbase_t* vocbase,
|
|||
TRI_col_parameter_t parameter;
|
||||
bool ok;
|
||||
|
||||
TRI_InitParameterCollection(¶meter, name, SHAPER_DATAFILE_SIZE);
|
||||
TRI_InitParameterCollection(vocbase, ¶meter, name, SHAPER_DATAFILE_SIZE);
|
||||
|
||||
collection = TRI_CreateBlobCollection(vocbase, path, ¶meter);
|
||||
|
||||
|
|
|
@ -719,10 +719,9 @@ static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t*
|
|||
TRI_sim_collection_t* sim;
|
||||
TRI_col_parameter_t parameter;
|
||||
|
||||
TRI_InitParameterCollection(¶meter, collection->_name, vocbase->_defaultMaximalSize);
|
||||
TRI_InitParameterCollection(vocbase, ¶meter, collection->_name, vocbase->_defaultMaximalSize);
|
||||
|
||||
parameter._type = type;
|
||||
parameter._waitForSync = false;
|
||||
|
||||
sim = TRI_CreateSimCollection(vocbase, vocbase->_path, ¶meter, collection->_cid);
|
||||
|
||||
|
@ -1100,6 +1099,7 @@ TRI_vocbase_t* TRI_OpenVocBase (char const* path) {
|
|||
// defaults
|
||||
vocbase->_removeOnDrop = true;
|
||||
vocbase->_removeOnCompacted = true;
|
||||
vocbase->_defaultWaitForSync = false;
|
||||
vocbase->_defaultMaximalSize = TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE;
|
||||
|
||||
// scan the database path for collections
|
||||
|
|
|
@ -347,6 +347,7 @@ typedef struct TRI_vocbase_s {
|
|||
|
||||
bool _removeOnDrop; // wipe collection from disk after dropping
|
||||
bool _removeOnCompacted; // wipe datafile from disk after compaction
|
||||
bool _defaultWaitForSync;
|
||||
TRI_voc_size_t _defaultMaximalSize;
|
||||
|
||||
TRI_read_write_lock_t _lock;
|
||||
|
|
|
@ -116,9 +116,11 @@ ApplicationServer::ApplicationServer (string const& title, string const& version
|
|||
_systemConfigFile(),
|
||||
_systemConfigPath(),
|
||||
_uid(),
|
||||
_loggingUid(0),
|
||||
_realUid(0),
|
||||
_effectiveUid(0),
|
||||
_gid(),
|
||||
_loggingGid(0),
|
||||
_realGid(0),
|
||||
_effectiveGid(0),
|
||||
_logApplicationName("triagens"),
|
||||
_logHostName("-"),
|
||||
_logFacility("-"),
|
||||
|
@ -193,24 +195,6 @@ void ApplicationServer::setUserConfigFile (string const& name) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationServer::setupLogging () {
|
||||
#ifdef TRI_HAVE_SETGID
|
||||
gid_t gid;
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETUID
|
||||
uid_t uid;
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETGID
|
||||
gid = getegid();
|
||||
setegid(_loggingGid);
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETUID
|
||||
uid = geteuid();
|
||||
seteuid(_loggingUid);
|
||||
#endif
|
||||
|
||||
bool threaded = TRI_ShutdownLogging();
|
||||
|
||||
TRI_InitialiseLogging(threaded);
|
||||
|
@ -250,14 +234,6 @@ void ApplicationServer::setupLogging () {
|
|||
}
|
||||
}
|
||||
TRI_CreateLogAppenderSyslog(_logPrefix, _logSyslog);
|
||||
|
||||
#ifdef TRI_HAVE_SETGID
|
||||
setegid(gid);
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETUID
|
||||
seteuid(uid);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -346,8 +322,18 @@ bool ApplicationServer::parse (int argc,
|
|||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// UID and GID
|
||||
// .............................................................................
|
||||
|
||||
storeRealPrivileges();
|
||||
extractPrivileges();
|
||||
dropPrivileges();
|
||||
|
||||
// .............................................................................
|
||||
// setup logging
|
||||
storeLoggingPrivileges();
|
||||
// .............................................................................
|
||||
|
||||
setupLogging();
|
||||
|
||||
// .............................................................................
|
||||
|
@ -375,7 +361,6 @@ bool ApplicationServer::parse (int argc,
|
|||
// re-set logging using the additional config file entries
|
||||
setupLogging();
|
||||
|
||||
|
||||
// .............................................................................
|
||||
// parse phase 2
|
||||
// .............................................................................
|
||||
|
@ -407,12 +392,6 @@ bool ApplicationServer::parse (int argc,
|
|||
}
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// now drop all privilegs
|
||||
// .............................................................................
|
||||
|
||||
dropPriviliges();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -489,6 +468,8 @@ void ApplicationServer::start () {
|
|||
|
||||
LOGGER_TRACE << "opened server feature '" << feature->getName() << "'";
|
||||
}
|
||||
|
||||
dropPrivilegesPermanently();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -588,6 +569,124 @@ void ApplicationServer::shutdown () {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief raise the privileges
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationServer::raisePrivileges () {
|
||||
|
||||
#ifdef TRI_HAVE_SETGID
|
||||
|
||||
if (_effectiveGid != _realGid) {
|
||||
int res = setegid(_realGid);
|
||||
|
||||
if (res != 0) {
|
||||
LOGGER_FATAL << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno);
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETUID
|
||||
|
||||
if (_effectiveUid != _realUid) {
|
||||
int res = seteuid(_realUid);
|
||||
|
||||
if (res != 0) {
|
||||
LOGGER_FATAL << "cannot set uid '" << _uid << "', because " << strerror(errno);
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops the privileges
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationServer::dropPrivileges () {
|
||||
|
||||
#ifdef TRI_HAVE_SETGID
|
||||
|
||||
if (_effectiveGid != _realGid) {
|
||||
int res = setegid(_effectiveGid);
|
||||
|
||||
if (res != 0) {
|
||||
LOGGER_FATAL << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno);
|
||||
cerr << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno) << endl;
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETUID
|
||||
|
||||
if (_effectiveUid != _realUid) {
|
||||
int res = seteuid(_effectiveUid);
|
||||
|
||||
if (res != 0) {
|
||||
LOGGER_FATAL << "cannot set uid '" << _uid << "', because " << strerror(errno);
|
||||
cerr << "cannot set uid '" << _uid << "', because " << strerror(errno) << endl;
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops the privileges permanently
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationServer::dropPrivilegesPermanently () {
|
||||
raisePrivileges();
|
||||
|
||||
#ifdef TRI_HAVE_SETGID
|
||||
|
||||
if (_effectiveGid != _realGid) {
|
||||
LOGGER_INFO << "permanently changing the gid to '" << _effectiveGid << "'";
|
||||
|
||||
int res = setgid(_effectiveGid);
|
||||
|
||||
if (res != 0) {
|
||||
LOGGER_FATAL << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno);
|
||||
cerr << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno) << endl;
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
_realGid = _effectiveGid;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETUID
|
||||
|
||||
if (_effectiveUid != _realUid) {
|
||||
LOGGER_INFO << "permanently changing the uid to '" << _effectiveUid << "'";
|
||||
|
||||
int res = setuid(_effectiveUid);
|
||||
|
||||
if (res != 0) {
|
||||
LOGGER_FATAL << "cannot set uid '" << _uid << "', because " << strerror(errno);
|
||||
cerr << "cannot set uid '" << _uid << "', because " << strerror(errno) << endl;
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
_realUid = _effectiveUid;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -853,40 +952,26 @@ bool ApplicationServer::readConfigurationFile () {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief saves the logging privileges
|
||||
/// @brief extract the privileges to use
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationServer::storeLoggingPrivileges () {
|
||||
#ifdef TRI_HAVE_SETGID
|
||||
_loggingGid = getegid();
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETUID
|
||||
_loggingUid = geteuid();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops the privileges
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationServer::dropPriviliges () {
|
||||
void ApplicationServer::extractPrivileges() {
|
||||
|
||||
#ifdef TRI_HAVE_SETGID
|
||||
|
||||
if (! _gid.empty()) {
|
||||
LOGGER_TRACE << "trying to switch to group '" << _gid << "'";
|
||||
|
||||
if (_gid.empty()) {
|
||||
_effectiveGid = getgid();
|
||||
}
|
||||
else {
|
||||
int gidNumber = TRI_Int32String(_gid.c_str());
|
||||
|
||||
if (TRI_errno() == TRI_ERROR_NO_ERROR) {
|
||||
LOGGER_TRACE << "trying to switch to numeric gid '" << gidNumber << "' for '" << _gid << "'";
|
||||
|
||||
#ifdef TRI_HAVE_GETGRGID
|
||||
group* g = getgrgid(gidNumber);
|
||||
|
||||
if (g == 0) {
|
||||
cerr << "unknown numeric gid '" << _gid << "'" << endl;
|
||||
LOGGER_FATAL << "unknown numeric gid '" << _gid << "'";
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -900,47 +985,41 @@ void ApplicationServer::dropPriviliges () {
|
|||
|
||||
if (g != 0) {
|
||||
gidNumber = g->gr_gid;
|
||||
LOGGER_TRACE << "trying to switch to numeric gid '" << gidNumber << "'";
|
||||
}
|
||||
else {
|
||||
cerr << "cannot convert groupname '" << _gid << "' to numeric gid" << endl;
|
||||
LOGGER_FATAL << "cannot convert groupname '" << _gid << "' to numeric gid";
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#else
|
||||
cerr << "cannot convert groupname '" << _gid << "' to numeric gid" << endl;
|
||||
LOGGER_FATAL << "cannot convert groupname '" << _gid << "' to numeric gid";
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
LOGGER_INFO << "changing gid to '" << gidNumber << "'";
|
||||
|
||||
int res = setegid(gidNumber);
|
||||
|
||||
if (res != 0) {
|
||||
LOGGER_FATAL << "cannot set gid '" << _gid << "', because " << strerror(errno);
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
_effectiveGid = gidNumber;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETUID
|
||||
|
||||
if (! _uid.empty()) {
|
||||
LOGGER_TRACE << "trying to switch to user '" << _uid << "'";
|
||||
|
||||
if (_uid.empty()) {
|
||||
_effectiveUid = getuid();
|
||||
}
|
||||
else {
|
||||
int uidNumber = TRI_Int32String(_uid.c_str());
|
||||
|
||||
if (TRI_errno() == TRI_ERROR_NO_ERROR) {
|
||||
LOGGER_TRACE << "trying to switch to numeric uid '" << uidNumber << "' for '" << _uid << "'";
|
||||
|
||||
#ifdef TRI_HAVE_GETPWUID
|
||||
passwd* p = getpwuid(uidNumber);
|
||||
|
||||
if (p == 0) {
|
||||
cerr << "unknown numeric uid '" << _uid << "'" << endl;
|
||||
LOGGER_FATAL << "unknown numeric uid '" << _uid << "'";
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -954,34 +1033,41 @@ void ApplicationServer::dropPriviliges () {
|
|||
|
||||
if (p != 0) {
|
||||
uidNumber = p->pw_uid;
|
||||
LOGGER_TRACE << "trying to switch to numeric uid '" << uidNumber << "'";
|
||||
}
|
||||
else {
|
||||
cerr << "cannot convert username '" << _uid << "' to numeric uid" << endl;
|
||||
LOGGER_FATAL << "cannot convert username '" << _uid << "' to numeric uid";
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#else
|
||||
cerr << "cannot convert username '" << _uid << "' to numeric uid" << endl;
|
||||
LOGGER_FATAL << "cannot convert username '" << _uid << "' to numeric uid";
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
LOGGER_INFO << "changing uid to '" << uidNumber << "'";
|
||||
|
||||
int res = seteuid(uidNumber);
|
||||
|
||||
if (res != 0) {
|
||||
LOGGER_FATAL << "cannot set uid '" << _uid << "', because " << strerror(errno);
|
||||
TRI_ShutdownLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
_effectiveUid = uidNumber;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief saves the logging privileges
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationServer::storeRealPrivileges () {
|
||||
#ifdef TRI_HAVE_SETGID
|
||||
_realGid = getgid();
|
||||
#endif
|
||||
|
||||
#ifdef TRI_HAVE_SETUID
|
||||
_realUid = getuid();
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -233,6 +233,24 @@ namespace triagens {
|
|||
|
||||
void shutdown ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief raises the privileges
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void raisePrivileges ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops the privileges
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void dropPrivileges ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops the privileges permanently
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void dropPrivilegesPermanently ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -282,16 +300,16 @@ namespace triagens {
|
|||
bool readConfigurationFile ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief saves the logging privileges
|
||||
/// @brief extracts the real privileges
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void storeLoggingPrivileges ();
|
||||
void storeRealPrivileges ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops the privileges
|
||||
/// @brief extracts the privileges from the command-line
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void dropPriviliges ();
|
||||
void extractPrivileges ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -484,10 +502,16 @@ namespace triagens {
|
|||
string _uid;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief uid for logging
|
||||
/// @brief real uid
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uid_t _loggingUid;
|
||||
uid_t _realUid;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief effective uid
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uid_t _effectiveUid;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the group id to use for the process
|
||||
|
@ -508,10 +532,16 @@ namespace triagens {
|
|||
string _gid;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief gid for logging
|
||||
/// @brief real gid
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
gid_t _loggingGid;
|
||||
gid_t _realGid;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief effective gid
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
gid_t _effectiveGid;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief log application name
|
||||
|
|
|
@ -51,9 +51,11 @@ using namespace std;
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ApplicationHttpServer::ApplicationHttpServer (ApplicationScheduler* applicationScheduler,
|
||||
ApplicationHttpServer::ApplicationHttpServer (ApplicationServer* applicationServer,
|
||||
ApplicationScheduler* applicationScheduler,
|
||||
ApplicationDispatcher* applicationDispatcher)
|
||||
: ApplicationFeature("HttpServer"),
|
||||
_applicationServer(applicationServer),
|
||||
_applicationScheduler(applicationScheduler),
|
||||
_applicationDispatcher(applicationDispatcher),
|
||||
_showPort(true),
|
||||
|
@ -253,6 +255,8 @@ HttpServer* ApplicationHttpServer::buildHttpServer (HttpServer* httpServer,
|
|||
deque<AddressPort> addresses;
|
||||
addresses.insert(addresses.begin(), ports.begin(), ports.end());
|
||||
|
||||
_applicationServer->raisePrivileges();
|
||||
|
||||
while (! addresses.empty()) {
|
||||
AddressPort ap = addresses[0];
|
||||
addresses.pop_front();
|
||||
|
@ -291,6 +295,8 @@ HttpServer* ApplicationHttpServer::buildHttpServer (HttpServer* httpServer,
|
|||
}
|
||||
}
|
||||
|
||||
_applicationServer->dropPrivileges();
|
||||
|
||||
return httpServer;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,9 @@ namespace triagens {
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ApplicationHttpServer (ApplicationScheduler*, ApplicationDispatcher*);
|
||||
ApplicationHttpServer (ApplicationServer*,
|
||||
ApplicationScheduler*,
|
||||
ApplicationDispatcher*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destructor
|
||||
|
@ -206,6 +208,12 @@ namespace triagens {
|
|||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief application server
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ApplicationServer* _applicationServer;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief application scheduler
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -91,9 +91,11 @@ namespace {
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ApplicationHttpsServer::ApplicationHttpsServer (ApplicationScheduler* applicationScheduler,
|
||||
ApplicationHttpsServer::ApplicationHttpsServer (ApplicationServer* applicationServer,
|
||||
ApplicationScheduler* applicationScheduler,
|
||||
ApplicationDispatcher* applicationDispatcher)
|
||||
: ApplicationFeature("HttpsServer"),
|
||||
_applicationServer(applicationServer),
|
||||
_applicationScheduler(applicationScheduler),
|
||||
_applicationDispatcher(applicationDispatcher),
|
||||
_showPort(true),
|
||||
|
@ -287,6 +289,8 @@ HttpsServer* ApplicationHttpsServer::buildHttpsServer (HttpHandlerFactory* httpH
|
|||
deque<AddressPort> addresses;
|
||||
addresses.insert(addresses.begin(), ports.begin(), ports.end());
|
||||
|
||||
_applicationServer->raisePrivileges();
|
||||
|
||||
while (! addresses.empty()) {
|
||||
AddressPort ap = addresses[0];
|
||||
addresses.pop_front();
|
||||
|
@ -325,6 +329,8 @@ HttpsServer* ApplicationHttpsServer::buildHttpsServer (HttpHandlerFactory* httpH
|
|||
}
|
||||
}
|
||||
|
||||
_applicationServer->dropPrivileges();
|
||||
|
||||
return httpsServer;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace triagens {
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ApplicationHttpsServer (ApplicationScheduler*, ApplicationDispatcher*);
|
||||
ApplicationHttpsServer (ApplicationServer*, ApplicationScheduler*, ApplicationDispatcher*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destructor
|
||||
|
@ -194,6 +194,12 @@ namespace triagens {
|
|||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief application server
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ApplicationServer* _applicationServer;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief application scheduler
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -334,6 +334,8 @@ void AnyServer::prepareServer () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int AnyServer::startupSupervisor () {
|
||||
static time_t MIN_TIME_ALIVE_IN_SEC = 30;
|
||||
|
||||
LOGGER_INFO << "starting up in supervisor mode";
|
||||
|
||||
string current;
|
||||
|
@ -341,10 +343,13 @@ int AnyServer::startupSupervisor () {
|
|||
|
||||
// main process
|
||||
if (result == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// child process
|
||||
else if (result == 1) {
|
||||
time_t startTime = time(0);
|
||||
time_t t;
|
||||
bool done = false;
|
||||
result = 0;
|
||||
|
||||
|
@ -368,8 +373,18 @@ int AnyServer::startupSupervisor () {
|
|||
done = true;
|
||||
}
|
||||
else {
|
||||
LOGGER_ERROR << "child " << pid << " died of a horrible death, exit status " << WEXITSTATUS(status);
|
||||
done = false;
|
||||
t = time(0) - startTime;
|
||||
|
||||
LOGGER_ERROR << "child " << pid << " died a horrible death, exit status " << WEXITSTATUS(status);
|
||||
|
||||
|
||||
if (t < MIN_TIME_ALIVE_IN_SEC) {
|
||||
LOGGER_FATAL << "child only survived for " << t << " seconds, this will not work - please fix the error first";
|
||||
done = true;
|
||||
}
|
||||
else {
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (WIFSIGNALED(status)) {
|
||||
|
@ -382,13 +397,23 @@ int AnyServer::startupSupervisor () {
|
|||
break;
|
||||
|
||||
default:
|
||||
LOGGER_ERROR << "child " << pid << " died of a horrible death, signal " << WTERMSIG(status);
|
||||
done = false;
|
||||
t = time(0) - startTime;
|
||||
|
||||
LOGGER_ERROR << "child " << pid << " died a horrible death, signal " << WTERMSIG(status);
|
||||
|
||||
if (t < MIN_TIME_ALIVE_IN_SEC) {
|
||||
LOGGER_FATAL << "child only survived for " << t << " seconds, this will not work - please fix the error first";
|
||||
done = true;
|
||||
}
|
||||
else {
|
||||
done = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOGGER_ERROR << "child " << pid << " died of a horrible death";
|
||||
LOGGER_ERROR << "child " << pid << " died a horrible death, unknown cause";
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue