Create utility methods in the library to support local write to disk
authorMichael Sills Lavoie <michael.sills-lavoie@polymtl.ca>
Fri, 26 Mar 2010 18:54:29 +0000 (14:54 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Fri, 26 Mar 2010 18:54:29 +0000 (14:54 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
liblttd/Makefile.am
liblttd/liblttd.c
liblttd/liblttd.h
liblttd/liblttdutils.c [new file with mode: 0644]
liblttd/liblttdutils.h [new file with mode: 0644]
lttd/lttd.c

index 3c1eedaa5ce26b6ff3c32a7511fdf13b0ba1488e..43859be4777ff4b025ac582b6a574e9b85234b64 100644 (file)
@@ -1,7 +1,7 @@
 
 
 lib_LTLIBRARIES = liblttd.la
-liblttd_la_SOURCES = liblttd.c
+liblttd_la_SOURCES = liblttd.c liblttdutils.c
 
 liblttdinclude_HEADERS = \
-       liblttd.h
+       liblttd.h liblttdutils.h
index 0f703f57b32f1f351df95a1be7f91833ac63914b..7ae01f86a85685ed438666ff2e325dd9518a9cac 100644 (file)
@@ -1,4 +1,4 @@
-/* lttd
+/* libttd
  *
  * Linux Trace Toolkit Daemon
  *
@@ -9,6 +9,9 @@
  *
  * Copyright 2005 -
  *     Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ * Copyright 2010 -
+ *     Michael Sills-Lavoie <michael.sills-lavoie@polymtl.ca>
+ *     Oumarou Dicko <oumarou.dicko@polymtl.ca>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -75,40 +78,6 @@ static inline int inotify_rm_watch (int fd, __u32 wd)
 #undef HAS_INOTIFY
 #endif
 
-struct channel_trace_fd {
-       struct fd_pair *pair;
-       int num_pairs;
-};
-
-struct inotify_watch {
-       int wd;
-       char path_channel[PATH_MAX];
-       char *base_path_channel;
-};
-
-struct inotify_watch_array {
-       struct inotify_watch *elem;
-       int num;
-};
-
-struct liblttd_instance {
-       struct liblttd_callbacks *callbacks;
-
-       int inotify_fd;
-       struct channel_trace_fd fd_pairs;
-       struct inotify_watch_array inotify_watch_array;
-
-       /* protects fd_pairs and inotify_watch_array */
-       pthread_rwlock_t fd_pairs_lock;
-
-       char            channel_name[PATH_MAX];
-       unsigned long   num_threads;
-       int             quit_program;   /* For signal handler */
-       int             dump_flight_only;
-       int             dump_normal_only;
-       int             verbose_mode;
-};
-
 struct liblttd_thread_data {
        int thread_num;
        struct liblttd_instance *instance;
@@ -189,7 +158,7 @@ int open_channel_trace_pairs(struct liblttd_instance *instance,
                goto end;
        }
 
-       printf_verbose("Calling on new channels folder\n");
+       printf_verbose("Calling on new channels folder\n");
        if(instance->callbacks->on_new_channels_folder) ret = instance->callbacks->
                        on_new_channels_folder(instance->callbacks,
                        base_subchannel_name);
@@ -742,7 +711,7 @@ int liblttd_start_instance(struct liblttd_instance *instance)
                close(instance->inotify_fd);
 
        if(instance->callbacks->on_trace_end)
-               instance->callbacks->on_trace_end(instance->callbacks);
+               instance->callbacks->on_trace_end(instance);
 
        delete_instance(instance);
 
index 02e7e9ce178056f52b3aecf8ed124741a83199f4..d871dd726870a1ea26238b32b5bd1c6f1b9f7f9e 100644 (file)
@@ -1,10 +1,11 @@
 /* liblttd header file
  *
+ * Copyright 2005 -
+ *              Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
  * Copyright 2010-
  *              Oumarou Dicko <oumarou.dicko@polymtl.ca>
  *              Michael Sills-Lavoie <michael.sills-lavoie@polymtl.ca>
  *
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -21,6 +22,7 @@
 #define _LIBLTTD_H
 
 #include <pthread.h>
+#include <dirent.h>
 
 /**
  * struct fd_pair - Contains the data associated with the channel file
@@ -43,7 +45,46 @@ struct fd_pair {
        void *user_data;
 };
 
-struct liblttd_instance;
+struct channel_trace_fd {
+       struct fd_pair *pair;
+       int num_pairs;
+};
+
+struct inotify_watch {
+       int wd;
+       char path_channel[PATH_MAX];
+       char *base_path_channel;
+};
+
+struct inotify_watch_array {
+       struct inotify_watch *elem;
+       int num;
+};
+
+struct liblttd_callbacks;
+
+/**
+ * struct liblttd_instance - Contains the data associated with a trace instance.
+ * The lib user can read but MUST NOT change any attributes but callbacks.
+ * @callbacks: Contains the necessary callbacks for a tracing session.
+ */
+struct liblttd_instance {
+       struct liblttd_callbacks *callbacks;
+
+       int inotify_fd;
+       struct channel_trace_fd fd_pairs;
+       struct inotify_watch_array inotify_watch_array;
+
+       /* protects fd_pairs and inotify_watch_array */
+       pthread_rwlock_t fd_pairs_lock;
+
+       char channel_name[PATH_MAX];
+       unsigned long num_threads;
+       int quit_program;
+       int dump_flight_only;
+       int dump_normal_only;
+       int verbose_mode;
+};
 
 /**
 * struct liblttd_callbacks - Contains the necessary callbacks for a tracing
@@ -116,17 +157,16 @@ struct liblttd_callbacks {
         * this time, all the channels have been closed and the threads have
         * been destroyed.
         *
-        * @data: pointeur to the callbacks struct that has been passed to the
-        * lib.
+        * @instance: pointeur to the instance struct that has been passed to
+        * the lib.
         *
         * Returns 0 if the callback succeeds else not 0.
         *
-        * It has to be thread safe, it'll be called by many threads.
         * After this callback is called, no other callback will be called
         * again and the tracing instance will be deleted automatically by
         * liblttd. After this call, the user must not use the liblttd instance.
         */
-       int(*on_trace_end)(struct liblttd_callbacks *data);
+       int(*on_trace_end)(struct liblttd_instance *instance);
 
        /**
         * on_new_thread - Is called after a new thread has been created.
diff --git a/liblttd/liblttdutils.c b/liblttd/liblttdutils.c
new file mode 100644 (file)
index 0000000..3368aba
--- /dev/null
@@ -0,0 +1,229 @@
+/* liblttdutils
+ *
+ * Linux Trace Toolkit utility library
+ *
+ * This is a simple daemon implementation that reads a few relay+debugfs
+ * channels and save them in a trace.
+ *
+ * CPU hot-plugging is supported using inotify.
+ *
+ * Copyright 2005 -
+ *     Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ * Copyright 2010 -
+ *     Michael Sills-Lavoie <michael.sills-lavoie@polymtl.ca>
+ *     Oumarou Dicko <oumarou.dicko@polymtl.ca>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _REENTRANT
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <sys/stat.h>
+
+#include "liblttdutils.h"
+
+struct liblttdutils_channel_data {
+       int trace;
+};
+
+struct liblttdutils_data {
+       char path_trace[PATH_MAX];
+       char *end_path_trace;
+       int path_trace_len;
+       int append_mode;
+       int verbose_mode;
+};
+
+static __thread int thread_pipe[2];
+
+#define printf_verbose(fmt, args...) \
+  do {                               \
+    if (callbacks_data->verbose_mode)                \
+      printf(fmt, ##args);           \
+  } while (0)
+
+int liblttdutils_local_on_open_channel(struct liblttd_callbacks *data, struct fd_pair *pair, char *relative_channel_path)
+{
+       int open_ret = 0;
+       int ret;
+       struct stat stat_buf;
+       struct liblttdutils_channel_data *channel_data;
+
+       pair->user_data = malloc(sizeof(struct liblttdutils_channel_data));
+       channel_data = pair->user_data;
+
+       struct liblttdutils_data* callbacks_data = data->user_data;
+
+       strncpy(callbacks_data->end_path_trace, relative_channel_path, PATH_MAX - callbacks_data->path_trace_len);
+       printf_verbose("Creating trace file %s\n", callbacks_data->path_trace);
+
+       ret = stat(callbacks_data->path_trace, &stat_buf);
+       if(ret == 0) {
+               if(callbacks_data->append_mode) {
+                       printf_verbose("Appending to file %s as requested\n",
+                               callbacks_data->path_trace);
+
+                       channel_data->trace = open(callbacks_data->path_trace, O_WRONLY, S_IRWXU|S_IRWXG|S_IRWXO);
+                       if(channel_data->trace == -1) {
+                               perror(callbacks_data->path_trace);
+                               open_ret = -1;
+                               goto end;
+                       }
+                       ret = lseek(channel_data->trace, 0, SEEK_END);
+                       if (ret < 0) {
+                               perror(callbacks_data->path_trace);
+                               open_ret = -1;
+                               close(channel_data->trace);
+                               goto end;
+                       }
+               } else {
+                       printf("File %s exists, cannot open. Try append mode.\n", callbacks_data->path_trace);
+                       open_ret = -1;
+                       goto end;
+               }
+       } else {
+               if(errno == ENOENT) {
+                       channel_data->trace =
+                               open(callbacks_data->path_trace, O_WRONLY|O_CREAT|O_EXCL, S_IRWXU|S_IRWXG|S_IRWXO);
+                       if(channel_data->trace == -1) {
+                               perror(callbacks_data->path_trace);
+                               open_ret = -1;
+                               goto end;
+                       }
+               }
+       }
+
+end:
+       return open_ret;
+
+}
+
+int liblttdutils_local_on_close_channel(struct liblttd_callbacks *data, struct fd_pair *pair)
+{
+       int ret;
+       ret = close(((struct liblttdutils_channel_data *)(pair->user_data))->trace);
+       free(pair->user_data);
+       return ret;
+}
+
+int liblttdutils_local_on_new_channels_folder(struct liblttd_callbacks *data, char *relative_folder_path)
+{
+       int ret;
+       int open_ret = 0;
+       struct liblttdutils_data* callbacks_data = data->user_data;
+
+       strncpy(callbacks_data->end_path_trace, relative_folder_path, PATH_MAX - callbacks_data->path_trace_len);
+       printf_verbose("Creating trace subdirectory %s\n", callbacks_data->path_trace);
+
+       ret = mkdir(callbacks_data->path_trace, S_IRWXU|S_IRWXG|S_IRWXO);
+       if(ret == -1) {
+               if(errno != EEXIST) {
+                       perror(callbacks_data->path_trace);
+                       open_ret = -1;
+                       goto end;
+               }
+       }
+
+end:
+       return open_ret;
+}
+
+int liblttdutils_local_on_read_subbuffer(struct liblttd_callbacks *data, struct fd_pair *pair, unsigned int len)
+{
+       long ret;
+       off_t offset = 0;
+
+       struct liblttdutils_data* callbacks_data = data->user_data;
+
+       while (len > 0) {
+               printf_verbose("splice chan to pipe offset %lu\n",
+                       (unsigned long)offset);
+               ret = splice(pair->channel, &offset, thread_pipe[1], NULL,
+                       len, SPLICE_F_MOVE | SPLICE_F_MORE);
+               printf_verbose("splice chan to pipe ret %ld\n", ret);
+               if (ret < 0) {
+                       perror("Error in relay splice");
+                       goto write_error;
+               }
+               ret = splice(thread_pipe[0], NULL,
+                       ((struct liblttdutils_channel_data *)(pair->user_data))->trace,
+                       NULL, ret, SPLICE_F_MOVE | SPLICE_F_MORE);
+               printf_verbose("splice pipe to file %ld\n", ret);
+               if (ret < 0) {
+                       perror("Error in file splice");
+                       goto write_error;
+               }
+               len -= ret;
+       }
+
+write_error:
+       return ret;
+}
+
+int liblttdutils_local_on_new_thread(struct liblttd_callbacks *data, unsigned long thread_num)
+{
+       int ret;
+       ret = pipe(thread_pipe);
+       if (ret < 0) {
+               perror("Error creating pipe");
+               return ret;
+       }
+       return 0;
+}
+
+int liblttdutils_local_on_close_thread(struct liblttd_callbacks *data, unsigned long thread_num)
+{
+       close(thread_pipe[0]);  /* close read end */
+       close(thread_pipe[1]);  /* close write end */
+       return 0;
+}
+
+int liblttdutils_local_on_trace_end(struct liblttd_instance *instance)
+{
+       struct liblttd_callbacks *callbacks = instance->callbacks;
+       struct liblttdutils_data *data = callbacks->user_data;
+
+       free(data);
+       free(callbacks);
+}
+
+struct liblttd_callbacks* liblttdutils_local_new_callbacks(char* trace_name,
+       int append_mode, int verbose_mode)
+{
+       struct liblttdutils_data *data;
+       struct liblttd_callbacks *callbacks;
+
+       if(!trace_name) return NULL;
+
+       data = malloc(sizeof(struct liblttdutils_data));
+
+       strncpy(data->path_trace, trace_name, PATH_MAX-1);
+       data->path_trace_len = strlen(data->path_trace);
+       data->end_path_trace = data->path_trace + data->path_trace_len;
+       data->append_mode = append_mode;
+       data->verbose_mode = verbose_mode;
+
+       callbacks = malloc(sizeof(struct liblttd_callbacks));
+
+       callbacks->on_open_channel = liblttdutils_local_on_open_channel;
+       callbacks->on_close_channel = liblttdutils_local_on_close_channel;
+       callbacks->on_new_channels_folder = liblttdutils_local_on_new_channels_folder;
+       callbacks->on_read_subbuffer = liblttdutils_local_on_read_subbuffer;
+       callbacks->on_trace_end = liblttdutils_local_on_trace_end;
+       callbacks->on_new_thread = liblttdutils_local_on_new_thread;
+       callbacks->on_close_thread = liblttdutils_local_on_close_thread;
+       callbacks->user_data = data;
+
+       return callbacks;
+}
+
diff --git a/liblttd/liblttdutils.h b/liblttd/liblttdutils.h
new file mode 100644 (file)
index 0000000..78439d2
--- /dev/null
@@ -0,0 +1,38 @@
+/* liblttdutils header file
+ *
+ * Copyright 2010-
+ *              Oumarou Dicko <oumarou.dicko@polymtl.ca>
+ *              Michael Sills-Lavoie <michael.sills-lavoie@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LIBLTTDUTILS_H
+#define _LIBLTTDUTILS_H
+
+#include "liblttd.h"
+
+/**
+ * liblttdutils_new_callbacks - Is a utility function called to create a new
+ * callbacks struct used by liblttd to write trace data to the disk.
+ *
+ * @trace_name: Directory name of the trace to write to. It will be created.
+ * @append_mode: Append to a possibly existing trace.
+ * @verbose_mode: Verbose mode.
+ *
+ * Returns the callbacks if the function succeeds else NULL.
+ */
+struct liblttd_callbacks* liblttdutils_local_new_callbacks(char* trace_name,
+       int append_mode, int verbose_mode);
+
+#endif /*_LIBLTTDUTILS_H */
+
index d3c12d5aca6b81e9b1d2da1852f261d4243bc9aa..b43b63765edf97252f26f6866fca4b31e922807d 100644 (file)
@@ -8,6 +8,8 @@
  * CPU hot-plugging is supported using inotify.
  *
  * Copyright 2009-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright 2010 - Michael Sills-Lavoie <michael.sills-lavoie@polymtl.ca>
+ * Copyright 2010 - Oumarou Dicko <oumarou.dicko@polymtl.ca>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,6 +24,7 @@
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
  */
 
 #ifdef HAVE_CONFIG_H
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <signal.h>
 #include <errno.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/stat.h>
 
 #include <liblttd/liblttd.h>
+#include <liblttd/liblttdutils.h>
 
-struct lttd_channel_data {
-       int trace;
-};
+struct liblttd_instance* instance;
 
-struct liblttd_instance *instance;
-static char            path_trace[PATH_MAX];
-static char            *end_path_trace;
-static int             path_trace_len = 0;
 static char            *trace_name = NULL;
 static char            *channel_name = NULL;
 static int             daemon_mode = 0;
@@ -59,13 +53,6 @@ static int           dump_flight_only = 0;
 static int             dump_normal_only = 0;
 static int             verbose_mode = 0;
 
-static __thread int thread_pipe[2];
-
-#define printf_verbose(fmt, args...) \
-  do {                               \
-    if (verbose_mode)                \
-      printf(fmt, ##args);           \
-  } while (0)
 
 /* Args :
  *
@@ -195,152 +182,11 @@ static void handler(int signo)
        liblttd_stop_instance(instance);
 }
 
-int lttd_on_open_channel(struct liblttd_callbacks *data, struct fd_pair *pair, char *relative_channel_path)
-{
-       int open_ret = 0;
-       int ret;
-       struct stat stat_buf;
-       struct lttd_channel_data *channel_data;
-
-       pair->user_data = malloc(sizeof(struct lttd_channel_data));
-       channel_data = pair->user_data;
-
-       strncpy(end_path_trace, relative_channel_path, PATH_MAX - path_trace_len);
-       printf_verbose("Creating trace file %s\n", path_trace);
-
-       ret = stat(path_trace, &stat_buf);
-       if(ret == 0) {
-               if(append_mode) {
-                       printf_verbose("Appending to file %s as requested\n",
-                               path_trace);
-
-                       channel_data->trace = open(path_trace, O_WRONLY, S_IRWXU|S_IRWXG|S_IRWXO);
-                       if(channel_data->trace == -1) {
-                               perror(path_trace);
-                               open_ret = -1;
-                               goto end;
-                       }
-                       ret = lseek(channel_data->trace, 0, SEEK_END);
-                       if (ret < 0) {
-                               perror(path_trace);
-                               open_ret = -1;
-                               close(channel_data->trace);
-                               goto end;
-                       }
-               } else {
-                       printf("File %s exists, cannot open. Try append mode.\n", path_trace);
-                       open_ret = -1;
-                       goto end;
-               }
-       } else {
-               if(errno == ENOENT) {
-                       channel_data->trace = open(path_trace, O_WRONLY|O_CREAT|O_EXCL, S_IRWXU|S_IRWXG|S_IRWXO);
-                       if(channel_data->trace == -1) {
-                               perror(path_trace);
-                               open_ret = -1;
-                               goto end;
-                       }
-               }
-       }
-
-end:
-       return open_ret;
-
-}
-
-int lttd_on_close_channel(struct liblttd_callbacks *data, struct fd_pair *pair)
-{
-       int ret;
-       ret = close(((struct lttd_channel_data *)(pair->user_data))->trace);
-       free(pair->user_data);
-       return ret;
-}
-
-int lttd_on_new_channels_folder(struct liblttd_callbacks *data, char *relative_folder_path)
-{
-       int ret;
-       int open_ret = 0;
-
-       strncpy(end_path_trace, relative_folder_path, PATH_MAX - path_trace_len);
-       printf_verbose("Creating trace subdirectory %s\n", path_trace);
-
-       ret = mkdir(path_trace, S_IRWXU|S_IRWXG|S_IRWXO);
-       if(ret == -1) {
-               if(errno != EEXIST) {
-                       perror(path_trace);
-                       open_ret = -1;
-                       goto end;
-               }
-       }
-
-end:
-       return open_ret;
-}
-
-int lttd_on_read_subbuffer(struct liblttd_callbacks *data, struct fd_pair *pair, unsigned int len)
-{
-       long ret;
-       off_t offset = 0;
-
-       while (len > 0) {
-               printf_verbose("splice chan to pipe offset %lu\n",
-                       (unsigned long)offset);
-               ret = splice(pair->channel, &offset, thread_pipe[1], NULL,
-                       len, SPLICE_F_MOVE | SPLICE_F_MORE);
-               printf_verbose("splice chan to pipe ret %ld\n", ret);
-               if (ret < 0) {
-                       perror("Error in relay splice");
-                       goto write_error;
-               }
-               ret = splice(thread_pipe[0], NULL,
-                       ((struct lttd_channel_data *)(pair->user_data))->trace,
-                       NULL, ret, SPLICE_F_MOVE | SPLICE_F_MORE);
-               printf_verbose("splice pipe to file %ld\n", ret);
-               if (ret < 0) {
-                       perror("Error in file splice");
-                       goto write_error;
-               }
-               len -= ret;
-       }
-
-write_error:
-       return ret;
-}
-
-int lttd_on_new_thread(struct liblttd_callbacks *data, unsigned long thread_num)
-{
-       int ret;
-       ret = pipe(thread_pipe);
-       if (ret < 0) {
-               perror("Error creating pipe");
-               return ret;
-       }
-       return 0;
-}
-
-int lttd_on_close_thread(struct liblttd_callbacks *data, unsigned long thread_num)
-{
-       close(thread_pipe[0]);  /* close read end */
-       close(thread_pipe[1]);  /* close write end */
-       return 0;
-}
-
 int main(int argc, char ** argv)
 {
        int ret = 0;
        struct sigaction act;
 
-       struct liblttd_callbacks callbacks = {
-               lttd_on_open_channel,
-               lttd_on_close_channel,
-               lttd_on_new_channels_folder,
-               lttd_on_read_subbuffer,
-               NULL,
-               lttd_on_new_thread,
-               lttd_on_close_thread,
-               NULL
-       };
-
        ret = parse_arguments(argc, argv);
 
        if(ret != 0) show_arguments();
@@ -368,12 +214,13 @@ int main(int argc, char ** argv)
                        exit(-1);
                }
        }
-       strncpy(path_trace, trace_name, PATH_MAX-1);
-       path_trace_len = strlen(path_trace);
-       end_path_trace = path_trace + path_trace_len;
 
-       instance = liblttd_new_instance(&callbacks, channel_name, num_threads,
+       struct liblttd_callbacks* callbacks = liblttdutils_local_new_callbacks(
+               trace_name, append_mode, verbose_mode);
+
+       instance = liblttd_new_instance(callbacks, channel_name, num_threads,
                dump_flight_only, dump_normal_only, verbose_mode);
+
        if(!instance) {
                perror("An error occured while creating the liblttd instance");
                return ret;
This page took 0.031243 seconds and 4 git commands to generate.