diff --git a/src/im_mad/collectd/OpenNebulaDriver.cc b/src/im_mad/collectd/OpenNebulaDriver.cc index 2d539a318a..99f14838ba 100644 --- a/src/im_mad/collectd/OpenNebulaDriver.cc +++ b/src/im_mad/collectd/OpenNebulaDriver.cc @@ -56,7 +56,7 @@ int OpenNebulaDriver::read_one(std::string& message) } while ( rc > 0 && c != '\n' ); - if (rc < 0) + if (rc <= 0) { return -1; } @@ -71,36 +71,42 @@ int OpenNebulaDriver::read_one(std::string& message) void OpenNebulaDriver::driver_loop() { + int rc; + while (true) { std::string message; - if (read_one(message) == 0) + rc = read_one(message); + + if ( rc == -1 ) //Error in select or read from OpenNebula, exit { - std::istringstream is(message); - std::string action; + break; + } - if ( is.good() ) - { - is >> action >> std::ws; - } - else - { - continue; - } + std::istringstream is(message); + std::string action; - if (action == "INIT") - { - write2one("INIT SUCCESS\n",13); - } - else if (action == "FINALIZE") - { - break; - } - else - { - driver_action(action, is); - } + if ( is.good() ) + { + is >> action >> std::ws; + } + else + { + continue; + } + + if (action == "INIT") + { + write2one("INIT SUCCESS\n",13); + } + else if (action == "FINALIZE") + { + break; + } + else + { + driver_action(action, is); } } } diff --git a/src/im_mad/collectd/collectd.cc b/src/im_mad/collectd/collectd.cc index 256392bdaa..c714acb7ab 100644 --- a/src/im_mad/collectd/collectd.cc +++ b/src/im_mad/collectd/collectd.cc @@ -19,6 +19,10 @@ #include #include #include +#include + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- static const char * usage = "\n collectd [-h] [-a address] [-p port] [-t threads] [-f flush]\n\n" @@ -31,8 +35,32 @@ static const char * usage = "\t-f\tInterval in seconds to flush collected information\n" "\t-t\tNumber of threads for the server\n"; +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + +extern "C" void * sig_thread(void *arg) +{ + // Wait for a SIGTERM or SIGINT signal & exit + sigset_t mask; + int signal; + + sigemptyset(&mask); + + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + + sigwait(&mask, &signal); + + _exit(0); +} + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + int main(int argc, char ** argv) { + sigset_t mask; + std::string address = "0.0.0.0"; int port = 4124; int threads = 50; @@ -79,7 +107,29 @@ int main(int argc, char ** argv) break; } + //-------------------------------------------------------------------------- + // Block all signals before creating server threads + //-------------------------------------------------------------------------- + sigfillset(&mask); + pthread_sigmask(SIG_BLOCK, &mask, NULL); + + // ------------------------------------------------------------------------- + //Handle SIGTERM and SIGQUIT in a specific thread + // ------------------------------------------------------------------------- + pthread_attr_t attr; + pthread_t id; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + pthread_create(&id, &attr, sig_thread, 0); + + pthread_attr_destroy(&attr); + + // ------------------------------------------------------------------------- + // Start the collector and server threads + // ------------------------------------------------------------------------- IMCollectorDriver collectd(address, port, threads, flush); if ( collectd.init_collector() != 0 )