00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00037 #include "OW_config.h"
00038 #include "OW_CIMOMEnvironment.hpp"
00039 #include "OW_ConfigOpts.hpp"
00040 #include "OW_Platform.hpp"
00041 #include "OW_PlatformSignal.hpp"
00042 #include "OW_Assertion.hpp"
00043 #include "OW_Format.hpp"
00044 #include "OW_Logger.hpp"
00045 #include "OW_CerrLogger.hpp"
00046 #include "OW_CmdLineParser.hpp"
00047
00048 #include <exception>
00049 #include <iostream>
00050 #include <new>
00051
00052 #ifdef OW_USE_DL
00053 #include "OW_dlSharedLibrary.hpp"
00054 #endif
00055
00056 using namespace OpenWBEM;
00057
00058
00059 namespace
00060 {
00061 enum
00062 {
00063 E_HELP_OPT,
00064 E_VERSION_OPT,
00065 E_LIBRARY_VERSION_OPT,
00066 E_DEBUG_MODE_OPT,
00067 E_CONFIG_FILE_OPT
00068 };
00069 const CmdLineParser::Option g_options[] =
00070 {
00071 {E_HELP_OPT, 'h', "help", CmdLineParser::E_NO_ARG, 0, "Show help about options and exit"},
00072 {E_VERSION_OPT, 'v', "version", CmdLineParser::E_NO_ARG, 0, "Show version information and exit"},
00073 {E_LIBRARY_VERSION_OPT, 'l', "libversion", CmdLineParser::E_NO_ARG, 0, "Show the required OpenWBEM library version and exit"},
00074 {E_DEBUG_MODE_OPT, 'd', "debug", CmdLineParser::E_NO_ARG, 0, "Use debug mode (does not detach from terminal)"},
00075 {E_CONFIG_FILE_OPT, 'c', "config", CmdLineParser::E_REQUIRED_ARG, 0, "Use <arg> instead of the default config file"},
00076 {0, 0, 0, CmdLineParser::E_NO_ARG, 0, 0}
00077 };
00078
00079
00080 void processCommandLine(int argc, char* argv[], CIMOMEnvironmentRef env);
00081 void printUsage(std::ostream& ostrm);
00082
00083 const String COMPONENT_NAME("ow.owcimomd");
00084 }
00085
00086 void owcimomd_new_handler();
00087
00089 int main(int argc, char* argv[])
00090 {
00091 int rval = 0;
00092 CIMOMEnvironmentRef env = CIMOMEnvironment::instance();
00093
00094
00095 LoggerRef logger(new CerrLogger());
00096
00097 try
00098 {
00099 processCommandLine(argc, argv, env);
00100
00101 env->init();
00102
00103
00104 bool debugMode = env->getConfigItem(ConfigOpts::DEBUGFLAG_opt, OW_DEFAULT_DEBUGFLAG).equalsIgnoreCase("true");
00105
00106
00107 logger = env->getLogger(COMPONENT_NAME);
00108 OW_LOG_INFO(logger, "owcimomd (" OW_VERSION ") beginning startup");
00109
00110 #ifdef OW_USE_DL
00111 if (env->getConfigItem("owcimomd.dont_call_dlclose", "false").equalsIgnoreCase("true"))
00112 {
00113 dlSharedLibrary::setCallDlclose(false);
00114 }
00115 #endif
00116
00117
00118 try
00119 {
00120 Platform::daemonize(debugMode, OW_DAEMON_NAME, env);
00121 }
00122 catch (const DaemonException& e)
00123 {
00124 OW_LOG_FATAL_ERROR(logger, e.getMessage());
00125 OW_LOG_FATAL_ERROR(logger, "owcimomd failed to initialize. Aborting...");
00126 return 1;
00127 }
00128
00129 env->startServices();
00130 OW_LOG_INFO(logger, "owcimomd is now running!");
00131
00132
00133 std::unexpected_handler oldUnexpectedHandler = 0;
00134 std::terminate_handler oldTerminateHandler = 0;
00135 std::new_handler oldNewHandler = std::set_new_handler(owcimomd_new_handler);
00136
00137 if (env->getConfigItem(ConfigOpts::RESTART_ON_ERROR_opt, OW_DEFAULT_RESTART_ON_ERROR).equalsIgnoreCase("true"))
00138 {
00139 const char* const restartDisabledMessage =
00140 "WARNING: even though the owcimomd.restart_on_error config option = true, it\n"
00141 "is not enabled. Possible reasons are that OpenWBEM is built in debug mode,\n"
00142 "owcimomd is running in debug mode (-d), or owcimomd was not run using an\n"
00143 "absolute path (argv[0][0] != '/')";
00144
00145
00146 #if !defined(OW_DEBUG)
00147 if ((debugMode == false) && argv[0][0] == '/')
00148 {
00149 Platform::installFatalSignalHandlers();
00150 oldUnexpectedHandler = std::set_unexpected(Platform::rerunDaemon);
00151 oldTerminateHandler = std::set_terminate(Platform::rerunDaemon);
00152 }
00153 else
00154 {
00155 OW_LOG_INFO(logger, restartDisabledMessage);
00156 }
00157 #else
00158 OW_LOG_INFO(logger, restartDisabledMessage);
00159 #endif
00160 }
00161
00162 int sig;
00163 bool shuttingDown(false);
00164
00165 Platform::sendDaemonizeStatus(Platform::DAEMONIZE_SUCCESS);
00166 while (!shuttingDown)
00167 {
00168
00169
00170 env->runSelectEngine();
00171 Platform::Signal::SignalInformation signalInfo;
00172
00173 sig = Platform::popSig(signalInfo);
00174 switch (sig)
00175 {
00176 case Platform::SHUTDOWN:
00177
00178 OW_LOG_INFO(logger, "owcimomd received shutdown notification."
00179 " Initiating shutdown");
00180 OW_LOG_INFO(logger, Format("signal details:\n%1", signalInfo));
00181 shuttingDown = true;
00182
00183
00184 #if !defined(OW_DEBUG)
00185
00186 Platform::removeFatalSignalHandlers();
00187 if (oldUnexpectedHandler)
00188 {
00189 std::set_unexpected(oldUnexpectedHandler);
00190 }
00191 if (oldTerminateHandler)
00192 {
00193 std::set_terminate(oldTerminateHandler);
00194 }
00195 #endif
00196
00197 env->shutdown();
00198 break;
00199 case Platform::REINIT:
00200 OW_LOG_INFO(logger, "owcimomd received restart notification."
00201 " Initiating restart");
00202 OW_LOG_INFO(logger, Format("signal details: %1", signalInfo));
00203 env->shutdown();
00204 env->clearConfigItems();
00205 env = CIMOMEnvironment::instance() = 0;
00206
00207 Platform::rerunDaemon();
00208
00209
00210
00211 env = CIMOMEnvironment::instance() = new CIMOMEnvironment;
00212 processCommandLine(argc, argv, env);
00213 env->init();
00214 env->startServices();
00215 break;
00216 default:
00217 OW_LOG_INFO(logger, Format("Ignoring signal. Details: %1", signalInfo));
00218 break;
00219 }
00220 }
00221 }
00222 catch (Exception& e)
00223 {
00224 OW_LOG_FATAL_ERROR(logger, "* EXCEPTION CAUGHT IN owcimomd MAIN!");
00225 OW_LOG_FATAL_ERROR(logger, Format("* %1", e));
00226 Platform::sendDaemonizeStatus(Platform::DAEMONIZE_FAIL);
00227 rval = 1;
00228 }
00229 catch (std::exception& se)
00230 {
00231 OW_LOG_FATAL_ERROR(logger, "* std::exception CAUGHT IN owcimomd MAIN!");
00232 OW_LOG_FATAL_ERROR(logger, Format("* Message: %1", se.what()));
00233 Platform::sendDaemonizeStatus(Platform::DAEMONIZE_FAIL);
00234 rval = 1;
00235 }
00236 catch(...)
00237 {
00238 OW_LOG_FATAL_ERROR(logger, "* UNKNOWN EXCEPTION CAUGHT owcimomd MAIN!");
00239 Platform::sendDaemonizeStatus(Platform::DAEMONIZE_FAIL);
00240 rval = 1;
00241 }
00242
00243 Platform::daemonShutdown(OW_DAEMON_NAME, env);
00244
00245 CIMOMEnvironment::instance() = env = 0;
00246
00247 OW_LOG_INFO(logger, "owcimomd has shutdown");
00248 return rval;
00249 }
00250
00251 namespace
00252 {
00253
00255 void
00256 processCommandLine(int argc, char* argv[], CIMOMEnvironmentRef env)
00257 {
00258
00259
00260 Platform::daemonInit(argc, argv);
00261
00262 try
00263 {
00264 CmdLineParser parser(argc, argv, g_options, CmdLineParser::E_NON_OPTION_ARGS_INVALID);
00265
00266
00267
00268
00269 if (parser.isSet(E_HELP_OPT))
00270 {
00271 printUsage(std::cout);
00272 exit(0);
00273 }
00274 else if (parser.isSet(E_VERSION_OPT))
00275 {
00276 std::cout << OW_DAEMON_NAME " from " OW_PACKAGE_STRING << std::endl;
00277 exit(0);
00278 }
00279 else if (parser.isSet(E_LIBRARY_VERSION_OPT))
00280 {
00281 #define STRINGIFY_ARGUMENT(x) #x
00282 #define STRINGIFY_DEFINITION_VALUE(x) STRINGIFY_ARGUMENT(x)
00283 std::cout << STRINGIFY_DEFINITION_VALUE(OW_OPENWBEM_LIBRARY_VERSION) << std::endl;
00284 #undef STRINGIFY_ARGUMENT
00285 #undef STRINGIFY_DEFINITION_VALUE
00286 exit(0);
00287 }
00288
00289
00290
00291
00292 if (parser.isSet(E_DEBUG_MODE_OPT))
00293 {
00294 env->setConfigItem(ConfigOpts::DEBUGFLAG_opt, "true", ServiceEnvironmentIFC::E_PRESERVE_PREVIOUS);
00295 env->setConfigItem(ConfigOpts::LOG_LEVEL_opt, "debug");
00296 }
00297 if (parser.isSet(E_CONFIG_FILE_OPT))
00298 {
00299 env->setConfigItem(ConfigOpts::CONFIG_FILE_opt, parser.getOptionValue(E_CONFIG_FILE_OPT));
00300 }
00301 }
00302 catch (const CmdLineParserException& e)
00303 {
00304 switch (e.getErrorCode())
00305 {
00306 case CmdLineParser::E_INVALID_OPTION:
00307 std::cerr << "Invalid option: " << e.getMessage() << std::endl;
00308 break;
00309 case CmdLineParser::E_MISSING_ARGUMENT:
00310 std::cerr << "Argument not specified for option: " << e.getMessage() << std::endl;
00311 break;
00312 }
00313 printUsage(std::cerr);
00314 exit(1);
00315 }
00316 }
00317
00319 void
00320 printUsage(std::ostream& ostrm)
00321 {
00322 ostrm << OW_DAEMON_NAME << " [OPTIONS]..." << std::endl;
00323 ostrm << CmdLineParser::getUsage(g_options) << std::endl;
00324 }
00325
00326 }
00328 void owcimomd_new_handler()
00329 {
00330 #if defined (OW_DEBUG) || defined (OW_NETWARE)
00331 abort();
00332 #endif
00333
00334 Platform::restartDaemon();
00335 throw std::bad_alloc();
00336 }
00337