aboutsummaryrefslogtreecommitdiff
path: root/tools/gator/daemon/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gator/daemon/main.cpp')
-rw-r--r--tools/gator/daemon/main.cpp95
1 files changed, 66 insertions, 29 deletions
diff --git a/tools/gator/daemon/main.cpp b/tools/gator/daemon/main.cpp
index 2998c7012221..fbce1e15d0d0 100644
--- a/tools/gator/daemon/main.cpp
+++ b/tools/gator/daemon/main.cpp
@@ -19,16 +19,15 @@
#include <sys/wait.h>
#include <unistd.h>
+#include "CCNDriver.h"
#include "Child.h"
#include "EventsXML.h"
-#include "KMod.h"
#include "Logging.h"
#include "Monitor.h"
#include "OlySocket.h"
#include "OlyUtility.h"
#include "SessionData.h"
-
-#define DEBUG false
+#include "Setup.h"
extern Child* child;
static int shutdownFilesystem();
@@ -40,8 +39,9 @@ static bool driverRunningAtStart = false;
static bool driverMountedAtStart = false;
struct cmdline_t {
+ char *module;
int port;
- char* module;
+ bool update;
};
#define DEFAULT_PORT 8080
@@ -105,7 +105,6 @@ static void child_exit(int) {
}
}
-static const int UDP_ANS_PORT = 30000;
static const int UDP_REQ_PORT = 30001;
typedef struct {
@@ -125,11 +124,10 @@ static const char DST_REQ[] = { 'D', 'S', 'T', '_', 'R', 'E', 'Q', ' ', 0, 0, 0,
class UdpListener {
public:
- UdpListener() : mDstAns(), mReq(-1), mAns(-1) {}
+ UdpListener() : mDstAns(), mReq(-1) {}
void setup(int port) {
mReq = udpPort(UDP_REQ_PORT);
- mAns = udpPort(UDP_ANS_PORT);
// Format the answer buffer
memset(&mDstAns, 0, sizeof(mDstAns));
@@ -161,16 +159,13 @@ public:
logg->logError(__FILE__, __LINE__, "recvfrom failed");
handleException();
} else if ((read == 12) && (memcmp(buf, DST_REQ, sizeof(DST_REQ)) == 0)) {
- if (sendto(mAns, &mDstAns, sizeof(mDstAns), 0, (struct sockaddr *)&sockaddr, addrlen) != sizeof(mDstAns)) {
- logg->logError(__FILE__, __LINE__, "sendto failed");
- handleException();
- }
+ // Don't care if sendto fails - gatord shouldn't exit because of it and Streamline will retry
+ sendto(mReq, &mDstAns, sizeof(mDstAns), 0, (struct sockaddr *)&sockaddr, addrlen);
}
}
void close() {
::close(mReq);
- ::close(mAns);
}
private:
@@ -180,10 +175,10 @@ private:
int on;
int family = AF_INET6;
- s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ s = socket_cloexec(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) {
family = AF_INET;
- s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ s = socket_cloexec(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) {
logg->logError(__FILE__, __LINE__, "socket failed");
handleException();
@@ -210,7 +205,6 @@ private:
RVIConfigureInfo mDstAns;
int mReq;
- int mAns;
};
static UdpListener udpListener;
@@ -233,7 +227,7 @@ static int mountGatorFS() {
static bool init_module (const char * const location) {
bool ret(false);
- const int fd = open(location, O_RDONLY);
+ const int fd = open(location, O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
struct stat st;
if (fstat(fd, &st) == 0) {
@@ -332,10 +326,26 @@ static int shutdownFilesystem() {
return 0; // success
}
+static const char OPTSTRING[] = "hvudap:s:c:e:m:o:";
+
+static bool hasDebugFlag(int argc, char** argv) {
+ int c;
+
+ optind = 1;
+ while ((c = getopt(argc, argv, OPTSTRING)) != -1) {
+ if (c == 'd') {
+ return true;
+ }
+ }
+
+ return false;
+}
+
static struct cmdline_t parseCommandLine(int argc, char** argv) {
struct cmdline_t cmdline;
cmdline.port = DEFAULT_PORT;
cmdline.module = NULL;
+ cmdline.update = false;
char version_string[256]; // arbitrary length to hold the version information
int c;
@@ -346,11 +356,15 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
snprintf(version_string, sizeof(version_string), "Streamline gatord development version %d", PROTOCOL_VERSION);
}
- while ((c = getopt(argc, argv, "hvp:s:c:e:m:o:")) != -1) {
- switch(c) {
+ optind = 1;
+ while ((c = getopt(argc, argv, OPTSTRING)) != -1) {
+ switch (c) {
case 'c':
gSessionData->mConfigurationXMLPath = optarg;
break;
+ case 'd':
+ // Already handled
+ break;
case 'e':
gSessionData->mEventsXMLPath = optarg;
break;
@@ -366,6 +380,12 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
case 'o':
gSessionData->mTargetPath = optarg;
break;
+ case 'u':
+ cmdline.update = true;
+ break;
+ case 'a':
+ gSessionData->mAllowCommands = true;
+ break;
case 'h':
case '?':
logg->logError(__FILE__, __LINE__,
@@ -375,9 +395,11 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
"-h this help page\n"
"-m module path and filename of gator.ko\n"
"-p port_number port upon which the server listens; default is 8080\n"
- "-s session_xml path and filename of a session xml used for local capture\n"
+ "-s session_xml path and filename of a session.xml used for local capture\n"
"-o apc_dir path and name of the output for a local capture\n"
"-v version information\n"
+ "-d enable debug messages\n"
+ "-a allow the user user to provide a command to run at the start of a capture"
, version_string);
handleException();
break;
@@ -407,7 +429,7 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
return cmdline;
}
-void handleClient() {
+static void handleClient() {
OlySocket client(sock->acceptConnection());
int pid = fork();
@@ -452,12 +474,15 @@ int main(int argc, char** argv) {
// e.g. it may not be the group leader when launched as 'sudo gatord'
setsid();
- logg = new Logging(DEBUG); // Set up global thread-safe logging
- gSessionData = new SessionData(); // Global data class
- util = new OlyUtility(); // Set up global utility class
+ // 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 KMod();
+ new CCNDriver();
prctl(PR_SET_NAME, (unsigned long)&"gatord-main", 0, 0, 0);
pthread_mutex_init(&numSessions_mutex, NULL);
@@ -474,6 +499,10 @@ int main(int argc, char** argv) {
// 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) {
@@ -490,17 +519,18 @@ int main(int argc, char** argv) {
" >>> 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) support to collect data via userspace only");
+ " >>> 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();
}
}
- gSessionData->hwmon.setup();
{
EventsXML eventsXML;
mxml_node_t *xml = eventsXML.getTree();
- gSessionData->fsDriver.setup(xml);
- gSessionData->maliVideo.setup(xml);
+ // Initialize all drivers
+ for (Driver *driver = Driver::getHead(); driver != NULL; driver = driver->getNext()) {
+ driver->readEvents(xml);
+ }
mxmlDelete(xml);
}
@@ -517,9 +547,14 @@ int main(int argc, char** argv) {
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())) {
+ 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();
}
@@ -537,6 +572,8 @@ int main(int argc, char** argv) {
handleClient();
} else if (events[i].data.fd == udpListener.getReq()) {
udpListener.handle();
+ } else if (events[i].data.fd == gSessionData->annotateListener.getFd()) {
+ gSessionData->annotateListener.handle();
}
}
}