8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-01 18:40:39 +01:00
firebird-mirror/src/common/config/config.cpp

595 lines
15 KiB
C++
Raw Normal View History

2002-11-03 17:26:12 +01:00
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.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.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
2002-11-03 17:26:12 +01:00
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
2002-11-03 17:26:12 +01:00
*
* The Original Code was created by Dmitry Yemanov
* for the Firebird Open Source RDBMS project.
2002-11-03 17:26:12 +01:00
*
* Copyright (c) 2002 Dmitry Yemanov <dimitr@users.sf.net>
* and all contributors signed below.
2002-11-03 17:26:12 +01:00
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
2002-11-03 17:26:12 +01:00
*/
#include "firebird.h"
#include "../common/config/config.h"
#include "../common/config/config_file.h"
#include "../jrd/os/config_root.h"
#include "../common/classes/init.h"
#include "../jrd/os/fbsyslog.h"
2002-11-03 17:26:12 +01:00
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
namespace {
/******************************************************************************
*
* firebird.conf implementation
*/
class ConfigImpl : public Firebird::PermanentStorage
{
public:
explicit ConfigImpl(Firebird::MemoryPool& p) : Firebird::PermanentStorage(p)
{
try
{
2010-03-08 02:21:24 +01:00
ConfigFile file(fb_utils::getPrefix(fb_utils::FB_DIR_CONF, CONFIG_FILE),
ConfigFile::EXCEPTION_ON_ERROR);
defaultConfig = new Config(file);
}
catch (const Firebird::fatal_exception& ex)
{
Firebird::Syslog::Record(Firebird::Syslog::Error, ex.what());
(Firebird::Arg::Gds(isc_random) << "Problems with master configuration file - "
"inform server admin please").raise();
}
}
/* void changeDefaultConfig(Config* newConfig)
{
defaultConfig = newConfig;
}
*/
Firebird::RefPtr<Config> getDefaultConfig() const
{
return defaultConfig;
}
private:
Firebird::RefPtr<Config> defaultConfig;
ConfigImpl(const ConfigImpl&);
void operator=(const ConfigImpl&);
};
/******************************************************************************
*
* Static instance of the system configuration file
*/
Firebird::InitInstance<ConfigImpl> firebirdConf;
/******************************************************************************
*
* Static instance of the root and install directories detector
*/
Firebird::InitInstance<ConfigRoot> rootDetector;
} // anonymous namespace
2002-11-03 17:26:12 +01:00
/******************************************************************************
*
* Configuration entries
2002-11-03 17:26:12 +01:00
*/
const char* GCPolicyCooperative = "cooperative";
const char* GCPolicyBackground = "background";
const char* GCPolicyCombined = "combined";
#ifdef SUPERSERVER
const char* GCPolicyDefault = GCPolicyCombined;
#else
const char* GCPolicyDefault = GCPolicyCooperative;
#endif
const char* AmNative = "native";
const char* AmTrusted = "trusted";
const char* AmMixed = "mixed";
const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
{
{TYPE_INTEGER, "TempBlockSize", (ConfigValue) 1048576}, // bytes
2003-02-02 17:01:12 +01:00
#ifdef SUPERSERVER
{TYPE_INTEGER, "TempCacheLimit", (ConfigValue) 67108864}, // bytes
#elif defined(WIN_NT) // win32 CS
{TYPE_INTEGER, "TempCacheLimit", (ConfigValue) 8388608}, // bytes
#else // non-win32 CS
{TYPE_INTEGER, "TempCacheLimit", (ConfigValue) 0}, // bytes
2003-02-02 17:01:12 +01:00
#endif
#ifdef BOOT_BUILD
{TYPE_BOOLEAN, "RemoteFileOpenAbility", (ConfigValue) true},
#else
{TYPE_BOOLEAN, "RemoteFileOpenAbility", (ConfigValue) false},
#endif
{TYPE_INTEGER, "GuardianOption", (ConfigValue) 1},
{TYPE_INTEGER, "CpuAffinityMask", (ConfigValue) 1},
2002-12-07 14:27:12 +01:00
{TYPE_INTEGER, "TcpRemoteBufferSize", (ConfigValue) 8192}, // bytes
{TYPE_BOOLEAN, "TcpNoNagle", (ConfigValue) true},
2002-12-06 22:12:59 +01:00
#ifdef SUPERSERVER
2002-12-07 14:27:12 +01:00
{TYPE_INTEGER, "DefaultDbCachePages", (ConfigValue) 2048}, // pages
2002-12-06 22:12:59 +01:00
#else
2002-12-07 14:27:12 +01:00
{TYPE_INTEGER, "DefaultDbCachePages", (ConfigValue) 75}, // pages
2002-12-06 22:12:59 +01:00
#endif
2002-12-07 14:27:12 +01:00
{TYPE_INTEGER, "ConnectionTimeout", (ConfigValue) 180}, // seconds
2003-08-22 00:30:20 +02:00
{TYPE_INTEGER, "DummyPacketInterval", (ConfigValue) 0}, // seconds
{TYPE_INTEGER, "LockMemSize", (ConfigValue) 1048576}, // bytes
2002-12-07 14:27:12 +01:00
{TYPE_BOOLEAN, "LockGrantOrder", (ConfigValue) true},
2007-01-25 13:56:16 +01:00
{TYPE_INTEGER, "LockHashSlots", (ConfigValue) 1009}, // slots
2003-12-01 20:44:29 +01:00
{TYPE_INTEGER, "LockAcquireSpins", (ConfigValue) 0},
2002-12-07 14:27:12 +01:00
{TYPE_INTEGER, "EventMemSize", (ConfigValue) 65536}, // bytes
{TYPE_INTEGER, "DeadlockTimeout", (ConfigValue) 10}, // seconds
{TYPE_INTEGER, "PrioritySwitchDelay", (ConfigValue) 100}, // milliseconds
{TYPE_BOOLEAN, "UsePriorityScheduler", (ConfigValue) true},
{TYPE_INTEGER, "PriorityBoost", (ConfigValue) 5}, // ratio oh high- to low-priority thread ticks in jrd.cpp
2003-01-15 15:10:07 +01:00
{TYPE_STRING, "RemoteServiceName", (ConfigValue) FB_SERVICE_NAME},
2003-06-25 09:39:04 +02:00
{TYPE_INTEGER, "RemoteServicePort", (ConfigValue) 0},
{TYPE_STRING, "RemotePipeName", (ConfigValue) FB_PIPE_NAME},
{TYPE_STRING, "IpcName", (ConfigValue) FB_IPC_NAME},
#ifdef WIN_NT
2003-02-16 14:26:53 +01:00
{TYPE_INTEGER, "MaxUnflushedWrites", (ConfigValue) 100},
2003-02-16 19:58:56 +01:00
{TYPE_INTEGER, "MaxUnflushedWriteTime", (ConfigValue) 5},
#else
2003-02-16 14:26:53 +01:00
{TYPE_INTEGER, "MaxUnflushedWrites", (ConfigValue) -1},
2003-02-16 19:58:56 +01:00
{TYPE_INTEGER, "MaxUnflushedWriteTime", (ConfigValue) -1},
#endif
2003-02-16 19:58:56 +01:00
{TYPE_INTEGER, "ProcessPriorityLevel", (ConfigValue) 0},
2003-03-11 15:57:08 +01:00
{TYPE_INTEGER, "RemoteAuxPort", (ConfigValue) 0},
2003-03-15 21:02:39 +01:00
{TYPE_STRING, "RemoteBindAddress", (ConfigValue) 0},
{TYPE_STRING, "ExternalFileAccess", (ConfigValue) "None"}, // location(s) of external files for tables
{TYPE_STRING, "DatabaseAccess", (ConfigValue) "Full"}, // location(s) of databases
#define UDF_DEFAULT_CONFIG_VALUE "Restrict UDF"
{TYPE_STRING, "UdfAccess", (ConfigValue) UDF_DEFAULT_CONFIG_VALUE}, // location(s) of UDFs
{TYPE_STRING, "TempDirectories", (ConfigValue) 0},
#ifdef DEV_BUILD
{TYPE_BOOLEAN, "BugcheckAbort", (ConfigValue) true}, // whether to abort() engine when internal error is found
#else
{TYPE_BOOLEAN, "BugcheckAbort", (ConfigValue) false}, // whether to abort() engine when internal error is found
#endif
2006-03-15 18:23:07 +01:00
{TYPE_BOOLEAN, "LegacyHash", (ConfigValue) true}, // let use old passwd hash verification
{TYPE_STRING, "GCPolicy", (ConfigValue) GCPolicyDefault}, // garbage collection policy
{TYPE_BOOLEAN, "Redirection", (ConfigValue) false},
{TYPE_STRING, "Authentication", (ConfigValue) AmNative}, // use native, trusted or mixed
{TYPE_INTEGER, "DatabaseGrowthIncrement", (ConfigValue) 128 * 1048576}, // bytes
2009-08-30 12:08:19 +02:00
{TYPE_INTEGER, "FileSystemCacheThreshold", (ConfigValue) 65536}, // page buffers
{TYPE_BOOLEAN, "RelaxedAliasChecking", (ConfigValue) false}, // if true relax strict alias checking rules in DSQL a bit
2009-02-01 23:10:12 +01:00
{TYPE_BOOLEAN, "OldSetClauseSemantics", (ConfigValue) false}, // if true disallow SET A = B, B = A to exchange column values
{TYPE_STRING, "AuditTraceConfigFile", (ConfigValue) ""}, // location of audit trace configuration file
{TYPE_INTEGER, "MaxUserTraceLogSize", (ConfigValue) 10}, // maximum size of user session trace log
{TYPE_INTEGER, "FileSystemCacheSize", (ConfigValue) 30} // percent
2002-11-03 17:26:12 +01:00
};
/******************************************************************************
*
* Config routines
2002-11-03 17:26:12 +01:00
*/
Config::Config(const ConfigFile& file)
{
// Iterate through the known configuration entries
2002-11-03 17:26:12 +01:00
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
{
values[i] = entries[i].default_value;
}
2002-11-03 17:26:12 +01:00
loadValues(file);
}
Config::Config(const ConfigFile& file, const Config& base)
2002-11-03 17:26:12 +01:00
{
// Iterate through the known configuration entries
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
{
values[i] = base.values[i];
}
loadValues(file);
}
2002-11-03 17:26:12 +01:00
void Config::loadValues(const ConfigFile& file)
{
2009-04-17 16:10:11 +02:00
// Iterate through the known configuration entries
2002-11-03 17:26:12 +01:00
for (int i = 0; i < MAX_CONFIG_KEY; i++)
2002-11-03 17:26:12 +01:00
{
const ConfigEntry& entry = entries[i];
const ConfigFile::String value = getValue(file, entry.key);
2002-11-03 17:26:12 +01:00
if (value.length())
{
// Assign the actual value
switch (entry.data_type)
{
case TYPE_BOOLEAN:
values[i] = (ConfigValue) asBoolean(value);
break;
case TYPE_INTEGER:
values[i] = (ConfigValue) asInteger(value);
break;
case TYPE_STRING:
values[i] = (ConfigValue) asString(value);
break;
//case TYPE_STRING_VECTOR:
// break;
}
if (entry.data_type == TYPE_STRING && values[i] != entry.default_value)
{
const char* src = (const char*) values[i];
char* dst = FB_NEW(getPool()) char[strlen(src) + 1];
2008-05-21 15:00:37 +02:00
strcpy(dst, src);
values[i] = (ConfigValue) dst;
}
}
2002-11-03 17:26:12 +01:00
}
}
Config::~Config()
2002-11-03 17:26:12 +01:00
{
2009-04-17 16:10:11 +02:00
// Free allocated memory
2002-11-03 17:26:12 +01:00
for (int i = 0; i < MAX_CONFIG_KEY; i++)
2002-11-03 17:26:12 +01:00
{
if (values[i] == entries[i].default_value)
continue;
switch (entries[i].data_type)
{
case TYPE_STRING:
2008-05-22 23:45:22 +02:00
delete[] (char*) values[i];
break;
2009-08-18 14:41:39 +02:00
//case TYPE_STRING_VECTOR:
// break;
}
2002-11-03 17:26:12 +01:00
}
}
ConfigFile::String Config::getValue(const ConfigFile& file, ConfigName key)
2002-11-03 17:26:12 +01:00
{
const ConfigFile::Parameter* p = file.findParameter(key);
return p ? p->value : "";
}
2002-11-03 17:26:12 +01:00
int Config::asInteger(const ConfigFile::String &value)
{
return atoi(value.data());
}
2002-11-03 17:26:12 +01:00
bool Config::asBoolean(const ConfigFile::String &value)
{
return (atoi(value.data()) != 0);
}
2002-11-03 17:26:12 +01:00
const char* Config::asString(const ConfigFile::String &value)
{
return value.c_str();
2002-11-03 17:26:12 +01:00
}
/******************************************************************************
*
* Public interface
*/
const Firebird::RefPtr<Config> Config::getDefaultConfig()
{
return firebirdConf().getDefaultConfig();
}
2005-05-28 00:45:31 +02:00
const char* Config::getInstallDirectory()
{
return rootDetector().getInstallDirectory();
2005-05-28 00:45:31 +02:00
}
static Firebird::PathName* rootFromCommandLine = 0;
void Config::setRootDirectoryFromCommandLine(const Firebird::PathName& newRoot)
{
delete rootFromCommandLine;
2008-12-05 02:20:14 +01:00
rootFromCommandLine = FB_NEW(*getDefaultMemoryPool())
Firebird::PathName(*getDefaultMemoryPool(), newRoot);
}
const Firebird::PathName* Config::getCommandLineRootDirectory()
{
return rootFromCommandLine;
}
const char* Config::getRootDirectory()
2002-11-03 17:26:12 +01:00
{
// must check it here - command line must override any other root settings
if (rootFromCommandLine)
{
return rootFromCommandLine->c_str();
}
return rootDetector().getRootDirectory();;
2002-11-03 17:26:12 +01:00
}
int Config::getTempBlockSize()
2002-11-03 17:26:12 +01:00
{
return (int) getDefaultConfig()->values[KEY_TEMP_BLOCK_SIZE];
2002-11-03 17:26:12 +01:00
}
int Config::getTempCacheLimit()
2002-11-03 17:26:12 +01:00
{
int v = (int) getDefaultConfig()->values[KEY_TEMP_CACHE_LIMIT];
return v < 0 ? 0 : v;
2002-11-03 17:26:12 +01:00
}
bool Config::getRemoteFileOpenAbility()
2002-11-03 17:26:12 +01:00
{
return (bool) getDefaultConfig()->values[KEY_REMOTE_FILE_OPEN_ABILITY];
2002-11-03 17:26:12 +01:00
}
int Config::getGuardianOption()
2002-11-03 17:26:12 +01:00
{
return (int) getDefaultConfig()->values[KEY_GUARDIAN_OPTION];
2002-11-03 17:26:12 +01:00
}
int Config::getCpuAffinityMask()
{
return (int) getDefaultConfig()->values[KEY_CPU_AFFINITY_MASK];
}
2002-12-06 13:34:43 +01:00
int Config::getTcpRemoteBufferSize()
{
int rc = (int) getDefaultConfig()->values[KEY_TCP_REMOTE_BUFFER_SIZE];
if (rc < 1448)
rc = 1448;
if (rc > MAX_SSHORT)
rc = MAX_SSHORT;
return rc;
2002-12-06 13:34:43 +01:00
}
bool Config::getTcpNoNagle()
{
return (bool) getDefaultConfig()->values[KEY_TCP_NO_NAGLE];
2002-12-06 13:34:43 +01:00
}
2002-12-06 22:12:59 +01:00
int Config::getDefaultDbCachePages() const
2002-12-06 22:12:59 +01:00
{
return get<int>(KEY_DEFAULT_DB_CACHE_PAGES);
2002-12-06 22:12:59 +01:00
}
int Config::getConnectionTimeout()
{
return (int) getDefaultConfig()->values[KEY_CONNECTION_TIMEOUT];
2002-12-06 22:12:59 +01:00
}
int Config::getDummyPacketInterval()
{
return (int) getDefaultConfig()->values[KEY_DUMMY_PACKET_INTERVAL];
2002-12-06 22:12:59 +01:00
}
2002-12-07 14:27:12 +01:00
int Config::getLockMemSize() const
2002-12-07 14:27:12 +01:00
{
return get<int>(KEY_LOCK_MEM_SIZE);
2002-12-07 14:27:12 +01:00
}
bool Config::getLockGrantOrder() const
2002-12-07 14:27:12 +01:00
{
return get<bool>(KEY_LOCK_GRANT_ORDER);
2002-12-07 14:27:12 +01:00
}
int Config::getLockHashSlots() const
2002-12-07 14:27:12 +01:00
{
return get<int>(KEY_LOCK_HASH_SLOTS);
2002-12-07 14:27:12 +01:00
}
int Config::getLockAcquireSpins() const
2002-12-07 14:27:12 +01:00
{
return get<int>(KEY_LOCK_ACQUIRE_SPINS);
2002-12-07 14:27:12 +01:00
}
int Config::getEventMemSize() const
2002-12-07 14:27:12 +01:00
{
return get<int>(KEY_EVENT_MEM_SIZE);
2002-12-07 14:27:12 +01:00
}
int Config::getDeadlockTimeout() const
2002-12-07 14:27:12 +01:00
{
return get<int>(KEY_DEADLOCK_TIMEOUT);
2002-12-07 14:27:12 +01:00
}
int Config::getPrioritySwitchDelay()
{
int rc = (int) getDefaultConfig()->values[KEY_PRIORITY_SWITCH_DELAY];
if (rc < 1)
rc = 1;
return rc;
}
int Config::getPriorityBoost()
{
int rc = (int) getDefaultConfig()->values[KEY_PRIORITY_BOOST];
if (rc < 1)
rc = 1;
if (rc > 1000)
rc = 1000;
return rc;
}
2003-01-15 15:10:07 +01:00
bool Config::getUsePriorityScheduler()
{
return (bool) getDefaultConfig()->values[KEY_USE_PRIORITY_SCHEDULER];
}
2003-01-15 15:10:07 +01:00
const char *Config::getRemoteServiceName()
{
return (const char*) getDefaultConfig()->values[KEY_REMOTE_SERVICE_NAME];
2003-01-15 15:10:07 +01:00
}
2004-01-13 14:38:36 +01:00
unsigned short Config::getRemoteServicePort()
2003-01-15 15:10:07 +01:00
{
return (unsigned short) getDefaultConfig()->values[KEY_REMOTE_SERVICE_PORT];
2003-01-15 15:10:07 +01:00
}
const char *Config::getRemotePipeName()
2003-01-15 15:10:07 +01:00
{
return (const char*) getDefaultConfig()->values[KEY_REMOTE_PIPE_NAME];
2003-01-15 15:10:07 +01:00
}
const char *Config::getIpcName()
2003-01-15 15:10:07 +01:00
{
return (const char*) getDefaultConfig()->values[KEY_IPC_NAME];
2003-01-15 15:10:07 +01:00
}
int Config::getMaxUnflushedWrites() const
{
return get<int>(KEY_MAX_UNFLUSHED_WRITES);
}
int Config::getMaxUnflushedWriteTime() const
{
return get<int>(KEY_MAX_UNFLUSHED_WRITE_TIME);
2003-02-09 12:22:10 +01:00
}
2003-02-16 19:58:56 +01:00
int Config::getProcessPriorityLevel()
{
return (int) getDefaultConfig()->values[KEY_PROCESS_PRIORITY_LEVEL];
2003-02-16 19:58:56 +01:00
}
2003-03-11 15:57:08 +01:00
int Config::getRemoteAuxPort()
{
return (int) getDefaultConfig()->values[KEY_REMOTE_AUX_PORT];
2003-03-11 15:57:08 +01:00
}
const char *Config::getRemoteBindAddress()
{
return (const char*) getDefaultConfig()->values[KEY_REMOTE_BIND_ADDRESS];
2003-03-11 15:57:08 +01:00
}
2003-03-15 21:02:39 +01:00
const char *Config::getExternalFileAccess() const
2003-03-15 21:02:39 +01:00
{
return get<const char*>(KEY_EXTERNAL_FILE_ACCESS);
2003-03-15 21:02:39 +01:00
}
const char *Config::getDatabaseAccess()
{
return (const char*) getDefaultConfig()->values[KEY_DATABASE_ACCESS];
}
const char *Config::getUdfAccess()
{
static Firebird::GlobalPtr<Firebird::Mutex> udfMutex;
static Firebird::GlobalPtr<Firebird::string> udfValue;
static const char* volatile value = 0;
if (value)
{
return value;
}
Firebird::MutexLockGuard guard(udfMutex);
if (value)
{
return value;
}
const char* v = (const char*) getDefaultConfig()->values[KEY_UDF_ACCESS];
if (CASE_SENSITIVITY ? (! strcmp(v, UDF_DEFAULT_CONFIG_VALUE) && FB_UDFDIR[0]) :
(! fb_utils::stricmp(v, UDF_DEFAULT_CONFIG_VALUE) && FB_UDFDIR[0]))
{
udfValue->printf("Restrict %s", FB_UDFDIR);
value = udfValue->c_str();
}
else
{
value = v;
}
return value;
}
2003-05-01 13:35:15 +02:00
const char *Config::getTempDirectories()
{
return (const char*) getDefaultConfig()->values[KEY_TEMP_DIRECTORIES];
2003-05-01 13:35:15 +02:00
}
bool Config::getBugcheckAbort()
{
return (bool) getDefaultConfig()->values[KEY_BUGCHECK_ABORT];
}
bool Config::getLegacyHash()
{
return (bool) getDefaultConfig()->values[KEY_LEGACY_HASH];
}
const char *Config::getGCPolicy() const
{
return get<const char*>(KEY_GC_POLICY);
}
2005-01-12 09:30:24 +01:00
bool Config::getRedirection()
{
return (bool) getDefaultConfig()->values[KEY_REDIRECTION];
}
const char *Config::getAuthMethod()
{
return (const char*) getDefaultConfig()->values[KEY_AUTH_METHOD];
}
int Config::getDatabaseGrowthIncrement() const
{
return get<int>(KEY_DATABASE_GROWTH_INCREMENT);
}
int Config::getFileSystemCacheThreshold() const
{
int rc = get<int>(KEY_FILESYSTEM_CACHE_THRESHOLD);
2009-11-05 09:27:03 +01:00
return rc < 0 ? 0 : rc;
}
bool Config::getRelaxedAliasChecking()
{
return (bool) getDefaultConfig()->values[KEY_RELAXED_ALIAS_CHECKING];
}
bool Config::getOldSetClauseSemantics()
{
return (bool) getDefaultConfig()->values[KEY_OLD_SET_CLAUSE_SEMANTICS];
}
2009-02-01 23:10:12 +01:00
int Config::getFileSystemCacheSize()
{
return (int) getDefaultConfig()->values[KEY_FILESYSTEM_CACHE_SIZE];
}
2009-02-01 23:10:12 +01:00
const char *Config::getAuditTraceConfigFile()
{
return (const char*) getDefaultConfig()->values[KEY_TRACE_CONFIG];
2009-02-01 23:10:12 +01:00
}
int Config::getMaxUserTraceLogSize()
{
return (int) getDefaultConfig()->values[KEY_MAX_TRACELOG_SIZE];
2009-02-01 23:10:12 +01:00
}