diff options
Diffstat (limited to 'tools/gator/daemon/main.cpp')
-rw-r--r-- | tools/gator/daemon/main.cpp | 100 |
1 files changed, 70 insertions, 30 deletions
diff --git a/tools/gator/daemon/main.cpp b/tools/gator/daemon/main.cpp index fbce1e15d0d0..c68a892e74fc 100644 --- a/tools/gator/daemon/main.cpp +++ b/tools/gator/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(); } } } |