Fix dynamic update of marker data across same channel tracefiles
[lttv.git] / ltt / tracefile.c
index 2ac0fa5865a15a1ef10acf234045c95c935992ca..2dbbbcf119be2573dc1991afe5ad36fecf5ffc7a 100644 (file)
@@ -148,9 +148,9 @@ static int parse_trace_header(ltt_subbuffer_header_t *header,
     break;
   case 2:
     switch(header->minor_version) {
-    case 5:
+    case 6:
       {
-        struct ltt_subbuffer_header_2_5 *vheader = header;
+        struct ltt_subbuffer_header_2_6 *vheader = header;
         tf->buffer_header_size = ltt_subbuffer_header_size();
         tf->tscbits = 27;
         tf->eventbits = 5;
@@ -544,12 +544,12 @@ static void ltt_tracefile_group_destroy(gpointer data)
   unsigned int i;
   LttTracefile *tf;
 
-  if (group->len > 0)
-    destroy_marker_data(g_array_index (group, LttTracefile, 0).mdata);
   for(i=0; i<group->len; i++) {
     tf = &g_array_index (group, LttTracefile, i);
-    if(tf->cpu_online)
+    if(tf->cpu_online) {
+      destroy_marker_data(tf->mdata);
       ltt_tracefile_close(tf);
+    }
   }
   g_array_free(group, TRUE);
 }
@@ -585,8 +585,7 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa
   DIR *dir = opendir(root_path);
   struct dirent *entry;
   struct stat stat_buf;
-  int ret, i;
-  struct marker_data *mdata;
+  int ret;
   
   gchar path[PATH_MAX];
   int path_len;
@@ -596,6 +595,7 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa
   gchar rel_path[PATH_MAX];
   gchar *rel_path_ptr;
   LttTracefile tmp_tf;
+  struct marker_data **mdata;
 
   if(dir == NULL) {
     perror(root_path);
@@ -658,7 +658,6 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa
       g_debug("Tracefile name is %s and number is %u", 
           g_quark_to_string(name), num);
 
-      mdata = NULL;
       tmp_tf.cpu_online = 1;
       tmp_tf.cpu_num = num;
       tmp_tf.name = name;
@@ -673,9 +672,6 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa
         group = g_array_sized_new (FALSE, TRUE, sizeof(LttTracefile), 10);
         g_datalist_id_set_data_full(&trace->tracefiles, name,
                                  group, ltt_tracefile_group_destroy);
-        mdata = allocate_marker_data();
-        if (!mdata)
-          g_error("Error in allocating marker data");
       }
 
       /* Add the per cpu tracefile to the named group */
@@ -683,15 +679,13 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa
       if(num+1 > old_len)
         group = g_array_set_size(group, num+1);
 
-      g_assert(group->len > 0);
-      if (!mdata)
-        mdata = g_array_index (group, LttTracefile, 0).mdata;
-
       g_array_index (group, LttTracefile, num) = tmp_tf;
       g_array_index (group, LttTracefile, num).event.tracefile = 
         &g_array_index (group, LttTracefile, num);
-      for (i = 0; i < group->len; i++)
-        g_array_index (group, LttTracefile, i).mdata = mdata;
+      mdata = &g_array_index (group, LttTracefile, num).mdata;
+      *mdata = allocate_marker_data();
+      if (!*mdata)
+        g_error("Error in allocating marker data");
     }
   }
   
@@ -1790,3 +1784,138 @@ static __attribute__((constructor)) void init(void)
 {
   LTT_TRACEFILE_NAME_METADATA = g_quark_from_string("metadata");
 }
