diff options
author | Drew Richardson <drew.richardson@arm.com> | 2011-11-29 12:00:00 -0800 |
---|---|---|
committer | Drew Richardson <drew.richardson@arm.com> | 2014-12-19 15:22:16 -0800 |
commit | 689b7539711ab098911503808cc3e24307d9bcf7 (patch) | |
tree | eded88dc8c354b94a0b930d3c44f9da2348a4ace /daemon | |
parent | 24395bff3db9e12e6f406ad783ecc9bcde626253 (diff) |
gator: Version 5.85.8
Signed-off-by: Drew Richardson <drew.richardson@arm.com>
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/Android.mk | 6 | ||||
-rw-r--r-- | daemon/CapturedXML.cpp | 8 | ||||
-rw-r--r-- | daemon/Child.cpp | 7 | ||||
-rw-r--r-- | daemon/Collector.cpp | 36 | ||||
-rw-r--r-- | daemon/ConfigurationXML.cpp | 11 | ||||
-rw-r--r-- | daemon/Fifo.cpp | 1 | ||||
-rw-r--r-- | daemon/Fifo.h | 4 | ||||
-rw-r--r-- | daemon/HashMap.cpp | 64 | ||||
-rw-r--r-- | daemon/HashMap.h | 34 | ||||
-rw-r--r-- | daemon/LocalCapture.cpp | 55 | ||||
-rw-r--r-- | daemon/LocalCapture.h | 2 | ||||
-rw-r--r-- | daemon/Logging.cpp | 1 | ||||
-rw-r--r-- | daemon/Logging.h | 15 | ||||
-rw-r--r-- | daemon/Makefile | 2 | ||||
-rw-r--r-- | daemon/OlySocket.cpp | 13 | ||||
-rw-r--r-- | daemon/OlySocket.h | 2 | ||||
-rw-r--r-- | daemon/OlyUtility.cpp | 9 | ||||
-rw-r--r-- | daemon/RequestXML.cpp | 1 | ||||
-rw-r--r-- | daemon/Sender.cpp | 11 | ||||
-rw-r--r-- | daemon/Sender.h | 2 | ||||
-rw-r--r-- | daemon/SessionData.cpp | 5 | ||||
-rw-r--r-- | daemon/SessionData.h | 2 | ||||
-rw-r--r-- | daemon/SessionXML.cpp (renamed from daemon/ReadSession.cpp) | 23 | ||||
-rw-r--r-- | daemon/SessionXML.h (renamed from daemon/ReadSession.h) | 12 | ||||
-rw-r--r-- | daemon/StreamlineSetup.cpp | 24 | ||||
-rw-r--r-- | daemon/XMLOut.cpp | 3 | ||||
-rw-r--r-- | daemon/XMLOut.h | 4 | ||||
-rw-r--r-- | daemon/XMLReader.cpp | 7 | ||||
-rw-r--r-- | daemon/main.cpp | 75 |
29 files changed, 198 insertions, 241 deletions
diff --git a/daemon/Android.mk b/daemon/Android.mk index 45f5b7d..ac3094c 100644 --- a/daemon/Android.mk +++ b/daemon/Android.mk @@ -1,6 +1,8 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +$(shell cd $(LOCAL_PATH);cat events_header.xml events-*\.xml events_footer.xml > events.xml;xxd -i events.xml > events_xml.h;xxd -i configuration.xml > configuration_xml.h) + LOCAL_CFLAGS += -Wall -O3 -ftree-vectorize LOCAL_SRC_FILES:= \ @@ -9,16 +11,15 @@ LOCAL_SRC_FILES:= \ Collector.cpp \ ConfigurationXML.cpp \ Fifo.cpp \ - HashMap.cpp \ LocalCapture.cpp \ Logging.cpp \ main.cpp \ OlySocket.cpp \ OlyUtility.cpp \ - ReadSession.cpp \ RequestXML.cpp \ Sender.cpp \ SessionData.cpp \ + SessionXML.cpp \ StreamlineSetup.cpp \ XMLOut.cpp \ XMLReader.cpp @@ -26,6 +27,7 @@ LOCAL_SRC_FILES:= \ LOCAL_C_INCLUDES := $(LOCAL_PATH) LOCAL_MODULE:= gatord +LOCAL_MODULE_TAGS:= optional LOCAL_LDLIBS := -lz -llog diff --git a/daemon/CapturedXML.cpp b/daemon/CapturedXML.cpp index 9d9fd84..5d1f295 100644 --- a/daemon/CapturedXML.cpp +++ b/daemon/CapturedXML.cpp @@ -6,8 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; -typedef long long int64_t; #include <stdlib.h> #include <string.h> #include <dirent.h> @@ -83,10 +81,10 @@ const char* CapturedXML::getXML() { } void CapturedXML::write(char* path) { - char file[PATH_MAX]; + char* file = (char*)malloc(PATH_MAX); // Set full path - snprintf(file, sizeof(file), "%s/captured.xml", path); + snprintf(file, PATH_MAX, "%s/captured.xml", path); // Write the file const char* xml = getXML(); @@ -94,4 +92,6 @@ void CapturedXML::write(char* path) { logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file); handleException(); } + + free(file); } diff --git a/daemon/Child.cpp b/daemon/Child.cpp index 0abfd1a..6cfbe60 100644 --- a/daemon/Child.cpp +++ b/daemon/Child.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <stdlib.h> #include <string.h> #include <signal.h> @@ -182,7 +181,6 @@ void Child::endSession() { gSessionData.mSessionIsActive = false; collector->stop(); sem_post(&haltPipeline); - sem_post(&haltPipeline); } void Child::run() { @@ -192,7 +190,7 @@ void Child::run() { prctl(PR_SET_NAME, (unsigned int)&"gatord-child", 0, 0, 0); - // Instantiate the Sender - must be done first, afterwhich error messages can be sent + // Instantiate the Sender - must be done first, after which error messages can be sent sender = new Sender(socket); if (numConnections > 1) { @@ -223,8 +221,7 @@ void Child::run() { delete xmlString; } - // Create user-space buffers to pass the driver data to the socket driver - // Could optimize by using a zero-copy pipe/splice to copy directly from the gator driver to the socket buffer + // Create user-space buffers int fifoBufferSize = collector->getBufferSize(); int numCollectorBuffers = (gSessionData.mTotalBufferSize * 1024 * 1024 + fifoBufferSize - 1) / fifoBufferSize; numCollectorBuffers = (numCollectorBuffers < 4) ? 4 : numCollectorBuffers; diff --git a/daemon/Collector.cpp b/daemon/Collector.cpp index c413347..18f6dee 100644 --- a/daemon/Collector.cpp +++ b/daemon/Collector.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <fcntl.h> #include <malloc.h> #include <unistd.h> @@ -27,19 +26,20 @@ Collector::Collector() { checkVersion(); + int enable = -1; + if (readIntDriver("enable", &enable) != 0 || enable != 0) { + logg->logError(__FILE__, __LINE__, "Driver already enabled, possibly a session is already in progress."); + handleException(); + } + readIntDriver("cpu_cores", &gSessionData.mCores); if (gSessionData.mCores == 0) { gSessionData.mCores = 1; } - if (writeDriver("buffer_size", 256*1024)) { - logg->logError(__FILE__, __LINE__, "Unable to set the cpu buffer settings"); - handleException(); - } - - readIntDriver("buffer_size", &bufferSize); - if (bufferSize <= 0) { - logg->logError(__FILE__, __LINE__, "bufferSize %d is invalid", bufferSize); + bufferSize = 512 * 1024; + if (writeReadDriver("buffer_size", &bufferSize) || bufferSize <= 0) { + logg->logError(__FILE__, __LINE__, "Unable to set the driver buffer size"); handleException(); } @@ -60,9 +60,10 @@ Collector::~Collector() { } void Collector::enablePerfCounters() { + char base[sizeof(gSessionData.mPerfCounterType[0]) + 10]; // sufficiently large to hold all events/<types> + char text[sizeof(gSessionData.mPerfCounterType[0]) + 20]; // sufficiently large to hold all events/<types>/<file> + for (int i=0; i<MAX_PERFORMANCE_COUNTERS; i++) { - char base[256]; - char text[256]; if (!gSessionData.mPerfCounterEnabled[i]) { continue; } @@ -135,7 +136,7 @@ void Collector::start() { handleException(); } - // set the frequency of syncing data, i.e. once per second + // notify the kernel of the streaming mode, currently used for network stats int streaming = (int)!gSessionData.mOneShot; if (writeReadDriver("streaming", &streaming) != 0) { logg->logError(__FILE__, __LINE__, "Unable to set streaming"); @@ -176,8 +177,8 @@ int Collector::collect(char* buffer) { } void Collector::getCoreName() { - char temp[256]; - strncpy(gSessionData.mCoreName, "unknown", sizeof(gSessionData.mCoreName)); + char temp[256]; // arbitrarily large amount + strcpy(gSessionData.mCoreName, "unknown"); FILE* f = fopen("/proc/cpuinfo", "r"); if (f == NULL) { @@ -198,6 +199,7 @@ void Collector::getCoreName() { return; } strncpy(gSessionData.mCoreName, (char *)((int)position + 2), sizeof(gSessionData.mCoreName)); + gSessionData.mCoreName[sizeof(gSessionData.mCoreName) - 1] = 0; // strncpy does not guarantee a null-terminated string fclose(f); return; } @@ -209,7 +211,7 @@ void Collector::getCoreName() { } char* Collector::resolvePath(const char* file) { - static char fullpath[128]; + static char fullpath[100]; // Sufficiently large to hold any path within /dev/gator snprintf(fullpath, sizeof(fullpath), "/dev/gator/%s", file); return fullpath; } @@ -222,7 +224,7 @@ int Collector::readIntDriver(const char* path, int* value) { } if (fscanf(file, "%u", value) != 1) { fclose(file); - logg->logMessage(__FILE__, __LINE__, "Invalid value in file %s", fullpath); + logg->logMessage("Invalid value in file %s", fullpath); return -1; } fclose(file); @@ -230,7 +232,7 @@ int Collector::readIntDriver(const char* path, int* value) { } int Collector::writeDriver(const char* path, int value) { - char data[40]; + char data[40]; // Sufficiently large to hold any integer snprintf(data, sizeof(data), "%d", value); return writeDriver(path, data); } diff --git a/daemon/ConfigurationXML.cpp b/daemon/ConfigurationXML.cpp index 365d422..6348818 100644 --- a/daemon/ConfigurationXML.cpp +++ b/daemon/ConfigurationXML.cpp @@ -6,8 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; -typedef long long int64_t; #include <string.h> #include <stdlib.h> #include <dirent.h> @@ -33,14 +31,14 @@ static const char* ATTR_DESCRIPTION = "description"; static const char* ATTR_EBS = "event_based_sampling"; ConfigurationXML::ConfigurationXML() { -#include "configuration_xml.h" - char path[PATH_MAX]; +#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len index = 0; + char* path = (char *)malloc(PATH_MAX); - if (util->getApplicationFullPath(path, sizeof(path)) != 0) { + if (util->getApplicationFullPath(path, PATH_MAX) != 0) { logg->logMessage("Unable to determine the full path of gatord, the cwd will be used"); } - strcat(path, "configuration.xml"); + strncat(path, "configuration.xml", PATH_MAX - strlen(path) - 1); mConfigurationXML = util->readFromDisk(path); if (mConfigurationXML == NULL) { @@ -66,6 +64,7 @@ ConfigurationXML::ConfigurationXML() { } collector->enablePerfCounters(); + free(path); } ConfigurationXML::~ConfigurationXML() { diff --git a/daemon/Fifo.cpp b/daemon/Fifo.cpp index bbc43a7..6ffebba 100644 --- a/daemon/Fifo.cpp +++ b/daemon/Fifo.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <stdlib.h> #include <string.h> #include <unistd.h> diff --git a/daemon/Fifo.h b/daemon/Fifo.h index 02372d5..14688a9 100644 --- a/daemon/Fifo.h +++ b/daemon/Fifo.h @@ -11,8 +11,8 @@ #include <semaphore.h> -// Driver buffer size is 512k, large buffer mode with 2GB of total RAM will allocate 256M -#define FIFO_BUFFER_LIMIT 256*1024/512 +// Number of buffers allowed with large buffer mode +#define FIFO_BUFFER_LIMIT 64 class Fifo { public: diff --git a/daemon/HashMap.cpp b/daemon/HashMap.cpp deleted file mode 100644 index 1ff6e31..0000000 --- a/daemon/HashMap.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (C) ARM Limited 2010-2011. 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 - * published by the Free Software Foundation. - */ - -#include <stdlib.h> -#include "HashMap.h" - -/* - * LRU Lossy HashMap - * Values are always inserted to first slot - * Value hits are moved to the first slot - */ - -HashMap::HashMap() { - history = (int*)calloc(HASHMAP_ENTRIES * MAX_COLLISIONS, sizeof(int)); -} - -HashMap::~HashMap() { - free(history); -} - -int *HashMap::hashEntries(int value) { - int hashCode = (value >> 24) & 0xff; - hashCode = hashCode * 31 + ((value >> 16) & 0xff); - hashCode = hashCode * 31 + ((value >> 8) & 0xff); - hashCode = hashCode * 31 + ((value >> 0) & 0xff); - hashCode &= (HASHMAP_ENTRIES-1); - return &history[hashCode * MAX_COLLISIONS]; -} - -/* - * Exists - * Pre: [0][1][v][3]..[n-1] - * Post: [v][0][1][3]..[n-1] - * Add - * Pre: [0][1][2][3]..[n-1] - * Post: [v][0][1][2]..[n-2] - */ -bool HashMap::existsAdd(int value) { - int *line = hashEntries(value); - - /* exists */ - for (int x = 0; x < MAX_COLLISIONS; x++) { - if (line[x] == value) { - for (; x > 0; x--) { - line[x] = line[x-1]; - } - line[0] = value; - return true; - } - } - - /* add */ - for (int x = MAX_COLLISIONS-1; x > 0; x--) { - line[x] = line[x-1]; - } - line[0] = value; - - return false; -} diff --git a/daemon/HashMap.h b/daemon/HashMap.h deleted file mode 100644 index 3831f03..0000000 --- a/daemon/HashMap.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (C) ARM Limited 2010-2011. 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 - * published by the Free Software Foundation. - */ - - -#ifndef __HASH_MAP_H__ -#define __HASH_MAP_H__ - -/********************************** -This class is a limited and lossy hash map, where each hash table bucket will contain at most MAX_COLLISIONS entries -If the limit is exceeded, one of the old entries is dropped from the table -This limit eliminates the need for dynamic memory allocation -It is efficient with a data set containing a lot of use-only-once data -Zero is used as an invalid (unused) hash entry value -**********************************/ - -#define HASHMAP_ENTRIES 1024 /* must be power of 2 */ -#define MAX_COLLISIONS 2 - -class HashMap { -public: - HashMap(); - ~HashMap(); - bool existsAdd(int value); -private: - int *hashEntries(int key); - int *history; -}; - -#endif //__HASH_MAP_H__ diff --git a/daemon/LocalCapture.cpp b/daemon/LocalCapture.cpp index 9927035..510a6c3 100644 --- a/daemon/LocalCapture.cpp +++ b/daemon/LocalCapture.cpp @@ -6,8 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; -typedef long long int64_t; #include <sys/stat.h> #include <sys/types.h> #include <dirent.h> @@ -34,56 +32,60 @@ void LocalCapture::createAPCDirectory(char* target_path, char* name) { } void LocalCapture::write(char* string) { - char file[PATH_MAX]; + char* file = (char*)malloc(PATH_MAX); // Set full path - snprintf(file, sizeof(file), "%s/session.xml", gSessionData.apcDir); + snprintf(file, PATH_MAX, "%s/session.xml", gSessionData.apcDir); // Write the file if (util->writeToDisk(file, string) < 0) { logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file); handleException(); } + + free(file); } char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* ending, char* title) { int i; - char path[PATH_MAX]; + char* output; + char* path = (char*)malloc(PATH_MAX); // Ensure the path is an absolute path, i.e. starts with a slash if (initialPath == 0 || strlen(initialPath) == 0) { - if (getcwd(path, sizeof(path)) == 0) + if (getcwd(path, PATH_MAX) == 0) logg->logMessage("Unable to retrive the current working directory"); - strncat(path, "/@F_@N", sizeof(path) - strlen(path) - 1); + strncat(path, "/@F_@N", PATH_MAX - strlen(path) - 1); } else if (initialPath[0] != '/') { - if (getcwd(path, sizeof(path)) == 0) + if (getcwd(path, PATH_MAX) == 0) logg->logMessage("Unable to retrive the current working directory"); - strncat(path, "/", sizeof(path) - strlen(path) - 1); - strncat(path, initialPath, sizeof(path) - strlen(path) - 1); + strncat(path, "/", PATH_MAX - strlen(path) - 1); + strncat(path, initialPath, PATH_MAX - strlen(path) - 1); } else { - strncpy(path, initialPath, sizeof(path)); + strncpy(path, initialPath, PATH_MAX); + path[PATH_MAX - 1] = 0; // strncpy does not guarantee a null-terminated string } // Convert to uppercase - replaceAll(path, "@f", "@F", sizeof(path)); - replaceAll(path, "@n", "@N", sizeof(path)); + replaceAll(path, "@f", "@F", PATH_MAX); + replaceAll(path, "@n", "@N", PATH_MAX); // Replace @F with the session xml title - replaceAll(path, "@F", title, sizeof(path)); + replaceAll(path, "@F", title, PATH_MAX); // Add ending if it is not already there if (strcmp(&path[strlen(path) - strlen(ending)], ending) != 0) { - strncat(path, ending, sizeof(path) - strlen(path) - 1); + strncat(path, ending, PATH_MAX - strlen(path) - 1); } // Replace @N with a unique integer if (strstr(path, "@N")) { - char tempPath[PATH_MAX]; + char* tempPath = (char*)malloc(PATH_MAX); for (i = 1; i < 1000; i++) { char number[4]; snprintf(number, sizeof(number), "%03d", i); - strncpy(tempPath, path, sizeof(tempPath)); - replaceAll(tempPath, "@N", number, sizeof(tempPath)); + strcpy(tempPath, path); + replaceAll(tempPath, "@N", number, PATH_MAX); struct stat mFileInfo; if (stat(tempPath, &mFileInfo) != 0) { // if the direcotry does not exist, break @@ -96,10 +98,13 @@ char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* e handleException(); } - strncpy(path, tempPath, sizeof(path)); + output = strdup(tempPath); + free(tempPath); + } else { + output = strdup(path); } - char* output = strdup(path); + free(path); return output; } @@ -184,13 +189,14 @@ int LocalCapture::removeDirAndAllContents(char *path) { } void LocalCapture::copyImages(ImageLinkList* ptr) { - char dstfilename[PATH_MAX]; + char* dstfilename = (char*)malloc(PATH_MAX); while (ptr) { - strncpy(dstfilename, gSessionData.apcDir, sizeof(dstfilename)); + strncpy(dstfilename, gSessionData.apcDir, PATH_MAX); + dstfilename[PATH_MAX - 1] = 0; // strncpy does not guarantee a null-terminated string if (gSessionData.apcDir[strlen(gSessionData.apcDir) - 1] != '/') - strncat(dstfilename, "/", sizeof(dstfilename)); - strncat(dstfilename, util->getFilePart(ptr->path), sizeof(dstfilename) - strlen(dstfilename) - 1); + strncat(dstfilename, "/", PATH_MAX - strlen(dstfilename) - 1); + strncat(dstfilename, util->getFilePart(ptr->path), PATH_MAX - strlen(dstfilename) - 1); if (util->copyFile(ptr->path, dstfilename)) logg->logMessage("copied file %s to %s", ptr->path, dstfilename); else @@ -198,4 +204,5 @@ void LocalCapture::copyImages(ImageLinkList* ptr) { ptr = ptr->next; } + free(dstfilename); } diff --git a/daemon/LocalCapture.h b/daemon/LocalCapture.h index f2db593..0bb6f94 100644 --- a/daemon/LocalCapture.h +++ b/daemon/LocalCapture.h @@ -9,7 +9,7 @@ #ifndef __LOCAL_CAPTURE_H__ #define __LOCAL_CAPTURE_H__ -#include "ReadSession.h" +#include "SessionXML.h" class LocalCapture { public: diff --git a/daemon/Logging.cpp b/daemon/Logging.cpp index 972a83f..d34209c 100644 --- a/daemon/Logging.cpp +++ b/daemon/Logging.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <stdio.h> #include <stdlib.h> #include <stdarg.h> diff --git a/daemon/Logging.h b/daemon/Logging.h index 4579f7c..cd8d7cd 100644 --- a/daemon/Logging.h +++ b/daemon/Logging.h @@ -9,13 +9,16 @@ #ifndef __LOGGING_H__ #define __LOGGING_H__ +#include <stdio.h> +#include <string.h> +#include <limits.h> #ifdef WIN32 #include <windows.h> +#define GATOR_PATH_MAX MAX_PATH #else #include <pthread.h> +#define GATOR_PATH_MAX PATH_MAX #endif -#include <stdio.h> -#include <string.h> #define DRIVER_ERROR "\n Driver issue:\n >> gator.ko must be built against the current kernel version & configuration\n >> gator.ko should be co-located with gatord in the same directory\n >> OR insmod gator.ko prior to launching gatord" @@ -25,14 +28,14 @@ public: ~Logging(); void logError(const char* file, int line, const char* fmt, ...); void logMessage(const char* fmt, ...); - void SetWarningFile(char* path) {strncpy(mWarningXMLPath, path, sizeof(mWarningXMLPath) - 1);} + void SetWarningFile(char* path) {strncpy(mWarningXMLPath, path, GATOR_PATH_MAX); mWarningXMLPath[GATOR_PATH_MAX - 1] = 0;} char* getLastError() {return mErrBuf;} char* getLastMessage() {return mLogBuf;} private: - char mWarningXMLPath[4096]; - char mErrBuf[4096]; - char mLogBuf[4096]; + char mWarningXMLPath[GATOR_PATH_MAX]; + char mErrBuf[4096]; // Arbitrarily large buffer to hold a string + char mLogBuf[4096]; // Arbitrarily large buffer to hold a string bool mDebug; bool mFileCreated; #ifdef WIN32 diff --git a/daemon/Makefile b/daemon/Makefile index 2ccc886..2a41e31 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -29,7 +29,7 @@ all: $(TARGET) $(CPP) $(INCLUDES) -c $(CFLAGS) -o $@ $< $(TARGET): convert $(TGT_OBJS) - $(CPP) -s -o $@ $(TGT_OBJS) -lc -lrt + $(CPP) -s -o $@ $(TGT_OBJS) -lc -lrt -lpthread rm events_xml.h configuration_xml.h convert: diff --git a/daemon/OlySocket.cpp b/daemon/OlySocket.cpp index d95210c..9b031dc 100644 --- a/daemon/OlySocket.cpp +++ b/daemon/OlySocket.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <stdio.h> #ifdef WIN32 #include <Winsock2.h> @@ -46,11 +45,10 @@ OlySocket::OlySocket(int port, bool multiple) { } } -// Implement client socket for windows -/*OlySocket::OlySocket(int port, char* host) { +OlySocket::OlySocket(int port, char* host) { fdServer = 0; createClientSocket(host, port); -}*/ +} OlySocket::~OlySocket() { if (mSocketID > 0) { @@ -79,9 +77,10 @@ void OlySocket::closeServerSocket() { fdServer = 0; } -// Implement for windows -/* void OlySocket::createClientSocket(char* hostname, int portno) { +#ifdef WIN32 + // TODO: Implement for Windows +#else char buf[32]; struct addrinfo hints, *res, *res0; @@ -113,8 +112,8 @@ void OlySocket::createClientSocket(char* hostname, int portno) { logg->logError(__FILE__, __LINE__, "Could not connect to client socket. Ensure ARM Streamline is running."); handleException(); } +#endif } -*/ void OlySocket::createSingleServerConnection(int port) { createServerSocket(port); diff --git a/daemon/OlySocket.h b/daemon/OlySocket.h index 5e110aa..9ba6ee8 100644 --- a/daemon/OlySocket.h +++ b/daemon/OlySocket.h @@ -30,7 +30,7 @@ public: private: char* strError; int mSocketID, fdServer; - // void createClientSocket(char* hostname, int port); + void createClientSocket(char* hostname, int port); void createSingleServerConnection(int port); void createServerSocket(int port); }; diff --git a/daemon/OlyUtility.cpp b/daemon/OlyUtility.cpp index 5c3bfcc..6216726 100644 --- a/daemon/OlyUtility.cpp +++ b/daemon/OlyUtility.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -110,8 +109,9 @@ int OlyUtility::appendToDisk(const char* path, const char* data) { * The dstFile will be overwritten if it exists. * 0 is returned on an error; otherwise 1. */ +#define TRANSFER_SIZE 1024 int OlyUtility::copyFile(const char * srcFile, const char * dstFile) { - char buffer[1024]; + char* buffer = (char*)malloc(TRANSFER_SIZE); FILE * f_src = fopen(srcFile,"rb"); if (!f_src) { return 0; @@ -122,8 +122,8 @@ int OlyUtility::copyFile(const char * srcFile, const char * dstFile) { return 0; } while (!feof(f_src)) { - int num_bytes_read = fread(buffer, 1, sizeof(buffer), f_src); - if (num_bytes_read < (int)sizeof(buffer) && !feof(f_src)) { + int num_bytes_read = fread(buffer, 1, TRANSFER_SIZE, f_src); + if (num_bytes_read < TRANSFER_SIZE && !feof(f_src)) { fclose(f_src); fclose(f_dst); return 0; @@ -137,6 +137,7 @@ int OlyUtility::copyFile(const char * srcFile, const char * dstFile) { } fclose(f_src); fclose(f_dst); + free(buffer); return 1; } diff --git a/daemon/RequestXML.cpp b/daemon/RequestXML.cpp index cdc1e8e..3dd7a43 100644 --- a/daemon/RequestXML.cpp +++ b/daemon/RequestXML.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <string.h> #include <stdlib.h> #include <limits.h> diff --git a/daemon/Sender.cpp b/daemon/Sender.cpp index 547d425..c547d67 100644 --- a/daemon/Sender.cpp +++ b/daemon/Sender.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <string.h> #include <sys/socket.h> #include <netinet/in.h> @@ -22,6 +21,7 @@ extern void handleException(); Sender::Sender(OlySocket* socket) { dataFile = NULL; + dataSocket = NULL; // Set up the socket connection if (socket) { @@ -44,6 +44,8 @@ Sender::Sender(OlySocket* socket) { gSessionData.mWaitingOnCommand = true; logg->logMessage("Completed magic sequence"); } + + pthread_mutex_init(&sendMutex, NULL); } Sender::~Sender() { @@ -72,10 +74,13 @@ void Sender::writeData(const char* data, int length, int type) { return; } + // Multiple threads call writeData() + pthread_mutex_lock(&sendMutex); + // Send data over the socket connection if (dataSocket) { // Start alarm - alarm(5); + alarm(8); // Send data over the socket, sending the type and size first logg->logMessage("Sending data with length %d", length); @@ -96,4 +101,6 @@ void Sender::writeData(const char* data, int length, int type) { handleException(); } } + + pthread_mutex_unlock(&sendMutex); } diff --git a/daemon/Sender.h b/daemon/Sender.h index 9584c10..147f190 100644 --- a/daemon/Sender.h +++ b/daemon/Sender.h @@ -10,6 +10,7 @@ #define __SENDER_H__ #include <stdio.h> +#include <pthread.h> #include "OlySocket.h" enum { @@ -31,6 +32,7 @@ private: OlySocket* dataSocket; FILE* dataFile; char* dataFileName; + pthread_mutex_t sendMutex; }; #endif //__SENDER_H__ diff --git a/daemon/SessionData.cpp b/daemon/SessionData.cpp index 0672804..f84253a 100644 --- a/daemon/SessionData.cpp +++ b/daemon/SessionData.cpp @@ -6,10 +6,9 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <string.h> #include "SessionData.h" -#include "ReadSession.h" +#include "SessionXML.h" #include "Logging.h" extern void handleException(); @@ -56,7 +55,7 @@ void SessionData::initializeCounters() { } void SessionData::parseSessionXML(char* xmlString) { - ReadSession session(xmlString); + SessionXML session(xmlString); session.parse(); // Parameter error checking diff --git a/daemon/SessionData.h b/daemon/SessionData.h index 7e8ce3c..f3ae4a3 100644 --- a/daemon/SessionData.h +++ b/daemon/SessionData.h @@ -13,7 +13,7 @@ #define MAX_STRING_LEN 80 #define MAX_DESCRIPTION_LEN 400 -#define PROTOCOL_VERSION 6 +#define PROTOCOL_VERSION 7 #define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions struct ImageLinkList { diff --git a/daemon/ReadSession.cpp b/daemon/SessionXML.cpp index 1aaf4d8..5034e48 100644 --- a/daemon/ReadSession.cpp +++ b/daemon/SessionXML.cpp @@ -6,11 +6,10 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <string.h> #include <stdlib.h> #include <limits.h> -#include "ReadSession.h" +#include "SessionXML.h" #include "Logging.h" extern void handleException(); @@ -29,7 +28,7 @@ static const char* ATTR_OUTPUT_PATH = "output_path"; static const char* ATTR_DURATION = "duration"; static const char* ATTR_PATH = "path"; -ReadSession::ReadSession(const char * str) { +SessionXML::SessionXML(const char * str) { parameters.title = 0; parameters.uuid[0] = 0; parameters.target_path = 0; @@ -44,13 +43,13 @@ ReadSession::ReadSession(const char * str) { logg->logMessage(mSessionXML); } -ReadSession::~ReadSession() { +SessionXML::~SessionXML() { if (mPath != 0) { free(mSessionXML); } } -void ReadSession::parse() { +void SessionXML::parse() { XMLReader reader(mSessionXML); char * tag = reader.nextTag(); while(tag != 0) { @@ -65,15 +64,15 @@ void ReadSession::parse() { handleException(); } -void ReadSession::sessionTag(XMLReader* in) { - char tempBuffer[PATH_MAX]; +void SessionXML::sessionTag(XMLReader* in) { + char* tempBuffer = (char*)malloc(PATH_MAX); int version = in->getAttributeAsInteger(ATTR_VERSION, 0); if (version != 1) { logg->logError(__FILE__, __LINE__, "Invalid session.xml version: %d", version); handleException(); } - in->getAttribute(ATTR_TITLE, tempBuffer, sizeof(tempBuffer), "unnamed"); + in->getAttribute(ATTR_TITLE, tempBuffer, PATH_MAX, "unnamed"); parameters.title = strdup(tempBuffer); // freed when the child process exits if (parameters.title == NULL) { logg->logError(__FILE__, __LINE__, "failed to allocate parameters.title (%d bytes)", strlen(tempBuffer)); @@ -84,19 +83,21 @@ void ReadSession::sessionTag(XMLReader* in) { parameters.call_stack_unwinding = in->getAttributeAsBoolean(ATTR_CALL_STACK_UNWINDING, true); in->getAttribute(ATTR_BUFFER_MODE, parameters.buffer_mode, sizeof(parameters.buffer_mode), "normal"); in->getAttribute(ATTR_SAMPLE_RATE, parameters.sample_rate, sizeof(parameters.sample_rate), ""); - in->getAttribute(ATTR_TARGET_PATH, tempBuffer, sizeof(tempBuffer), ""); + in->getAttribute(ATTR_TARGET_PATH, tempBuffer, PATH_MAX, ""); parameters.target_path = strdup(tempBuffer); // freed when the child process exits if (parameters.target_path == NULL) { logg->logError(__FILE__, __LINE__, "failed to allocate parameters.target_path (%d bytes)", strlen(tempBuffer)); handleException(); } - in->getAttribute(ATTR_OUTPUT_PATH, tempBuffer, sizeof(tempBuffer), ""); + in->getAttribute(ATTR_OUTPUT_PATH, tempBuffer, PATH_MAX, ""); parameters.output_path = strdup(tempBuffer); // freed when the child process exits if (parameters.output_path == NULL) { logg->logError(__FILE__, __LINE__, "failed to allocate parameters.output_path (%d bytes)", strlen(tempBuffer)); handleException(); } + free(tempBuffer); + char * tag = in->nextTag(); while(tag != 0) { if (strcmp(tag, TAG_IMAGE) == 0) { @@ -106,7 +107,7 @@ void ReadSession::sessionTag(XMLReader* in) { } } -void ReadSession::sessionImage(XMLReader* in) { +void SessionXML::sessionImage(XMLReader* in) { int length = in->getAttributeLength(ATTR_PATH); struct ImageLinkList *image; diff --git a/daemon/ReadSession.h b/daemon/SessionXML.h index b2e3eae..b52b57f 100644 --- a/daemon/ReadSession.h +++ b/daemon/SessionXML.h @@ -6,8 +6,8 @@ * published by the Free Software Foundation. */ -#ifndef READ_SESSION_H -#define READ_SESSION_H +#ifndef SESSION_XML_H +#define SESSION_XML_H #include "XMLReader.h" #include "SessionData.h" @@ -24,10 +24,10 @@ struct ConfigParameters { struct ImageLinkList *images; // linked list of image strings }; -class ReadSession { +class SessionXML { public: - ReadSession(const char * str); - ~ReadSession(); + SessionXML(const char * str); + ~SessionXML(); void parse(); ConfigParameters parameters; private: @@ -37,4 +37,4 @@ private: void sessionImage(XMLReader* in); }; -#endif // READ_SESSION_H +#endif // SESSION_XML_H diff --git a/daemon/StreamlineSetup.cpp b/daemon/StreamlineSetup.cpp index 8473f8f..80a4ebb 100644 --- a/daemon/StreamlineSetup.cpp +++ b/daemon/StreamlineSetup.cpp @@ -6,8 +6,6 @@ * published by the Free Software Foundation. */ -typedef long long int64_t; -typedef unsigned long long uint64_t; #include <string.h> #include <stdlib.h> #include <unistd.h> @@ -235,13 +233,13 @@ void StreamlineSetup::sendProtocol() { } void StreamlineSetup::sendEvents() { -#include "events_xml.h" - char path[PATH_MAX]; - char * buffer; +#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len + char* path = (char*)malloc(PATH_MAX);; + char* buffer; unsigned int size = 0; - util->getApplicationFullPath(path, sizeof(path)); - strncat(path, "events.xml", sizeof(path) - strlen(path) - 1); + util->getApplicationFullPath(path, PATH_MAX); + strncat(path, "events.xml", PATH_MAX - strlen(path) - 1); buffer = util->readFromDisk(path, &size); if (buffer == NULL) { logg->logMessage("Unable to locate events.xml, using default"); @@ -253,6 +251,7 @@ void StreamlineSetup::sendEvents() { if (buffer != (char*)events_xml) { free(buffer); } + free(path); } void StreamlineSetup::sendConfiguration() { @@ -263,7 +262,7 @@ void StreamlineSetup::sendConfiguration() { } void StreamlineSetup::sendDefaults() { -#include "configuration_xml.h" +#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len // Send the config built into the binary char* xml = (char*)configuration_xml; unsigned int size = configuration_xml_len; @@ -306,14 +305,15 @@ void StreamlineSetup::sendCounters() { } void StreamlineSetup::writeConfiguration(char* xml) { - char path[PATH_MAX]; + char* path = (char*)malloc(PATH_MAX); - util->getApplicationFullPath(path, sizeof(path)); - strncat(path, "configuration.xml", sizeof(path) - strlen(path) - 1); + util->getApplicationFullPath(path, PATH_MAX); + strncat(path, "configuration.xml", PATH_MAX - strlen(path) - 1); if (util->writeToDisk(path, xml) < 0) { - logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", path); + logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify write permissions to this path.", path); handleException(); } new ConfigurationXML(); + free(path); } diff --git a/daemon/XMLOut.cpp b/daemon/XMLOut.cpp index 540f103..647e799 100644 --- a/daemon/XMLOut.cpp +++ b/daemon/XMLOut.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <stdio.h> #include <string.h> #include <stdarg.h> @@ -58,7 +57,7 @@ void XMLOut::writeData(const char *format, ...) { vsnprintf(temp_buffer, sizeof(temp_buffer), format, ap); va_end(ap); - strncat(xml_string, temp_buffer, sizeof(xml_string)-strlen(xml_string)-1); + strncat(xml_string, temp_buffer, sizeof(xml_string) - strlen(xml_string) - 1); } const XMLOut & XMLOut::xmlHeader(void) { diff --git a/daemon/XMLOut.h b/daemon/XMLOut.h index 057222c..479cfa9 100644 --- a/daemon/XMLOut.h +++ b/daemon/XMLOut.h @@ -12,8 +12,8 @@ class XMLOut { int indent; bool incomplete; - char temp_buffer[4096]; - char xml_string[64*1024]; + char temp_buffer[4096]; // arbitrarilly large buffer to hold variable arguments + char xml_string[64*1024]; // arbitrarilly large buffer to hold an xml file output by the daemon void writeTabs(); void encodeAttributeData(const char* data); diff --git a/daemon/XMLReader.cpp b/daemon/XMLReader.cpp index 6766dfd..45231ed 100644 --- a/daemon/XMLReader.cpp +++ b/daemon/XMLReader.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <string.h> #include <stdlib.h> #include <ctype.h> @@ -23,7 +22,7 @@ XMLReader::~XMLReader() { } char* XMLReader::nextTag() { - static char tag[128]; + static char tag[128]; // arbitrarily set max tag size to 127 characters + nul // Check if past the end of the root tag if (mNoMore) return NULL; @@ -117,7 +116,7 @@ int XMLReader::getAttributeAsInteger(const char* name, int defValue) { if (value[0] == '0' && value[1] == 'x') { return (int) strtoul(&value[2], (char**)NULL, 16); } - return atoi(value); + return strtol(value, NULL, 10); } bool XMLReader::getAttributeAsBoolean(const char* name, bool defValue) { @@ -138,7 +137,7 @@ bool XMLReader::getAttributeAsBoolean(const char* name, bool defValue) { } int XMLReader::getAttributeLength(const char* name) { - char searchString[128]; + char searchString[128]; // arbitrarily large amount // Determine search string by ending the name with =" if (strlen(name) > sizeof(searchString) - 3) return 0; diff --git a/daemon/main.cpp b/daemon/main.cpp index 4e8f38b..cf28bfc 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -6,7 +6,6 @@ * published by the Free Software Foundation. */ -typedef unsigned long long uint64_t; #include <stdint.h> #include <stdlib.h> #include <signal.h> @@ -24,7 +23,7 @@ typedef unsigned long long uint64_t; #include "Logging.h" #include "OlyUtility.h" -#define DEBUG false +#define DEBUG false extern Child* child; extern void handleException(); @@ -33,6 +32,7 @@ static pthread_mutex_t numSessions_mutex; static int numSessions = 0; static OlySocket* socket = NULL; static bool driverRunningAtStart = false; +static bool driverMountedAtStart = false; struct cmdline_t { int port; @@ -51,10 +51,35 @@ void cleanUp() { // CTRL C Signal Handler void handler(int signum) { logg->logMessage("Received signal %d, gator daemon exiting", signum); + + // Case 1: both child and parent receive the signal + if (numSessions > 0) { + // Arbitrary sleep of 1 second to give time for the child to exit; + // if something bad happens, continue the shutdown process regardless + sleep(1); + } + + // Case 2: only the parent received the signal if (numSessions > 0) { - // Kill child threads + // Kill child threads - the first signal exits gracefully logg->logMessage("Killing process group as %d child was running when signal was received", numSessions); kill(0, SIGINT); + + // Give time for the child to exit + sleep(1); + + if (numSessions > 0) { + // The second signal force kills the child + logg->logMessage("Force kill the child"); + kill(0, SIGINT); + // Again, sleep for 1 second + sleep(1); + + if (numSessions > 0) { + // Something bad has really happened; the child is not exiting and therefore may hold the /dev/gator resource open + printf("Unable to kill the gatord child process, thus gator.ko may still be loaded.\n"); + } + } } cleanUp(); @@ -88,6 +113,8 @@ int mountGatorFS() { } int setupFilesystem() { + int retval; + // Verify root permissions uid_t euid = geteuid(); if (euid) { @@ -95,20 +122,34 @@ int setupFilesystem() { handleException(); } - if (mountGatorFS() >= 0) { + retval = mountGatorFS(); + if (retval == 1) { logg->logMessage("Driver already running at startup"); driverRunningAtStart = true; + } else if (retval == 0) { + logg->logMessage("Driver already mounted at startup"); + driverRunningAtStart = driverMountedAtStart = true; } else { - // Load driver - char command[512]; - strcpy(command, "insmod "); - if (util->getApplicationFullPath(&command[7], sizeof(command) - 64) != 0) { + char command[256]; // arbitrarily large amount + + // Is the driver co-located in the same directory? + if (util->getApplicationFullPath(command, sizeof(command)) != 0) { // allow some buffer space logg->logMessage("Unable to determine the full path of gatord, the cwd will be used"); } + strcat(command, "gator.ko"); + if (access(command, F_OK) == -1) { + 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"); + handleException(); + } + + // Load driver + strcpy(command, "insmod "); + util->getApplicationFullPath(&command[7], sizeof(command) - 64); // allow some buffer space strcat(command, "gator.ko >/dev/null 2>&1"); + 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. %s", DRIVER_ERROR); + 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"); handleException(); } @@ -122,12 +163,13 @@ int setupFilesystem() { } int shutdownFilesystem() { - umount("/dev/gator"); - if (driverRunningAtStart == true || system("rmmod gator >/dev/null 2>&1") == 0) { - return 0; - } + if (driverMountedAtStart == false) + umount("/dev/gator"); + if (driverRunningAtStart == false) + if (system("rmmod gator >/dev/null 2>&1") != 0) + return -1; - return -1; + return 0; // success } struct cmdline_t parseCommandLine(int argc, char** argv) { @@ -137,8 +179,8 @@ struct cmdline_t parseCommandLine(int argc, char** argv) { for (int i = 1; i < argc; i++) { // Is the argument a number? - if (atoi(argv[i]) > 0) { - cmdline.port = atoi(argv[i]); + if (strtol(argv[i], NULL, 10) > 0) { + cmdline.port = strtol(argv[i], NULL, 10); continue; } @@ -217,7 +259,6 @@ int main(int argc, char** argv, char *envp[]) { logg->logError(__FILE__, __LINE__, "Fork process failed. Please power cycle the target device if this error persists."); } else if (pid == 0) { // Child - strncpy(argv[0],"gatorc",strlen(argv[0])); // rename command line name to gatorc socket->closeServerSocket(); child = new Child(socket, numSessions + 1); child->run(); |