in hphp/runtime/base/runtime-option.cpp [1530:2973]
void RuntimeOption::Load(
IniSetting::Map& ini, Hdf& config,
const std::vector<std::string>& iniClis /* = std::vector<std::string>() */,
const std::vector<std::string>& hdfClis /* = std::vector<std::string>() */,
std::vector<std::string>* messages /* = nullptr */,
std::string cmd /* = "" */) {
// Intialize the memory manager here because various settings and
// initializations that we do here need it
tl_heap.getCheck();
// Get the ini (-d) and hdf (-v) strings, which may override some
// of options that were set from config files. We also do these
// now so we can override Tier.*.[machine | tier | cpu] on the
// command line, along with any fields within a Tier (e.g.,
// CoreFileSize)
for (auto& istr : iniClis) {
Config::ParseIniString(istr, ini);
}
for (auto& hstr : hdfClis) {
Config::ParseHdfString(hstr, config);
}
// See if there are any Tier-based overrides
auto m = getTierOverwrites(ini, config);
if (messages) *messages = std::move(m);
// RelativeConfigs can be set by commandline flags and tier overwrites, they
// may also contain tier overwrites. They are, however, only included once, so
// relative configs may not specify other relative configs which must to be
// loaded. If RelativeConfigs is modified while loading configs an error is
// raised, but we defer doing so until the logger is initialized below. If a
// relative config cannot be found it is silently skipped (this is to allow
// configs to be conditionally applied to scripts based on their location). By
// reading the "hhvm.relative_configs" ini setting at runtime it is possible
// to determine which configs were actually loaded.
std::string relConfigsError;
Config::Bind(s_RelativeConfigs, ini, config, "RelativeConfigs");
if (!cmd.empty() && !s_RelativeConfigs.empty()) {
String strcmd(cmd, CopyString);
Process::InitProcessStatics();
auto const currentDir = Process::CurrentWorkingDirectory.data();
std::vector<std::string> newConfigs;
auto const original = s_RelativeConfigs;
for (auto& str : original) {
if (str.empty()) continue;
std::string fullpath;
auto const found = FileUtil::runRelative(
str, strcmd, currentDir,
[&] (const String& f) {
if (access(f.data(), R_OK) == 0) {
fullpath = f.toCppString();
FTRACE_MOD(Trace::facts, 3, "Parsing {}\n", fullpath);
Config::ParseConfigFile(fullpath, ini, config);
return true;
}
return false;
}
);
if (found) newConfigs.emplace_back(std::move(fullpath));
}
if (!newConfigs.empty()) {
auto m2 = getTierOverwrites(ini, config);
if (messages) *messages = std::move(m2);
if (s_RelativeConfigs != original) {
relConfigsError = folly::sformat(
"RelativeConfigs node was modified while loading configs from [{}] "
"to [{}]",
folly::join(", ", original),
folly::join(", ", s_RelativeConfigs)
);
}
}
s_RelativeConfigs.swap(newConfigs);
} else {
s_RelativeConfigs.clear();
}
// Then get the ini and hdf cli strings again, in case the tier overwrites
// overrode any non-tier based command line option we set. The tier-based
// command line overwrites will already have been set in the call above.
// This extra call is for the other command line options that may have been
// overridden by a tier, but shouldn't have been.
for (auto& istr : iniClis) {
Config::ParseIniString(istr, ini);
}
for (auto& hstr : hdfClis) {
Config::ParseHdfString(hstr, config);
}
Config::Bind(PidFile, ini, config, "PidFile", "www.pid");
Config::Bind(DeploymentId, ini, config, "DeploymentId");
{
static std::string deploymentIdOverride;
Config::Bind(deploymentIdOverride, ini, config, "DeploymentIdOverride");
if (!deploymentIdOverride.empty()) {
RuntimeOption::DeploymentId = deploymentIdOverride;
}
}
{
// Config ID
Config::Bind(ConfigId, ini, config, "ConfigId", 0);
auto configIdCounter = ServiceData::createCounter("vm.config.id");
configIdCounter->setValue(ConfigId);
}
{
// Logging
auto setLogLevel = [](const std::string& value) {
// ini parsing treats "None" as ""
if (value == "None" || value == "") {
Logger::LogLevel = Logger::LogNone;
} else if (value == "Error") {
Logger::LogLevel = Logger::LogError;
} else if (value == "Warning") {
Logger::LogLevel = Logger::LogWarning;
} else if (value == "Info") {
Logger::LogLevel = Logger::LogInfo;
} else if (value == "Verbose") {
Logger::LogLevel = Logger::LogVerbose;
} else {
return false;
}
return true;
};
auto str = Config::GetString(ini, config, "Log.Level");
if (!str.empty()) {
setLogLevel(str);
}
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"hhvm.log.level", IniSetting::SetAndGet<std::string>(
setLogLevel,
[]() {
switch (Logger::LogLevel) {
case Logger::LogNone:
return "None";
case Logger::LogError:
return "Error";
case Logger::LogWarning:
return "Warning";
case Logger::LogInfo:
return "Info";
case Logger::LogVerbose:
return "Verbose";
}
return "";
}
));
Config::Bind(Logger::UseLogFile, ini, config, "Log.UseLogFile", true);
Config::Bind(LogFile, ini, config, "Log.File");
Config::Bind(LogFileSymLink, ini, config, "Log.SymLink");
Config::Bind(LogFilePeriodMultiplier, ini,
config, "Log.PeriodMultiplier", 0);
if (Logger::UseLogFile && RuntimeOption::ServerExecutionMode()) {
RuntimeOption::ErrorLogs[Logger::DEFAULT] =
ErrorLogFileData(LogFile, LogFileSymLink, LogFilePeriodMultiplier);
}
if (Config::GetBool(ini, config, "Log.AlwaysPrintStackTraces")) {
Logger::SetTheLogger(Logger::DEFAULT, new ExtendedLogger());
ExtendedLogger::EnabledByDefault = true;
}
Config::Bind(Logger::LogHeader, ini, config, "Log.Header");
Config::Bind(Logger::LogNativeStackTrace, ini, config,
"Log.NativeStackTrace", true);
Config::Bind(Logger::UseSyslog, ini, config, "Log.UseSyslog", false);
Config::Bind(Logger::UseRequestLog, ini, config, "Log.UseRequestLog",
false);
Config::Bind(Logger::AlwaysEscapeLog, ini, config, "Log.AlwaysEscapeLog",
true);
Config::Bind(Logger::UseCronolog, ini, config, "Log.UseCronolog", false);
Config::Bind(Logger::MaxMessagesPerRequest, ini,
config, "Log.MaxMessagesPerRequest", -1);
Config::Bind(LogFileFlusher::DropCacheChunkSize, ini,
config, "Log.DropCacheChunkSize", 1 << 20);
Config::Bind(RuntimeOption::LogHeaderMangle, ini, config,
"Log.HeaderMangle", 0);
Config::Bind(AlwaysLogUnhandledExceptions, ini,
config, "Log.AlwaysLogUnhandledExceptions",
true);
Config::Bind(NoSilencer, ini, config, "Log.NoSilencer");
Config::Bind(RuntimeErrorReportingLevel, ini,
config, "Log.RuntimeErrorReportingLevel",
static_cast<int>(ErrorMode::HPHP_ALL));
Config::Bind(ForceErrorReportingLevel, ini,
config, "Log.ForceErrorReportingLevel", 0);
Config::Bind(AccessLogDefaultFormat, ini, config,
"Log.AccessLogDefaultFormat", "%h %l %u %t \"%r\" %>s %b");
auto parseLogs = [] (const Hdf &config, const IniSetting::Map& ini,
const std::string &name,
std::map<std::string, AccessLogFileData> &logs) {
auto parse_logs_callback = [&] (const IniSetting::Map &ini_pl,
const Hdf &hdf_pl,
const std::string &ini_pl_key) {
string logName = hdf_pl.exists() && !hdf_pl.isEmpty()
? hdf_pl.getName()
: ini_pl_key;
string fname = Config::GetString(ini_pl, hdf_pl, "File", "", false);
if (!fname.empty()) {
string symlink = Config::GetString(ini_pl, hdf_pl, "SymLink", "",
false);
string format = Config::GetString(ini_pl, hdf_pl, "Format",
AccessLogDefaultFormat, false);
auto periodMultiplier = Config::GetUInt16(ini_pl, hdf_pl,
"PeriodMultiplier",
0, false);
logs[logName] = AccessLogFileData(fname, symlink,
format, periodMultiplier);
}
};
Config::Iterate(parse_logs_callback, ini, config, name);
};
parseLogs(config, ini, "Log.Access", AccessLogs);
RPCLogs = AccessLogs;
parseLogs(config, ini, "Log.RPC", RPCLogs);
Config::Bind(AdminLogFormat, ini, config, "Log.AdminLog.Format",
"%h %t %s %U");
Config::Bind(AdminLogFile, ini, config, "Log.AdminLog.File");
Config::Bind(AdminLogSymLink, ini, config, "Log.AdminLog.SymLink");
}
{
// Error Handling
Config::Bind(ErrorUpgradeLevel, ini, config, "ErrorHandling.UpgradeLevel",
0);
Config::Bind(MaxSerializedStringSize, ini,
config, "ErrorHandling.MaxSerializedStringSize",
64 * 1024 * 1024);
Config::Bind(CallUserHandlerOnFatals, ini,
config, "ErrorHandling.CallUserHandlerOnFatals", false);
Config::Bind(ThrowExceptionOnBadMethodCall, ini,
config, "ErrorHandling.ThrowExceptionOnBadMethodCall", true);
Config::Bind(LogNativeStackOnOOM, ini,
config, "ErrorHandling.LogNativeStackOnOOM", false);
Config::Bind(NoticeFrequency, ini, config, "ErrorHandling.NoticeFrequency",
1);
Config::Bind(WarningFrequency, ini, config,
"ErrorHandling.WarningFrequency", 1);
}
// If we generated errors while loading RelativeConfigs report those now that
// error reporting is initialized
if (!relConfigsError.empty()) Logger::Error(relConfigsError);
{
if (Config::GetInt64(ini, config, "ResourceLimit.CoreFileSizeOverride")) {
setResourceLimit(RLIMIT_CORE, ini, config,
"ResourceLimit.CoreFileSizeOverride");
} else {
setResourceLimit(RLIMIT_CORE, ini, config, "ResourceLimit.CoreFileSize");
}
setResourceLimit(RLIMIT_NOFILE, ini, config, "ResourceLimit.MaxSocket");
setResourceLimit(RLIMIT_DATA, ini, config, "ResourceLimit.RSS");
// These don't have RuntimeOption::xxx bindings, but we still want to be
// able to use ini_xxx functionality on them; so directly bind to a local
// static via Config::Bind.
static int64_t s_core_file_size_override, s_core_file_size, s_rss = 0;
static int32_t s_max_socket = 0;
Config::Bind(s_core_file_size_override, ini, config,
"ResourceLimit.CoreFileSizeOverride", 0);
Config::Bind(s_core_file_size, ini, config, "ResourceLimit.CoreFileSize",
0);
Config::Bind(s_max_socket, ini, config, "ResourceLimit.MaxSocket", 0);
Config::Bind(s_rss, ini, config, "ResourceLimit.RSS", 0);
Config::Bind(SocketDefaultTimeout, ini, config,
"ResourceLimit.SocketDefaultTimeout", 60);
Config::Bind(MaxSQLRowCount, ini, config, "ResourceLimit.MaxSQLRowCount",
0);
Config::Bind(SerializationSizeLimit, ini, config,
"ResourceLimit.SerializationSizeLimit", StringData::MaxSize);
Config::Bind(HeapSizeMB, ini, config, "ResourceLimit.HeapSizeMB",
HeapSizeMB);
Config::Bind(HeapResetCountBase, ini, config,
"ResourceLimit.HeapResetCountBase", HeapResetCountBase);
Config::Bind(HeapResetCountMultiple, ini, config,
"ResourceLimit.HeapResetCountMultiple",
HeapResetCountMultiple);
Config::Bind(HeapLowWaterMark , ini, config,
"ResourceLimit.HeapLowWaterMark", HeapLowWaterMark);
Config::Bind(HeapHighWaterMark , ini, config,
"ResourceLimit.HeapHighWaterMark",HeapHighWaterMark);
}
{
// watchman
Config::Bind(WatchmanRootSocket, ini, config, "watchman.socket.root", "");
Config::Bind(WatchmanDefaultSocket, ini, config,
"watchman.socket.default", "");
}
{
// PHPisms
Config::Bind(DisableCallUserFunc, ini, config,
"Hack.Lang.Phpism.DisableCallUserFunc",
DisableCallUserFunc);
Config::Bind(DisableCallUserFuncArray, ini, config,
"Hack.Lang.Phpism.DisableCallUserFuncArray",
DisableCallUserFuncArray);
Config::Bind(DisableConstant, ini, config,
"Hack.Lang.Phpism.DisableConstant",
DisableConstant);
}
{
// Repo
auto repoModeToStr = [](RepoMode mode) {
switch (mode) {
case RepoMode::Closed:
return "--";
case RepoMode::ReadOnly:
return "r-";
case RepoMode::ReadWrite:
return "rw";
}
always_assert(false);
return "";
};
auto parseRepoMode = [&](const std::string& repoModeStr, const char* type, RepoMode defaultMode) {
if (repoModeStr.empty()) {
return defaultMode;
}
if (repoModeStr == "--") {
return RepoMode::Closed;
}
if (repoModeStr == "r-") {
return RepoMode::ReadOnly;
}
if (repoModeStr == "rw") {
return RepoMode::ReadWrite;
}
Logger::Error("Bad config setting: Repo.%s.Mode=%s",
type, repoModeStr.c_str());
return RepoMode::ReadWrite;
};
// Local Repo
static std::string repoLocalMode;
Config::Bind(repoLocalMode, ini, config, "Repo.Local.Mode", repoModeToStr(RepoLocalMode));
RepoLocalMode = parseRepoMode(repoLocalMode, "Local", RepoMode::ReadOnly);
// Repo.Path
Config::Bind(RepoPath, ini, config, "Repo.Path", RepoPath);
// Repo.Local.Path
Config::Bind(RepoLocalPath, ini, config, "Repo.Local.Path");
if (RepoLocalPath.empty()) {
const char* HHVM_REPO_LOCAL_PATH = getenv("HHVM_REPO_LOCAL_PATH");
if (HHVM_REPO_LOCAL_PATH != nullptr) {
RepoLocalPath = HHVM_REPO_LOCAL_PATH;
}
}
// Central Repo
static std::string repoCentralMode;
Config::Bind(repoCentralMode, ini, config, "Repo.Central.Mode", repoModeToStr(RepoCentralMode));
RepoCentralMode = parseRepoMode(repoCentralMode, "Central", RepoMode::ReadWrite);
// Repo.Central.Path
Config::Bind(RepoCentralPath, ini, config, "Repo.Central.Path");
Config::Bind(RepoCentralFileMode, ini, config, "Repo.Central.FileMode");
Config::Bind(RepoCentralFileUser, ini, config, "Repo.Central.FileUser");
Config::Bind(RepoCentralFileGroup, ini, config, "Repo.Central.FileGroup");
Config::Bind(RepoAllowFallbackPath, ini, config, "Repo.AllowFallbackPath",
RepoAllowFallbackPath);
replacePlaceholders(RepoLocalPath);
replacePlaceholders(RepoCentralPath);
replacePlaceholders(RepoPath);
Config::Bind(RepoJournal, ini, config, "Repo.Journal", RepoJournal);
Config::Bind(RepoCommit, ini, config, "Repo.Commit",
RepoCommit);
Config::Bind(RepoDebugInfo, ini, config, "Repo.DebugInfo", RepoDebugInfo);
Config::Bind(RepoLitstrLazyLoad, ini, config, "Repo.LitstrLazyLoad",
RepoLitstrLazyLoad);
Config::Bind(RepoAuthoritative, ini, config, "Repo.Authoritative",
RepoAuthoritative);
Config::Bind(RepoLocalReadaheadRate, ini, config,
"Repo.LocalReadaheadRate", 0);
Config::Bind(RepoLocalReadaheadConcurrent, ini, config,
"Repo.LocalReadaheadConcurrent", false);
Config::Bind(RepoBusyTimeoutMS, ini, config,
"Repo.BusyTimeoutMS", RepoBusyTimeoutMS);
if (RepoPath.empty()) {
if (!RepoLocalPath.empty()) {
RepoPath = RepoLocalPath;
} else if (!RepoCentralPath.empty()) {
RepoPath = RepoCentralPath;
} else if (auto const env = getenv("HHVM_REPO_CENTRAL_PATH")) {
RepoPath = env;
replacePlaceholders(RepoPath);
} else {
always_assert_flog(
!RepoAuthoritative,
"Either Repo.Path, Repo.LocalPath, or Repo.CentralPath "
"must be set in RepoAuthoritative mode"
);
}
}
}
if (use_jemalloc) {
// HHProf
Config::Bind(HHProfEnabled, ini, config, "HHProf.Enabled", false);
Config::Bind(HHProfActive, ini, config, "HHProf.Active", false);
Config::Bind(HHProfAccum, ini, config, "HHProf.Accum", false);
Config::Bind(HHProfRequest, ini, config, "HHProf.Request", false);
}
{
// Eval
Config::Bind(EnableHipHopSyntax, ini, config, "Eval.EnableHipHopSyntax",
EnableHipHopSyntax);
Config::Bind(EnableXHP, ini, config, "Eval.EnableXHP", EnableXHP);
Config::Bind(TimeoutsUseWallTime, ini, config, "Eval.TimeoutsUseWallTime",
true);
Config::Bind(CheckFlushOnUserClose, ini, config,
"Eval.CheckFlushOnUserClose", true);
Config::Bind(EvalInitialNamedEntityTableSize, ini, config,
"Eval.InitialNamedEntityTableSize",
EvalInitialNamedEntityTableSize);
Config::Bind(EvalInitialStaticStringTableSize, ini, config,
"Eval.InitialStaticStringTableSize",
EvalInitialStaticStringTableSize);
static std::string jitSerdesMode;
Config::Bind(jitSerdesMode, ini, config, "Eval.JitSerdesMode", "Off");
EvalJitSerdesMode = [&] {
#define X(x) if (jitSerdesMode == #x) return JitSerdesMode::x
X(Serialize);
X(SerializeAndExit);
X(Deserialize);
X(DeserializeOrFail);
X(DeserializeOrGenerate);
X(DeserializeAndDelete);
X(DeserializeAndExit);
#undef X
return JitSerdesMode::Off;
}();
Config::Bind(EvalJitSerdesFile, ini, config,
"Eval.JitSerdesFile", EvalJitSerdesFile);
replacePlaceholders(EvalJitSerdesFile);
// DumpPreciseProfileData defaults to true only when we can possibly write
// profile data to disk. It can be set to false to avoid the performance
// penalty of only running the interpreter during retranslateAll. We will
// assume that DumpPreciseProfileData implies (JitSerdesMode::Serialize ||
// JitSerdesMode::SerializeAndExit), to avoid checking too many flags in a
// few places. The config file should never need to explicitly set
// DumpPreciseProfileData to true.
auto const couldDump = !EvalJitSerdesFile.empty() &&
(isJitSerializing() ||
(EvalJitSerdesMode == JitSerdesMode::DeserializeOrGenerate));
Config::Bind(DumpPreciseProfData, ini, config,
"Eval.DumpPreciseProfData", couldDump);
Config::Bind(ProfDataTTLHours, ini, config,
"Eval.ProfDataTTLHours", ProfDataTTLHours);
Config::Bind(ProfDataTag, ini, config, "Eval.ProfDataTag", ProfDataTag);
Config::Bind(CheckSymLink, ini, config, "Eval.CheckSymLink", true);
Config::Bind(TrustAutoloaderPath, ini, config,
"Eval.TrustAutoloaderPath", false);
#define F(type, name, defaultVal) \
Config::Bind(Eval ## name, ini, config, "Eval."#name, defaultVal);
EVALFLAGS()
#undef F
if (EvalJitSerdesModeForceOff) EvalJitSerdesMode = JitSerdesMode::Off;
if (!EvalEnableReusableTC) EvalReusableTCPadding = 0;
if (numa_num_nodes <= 1) {
EvalEnableNuma = false;
}
Config::Bind(ServerForkEnabled, ini, config,
"Server.Forking.Enabled", ServerForkEnabled);
Config::Bind(ServerForkLogging, ini, config,
"Server.Forking.LogForkAttempts", ServerForkLogging);
if (!ServerForkEnabled && ServerExecutionMode()) {
// Only use hugetlb pages when we don't fork().
low_2m_pages(EvalMaxLowMemHugePages);
high_2m_pages(EvalMaxHighArenaHugePages);
}
#if USE_JEMALLOC_EXTENT_HOOKS
g_useTHPUponHugeTLBFailure =
Config::GetBool(ini, config, "Eval.UseTHPUponHugeTLBFailure",
g_useTHPUponHugeTLBFailure);
#endif
s_enable_static_arena =
Config::GetBool(ini, config, "Eval.UseTLStaticArena", true);
replacePlaceholders(EvalEmbeddedDataExtractPath);
replacePlaceholders(EvalEmbeddedDataFallbackPath);
if (!jit::mcgen::retranslateAllEnabled()) {
EvalJitWorkerThreads = 0;
if (EvalJitSerdesMode != JitSerdesMode::Off) {
if (ServerMode) {
Logger::Warning("Eval.JitSerdesMode reset from " + jitSerdesMode +
" to off, becasue JitRetranslateAll isn't enabled.");
}
EvalJitSerdesMode = JitSerdesMode::Off;
}
EvalJitSerdesFile.clear();
DumpPreciseProfData = false;
}
EvalJitPGOUseAddrCountedCheck &= addr_encodes_persistency;
HardwareCounter::Init(EvalProfileHWEnable,
url_decode(EvalProfileHWEvents.data(),
EvalProfileHWEvents.size()).toCppString(),
false,
EvalProfileHWExcludeKernel,
EvalProfileHWFastReads,
EvalProfileHWExportInterval);
Config::Bind(EnableIntrinsicsExtension, ini,
config, "Eval.EnableIntrinsicsExtension",
EnableIntrinsicsExtension);
Config::Bind(RecordCodeCoverage, ini, config, "Eval.RecordCodeCoverage");
if (EvalJit && RecordCodeCoverage) {
throw std::runtime_error("Code coverage is not supported with "
"Eval.Jit=true");
}
Config::Bind(DisableSmallAllocator, ini, config,
"Eval.DisableSmallAllocator", DisableSmallAllocator);
SetArenaSlabAllocBypass(DisableSmallAllocator);
EvalSlabAllocAlign = folly::nextPowTwo(EvalSlabAllocAlign);
EvalSlabAllocAlign = std::min(EvalSlabAllocAlign,
decltype(EvalSlabAllocAlign){4096});
if (RecordCodeCoverage) CheckSymLink = true;
Config::Bind(CodeCoverageOutputFile, ini, config,
"Eval.CodeCoverageOutputFile");
// NB: after we know the value of RepoAuthoritative.
Config::Bind(EnableArgsInBacktraces, ini, config,
"Eval.EnableArgsInBacktraces", !RepoAuthoritative);
Config::Bind(EvalAuthoritativeMode, ini, config, "Eval.AuthoritativeMode",
false);
Config::Bind(CheckCLIClientCommands, ini, config, "Eval.CheckCLIClientCommands", 1);
if (RepoAuthoritative) {
EvalAuthoritativeMode = true;
}
{
// Debugger (part of Eval)
Config::Bind(EnableHphpdDebugger, ini, config,
"Eval.Debugger.EnableDebugger");
Config::Bind(EnableVSDebugger, ini, config,
"Eval.Debugger.VSDebugEnable", EnableVSDebugger);
Config::Bind(EnableDebuggerColor, ini, config,
"Eval.Debugger.EnableDebuggerColor", true);
Config::Bind(EnableDebuggerPrompt, ini, config,
"Eval.Debugger.EnableDebuggerPrompt", true);
Config::Bind(EnableDebuggerServer, ini, config,
"Eval.Debugger.EnableDebuggerServer");
Config::Bind(EnableDebuggerUsageLog, ini, config,
"Eval.Debugger.EnableDebuggerUsageLog");
Config::Bind(DebuggerServerIP, ini, config, "Eval.Debugger.IP");
Config::Bind(DebuggerServerPort, ini, config, "Eval.Debugger.Port", 8089);
Config::Bind(DebuggerDisableIPv6, ini, config,
"Eval.Debugger.DisableIPv6", false);
Config::Bind(DebuggerDefaultSandboxPath, ini, config,
"Eval.Debugger.DefaultSandboxPath");
Config::Bind(DebuggerStartupDocument, ini, config,
"Eval.Debugger.StartupDocument");
Config::Bind(DebuggerSignalTimeout, ini, config,
"Eval.Debugger.SignalTimeout", 1);
Config::Bind(DebuggerAuthTokenScriptBin, ini, config,
"Eval.Debugger.Auth.TokenScriptBin");
Config::Bind(DebuggerSessionAuthScriptBin, ini, config,
"Eval.Debugger.Auth.SessionAuthScriptBin");
}
}
{
// CodeCache
using jit::CodeCache;
Config::Bind(CodeCache::ASize, ini, config, "Eval.JitASize", 60 << 20);
Config::Bind(CodeCache::AColdSize, ini, config, "Eval.JitAColdSize",
24 << 20);
Config::Bind(CodeCache::AFrozenSize, ini, config, "Eval.JitAFrozenSize",
40 << 20);
Config::Bind(CodeCache::ABytecodeSize, ini, config,
"Eval.JitABytecodeSize", 0);
Config::Bind(CodeCache::GlobalDataSize, ini, config,
"Eval.JitGlobalDataSize", CodeCache::ASize >> 2);
Config::Bind(CodeCache::MapTCHuge, ini, config, "Eval.MapTCHuge",
hugePagesSoundNice());
Config::Bind(CodeCache::TCNumHugeHotMB, ini, config,
"Eval.TCNumHugeHotMB", 64);
Config::Bind(CodeCache::TCNumHugeMainMB, ini, config,
"Eval.TCNumHugeMainMB", 16);
Config::Bind(CodeCache::TCNumHugeColdMB, ini, config,
"Eval.TCNumHugeColdMB", 4);
Config::Bind(CodeCache::AutoTCShift, ini, config, "Eval.JitAutoTCShift", 1);
}
{
// Hack Language
Config::Bind(CheckIntOverflow, ini, config,
"Hack.Lang.CheckIntOverflow", 0);
Config::Bind(StrictArrayFillKeys, ini, config,
"Hack.Lang.StrictArrayFillKeys", HackStrictOption::ON);
Config::Bind(LookForTypechecker, ini, config,
"Hack.Lang.LookForTypechecker", false);
// If you turn off LookForTypechecker, you probably want to turn this off
// too -- basically, make the two look like the same option to external
// users, unless you really explicitly want to set them differently for
// some reason.
Config::Bind(AutoTypecheck, ini, config, "Hack.Lang.AutoTypecheck",
LookForTypechecker);
Config::Bind(EnableClassLevelWhereClauses, ini, config,
"Hack.Lang.EnableClassLevelWhereClauses",
false);
}
{
// Options for PHP7 features which break BC. (Features which do not break
// BC don't need options here and can just always be turned on.)
//
// NB that the "PHP7.all" option is intended to be only a master switch;
// all runtime behavior gating should be based on sub-options (that's why
// it's a file static not a static member of RuntimeOption). Also don't
// forget to update mangleUnitPHP7Options if needed.
//
// TODO: we may eventually want to make an option which specifies
// directories or filenames to exclude from PHP7 behavior, and so checking
// these may want to be per-file. We originally planned to do this from the
// get-go, but threading that through turns out to be kind of annoying and
// of questionable value, so just doing this for now.
Config::Bind(s_PHP7_master, ini, config, "PHP7.all", s_PHP7_default);
Config::Bind(PHP7_EngineExceptions, ini, config, "PHP7.EngineExceptions",
s_PHP7_master);
Config::Bind(PHP7_NoHexNumerics, ini, config, "PHP7.NoHexNumerics",
s_PHP7_master);
Config::Bind(PHP7_Builtins, ini, config, "PHP7.Builtins", s_PHP7_master);
Config::Bind(PHP7_Substr, ini, config, "PHP7.Substr",
s_PHP7_master);
Config::Bind(PHP7_DisallowUnsafeCurlUploads, ini, config,
"PHP7.DisallowUnsafeCurlUploads", s_PHP7_master);
}
{
// Server
Config::Bind(Host, ini, config, "Server.Host");
Config::Bind(DefaultServerNameSuffix, ini, config,
"Server.DefaultServerNameSuffix");
Config::Bind(AlwaysDecodePostDataDefault, ini, config,
"Server.AlwaysDecodePostDataDefault",
AlwaysDecodePostDataDefault);
Config::Bind(ServerType, ini, config, "Server.Type", ServerType);
Config::Bind(ServerIP, ini, config, "Server.IP");
Config::Bind(ServerFileSocket, ini, config, "Server.FileSocket");
#ifdef FACEBOOK
//Do not cause slowness on startup -- except for Facebook
if (GetServerPrimaryIPv4().empty() && GetServerPrimaryIPv6().empty()) {
throw std::runtime_error("Unable to resolve the server's "
"IPv4 or IPv6 address");
}
#endif
Config::Bind(ServerPort, ini, config, "Server.Port", 80);
Config::Bind(ServerBacklog, ini, config, "Server.Backlog", 128);
Config::Bind(ServerConnectionLimit, ini, config,
"Server.ConnectionLimit", 0);
Config::Bind(ServerThreadCount, ini, config, "Server.ThreadCount",
Process::GetCPUCount() * 2);
Config::Bind(ServerQueueCount, ini, config, "Server.QueueCount",
ServerThreadCount);
Config::Bind(ServerIOThreadCount, ini, config,
"Server.IOThreadCount", 1);
Config::Bind(ServerLegacyBehavior, ini, config, "Server.LegacyBehavior",
ServerLegacyBehavior);
Config::Bind(ServerHugeThreadCount, ini, config,
"Server.HugeThreadCount", 0);
Config::Bind(ServerHugeStackKb, ini, config, "Server.HugeStackSizeKb", 384);
ServerSchedPolicy =
Config::GetInt32(ini, config, "Server.SchedPolicy", ServerSchedPolicy);
ServerSchedPriority =
Config::GetInt32(ini, config, "Server.SchedPriority", ServerSchedPriority);
Config::Bind(ServerLoopSampleRate, ini, config,
"Server.LoopSampleRate", 0);
Config::Bind(ServerWarmupThrottleRequestCount, ini, config,
"Server.WarmupThrottleRequestCount",
ServerWarmupThrottleRequestCount);
Config::Bind(ServerWarmupThrottleThreadCount, ini, config,
"Server.WarmupThrottleThreadCount",
Process::GetCPUCount());
Config::Bind(ServerThreadDropCacheTimeoutSeconds, ini, config,
"Server.ThreadDropCacheTimeoutSeconds", 0);
if (Config::GetBool(ini, config, "Server.ThreadJobLIFO")) {
ServerThreadJobLIFOSwitchThreshold = 0;
}
Config::Bind(ServerThreadJobLIFOSwitchThreshold, ini, config,
"Server.ThreadJobLIFOSwitchThreshold",
ServerThreadJobLIFOSwitchThreshold);
Config::Bind(ServerThreadJobMaxQueuingMilliSeconds, ini, config,
"Server.ThreadJobMaxQueuingMilliSeconds", -1);
Config::Bind(ServerThreadDropStack, ini, config, "Server.ThreadDropStack");
Config::Bind(ServerHttpSafeMode, ini, config, "Server.HttpSafeMode");
Config::Bind(ServerStatCache, ini, config, "Server.StatCache", false);
Config::Bind(ServerFixPathInfo, ini, config, "Server.FixPathInfo", false);
Config::Bind(ServerAddVaryEncoding, ini, config, "Server.AddVaryEncoding",
ServerAddVaryEncoding);
Config::Bind(ServerLogSettingsOnStartup, ini, config,
"Server.LogSettingsOnStartup", false);
Config::Bind(ServerLogReorderProps, ini, config,
"Server.LogReorderProps", false);
Config::Bind(ServerWarmupConcurrently, ini, config,
"Server.WarmupConcurrently", false);
Config::Bind(ServerDedupeWarmupRequests, ini, config,
"Server.DedupeWarmupRequests", false);
Config::Bind(ServerWarmupThreadCount, ini, config,
"Server.WarmupThreadCount", ServerWarmupThreadCount);
Config::Bind(ServerExtendedWarmupThreadCount, ini, config,
"Server.ExtendedWarmup.ThreadCount",
ServerExtendedWarmupThreadCount);
Config::Bind(ServerExtendedWarmupDelaySeconds, ini, config,
"Server.ExtendedWarmup.DelaySeconds",
ServerExtendedWarmupDelaySeconds);
Config::Bind(ServerExtendedWarmupRepeat, ini, config,
"Server.ExtendedWarmup.Repeat", ServerExtendedWarmupRepeat);
Config::Bind(ServerWarmupRequests, ini, config, "Server.WarmupRequests");
Config::Bind(ServerExtendedWarmupRequests, ini, config,
"Server.ExtendedWarmup.Requests");
Config::Bind(ServerCleanupRequest, ini, config, "Server.CleanupRequest");
Config::Bind(ServerInternalWarmupThreads, ini, config,
"Server.InternalWarmupThreads", 0); // 0 = skip
Config::Bind(ServerHighPriorityEndPoints, ini, config,
"Server.HighPriorityEndPoints");
Config::Bind(ServerExitOnBindFail, ini, config, "Server.ExitOnBindFail",
false);
Config::Bind(RequestTimeoutSeconds, ini, config,
"Server.RequestTimeoutSeconds", 0);
Config::Bind(MaxRequestAgeFactor, ini, config, "Server.MaxRequestAgeFactor",
0);
Config::Bind(PspTimeoutSeconds, ini, config, "Server.PspTimeoutSeconds", 0);
Config::Bind(PspCpuTimeoutSeconds, ini, config,
"Server.PspCpuTimeoutSeconds", 0);
Config::Bind(RequestMemoryMaxBytes, ini, config,
"Server.RequestMemoryMaxBytes", (16LL << 30)); // 16GiB
RequestInfo::setOOMKillThreshold(
Config::GetUInt64(ini, config, "Server.RequestMemoryOOMKillBytes",
128ULL << 20));
Config::Bind(RequestHugeMaxBytes, ini, config,
"Server.RequestHugeMaxBytes", (24LL << 20));
Config::Bind(ServerGracefulShutdownWait, ini,
config, "Server.GracefulShutdownWait", 0);
Config::Bind(ServerHarshShutdown, ini, config, "Server.HarshShutdown",
true);
Config::Bind(ServerKillOnTimeout, ini, config, "Server.KillOnTimeout",
true);
Config::Bind(ServerEvilShutdown, ini, config, "Server.EvilShutdown", true);
Config::Bind(ServerPreShutdownWait, ini, config,
"Server.PreShutdownWait", 0);
Config::Bind(ServerShutdownListenWait, ini, config,
"Server.ShutdownListenWait", 0);
Config::Bind(ServerShutdownEOMWait, ini, config,
"Server.ShutdownEOMWait", 0);
Config::Bind(ServerPrepareToStopTimeout, ini, config,
"Server.PrepareToStopTimeout", 240);
Config::Bind(ServerPartialPostStatusCode, ini, config,
"Server.PartialPostStatusCode", -1);
Config::Bind(StopOldServer, ini, config, "Server.StopOld", false);
Config::Bind(OldServerWait, ini, config, "Server.StopOldWait", 30);
Config::Bind(ServerRSSNeededMb, ini, config, "Server.RSSNeededMb", 4096);
Config::Bind(ServerCriticalFreeMb, ini, config,
"Server.CriticalFreeMb", 512);
Config::Bind(CacheFreeFactor, ini, config, "Server.CacheFreeFactor", 50);
if (CacheFreeFactor > 100) CacheFreeFactor = 100;
if (CacheFreeFactor < 0) CacheFreeFactor = 0;
Config::Bind(ServerNextProtocols, ini, config, "Server.SSLNextProtocols");
Config::Bind(ServerEnableH2C, ini, config, "Server.EnableH2C");
extern bool g_brotliUseLocalArena;
Config::Bind(g_brotliUseLocalArena, ini, config,
"Server.BrotliUseLocalArena", g_brotliUseLocalArena);
Config::Bind(BrotliCompressionEnabled, ini, config,
"Server.BrotliCompressionEnabled", -1);
Config::Bind(BrotliChunkedCompressionEnabled, ini, config,
"Server.BrotliChunkedCompressionEnabled", -1);
Config::Bind(BrotliCompressionLgWindowSize, ini, config,
"Server.BrotliCompressionLgWindowSize", 20);
Config::Bind(BrotliCompressionMode, ini, config,
"Server.BrotliCompressionMode", 0);
Config::Bind(BrotliCompressionQuality, ini, config,
"Server.BrotliCompressionQuality", 6);
Config::Bind(ZstdCompressionEnabled, ini, config,
"Server.ZstdCompressionEnabled", -1);
Config::Bind(ZstdCompressor::s_useLocalArena, ini, config,
"Server.ZstdUseLocalArena", ZstdCompressor::s_useLocalArena);
Config::Bind(ZstdCompressionLevel, ini, config,
"Server.ZstdCompressionLevel", 3);
Config::Bind(ZstdChecksumRate, ini, config,
"Server.ZstdChecksumRate", 0);
Config::Bind(GzipCompressionLevel, ini, config,
"Server.GzipCompressionLevel", 3);
Config::Bind(GzipMaxCompressionLevel, ini, config,
"Server.GzipMaxCompressionLevel", 9);
Config::Bind(GzipCompressor::s_useLocalArena, ini, config,
"Server.GzipUseLocalArena", GzipCompressor::s_useLocalArena);
Config::Bind(EnableKeepAlive, ini, config, "Server.EnableKeepAlive", true);
Config::Bind(ExposeHPHP, ini, config, "Server.ExposeHPHP", true);
Config::Bind(ExposeXFBServer, ini, config, "Server.ExposeXFBServer", false);
Config::Bind(ExposeXFBDebug, ini, config, "Server.ExposeXFBDebug", false);
Config::Bind(XFBDebugSSLKey, ini, config, "Server.XFBDebugSSLKey", "");
Config::Bind(ConnectionTimeoutSeconds, ini, config,
"Server.ConnectionTimeoutSeconds", -1);
Config::Bind(EnableOutputBuffering, ini, config,
"Server.EnableOutputBuffering");
Config::Bind(OutputHandler, ini, config, "Server.OutputHandler");
Config::Bind(ImplicitFlush, ini, config, "Server.ImplicitFlush");
Config::Bind(EnableEarlyFlush, ini, config, "Server.EnableEarlyFlush",
true);
Config::Bind(ForceChunkedEncoding, ini, config,
"Server.ForceChunkedEncoding");
Config::Bind(MaxPostSize, ini, config, "Server.MaxPostSize", 100);
MaxPostSize <<= 20;
Config::Bind(AlwaysPopulateRawPostData, ini, config,
"Server.AlwaysPopulateRawPostData", false);
Config::Bind(TakeoverFilename, ini, config, "Server.TakeoverFilename");
Config::Bind(ExpiresActive, ini, config, "Server.ExpiresActive", true);
Config::Bind(ExpiresDefault, ini, config, "Server.ExpiresDefault", 2592000);
if (ExpiresDefault < 0) ExpiresDefault = 2592000;
Config::Bind(DefaultCharsetName, ini, config, "Server.DefaultCharsetName",
"");
Config::Bind(RequestBodyReadLimit, ini, config,
"Server.RequestBodyReadLimit", -1);
Config::Bind(EnableSSL, ini, config, "Server.EnableSSL");
Config::Bind(SSLPort, ini, config, "Server.SSLPort", 443);
Config::Bind(SSLCertificateFile, ini, config, "Server.SSLCertificateFile");
Config::Bind(SSLCertificateKeyFile, ini, config,
"Server.SSLCertificateKeyFile");
Config::Bind(SSLCertificateDir, ini, config, "Server.SSLCertificateDir");
Config::Bind(SSLTicketSeedFile, ini, config, "Server.SSLTicketSeedFile");
Config::Bind(TLSDisableTLS1_2, ini, config, "Server.TLSDisableTLS1_2",
false);
Config::Bind(TLSClientCipherSpec, ini, config,
"Server.TLSClientCipherSpec");
Config::Bind(EnableSSLWithPlainText, ini, config,
"Server.EnableSSLWithPlainText");
Config::Bind(SSLClientAuthLevel, ini, config,
"Server.SSLClientAuthLevel", 0);
if (SSLClientAuthLevel < 0) SSLClientAuthLevel = 0;
if (SSLClientAuthLevel > 2) SSLClientAuthLevel = 2;
Config::Bind(SSLClientCAFile, ini, config, "Server.SSLClientCAFile", "");
if (!SSLClientAuthLevel) {
SSLClientCAFile = "";
} else if (SSLClientCAFile.empty()) {
throw std::runtime_error(
"SSLClientCAFile is required to enable client auth");
}
Config::Bind(ClientAuthAclIdentity, ini, config,
"Server.ClientAuthAclIdentity", "");
Config::Bind(ClientAuthAclAction, ini, config,
"Server.ClientAuthAclAction", "");
Config::Bind(ClientAuthFailClose, ini, config,
"Server.ClientAuthFailClose", false);
Config::Bind(ClientAuthLogSampleBase, ini, config,
"Server.ClientAuthLogSampleBase", 100);
if (ClientAuthLogSampleBase < 1) {
ClientAuthLogSampleBase = 1;
}
Config::Bind(SSLClientAuthLoggingSampleRatio, ini, config,
"Server.SSLClientAuthLoggingSampleRatio", 0);
if (SSLClientAuthLoggingSampleRatio < 0) {
SSLClientAuthLoggingSampleRatio = 0;
}
if (SSLClientAuthLoggingSampleRatio > ClientAuthLogSampleBase) {
SSLClientAuthLoggingSampleRatio = ClientAuthLogSampleBase;
}
Config::Bind(ClientAuthSuccessLogSampleRatio, ini, config,
"Server.ClientAuthSuccessLogSampleRatio", 0);
if (ClientAuthSuccessLogSampleRatio <
SSLClientAuthLoggingSampleRatio) {
ClientAuthSuccessLogSampleRatio = SSLClientAuthLoggingSampleRatio;
}
if (ClientAuthSuccessLogSampleRatio > ClientAuthLogSampleBase) {
ClientAuthSuccessLogSampleRatio = ClientAuthLogSampleBase;
}
Config::Bind(ClientAuthFailureLogSampleRatio, ini, config,
"Server.ClientAuthFailureLogSampleRatio", 0);
if (ClientAuthFailureLogSampleRatio <
SSLClientAuthLoggingSampleRatio) {
ClientAuthFailureLogSampleRatio = SSLClientAuthLoggingSampleRatio;
}
if (ClientAuthFailureLogSampleRatio > ClientAuthLogSampleBase) {
ClientAuthFailureLogSampleRatio = ClientAuthLogSampleBase;
}
// SourceRoot has been default to: Process::GetCurrentDirectory() + '/'
auto defSourceRoot = SourceRoot;
Config::Bind(SourceRoot, ini, config, "Server.SourceRoot", SourceRoot);
SourceRoot = FileUtil::normalizeDir(SourceRoot);
if (SourceRoot.empty()) {
SourceRoot = defSourceRoot;
}
FileCache::SourceRoot = SourceRoot;
Config::Bind(IncludeSearchPaths, ini, config, "Server.IncludeSearchPaths");
for (unsigned int i = 0; i < IncludeSearchPaths.size(); i++) {
IncludeSearchPaths[i] = FileUtil::normalizeDir(IncludeSearchPaths[i]);
}
IncludeSearchPaths.insert(IncludeSearchPaths.begin(), ".");
Config::Bind(AutoloadEnabled, ini, config, "Autoload.Enabled", false);
Config::Bind(AutoloadDBPath, ini, config, "Autoload.DB.Path");
Config::Bind(AutoloadDBPerms, ini, config, "Autoload.DB.Perms", "0644");
Config::Bind(AutoloadDBGroup, ini, config, "Autoload.DB.Group");
Config::Bind(AutoloadLogging, ini, config, "Autoload.Logging",
"hphp.runtime.ext.facts:=CRITICAL:slog;slog=hhvm");
Config::Bind(AutoloadExcludedRepos, ini, config, "Autoload.ExcludedRepos");
Config::Bind(AutoloadLoggingAllowPropagation, ini, config,
"Autoload.AllowLoggingPropagation", false);
Config::Bind(AutoloadRethrowExceptions, ini, config,
"Autoload.RethrowExceptions", true);
Config::Bind(FileCache, ini, config, "Server.FileCache");
Config::Bind(DefaultDocument, ini, config, "Server.DefaultDocument",
"index.php");
Config::Bind(GlobalDocument, ini, config, "Server.GlobalDocument");
Config::Bind(ErrorDocument404, ini, config, "Server.ErrorDocument404");
normalizePath(ErrorDocument404);
Config::Bind(ForbiddenAs404, ini, config, "Server.ForbiddenAs404");
Config::Bind(ErrorDocument500, ini, config, "Server.ErrorDocument500");
normalizePath(ErrorDocument500);
Config::Bind(FatalErrorMessage, ini, config, "Server.FatalErrorMessage");
FontPath = FileUtil::normalizeDir(
Config::GetString(ini, config, "Server.FontPath"));
Config::Bind(EnableStaticContentFromDisk, ini, config,
"Server.EnableStaticContentFromDisk", true);
Config::Bind(EnableOnDemandUncompress, ini, config,
"Server.EnableOnDemandUncompress", true);
Config::Bind(EnableStaticContentMMap, ini, config,
"Server.EnableStaticContentMMap", true);
if (EnableStaticContentMMap) {
EnableOnDemandUncompress = true;
}
Config::Bind(Utf8izeReplace, ini, config, "Server.Utf8izeReplace", true);
Config::Bind(RequestInitFunction, ini, config,
"Server.RequestInitFunction");
Config::Bind(RequestInitDocument, ini, config,
"Server.RequestInitDocument");
Config::Bind(SafeFileAccess, ini, config, "Server.SafeFileAccess");
Config::Bind(AllowedDirectories, ini, config, "Server.AllowedDirectories");
Config::Bind(WhitelistExec, ini, config, "Server.WhitelistExec");
Config::Bind(WhitelistExecWarningOnly, ini, config,
"Server.WhitelistExecWarningOnly");
Config::Bind(AllowedExecCmds, ini, config, "Server.AllowedExecCmds");
Config::Bind(UnserializationWhitelistCheck, ini, config,
"Server.UnserializationWhitelistCheck", false);
Config::Bind(UnserializationWhitelistCheckWarningOnly, ini, config,
"Server.UnserializationWhitelistCheckWarningOnly", true);
Config::Bind(UnserializationBigMapThreshold, ini, config,
"Server.UnserializationBigMapThreshold", 1 << 16);
Config::Bind(AllowedFiles, ini, config, "Server.AllowedFiles");
Config::Bind(ForbiddenFileExtensions, ini, config,
"Server.ForbiddenFileExtensions");
Config::Bind(LockCodeMemory, ini, config, "Server.LockCodeMemory", false);
Config::Bind(MaxArrayChain, ini, config, "Server.MaxArrayChain", INT_MAX);
if (MaxArrayChain != INT_MAX) {
// VanillaDict needs a higher threshold to avoid false-positives.
// (and we always use VanillaDict)
MaxArrayChain *= 2;
}
Config::Bind(WarnOnCollectionToArray, ini, config,
"Server.WarnOnCollectionToArray", false);
Config::Bind(UseDirectCopy, ini, config, "Server.UseDirectCopy", false);
Config::Bind(AlwaysUseRelativePath, ini, config,
"Server.AlwaysUseRelativePath", false);
{
// Server Upload
Config::Bind(UploadMaxFileSize, ini, config,
"Server.Upload.UploadMaxFileSize", 100);
UploadMaxFileSize <<= 20;
Config::Bind(UploadTmpDir, ini, config, "Server.Upload.UploadTmpDir",
"/tmp");
Config::Bind(EnableFileUploads, ini, config,
"Server.Upload.EnableFileUploads", true);
Config::Bind(MaxFileUploads, ini, config, "Server.Upload.MaxFileUploads",
20);
Config::Bind(EnableUploadProgress, ini, config,
"Server.Upload.EnableUploadProgress");
Config::Bind(Rfc1867Freq, ini, config, "Server.Upload.Rfc1867Freq",
256 * 1024);
if (Rfc1867Freq < 0) Rfc1867Freq = 256 * 1024;
Config::Bind(Rfc1867Prefix, ini, config, "Server.Upload.Rfc1867Prefix",
"vupload_");
Config::Bind(Rfc1867Name, ini, config, "Server.Upload.Rfc1867Name",
"video_ptoken");
}
Config::Bind(ImageMemoryMaxBytes, ini, config,
"Server.ImageMemoryMaxBytes", 0);
if (ImageMemoryMaxBytes == 0) {
ImageMemoryMaxBytes = UploadMaxFileSize * 2;
}
Config::Bind(LightProcessFilePrefix, ini, config,
"Server.LightProcessFilePrefix", "./lightprocess");
Config::Bind(LightProcessCount, ini, config,
"Server.LightProcessCount", 0);
Config::Bind(LightProcess::g_strictUser, ini, config,
"Server.LightProcessStrictUser", false);
Config::Bind(ForceServerNameToHeader, ini, config,
"Server.ForceServerNameToHeader");
Config::Bind(PathDebug, ini, config, "Server.PathDebug", false);
Config::Bind(ServerUser, ini, config, "Server.User", "");
Config::Bind(AllowRunAsRoot, ini, config, "Server.AllowRunAsRoot", false);
}
VirtualHost::SortAllowedDirectories(AllowedDirectories);
{
auto vh_callback = [] (const IniSettingMap &ini_vh, const Hdf &hdf_vh,
const std::string &ini_vh_key) {
if (VirtualHost::IsDefault(ini_vh, hdf_vh, ini_vh_key)) {
VirtualHost::GetDefault().init(ini_vh, hdf_vh, ini_vh_key);
VirtualHost::GetDefault().addAllowedDirectories(AllowedDirectories);
} else {
auto host = std::make_shared<VirtualHost>(ini_vh, hdf_vh, ini_vh_key);
host->addAllowedDirectories(AllowedDirectories);
VirtualHosts.push_back(host);
}
};
// Virtual Hosts have to be iterated in order. Because only the first
// one that matches in the VirtualHosts vector gets applied and used.
// Hdf's and ini (via Variant arrays) internal storage handles ordering
// naturally (as specified top to bottom in the file and left to right on
// the command line.
Config::Iterate(vh_callback, ini, config, "VirtualHost");
LowestMaxPostSize = VirtualHost::GetLowestMaxPostSize();
}
{
// IpBlocks
IpBlocks = std::make_shared<IpBlockMap>(ini, config);
}
{
ReadSatelliteInfo(ini, config, SatelliteServerInfos,
XboxPassword, XboxPasswords);
}
{
// Xbox
Config::Bind(XboxServerThreadCount, ini, config,
"Xbox.ServerInfo.ThreadCount", 10);
Config::Bind(XboxServerMaxQueueLength, ini, config,
"Xbox.ServerInfo.MaxQueueLength", INT_MAX);
if (XboxServerMaxQueueLength < 0) XboxServerMaxQueueLength = INT_MAX;
Config::Bind(XboxServerInfoMaxRequest, ini, config,
"Xbox.ServerInfo.MaxRequest", 500);
Config::Bind(XboxServerInfoDuration, ini, config,
"Xbox.ServerInfo.MaxDuration", 120);
Config::Bind(XboxServerInfoReqInitFunc, ini, config,
"Xbox.ServerInfo.RequestInitFunction", "");
Config::Bind(XboxServerInfoReqInitDoc, ini, config,
"Xbox.ServerInfo.RequestInitDocument", "");
Config::Bind(XboxServerInfoAlwaysReset, ini, config,
"Xbox.ServerInfo.AlwaysReset", false);
Config::Bind(XboxServerLogInfo, ini, config, "Xbox.ServerInfo.LogInfo",
false);
Config::Bind(XboxProcessMessageFunc, ini, config, "Xbox.ProcessMessageFunc",
"xbox_process_message");
}
{
// Pagelet Server
Config::Bind(PageletServerThreadCount, ini, config,
"PageletServer.ThreadCount", 0);
Config::Bind(PageletServerHugeThreadCount, ini, config,
"PageletServer.HugeThreadCount", 0);
Config::Bind(PageletServerThreadDropStack, ini, config,
"PageletServer.ThreadDropStack");
Config::Bind(PageletServerThreadDropCacheTimeoutSeconds, ini, config,
"PageletServer.ThreadDropCacheTimeoutSeconds", 0);
Config::Bind(PageletServerQueueLimit, ini, config,
"PageletServer.QueueLimit", 0);
}
{
// Static File
hphp_string_imap<std::string> staticFileDefault;
staticFileDefault["css"] = "text/css";
staticFileDefault["gif"] = "image/gif";
staticFileDefault["html"] = "text/html";
staticFileDefault["jpeg"] = "image/jpeg";
staticFileDefault["jpg"] = "image/jpeg";
staticFileDefault["mp3"] = "audio/mpeg";
staticFileDefault["png"] = "image/png";
staticFileDefault["tif"] = "image/tiff";
staticFileDefault["tiff"] = "image/tiff";
staticFileDefault["txt"] = "text/plain";
staticFileDefault["zip"] = "application/zip";
Config::Bind(StaticFileExtensions, ini, config, "StaticFile.Extensions",
staticFileDefault);
auto matches_callback = [](const IniSettingMap& ini_m, const Hdf& hdf_m,
const std::string& /*ini_m_key*/) {
FilesMatches.push_back(std::make_shared<FilesMatch>(ini_m, hdf_m));
};
Config::Iterate(matches_callback, ini, config, "StaticFile.FilesMatch");
}
{
// PhpFile
Config::Bind(PhpFileExtensions, ini, config, "PhpFile.Extensions");
}
{
// Admin Server
Config::Bind(AdminServerIP, ini, config, "AdminServer.IP", ServerIP);
Config::Bind(AdminServerPort, ini, config, "AdminServer.Port", 0);
Config::Bind(AdminThreadCount, ini, config, "AdminServer.ThreadCount", 1);
Config::Bind(AdminServerEnableSSLWithPlainText, ini, config,
"AdminServer.EnableSSLWithPlainText", false);
Config::Bind(AdminServerStatsNeedPassword, ini, config,
"AdminServer.StatsNeedPassword", AdminServerStatsNeedPassword);
AdminPassword = Config::GetString(ini, config, "AdminServer.Password");
AdminPasswords = Config::GetSet(ini, config, "AdminServer.Passwords");
HashedAdminPasswords =
Config::GetSet(ini, config, "AdminServer.HashedPasswords");
Config::Bind(AdminDumpPath, ini, config,
"AdminServer.DumpPath", "/tmp/hhvm_admin_dump");
}
{
// Proxy
Config::Bind(ProxyOriginRaw, ini, config, "Proxy.Origin");
Config::Bind(ProxyPercentageRaw, ini, config, "Proxy.Percentage", 0);
Config::Bind(ProxyRetry, ini, config, "Proxy.Retry", 3);
Config::Bind(UseServeURLs, ini, config, "Proxy.ServeURLs");
Config::Bind(ServeURLs, ini, config, "Proxy.ServeURLs");
Config::Bind(UseProxyURLs, ini, config, "Proxy.ProxyURLs");
Config::Bind(ProxyURLs, ini, config, "Proxy.ProxyURLs");
Config::Bind(ProxyPatterns, ini, config, "Proxy.ProxyPatterns");
}
{
// Http
Config::Bind(HttpDefaultTimeout, ini, config, "Http.DefaultTimeout", 30);
Config::Bind(HttpSlowQueryThreshold, ini, config, "Http.SlowQueryThreshold",
5000);
}
{
// Debug
Config::Bind(NativeStackTrace, ini, config, "Debug.NativeStackTrace");
StackTrace::Enabled = NativeStackTrace;
Config::Bind(ServerErrorMessage, ini, config, "Debug.ServerErrorMessage");
Config::Bind(RecordInput, ini, config, "Debug.RecordInput");
Config::Bind(ClearInputOnSuccess, ini, config, "Debug.ClearInputOnSuccess",
true);
Config::Bind(ProfilerOutputDir, ini, config, "Debug.ProfilerOutputDir",
"/tmp");
Config::Bind(CoreDumpEmail, ini, config, "Debug.CoreDumpEmail");
Config::Bind(CoreDumpReport, ini, config, "Debug.CoreDumpReport", true);
if (CoreDumpReport) {
install_crash_reporter();
}
// Binding default dependenant on whether we are using an OSS build or
// not, and that is set at initialization time of CoreDumpReportDirectory.
Config::Bind(CoreDumpReportDirectory, ini, config,
"Debug.CoreDumpReportDirectory", CoreDumpReportDirectory);
std::ostringstream stack_trace_stream;
stack_trace_stream << CoreDumpReportDirectory << "/stacktrace."
<< (int64_t)getpid() << ".log";
StackTraceFilename = stack_trace_stream.str();
Config::Bind(StackTraceTimeout, ini, config, "Debug.StackTraceTimeout", 0);
Config::Bind(RemoteTraceOutputDir, ini, config,
"Debug.RemoteTraceOutputDir", "/tmp");
Config::Bind(TraceFunctions, ini, config,
"Debug.TraceFunctions", TraceFunctions);
}
{
// Stats
Config::Bind(EnableStats, ini, config, "Stats.Enable",
false); // main switch
Config::Bind(EnableAPCStats, ini, config, "Stats.APC", false);
Config::Bind(EnableWebStats, ini, config, "Stats.Web");
Config::Bind(EnableMemoryStats, ini, config, "Stats.Memory");
Config::Bind(EnableSQLStats, ini, config, "Stats.SQL");
Config::Bind(EnableSQLTableStats, ini, config, "Stats.SQLTable");
Config::Bind(EnableNetworkIOStatus, ini, config, "Stats.NetworkIO");
Config::Bind(StatsXSL, ini, config, "Stats.XSL");
Config::Bind(StatsXSLProxy, ini, config, "Stats.XSLProxy");
Config::Bind(StatsSlotDuration, ini, config, "Stats.SlotDuration", 10 * 60);
Config::Bind(StatsMaxSlot, ini, config, "Stats.MaxSlot",
12 * 6); // 12 hours
StatsSlotDuration = std::max(1u, StatsSlotDuration);
StatsMaxSlot = std::max(2u, StatsMaxSlot);
Config::Bind(EnableHotProfiler, ini, config, "Stats.EnableHotProfiler",
true);
Config::Bind(ProfilerTraceBuffer, ini, config, "Stats.ProfilerTraceBuffer",
2000000);
Config::Bind(ProfilerTraceExpansion, ini, config,
"Stats.ProfilerTraceExpansion", 1.2);
Config::Bind(ProfilerMaxTraceBuffer, ini, config,
"Stats.ProfilerMaxTraceBuffer", 0);
Config::Bind(TrackPerUnitMemory, ini, config,
"Stats.TrackPerUnitMemory", false);
}
{
Config::Bind(ServerVariables, ini, config, "ServerVariables");
Config::Bind(EnvVariables, ini, config, "EnvVariables");
}
{
// Sandbox
Config::Bind(SandboxMode, ini, config, "Sandbox.SandboxMode");
Config::Bind(SandboxPattern, ini, config, "Sandbox.Pattern");
SandboxPattern = format_pattern(SandboxPattern, true);
Config::Bind(SandboxHome, ini, config, "Sandbox.Home");
Config::Bind(SandboxFallback, ini, config, "Sandbox.Fallback");
Config::Bind(SandboxConfFile, ini, config, "Sandbox.ConfFile");
Config::Bind(SandboxFromCommonRoot, ini, config, "Sandbox.FromCommonRoot");
Config::Bind(SandboxDirectoriesRoot, ini, config,
"Sandbox.DirectoriesRoot");
Config::Bind(SandboxLogsRoot, ini, config, "Sandbox.LogsRoot");
Config::Bind(SandboxServerVariables, ini, config,
"Sandbox.ServerVariables");
Config::Bind(SandboxDefaultUserFile, ini, config,
"Sandbox.DefaultUserFile");
Config::Bind(SandboxHostAlias, ini, config, "Sandbox.HostAlias");
}
{
// Mail
Config::Bind(SendmailPath, ini, config, "Mail.SendmailPath",
"/usr/lib/sendmail -t -i");
Config::Bind(MailForceExtraParameters, ini, config,
"Mail.ForceExtraParameters");
}
{
// Preg
Config::Bind(PregBacktraceLimit, ini, config, "Preg.BacktraceLimit",
1000000);
Config::Bind(PregRecursionLimit, ini, config, "Preg.RecursionLimit",
100000);
Config::Bind(EnablePregErrorLog, ini, config, "Preg.ErrorLog", true);
}
{
// SimpleXML
Config::Bind(SimpleXMLEmptyNamespaceMatchesAll, ini, config,
"SimpleXML.EmptyNamespaceMatchesAll", false);
}
#ifdef FACEBOOK
{
// Fb303Server
Config::Bind(EnableFb303Server, ini, config, "Fb303Server.Enable",
EnableFb303Server);
Config::Bind(Fb303ServerPort, ini, config, "Fb303Server.Port", 0);
Config::Bind(Fb303ServerIP, ini, config, "Fb303Server.IP");
Config::Bind(Fb303ServerThreadStackSizeMb, ini, config,
"Fb303Server.ThreadStackSizeMb", 8);
Config::Bind(Fb303ServerWorkerThreads, ini, config,
"Fb303Server.WorkerThreads", 1);
Config::Bind(Fb303ServerPoolThreads, ini, config, "Fb303Server.PoolThreads",
1);
}
#endif
{
// Xenon
Config::Bind(XenonPeriodSeconds, ini, config, "Xenon.Period", 0.0);
Config::Bind(XenonRequestFreq, ini, config, "Xenon.RequestFreq", 1);
Config::Bind(XenonForceAlwaysOn, ini, config, "Xenon.ForceAlwaysOn", false);
}
{
// Strobelight
Config::Bind(StrobelightEnabled, ini, config, "Strobelight.Enabled", false);
}
{
// Profiling
Config::Bind(SetProfileNullThisObject, ini, config,
"SetProfile.NullThisObject", true);
}
{
// Loadhint queue penalty
Config::Bind(ApplySecondaryQueuePenalty, ini, config, "Server.ApplySecondaryQueuePenalty", false);
}
Config::Bind(TzdataSearchPaths, ini, config, "TzdataSearchPaths");
Config::Bind(CustomSettings, ini, config, "CustomSettings");
// Run initializers depedent on options, e.g., resizing atomic maps/vectors.
refineStaticStringTableSize();
InitFiniNode::ProcessPostRuntimeOptions();
// **************************************************************************
// DANGER
//
// Do not bind any PHP_INI_ALL, PHP_INI_USER or PHP_INI_PERDIR settings here!
// These settings are process-wide, while those need to be thread-local since
// they are per-request. They should go into RequestInjectionData. Getting
// this wrong will cause subtle breakage -- in particular, it probably will
// not show up in CLI mode, since everything there tends to be single
// theaded.
// **************************************************************************
// Language and Misc Configuration Options
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ONLY, "expose_php",
&RuntimeOption::ExposeHPHP);
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"auto_prepend_file", &RuntimeOption::AutoPrependFile);
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"auto_append_file", &RuntimeOption::AutoAppendFile);
// Data Handling
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"post_max_size",
IniSetting::SetAndGet<int64_t>(
nullptr,
[]() {
return VirtualHost::GetMaxPostSize();
}
),
&RuntimeOption::MaxPostSize);
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"always_populate_raw_post_data",
&RuntimeOption::AlwaysPopulateRawPostData);
// Paths and Directories
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"doc_root", &RuntimeOption::SourceRoot);
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"sendmail_path", &RuntimeOption::SendmailPath);
// FastCGI
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ONLY,
"pid", &RuntimeOption::PidFile);
// File Uploads
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"file_uploads", "true",
&RuntimeOption::EnableFileUploads);
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"upload_tmp_dir", &RuntimeOption::UploadTmpDir);
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"upload_max_filesize",
IniSetting::SetAndGet<std::string>(
[](const std::string& value) {
return ini_on_update(
value, RuntimeOption::UploadMaxFileSize);
},
[]() {
return convert_long_to_bytes(
VirtualHost::GetUploadMaxFileSize());
}
));
// Filesystem and Streams Configuration Options
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"allow_url_fopen",
IniSetting::SetAndGet<std::string>(
[](const std::string& /*value*/) { return false; },
[]() { return "1"; }));
// HPHP specific
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_NONE,
"hphp.compiler_id",
IniSetting::SetAndGet<std::string>(
[](const std::string& /*value*/) { return false; },
[]() { return compilerId().begin(); }));
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_NONE,
"hphp.compiler_timestamp",
IniSetting::SetAndGet<int64_t>(
[](const int64_t& /*value*/) { return false; },
[]() { return compilerTimestamp(); }));
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_NONE,
"hphp.compiler_version",
IniSetting::SetAndGet<std::string>(
[](const std::string& /*value*/) { return false; },
[]() { return getHphpCompilerVersion(); }));
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_NONE,
"hphp.cli_server_api_version",
IniSetting::SetAndGet<uint64_t>(
[](const uint64_t /*value*/) { return false; },
[]() { return cli_server_api_version(); }));
IniSetting::Bind(
IniSetting::CORE, IniSetting::PHP_INI_NONE, "hphp.build_id",
IniSetting::SetAndGet<std::string>(
[](const std::string& /*value*/) { return false; }, nullptr),
&RuntimeOption::BuildId);
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"notice_frequency",
&RuntimeOption::NoticeFrequency);
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM,
"warning_frequency",
&RuntimeOption::WarningFrequency);
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ONLY,
"hhvm.build_type",
IniSetting::SetAndGet<std::string>(
[](const std::string&) {
return false;
},
[]() {
return s_hhvm_build_type.c_str();
}
));
// Extensions
Config::Bind(RuntimeOption::ExtensionDir, ini, config, "extension_dir",
RuntimeOption::ExtensionDir, false);
Config::Bind(RuntimeOption::DynamicExtensionPath, ini,
config, "DynamicExtensionPath",
RuntimeOption::DynamicExtensionPath);
Config::Bind(RuntimeOption::Extensions, ini, config, "extensions");
Config::Bind(RuntimeOption::DynamicExtensions, ini,
config, "DynamicExtensions");
ExtensionRegistry::moduleLoad(ini, config);
initialize_apc();
if (TraceFunctions.size()) Trace::ensureInit(getTraceOutputFile());
if (RO::EvalJitEnableRenameFunction && RO::RepoAuthoritative) {
throw std::runtime_error("Can't use Eval.JitEnableRenameFunction if "
" RepoAuthoritative is turned on");
}
// Bespoke array-likes
auto const enable_logging = RO::EvalBespokeArrayLikeMode != 0;
bespoke::setLoggingEnabled(enable_logging);
specializeVanillaDestructors();
// Coeffects
CoeffectsConfig::init(RO::EvalCoeffectEnforcementLevels);
// Initialize defaults for repo-specific parser configuration options.
RepoOptions::setDefaults(config, ini);
}