int main(int argc, char **argv) { //some tests rely on the local path char *myPath = strdup(argv[0]); if (chdir (dirname(myPath)) != 0) { printf("WARNING: could not chdir to %s\n", myPath); } try { log4cxx::BasicConfigurator::configure(); log4cxx::LoggerPtr rootLogger(log4cxx::Logger::getRootLogger()); rootLogger->setLevel(log4cxx::Level::toLevel("INFO")); Config *cfg = Config::getInstance(); cfg->addOption(scidb::CONFIG_PLUGINS, 'u', "plugins", "PLUGINS", "", scidb::Config::STRING, "Plugins folder.", string("/../../bin/plugins"), false); TypeLibrary::registerBuiltInTypes(); FunctionLibrary::getInstance()->registerBuiltInFunctions(); initConfig(argc, argv); cfg->setOption(CONFIG_PORT,0); SystemCatalog* catalog = SystemCatalog::getInstance(); catalog->connect(cfg->getOption<string>(CONFIG_CATALOG_CONNECTION_STRING)); CppUnit::TextUi::TestRunner runner; CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); runner.addTest(registry.makeTest()); const bool wasSuccessful = runner.run("", false); return wasSuccessful ? 0 : 3; } catch(const std::exception& e) { cout << "Unhandled std::exception: " << e.what() << endl; return 1; } catch(...) { cout << "Unhabdled exception" << endl; return 2; } }
void runSciDB() { struct sigaction action; action.sa_handler = scidb_termination_handler; sigemptyset(&action.sa_mask); action.sa_flags = 0; sigaction (SIGINT, &action, NULL); sigaction (SIGTERM, &action, NULL); Config *cfg = Config::getInstance(); assert(cfg); // Configuring loggers const std::string& log4cxxProperties = cfg->getOption<string>(CONFIG_LOG4CXX_PROPERTIES); if (log4cxxProperties.empty()) { log4cxx::BasicConfigurator::configure(); const std::string& log_level = cfg->getOption<string>(CONFIG_LOG_LEVEL); log4cxx::LoggerPtr rootLogger(log4cxx::Logger::getRootLogger()); rootLogger->setLevel(log4cxx::Level::toLevel(log_level)); } else { log4cxx::PropertyConfigurator::configure(log4cxxProperties.c_str()); } //Initialize random number generator //We will try to read seed from /dev/urandom and if we can't for some reason we will take time and pid as seed ifstream file ("/dev/urandom", ios::in|ios::binary); unsigned int seed; if (file.is_open()) { const size_t size = sizeof(unsigned int); char buf[size]; file.read(buf, size); file.close(); seed = *reinterpret_cast<unsigned int*>(buf); } else { seed = time(0) ^ (getpid() << 8); LOG4CXX_WARN(logger, "Can not open /dev/urandom. srandom will be initialized with fallback seed based on time and pid."); } srandom(seed); LOG4CXX_INFO(logger, "Start SciDB instance (pid="<<getpid()<<"). " << SCIDB_BUILD_INFO_STRING(". ")); LOG4CXX_INFO(logger, "Configuration:\n" << cfg->toString()); if (cfg->getOption<int>(CONFIG_MAX_MEMORY_LIMIT) > 0) { size_t maxMem = ((int64_t) cfg->getOption<int>(CONFIG_MAX_MEMORY_LIMIT)) * 1024 * 1024; LOG4CXX_DEBUG(logger, "Capping maximum memory:"); struct rlimit rlim; if (getrlimit(RLIMIT_AS, &rlim) != 0) { LOG4CXX_DEBUG(logger, ">getrlimit call failed with errno "<<errno<<"; memory cap not set."); } else { if (rlim.rlim_cur == RLIM_INFINITY || rlim.rlim_cur > maxMem) { rlim.rlim_cur = maxMem; if (setrlimit(RLIMIT_AS, &rlim) != 0) { LOG4CXX_DEBUG(logger, ">setrlimit call failed with errno "<<errno<<"; memory cap not set."); } else { LOG4CXX_DEBUG(logger, ">memory cap set to " << rlim.rlim_cur << " bytes."); } } else { LOG4CXX_DEBUG(logger, ">memory cap "<<rlim.rlim_cur<<" is already under "<<maxMem<<"; not changed."); } } } std::string tmpDir = Config::getInstance()->getOption<std::string>(CONFIG_TMP_PATH); // If the tmp directory does not exist, create it. // Note that multiple levels of directories may need to be created. if (tmpDir.length() == 0 || tmpDir[tmpDir.length()-1] != '/') { tmpDir += '/'; } if (access(tmpDir.c_str(),0) != 0) { size_t end = 0; do { while (end < tmpDir.length() && tmpDir[end] != '/') { ++ end; } if (end < tmpDir.length()) { ++ end; string subdir = tmpDir.substr(0, end); if (access(subdir.c_str(),0) != 0) { if (mkdir(subdir.c_str(), 0755) != 0) { LOG4CXX_DEBUG(logger, "Could not create temp directory "<<subdir<<" errno "<<errno); throw SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_CANT_OPEN_FILE) << subdir.c_str() << errno; } LOG4CXX_DEBUG(logger, "Created temp directory "<<subdir); } } } while (end<tmpDir.length()); } #ifndef __APPLE__ const int memThreshold = Config::getInstance()->getOption<int>(CONFIG_MEM_ARRAY_THRESHOLD); SharedMemCache::getInstance().setMemThreshold(memThreshold * MB); int largeMemLimit = cfg->getOption<int>(CONFIG_LARGE_MEMALLOC_LIMIT); if (largeMemLimit>0 && (0==mallopt(M_MMAP_MAX, largeMemLimit))) { LOG4CXX_WARN(logger, "Failed to set large-memalloc-limit"); } int smallMemSize = cfg->getOption<int>(CONFIG_SMALL_MEMALLOC_SIZE); if (smallMemSize>0 && (0==mallopt(M_MMAP_THRESHOLD, smallMemSize))) { LOG4CXX_WARN(logger, "Failed to set small-memalloc-size"); } #endif boost::shared_ptr<JobQueue> messagesJobQueue = boost::make_shared<JobQueue>(); // Here we can play with thread number // TODO: For SG operations probably we should have separate thread pool const uint32_t nJobs = std::max(cfg->getOption<int>(CONFIG_MAX_JOBS),2); messagesThreadPool = make_shared<ThreadPool>(nJobs, messagesJobQueue); SystemCatalog* catalog = SystemCatalog::getInstance(); const bool initializeCluster = Config::getInstance()->getOption<bool>(CONFIG_INITIALIZE); try { //Disable metadata upgrade in initialize mode catalog->connect( Config::getInstance()->getOption<string>(CONFIG_CATALOG_CONNECTION_STRING), !initializeCluster); } catch (const std::exception &e) { LOG4CXX_ERROR(logger, "System catalog connection failed: " << e.what()); scidb::exit(1); } int errorCode = 0; try { if (!catalog->isInitialized() || initializeCluster) { catalog->initializeCluster(); } TypeLibrary::registerBuiltInTypes(); FunctionLibrary::getInstance()->registerBuiltInFunctions(); // Force preloading builtin operators OperatorLibrary::getInstance(); PluginManager::getInstance()->preLoadLibraries(); // Pull in the injected error library symbols InjectedErrorLibrary::getLibrary()->getError(0); PhysicalOperator::getInjectedErrorListener(); ThreadPool::startInjectedErrorListener(); ReplicationManager::getInstance()->start(messagesJobQueue); messagesThreadPool->start(); NetworkManager::getInstance()->run(messagesJobQueue); } catch (const std::exception &e) { LOG4CXX_ERROR(logger, "Error during SciDB execution: " << e.what()); errorCode = 1; } try { Query::freeQueries(); if (messagesThreadPool) { messagesThreadPool->stop(); } StorageManager::getInstance().close(); ReplicationManager::getInstance()->stop(); } catch (const std::exception &e) { LOG4CXX_ERROR(logger, "Error during SciDB exit: " << e.what()); errorCode = 1; } LOG4CXX_INFO(logger, "SciDB instance. " << SCIDB_BUILD_INFO_STRING(". ") << " is exiting."); log4cxx::Logger::getRootLogger()->setLevel(log4cxx::Level::getOff()); scidb::exit(errorCode); }