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 &registry = 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;
    }
}
Ejemplo n.º 2
0
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);
}