void Thread::Startup() { threads.init(); threads.setMax(MAX_THREADS); Thread* main = (Thread*)malloc( sizeof(Thread)*1); main->main = &env->methods[manifest.entryMethod]; main->Create("Main"); #ifdef WIN32_ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); SetPriorityClass(GetCurrentThread(), HIGH_PRIORITY_CLASS); #endif setupSigHandler(); }
/** * daemonize() - detach process from user and disappear into the background * Throws DaemonException on error. */ void daemonize(bool dbgFlg, const String& daemonName, const ServiceEnvironmentIFCRef& env) { #ifndef WIN32 #ifdef OW_NETWARE { NonRecursiveMutexLock l(g_shutdownGuard); g_shutDown = false; } #endif initDaemonizePipe(); // If we're running as root and owcimomd.drop_root_privileges != "false", then try to switch users/groups to owcimomd/owcimomd if (geteuid() == 0 && !env->getConfigItem(ConfigOpts::DROP_ROOT_PRIVILEGES_opt, OW_DEFAULT_DROP_ROOT_PRIVILEGES).equalsIgnoreCase("false")) { const char OWCIMOMD_USER[] = "owcimomd"; // dont need to worry about thread safety here, the threads won't start until later. struct passwd* owcimomdInfo = ::getpwnam(OWCIMOMD_USER); if (!owcimomdInfo) { OW_THROW_ERRNO_MSG(DaemonException, "Platform::daemonize(): getpwnam(\"owcimomd\")"); } if (::setgid(owcimomdInfo->pw_gid) != 0) { OW_THROW_ERRNO_MSG(DaemonException, "Platform::daemonize(): setgid"); } if (::initgroups(owcimomdInfo->pw_name, owcimomdInfo->pw_gid) != 0) { OW_THROW_ERRNO_MSG(DaemonException, "Platform::daemonize(): initgroups"); } if (::setuid(owcimomdInfo->pw_uid) != 0) { OW_THROW_ERRNO_MSG(DaemonException, "Platform::daemonize(): setuid"); } } int pid = -1; #if !defined(OW_NETWARE) String pidFile(env->getConfigItem(ConfigOpts::PIDFILE_opt, OW_DEFAULT_PIDFILE)); pid = PidFile::checkPid(pidFile.c_str()); // Is there already another instance of the cimom running? if (pid != -1) { OW_THROW(DaemonException, Format("Another instance of %1 is already running [%2]", daemonName, pid).c_str()); } #endif if (!dbgFlg) { #if !defined(OW_NETWARE) && !defined(WIN32) pid = fork(); switch (pid) { case 0: break; case -1: OW_THROW_ERRNO_MSG(DaemonException, "FAILED TO DETACH FROM THE TERMINAL - First fork"); default: int status = DAEMONIZE_FAIL; if (daemonize_upipe->readInt(&status) < 1 || status != DAEMONIZE_SUCCESS) { cerr << "Error starting CIMOM. Check the log files." << endl; _exit(1); } _exit(0); // exit the original process } if (setsid() < 0) // shoudn't fail on linux { OW_THROW(DaemonException, "FAILED TO DETACH FROM THE TERMINAL - setsid failed"); } pid = fork(); switch (pid) { case 0: break; case -1: { // Save the error number, since the sendDaemonizeStatus function can cause it to change. int saved_errno = errno; sendDaemonizeStatus(DAEMONIZE_FAIL); // Restore the real error number. errno = saved_errno; OW_THROW_ERRNO_MSG(DaemonException, "FAILED TO DETACH FROM THE TERMINAL - Second fork"); exit(1); } default: _exit(0); } #endif chdir("/"); close(0); close(1); close(2); open("/dev/null", O_RDONLY); open("/dev/null", O_WRONLY); dup(1); } else { pid = getpid(); } umask(0077); // ensure all files we create are only accessible by us. #if !defined(OW_NETWARE) if (PidFile::writePid(pidFile.c_str()) == -1) { // Save the error number, since the sendDaemonizeStatus function can cause it to change. int saved_errno = errno; sendDaemonizeStatus(DAEMONIZE_FAIL); // Restore the real error number. errno = saved_errno; OW_THROW_ERRNO_MSG(DaemonException, Format("Failed to write the pid file (%1)", pidFile).c_str()); } #endif OW_LOG_INFO(env->getLogger(COMPONENT_NAME), Format("Platform::daemonize() pid = %1", ::getpid())); #endif initSig(); #ifndef WIN32 setupSigHandler(dbgFlg); #endif #ifdef OW_HAVE_PTHREAD_ATFORK // this registers shutdownSig to be run in the child whenever a fork() happens. // This will prevent a child process from writing to the signal pipe and shutting down the parent. ::pthread_atfork(NULL, NULL, &shutdownSig); #endif }