+
+/*****************************************************************************
+ *Function name
+ *    ltt_tracefile_open_header    : based on ltt_tracefile_open but it stops
+ *                                  when it gets the header
+ *Input params
+ *    fileName       : path to the tracefile
+ *    tf             : the tracefile (metadata_0) where the header will be read
+ *Return value
+ *    ltt_subbuffer_header_t         : the header containing the version number
+ ****************************************************************************/
+static ltt_subbuffer_header_t * ltt_tracefile_open_header(gchar *fileName, LttTracefile *tf)
+{
+        struct stat    lTDFStat;    /* Trace data file status */
+        ltt_subbuffer_header_t *header;
+        int page_size = getpagesize();
+
+        /* open the file */
+        tf->long_name = g_quark_from_string(fileName);
+        tf->fd = open(fileName, O_RDONLY);
+        if(tf->fd < 0){
+                g_warning("Unable to open input data file %s\n", fileName);
+                goto end;
+        }
+
+        /* Get the file's status */
+        if(fstat(tf->fd, &lTDFStat) < 0){
+                g_warning("Unable to get the status of the input data file %s\n", fileName);
+                goto close_file;
+        }
+
+        /* Is the file large enough to contain a trace */
+        if(lTDFStat.st_size < (off_t)(ltt_subbuffer_header_size())) {
+                g_print("The input data file %s does not contain a trace\n", fileName);
+                goto close_file;
+        }
+
+        /* Temporarily map the buffer start header to get trace information */
+        /* Multiple of pages aligned head */
+        tf->buffer.head = mmap(0,PAGE_ALIGN(ltt_subbuffer_header_size()), PROT_READ, MAP_PRIVATE, tf->fd, 0);
+
+        if(tf->buffer.head == MAP_FAILED) {
+                perror("Error in allocating memory for buffer of tracefile");
+                goto close_file;
+        }
+        g_assert( ( (gulong)tf->buffer.head&(8-1) ) == 0); // make sure it's aligned.
+
+        header = (ltt_subbuffer_header_t *)tf->buffer.head;
+
+        return header;
+
+        close_file:
+                close(tf->fd);
+        end:
+                return 0;
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    get_version    : get the trace version from a metadata_0 trace file
+ *Input params
+ *    pathname       : path to the trace
+ *    version_number  : the struct that will get the version number
+ *Return value
+ *    int         : 1 if succeed, -1 if error
+ ****************************************************************************/
+int ltt_get_trace_version(const gchar *pathname, struct LttTraceVersion *version_number)
+{
+       gchar abs_path[PATH_MAX];
+       int ret = 0;
+       DIR *dir;
+       struct dirent *entry;
+       struct stat stat_buf;
+       gchar path[PATH_MAX];
+
+       LttTracefile tmp_tf;
+       LttTrace  * t;
+       ltt_subbuffer_header_t *header;
+
+       t = g_new(LttTrace, 1);
+
+       get_absolute_pathname(pathname, abs_path);
+
+       /* Test to see if it looks like a trace */
+       dir = opendir(abs_path);
+
+       if(dir == NULL) {
+               perror(abs_path);
+               goto open_error;
+       }
+
+       while((entry = readdir(dir)) != NULL) {
+               strcpy(path, abs_path);
+               strcat(path, "/");
+               strcat(path, entry->d_name);
+               ret = stat(path, &stat_buf);
+               if(ret == -1) {
+                       perror(path);
+                       continue;
+               }
+       }
+
+       closedir(dir);
+       dir = opendir(abs_path);
+
+       while((entry = readdir(dir)) != NULL) {
+               if(entry->d_name[0] == '.') continue;
+               if(g_strcmp0(entry->d_name, "metadata_0") != 0) continue;
+
+               strcpy(path, abs_path);
+               strcat(path, "/");
+               strcat(path, entry->d_name);
+               if(ret == -1) {
+                       perror(path);
+                       continue;
+               }
+
+                header = ltt_tracefile_open_header(path, &tmp_tf);
+
+               if(header == NULL) {
+                       g_info("Error getting the header %s", path);
+                       continue; /* error opening the tracefile : bad magic number ? */
+               }
+
+                version_number->ltt_major_version = header->major_version;
+                version_number->ltt_minor_version = header->minor_version;
+       }
+
+       return 0;
+
+       open_error:
+                g_free(t);
+                return -1;
+}
This page took 0.025608 seconds and 4 git commands to generate.