aboutsummaryrefslogtreecommitdiff
path: root/daemon/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/main.cpp')
-rw-r--r--daemon/main.cpp100
1 files changed, 70 insertions, 30 deletions
diff --git a/daemon/main.cpp b/daemon/main.cpp
index fbce1e1..c68a892 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
#include <sys/wait.h>
#include <unistd.h>
+#include "AnnotateListener.h"
#include "CCNDriver.h"
#include "Child.h"
#include "EventsXML.h"
@@ -133,7 +134,7 @@ public:
memset(&mDstAns, 0, sizeof(mDstAns));
memcpy(mDstAns.rviHeader, "STR_ANS ", sizeof(mDstAns.rviHeader));
if (gethostname(mDstAns.dhcpName, sizeof(mDstAns.dhcpName) - 1) != 0) {
- logg->logError(__FILE__, __LINE__, "gethostname failed");
+ logg->logError("gethostname failed");
handleException();
}
// Subvert the defaultGateway field for the port number
@@ -156,7 +157,7 @@ public:
addrlen = sizeof(sockaddr);
read = recvfrom(mReq, &buf, sizeof(buf), 0, (struct sockaddr *)&sockaddr, &addrlen);
if (read < 0) {
- logg->logError(__FILE__, __LINE__, "recvfrom failed");
+ logg->logError("recvfrom failed");
handleException();
} else if ((read == 12) && (memcmp(buf, DST_REQ, sizeof(DST_REQ)) == 0)) {
// Don't care if sendto fails - gatord shouldn't exit because of it and Streamline will retry
@@ -180,23 +181,29 @@ private:
family = AF_INET;
s = socket_cloexec(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) {
- logg->logError(__FILE__, __LINE__, "socket failed");
+ logg->logError("socket failed");
handleException();
}
}
on = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) {
- logg->logError(__FILE__, __LINE__, "setsockopt failed");
+ logg->logError("setsockopt REUSEADDR failed");
handleException();
}
+ // Listen on both IPv4 and IPv6
+ on = 0;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(on)) != 0) {
+ logg->logMessage("setsockopt IPV6_V6ONLY failed");
+ }
+
memset((void*)&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin6_family = family;
sockaddr.sin6_port = htons(port);
sockaddr.sin6_addr = in6addr_any;
if (bind(s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) {
- logg->logError(__FILE__, __LINE__, "socket failed");
+ logg->logError("socket failed");
handleException();
}
@@ -252,7 +259,7 @@ static bool setupFilesystem(char* module) {
// if still mounted
if (access("/dev/gator/buffer", F_OK) == 0) {
- logg->logError(__FILE__, __LINE__, "Unable to remove the running gator.ko. Manually remove the module or use the running module by not specifying one on the commandline");
+ logg->logError("Unable to remove the running gator.ko. Manually remove the module or use the running module by not specifying one on the commandline");
handleException();
}
}
@@ -284,7 +291,7 @@ static bool setupFilesystem(char* module) {
return false;
} else {
// gator location specified on the command line but it was not found
- logg->logError(__FILE__, __LINE__, "gator module not found at %s", location);
+ logg->logError("gator module not found at %s", location);
handleException();
}
}
@@ -296,13 +303,13 @@ static bool setupFilesystem(char* module) {
snprintf(command, sizeof(command), "insmod %s >/dev/null 2>&1", location);
if (system(command) != 0) {
logg->logMessage("Unable to load gator.ko driver with command: %s", command);
- logg->logError(__FILE__, __LINE__, "Unable to load (insmod) gator.ko driver:\n >>> gator.ko must be built against the current kernel version & configuration\n >>> See dmesg for more details");
+ logg->logError("Unable to load (insmod) gator.ko driver:\n >>> gator.ko must be built against the current kernel version & configuration\n >>> See dmesg for more details");
handleException();
}
}
if (mountGatorFS() == -1) {
- logg->logError(__FILE__, __LINE__, "Unable to mount the gator filesystem needed for profiling.");
+ logg->logError("Unable to mount the gator filesystem needed for profiling.");
handleException();
}
}
@@ -326,7 +333,7 @@ static int shutdownFilesystem() {
return 0; // success
}
-static const char OPTSTRING[] = "hvudap:s:c:e:m:o:";
+static const char OPTSTRING[] = "hvVudap:s:c:e:E:m:o:";
static bool hasDebugFlag(int argc, char** argv) {
int c;
@@ -368,11 +375,18 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
case 'e':
gSessionData->mEventsXMLPath = optarg;
break;
+ case 'E':
+ gSessionData->mEventsXMLAppend = optarg;
+ break;
case 'm':
cmdline.module = optarg;
break;
case 'p':
cmdline.port = strtol(optarg, NULL, 10);
+ if ((cmdline.port == 8082) || (cmdline.port == 8083)) {
+ logg->logError("Gator can't use port %i, as it already uses ports 8082 and 8083 for annotations. Please select a different port.", cmdline.port);
+ handleException();
+ }
break;
case 's':
gSessionData->mSessionXMLPath = optarg;
@@ -388,10 +402,11 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
break;
case 'h':
case '?':
- logg->logError(__FILE__, __LINE__,
+ logg->logError(
"%s. All parameters are optional:\n"
- "-c config_xml path and filename of the configuration.xml to use\n"
- "-e events_xml path and filename of the events.xml to use\n"
+ "-c config_xml path and filename of the configuration XML to use\n"
+ "-e events_xml path and filename of the events XML to use\n"
+ "-E events_xml path and filename of events XML to append\n"
"-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"
@@ -399,12 +414,16 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
"-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"
+ "-a allow the user to issue a command from Streamline"
, version_string);
handleException();
break;
case 'v':
- logg->logError(__FILE__, __LINE__, version_string);
+ logg->logError("%s", version_string);
+ handleException();
+ break;
+ case 'V':
+ logg->logError("%s\nSRC_MD5: %s", version_string, gSrcMd5);
handleException();
break;
}
@@ -412,35 +431,38 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
// Error checking
if (cmdline.port != DEFAULT_PORT && gSessionData->mSessionXMLPath != NULL) {
- logg->logError(__FILE__, __LINE__, "Only a port or a session xml can be specified, not both");
+ logg->logError("Only a port or a session xml can be specified, not both");
handleException();
}
if (gSessionData->mTargetPath != NULL && gSessionData->mSessionXMLPath == NULL) {
- logg->logError(__FILE__, __LINE__, "Missing -s command line option required for a local capture.");
+ logg->logError("Missing -s command line option required for a local capture.");
handleException();
}
if (optind < argc) {
- logg->logError(__FILE__, __LINE__, "Unknown argument: %s. Use '-h' for help.", argv[optind]);
+ logg->logError("Unknown argument: %s. Use '-h' for help.", argv[optind]);
handleException();
}
return cmdline;
}
+static AnnotateListener annotateListener;
+
static void handleClient() {
OlySocket client(sock->acceptConnection());
int pid = fork();
if (pid < 0) {
// Error
- logg->logError(__FILE__, __LINE__, "Fork process failed. Please power cycle the target device if this error persists.");
+ logg->logError("Fork process failed. Please power cycle the target device if this error persists.");
} else if (pid == 0) {
// Child
sock->closeServerSocket();
udpListener.close();
monitor.close();
+ annotateListener.close();
child = new Child(&client, numSessions + 1);
child->run();
delete child;
@@ -500,21 +522,23 @@ int main(int argc, char** argv) {
struct cmdline_t cmdline = parseCommandLine(argc, argv);
if (cmdline.update) {
- return update(argv[0]);
+ update(argv[0]);
+ cmdline.update = false;
+ gSessionData->mAllowCommands = true;
}
// Verify root permissions
uid_t euid = geteuid();
if (euid) {
- logg->logError(__FILE__, __LINE__, "gatord must be launched with root privileges");
+ logg->logError("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");
+ logg->logMessage("Unable to set up gatorfs, trying perf");
if (!gSessionData->perf.setup()) {
- logg->logError(__FILE__, __LINE__,
+ 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"
@@ -547,15 +571,23 @@ int main(int argc, char** argv) {
child->run();
delete child;
} else {
- gSessionData->annotateListener.setup();
+ 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(gSessionData->annotateListener.getFd()) ||
+ !monitor.add(annotateListener.getSockFd()) ||
+ !monitor.add(annotateListener.getUdsFd()) ||
+ !monitor.add(pipefd[0]) ||
false) {
- logg->logError(__FILE__, __LINE__, "Monitor setup failed");
+ logg->logError("Monitor setup failed");
handleException();
}
// Forever loop, can be exited via a signal or exception
@@ -564,7 +596,7 @@ int main(int argc, char** argv) {
logg->logMessage("Waiting on connection...");
int ready = monitor.wait(events, ARRAY_LENGTH(events), -1);
if (ready < 0) {
- logg->logError(__FILE__, __LINE__, "Monitor::wait failed");
+ logg->logError("Monitor::wait failed");
handleException();
}
for (int i = 0; i < ready; ++i) {
@@ -572,8 +604,16 @@ 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();
+ } 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();
}
}
}