gator-daemon: ARM DS-5.8 Streamline gator daemon (RC1)
authorPawel Moll <pawel.moll@arm.com>
Thu, 17 Nov 2011 18:13:23 +0000 (18:13 +0000)
committerPawel Moll <pawel.moll@arm.com>
Thu, 17 Nov 2011 18:13:23 +0000 (18:13 +0000)
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
29 files changed:
daemon/Android.mk
daemon/CapturedXML.cpp
daemon/Child.cpp
daemon/Collector.cpp
daemon/ConfigurationXML.cpp
daemon/Fifo.cpp
daemon/Fifo.h
daemon/HashMap.cpp [deleted file]
daemon/HashMap.h [deleted file]
daemon/LocalCapture.cpp
daemon/LocalCapture.h
daemon/Logging.cpp
daemon/Logging.h
daemon/Makefile
daemon/OlySocket.cpp
daemon/OlySocket.h
daemon/OlyUtility.cpp
daemon/RequestXML.cpp
daemon/Sender.cpp
daemon/Sender.h
daemon/SessionData.cpp
daemon/SessionData.h
daemon/SessionXML.cpp [moved from daemon/ReadSession.cpp with 87% similarity]
daemon/SessionXML.h [moved from daemon/ReadSession.h with 88% similarity]
daemon/StreamlineSetup.cpp
daemon/XMLOut.cpp
daemon/XMLOut.h
daemon/XMLReader.cpp
daemon/main.cpp

index 45f5b7d1d0dc63817cfac37b3cc924d34697ca53..ac3094c8f4b66dd79f4443d41bacd7faa31d0f0b 100644 (file)
@@ -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
 
index 9d9fd846ae7b0e754a74d82b9657d6dc03f16169..5d1f295fdd25394a655e5a093da192bb45723cfa 100644 (file)
@@ -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);
 }
index 0abfd1aeccc892120384fb3f9965742145daff03..6cfbe609d46200c6209e20c98cce184a149c6839 100644 (file)
@@ -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;
index c4133475838abf9c61f6bf48ab59afcfa56b2830..18f6dee92a9989f1cbdffa055ad382de779ce615 100644 (file)
@@ -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);
 }
index 365d422ddb96dd97f5e592f0256d22050b28d8dc..6348818fd795332153feb028f94d08e91476a213 100644 (file)
@@ -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() {
index bbc43a719aeb914f42268c3f3232cf81a3bd0e6e..6ffebba08b59ab7d79417d59a97b08b1ac956f2b 100644 (file)
@@ -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>
index 02372d5ba50735db145835bda106f3509b7f657b..14688a99a8741ed5e9a512b5e3d645c6ea909cc0 100644 (file)
@@ -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 (file)
index 1ff6e31..0000000
+++ /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 (file)
index 3831f03..0000000
+++ /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__
index 9927035fcc941eaefdc56939306d132dc19be248..510a6c32bbab2fd422572b78d3dc3e5736f3ff76 100644 (file)
@@ -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);
 }
index f2db593757f2148cfad4021bc41851e42da9e0b3..0bb6f94b986a749ea7c422b1058ae28c05199efb 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef        __LOCAL_CAPTURE_H__
 #define        __LOCAL_CAPTURE_H__
 
-#include "ReadSession.h"
+#include "SessionXML.h"
 
 class LocalCapture {
 public:
index 972a83f4e68fa5f7549188072295278ec4db69fb..d34209c3ee7b9c2f2e99716e2508c88539f04401 100644 (file)
@@ -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>
index 4579f7ccbdcef360cc6fb2fc4de530ba04a98c79..cd8d7cd1e21d8f58aacbaf340de02535e50bb9a2 100644 (file)
@@ -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
index 2ccc8867817863710e35249d74c29259c14c8bab..2a41e31f9c3e7e10b851d4f7d707f7b387859a78 100644 (file)
@@ -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:
index d95210c87aa3c5860de81bd13af331880f0c6539..9b031dcfe56ccea01ea1f837a400f25f70cb28c1 100644 (file)
@@ -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);
index 5e110aa243905ba301280c7699036dd8c775600e..9ba6ee8eb6eb709dbdbf0f3182d337eff82924bf 100644 (file)
@@ -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);
 };
index 5c3bfcca2356433340b98a38bf6417abf8debb76..6216726013f7caa3a38df88603d9419a6d76d10a 100644 (file)
@@ -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;
 }
 
index cdc1e8e1627cd822554fa8aed3a1f4947da60747..3dd7a43a811ba33171c1bdf86bd71e701bf44db1 100644 (file)
@@ -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>
index 547d425691979083ca48aa05e2dfc7879836508d..c547d671982893bd697b16f69958019bdbd4726a 100644 (file)
@@ -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);
 }
index 9584c105b1c7be84cde7d3ebed16f0eb136e30bc..147f19065a13552635f8e2471f8ba9d959355312 100644 (file)
@@ -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__
index 0672804a09c6c4b91c0a6a49f1cd3a196506a62d..f84253a3b7516a28a19c934104ac43860abb07f7 100644 (file)
@@ -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
index 7e8ce3c57cce5c3a618117dac6edd15f6510a388..f3ae4a35614ebbdec429e54b29ada9cfc05fb78c 100644 (file)
@@ -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 {
similarity index 87%
rename from daemon/ReadSession.cpp
rename to daemon/SessionXML.cpp
index 1aaf4d85598e05e82f48b44b442b6a3a251eb61d..5034e48229c95e2e1562ca02dd55b6d87ddba73d 100644 (file)
@@ -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;
 
similarity index 88%
rename from daemon/ReadSession.h
rename to daemon/SessionXML.h
index b2e3eae858b40f2f6ad78f971cb760b8c9f96bd9..b52b57f12ba0cfd55e4f412666650145ecce8157 100644 (file)
@@ -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
index 8473f8fb3d6a100750d73bca8aa850d14d74c169..80a4ebbdb58733240af5a4b2d87f9da4bf7d0a9b 100644 (file)
@@ -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);
 }
index 540f103faf84beb857253dc2df65b33b70218b24..647e799a9aa779b33bf4980458d525c2c13c3c9c 100644 (file)
@@ -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) {
index 057222cba969bfa748e1b050d94d991e259c8b61..479cfa95e81b03a714df23e7301f0e77aae63e36 100644 (file)
@@ -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);
index 6766dfd5d77dffb13c3bb5de40fa2bf480de9477..45231edd8373a447283d209ac5f91fb719bd56f6 100644 (file)
@@ -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;
index 4e8f38b66314432a10fdcea74e6f03b4c5ad26a8..cf28bfc703af9e9283dff658cfa78ee730570f3f 100644 (file)
@@ -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();