// Gator data flow: collector -> collector fifo -> sender int main(int argc, char** argv) { // Ensure proper signal handling by making gatord the process group leader // e.g. it may not be the group leader when launched as 'sudo gatord' setsid(); // Set up global thread-safe logging logg.setDebug(hasDebugFlag(argc, argv)); gSessionData.initialize(); prctl(PR_SET_NAME, (unsigned long)&"gatord-main", 0, 0, 0); pthread_mutex_init(&numSessions_mutex, NULL); signal(SIGINT, handler); signal(SIGTERM, handler); signal(SIGABRT, handler); // Set to high priority if (setpriority(PRIO_PROCESS, syscall(__NR_gettid), -19) == -1) { logg.logMessage("setpriority() failed"); } // Try to increase the maximum number of file descriptors { struct rlimit rlim; memset(&rlim, 0, sizeof(rlim)); if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { logg.logMessage("Unable to get the maximum number of files"); // Not good, but not a fatal error either } else { rlim.rlim_cur = max(((rlim_t)1)<<15, rlim.rlim_cur); rlim.rlim_max = max(rlim.rlim_cur, rlim.rlim_max); if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { logg.logMessage("Unable to increase the maximum number of files"); // Not good, but not a fatal error either } } } // Parse the command line parameters struct cmdline_t cmdline = parseCommandLine(argc, argv); // Verify root permissions uid_t euid = geteuid(); if (euid) { logg.logError("gatord must be launched with root privileges"); handleException(); } PmuXML::read(cmdline.pmuPath); // Call before setting up the SIGCHLD handler, as system() spawns child processes if (setupFilesystem(cmdline.module)) { DriverSource::checkVersion(); PmuXML::writeToKernel(); } else { logg.logMessage("Unable to set up gatorfs, trying perf"); if (!gSessionData.mPerf.setup()) { logg.logError( "Unable to locate gator.ko driver:\n" " >>> gator.ko should be co-located with gatord in the same directory\n" " >>> OR insmod gator.ko prior to launching gatord\n" " >>> OR specify the location of gator.ko on the command line\n" " >>> OR run Linux 3.4 or later with perf (CONFIG_PERF_EVENTS and CONFIG_HW_PERF_EVENTS) and tracing (CONFIG_TRACING and CONFIG_CONTEXT_SWITCH_TRACER) support to collect data via userspace only"); handleException(); } } { EventsXML eventsXML; mxml_node_t *xml = eventsXML.getTree(); // Initialize all drivers for (Driver *driver = Driver::getHead(); driver != NULL; driver = driver->getNext()) { driver->readEvents(xml); } mxmlDelete(xml); } // Handle child exit codes signal(SIGCHLD, child_exit); // Ignore the SIGPIPE signal so that any send to a broken socket will return an error code instead of asserting a signal // Handling the error at the send function call is much easier than trying to do anything intelligent in the sig handler signal(SIGPIPE, SIG_IGN); // If the command line argument is a session xml file, no need to open a socket if (gSessionData.mSessionXMLPath) { child = new Child(); child->run(); delete child; } else { annotateListener.setup(); int pipefd[2]; if (pipe_cloexec(pipefd) != 0) { logg.logError("Unable to set up annotate pipe"); handleException(); } gSessionData.mAnnotateStart = pipefd[1]; sock = new OlyServerSocket(cmdline.port); udpListener.setup(cmdline.port); if (!monitor.init() || !monitor.add(sock->getFd()) || !monitor.add(udpListener.getReq()) || !monitor.add(annotateListener.getSockFd()) || !monitor.add(annotateListener.getUdsFd()) || !monitor.add(pipefd[0]) || false) { logg.logError("Monitor setup failed"); handleException(); } // Forever loop, can be exited via a signal or exception while (1) { struct epoll_event events[2]; logg.logMessage("Waiting on connection..."); int ready = monitor.wait(events, ARRAY_LENGTH(events), -1); if (ready < 0) { logg.logError("Monitor::wait failed"); handleException(); } for (int i = 0; i < ready; ++i) { if (events[i].data.fd == sock->getFd()) { handleClient(); } else if (events[i].data.fd == udpListener.getReq()) { udpListener.handle(); } else if (events[i].data.fd == annotateListener.getSockFd()) { annotateListener.handleSock(); } else if (events[i].data.fd == annotateListener.getUdsFd()) { annotateListener.handleUds(); } else if (events[i].data.fd == pipefd[0]) { uint64_t val; if (read(pipefd[0], &val, sizeof(val)) != sizeof(val)) { logg.logMessage("Reading annotate pipe failed"); } annotateListener.signal(); } } } } cleanUp(); return 0; }
// Gator data flow: collector -> collector fifo -> sender int main(int argc, char** argv) { // Ensure proper signal handling by making gatord the process group leader // e.g. it may not be the group leader when launched as 'sudo gatord' setsid(); // Set up global thread-safe logging logg = new Logging(hasDebugFlag(argc, argv)); // Global data class gSessionData = new SessionData(); // Set up global utility class util = new OlyUtility(); // Initialize drivers new CCNDriver(); prctl(PR_SET_NAME, (unsigned long)&"gatord-main", 0, 0, 0); pthread_mutex_init(&numSessions_mutex, NULL); signal(SIGINT, handler); signal(SIGTERM, handler); signal(SIGABRT, handler); // Set to high priority if (setpriority(PRIO_PROCESS, syscall(__NR_gettid), -19) == -1) { logg->logMessage("setpriority() failed"); } // Parse the command line parameters struct cmdline_t cmdline = parseCommandLine(argc, argv); if (cmdline.update) { return update(argv[0]); } // Verify root permissions uid_t euid = geteuid(); if (euid) { logg->logError(__FILE__, __LINE__, "gatord must be launched with root privileges"); handleException(); } // Call before setting up the SIGCHLD handler, as system() spawns child processes if (!setupFilesystem(cmdline.module)) { logg->logMessage("Unable to setup gatorfs, trying perf"); if (!gSessionData->perf.setup()) { logg->logError(__FILE__, __LINE__, "Unable to locate gator.ko driver:\n" " >>> gator.ko should be co-located with gatord in the same directory\n" " >>> OR insmod gator.ko prior to launching gatord\n" " >>> OR specify the location of gator.ko on the command line\n" " >>> OR run Linux 3.4 or later with perf (CONFIG_PERF_EVENTS and CONFIG_HW_PERF_EVENTS) and tracing (CONFIG_TRACING and CONFIG_CONTEXT_SWITCH_TRACER) support to collect data via userspace only"); handleException(); } } { EventsXML eventsXML; mxml_node_t *xml = eventsXML.getTree(); // Initialize all drivers for (Driver *driver = Driver::getHead(); driver != NULL; driver = driver->getNext()) { driver->readEvents(xml); } mxmlDelete(xml); } // Handle child exit codes signal(SIGCHLD, child_exit); // Ignore the SIGPIPE signal so that any send to a broken socket will return an error code instead of asserting a signal // Handling the error at the send function call is much easier than trying to do anything intelligent in the sig handler signal(SIGPIPE, SIG_IGN); // If the command line argument is a session xml file, no need to open a socket if (gSessionData->mSessionXMLPath) { child = new Child(); child->run(); delete child; } else { gSessionData->annotateListener.setup(); sock = new OlyServerSocket(cmdline.port); udpListener.setup(cmdline.port); if (!monitor.init() || !monitor.add(sock->getFd()) || !monitor.add(udpListener.getReq()) || !monitor.add(gSessionData->annotateListener.getFd()) || false) { logg->logError(__FILE__, __LINE__, "Monitor setup failed"); handleException(); } // Forever loop, can be exited via a signal or exception while (1) { struct epoll_event events[2]; logg->logMessage("Waiting on connection..."); int ready = monitor.wait(events, ARRAY_LENGTH(events), -1); if (ready < 0) { logg->logError(__FILE__, __LINE__, "Monitor::wait failed"); handleException(); } for (int i = 0; i < ready; ++i) { if (events[i].data.fd == sock->getFd()) { handleClient(); } else if (events[i].data.fd == udpListener.getReq()) { udpListener.handle(); } else if (events[i].data.fd == gSessionData->annotateListener.getFd()) { gSessionData->annotateListener.handle(); } } } } cleanUp(); return 0; }
void StreamlineSetup::sendEvents() { EventsXML eventsXML; char* string = eventsXML.getXML(); sendString(string, RESPONSE_XML); free(string); }