Example #1
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;
}
Example #2
0
File: main.cpp Project: bigzz/gator
// 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;
}