in host/cxpslib/serverctl.cpp [60:283]
void startServers(std::string const& confFile, errorCallback_t errorCallback, std::string const& installDir)
{
g_ioService = new boost::asio::io_service(); // NOTE: we do not delete this on exit on purpose
CxpsTelemetry::CxpsTelemetryLogger &s_telLoggerInst = CxpsTelemetry::CxpsTelemetryLogger::GetInstance();
PSSettings::PSSettingsConfigurator& s_configurator = PSSettings::PSSettingsConfigurator::GetInstance();
serverOptionsPtr serverOptions(new ServerOptions(confFile, installDir));
g_sessionTracker.reset(new SessionTracker(serverOptions->delaySessionDeleteSeconds()));
g_sessionTracker->run();
g_nonceMgr.run(serverOptions->cnonceDurationSeconds());
// error logging
setupErrorLogging(serverOptions->errorLogFile(),
serverOptions->errorLogMaxSizeBytes(),
serverOptions->errorLogRotateCount(),
serverOptions->errorLogRetainSizeBytes(),
serverOptions->errorLogWarningsEnabled());
g_threads.push_back(startErrorLogMonitor());
// xfer logging
setupXferLogging(serverOptions->xferLogFile(),
serverOptions->xferLogMaxSizeBytes(),
serverOptions->xferLogRotateCount(),
serverOptions->xferLogRetainSizeBytes(),
serverOptions->xferLogEnabled());
g_threads.push_back(startXferLogMonitor());
// monitor logging
setupMonitorLogging(serverOptions->monitorLogFile(),
serverOptions->monitorLogMaxSizeBytes(),
serverOptions->monitorLogRotateCount(),
serverOptions->monitorLogRetainSizeBytes(),
serverOptions->monitorLogEnabled(),
serverOptions->monitorLogLevel());
g_threads.push_back(startMonitorLogMonitor());
CXPS_LOG_MONITOR(MONITOR_LOG_LEVEL_1, "VER " << REQUEST_VER_CURRENT << ", BUILD " << __DATE__ << ' ' << __TIME__);
CXPS_LOG_ERROR_INFO("VER " << REQUEST_VER_CURRENT << ", BUILD " << __DATE__ << ' ' << __TIME__);
CSMode csMode = GetCSMode();
std::wstring csModeStr;
switch (csMode) {
case CS_MODE_UNKNOWN:
csModeStr = CSMode_String::Unknown;
break;
case CS_MODE_LEGACY_CS:
csModeStr = CSMode_String::LegacyCS;
break;
case CS_MODE_RCM:
csModeStr = CSMode_String::Rcm;
break;
default:
csModeStr = boost::lexical_cast<std::wstring>(csMode);
break;
}
CXPS_LOG_ERROR_INFO("CS Mode - " << csModeStr);
if (csMode == CS_MODE_RCM) {
CXPS_LOG_ERROR_INFO("PS Installation Info - " << GetRcmPSInstallationInfo().ToString());
}
bool startListeners = true;
if ((csMode == CS_MODE_RCM) && !serverOptions->isRcmPSFirstTimeConfigured())
{
// Don't start the HTTP/S listeners in RCM mode, before the first time
// configuration is performed. Otherwise, we wouldn't have passphrase,
// ssl_port, etc. from the appliance updated in the cxps configuration
// file yet.
CXPS_LOG_ERROR_INFO("Not starting any HTTP/S listeners, since RCM PS isn't yet first time configured.");
startListeners = false;
}
if (startListeners)
{
// cxps telemetry logging
boost::filesystem::path cxpsTelemetryFolderPath = serverOptions->installDir();
// TODO-SanKumar-1709: Move these parameters into cxps conf / Tunables class.
cxpsTelemetryFolderPath /= "..";
cxpsTelemetryFolderPath /= "var";
cxpsTelemetryFolderPath /= "cxps_telemetry";
// </home/svsystems>/var/cxps_telemetry
const boost::chrono::seconds CxpsTelemetryWriteInterval = boost::chrono::seconds(15 * 60); // 15 mins
const int MaxCompletedCxpsTelFilesCnt = 96; // 96 * 15 mins = 1 day worth of cache.
s_telLoggerInst.Initialize(
serverOptions->id(),
cxpsTelemetryFolderPath,
CxpsTelemetryWriteInterval,
MaxCompletedCxpsTelFilesCnt);
s_telLoggerInst.Start();
const boost::filesystem::path psSettingsFilePath(
(csMode == CS_MODE_RCM) ?
GetRcmPSInstallationInfo().m_settingsPath :
serverOptions->installDir() / ".." / "etc" / "PSSettings.json");
const boost::filesystem::path psSettingsLckFilePath =
boost::filesystem::change_extension(
psSettingsFilePath, psSettingsFilePath.extension().string() + ".lck");
s_configurator.Initialize(psSettingsFilePath, psSettingsLckFilePath, serverOptions);
// Process the initial settings with a query to s_configurator.GetPSSettings().
// Subscribe to callbacks, which must be valid till s_configurtor.Stop() is called.
// Callbacks can be added, even after the configurator has been started.
s_configurator.Start();
// Start timers for cumulative throttle
// Start this before starting servers
if (serverOptions->enableCumulativeThrottle())
{
g_cumulativeThrottlerInstance.reset(new CumulativeThrottlingHelper(serverOptions, *g_ioService));
g_cumulativeThrottlerInstance->start();
}
// Start timers for diff and resync throttle
// Start this before starting servers
if (serverOptions->enableDiffAndResyncThrottle())
{
g_diffResyncThrottlerInstance.reset(new DiffResyncThrottlingHelper(serverOptions, *g_ioService));
g_diffResyncThrottlerInstance->start();
}
// NOTE:
// http and https servers will use the same io_service wich means
// they will actually share their thread pools. Initialy split the number
// of threads up between them (since there are 2, round up to nearest even
// number). Also need at least 1 thread for each so that they will both
// start their listening socket.
int threadCount = serverOptions->maxThreads();
// adding option in configuration file to divide the number of http and https threads.
// 0 means all https threads
// 1 means half http and half https threads
// 2 means all http threads
int httpEnabled = serverOptions->httpEnabled();
if (threadCount < 1) {
threadCount = 1; // need at least 1 thread
}
if (threadCount & 0x1) {
++threadCount; // odd make it even
}
if (httpEnabled == 1)
{
threadCount = threadCount >> 1; // initially divide evenly between http and https
// http server
BasicServer::ptr httpServer(new Server(serverOptions, errorCallback, *g_ioService));
g_servers.push_back(httpServer);
g_threads.push_back(threadPtr(new boost::thread(
boost::bind(&Server::run,
httpServer,
threadCount))));
// https server
BasicServer::ptr httpsServer(new SslServer(serverOptions, errorCallback, *g_ioService));
g_servers.push_back(httpsServer);
g_threads.push_back(threadPtr(new boost::thread(
boost::bind(&SslServer::run,
httpsServer,
threadCount))));
}
else if (httpEnabled == 2)
{
// http server
BasicServer::ptr httpServer(new Server(serverOptions, errorCallback, *g_ioService));
g_servers.push_back(httpServer);
g_threads.push_back(threadPtr(new boost::thread(
boost::bind(&Server::run,
httpServer,
threadCount))));
}
else
{
// https server
BasicServer::ptr httpsServer(new SslServer(serverOptions, errorCallback, *g_ioService));
g_servers.push_back(httpsServer);
g_threads.push_back(threadPtr(new boost::thread(
boost::bind(&SslServer::run,
httpsServer,
(threadCount)))));
}
}
// only fire up CFS support if needed
if (serverOptions->cfsMode() && !serverOptions->csIpAddress().empty()) {
g_cfsManager.reset(new CfsManager(*g_ioService, serverOptions));
g_threads.push_back(threadPtr(new boost::thread(
boost::bind(&CfsManager::run,
g_cfsManager))));
}
else if ((csMode == CS_MODE_LEGACY_CS) && (serverOptions->csIpAddress().empty())) {
// normally would expect cs ip addres but want to be able to
// use cxps for general transfer without the need to talk
// to cs (both in production and for development), treat as wraning
CXPS_LOG_WARNING(AT_LOC << "CS ip address not found");
}
// only fire up CFS support if needed
if (serverOptions->cfsMode()) {
startCfsServer(serverOptions, *g_ioService);
}
// older versions of gcc have problems with boost::message_queue
#if !defined(__GNUC__) || (__GNUC__ >= 4)
// simple logger message queue
g_threads.push_back(threadPtr(new boost::thread(
boost::bind(&CxPsMsgQueue::start,
&g_cxpsMsgQueue,
errorCallback))));
#endif
}