fix offset from header
[lttv.git] / ltt / branches / poly / ltt / tracefile.c
index fc1f4583d009a732982d96d94a8cd57bb418eb6d..c9564bf444e8fa8540c72989a77f1f2f7179dce9 100644 (file)
@@ -185,6 +185,78 @@ LttFacility *ltt_trace_get_facility_by_num(LttTrace *t,
 
 }
 
+guint ltt_trace_get_num_cpu(LttTrace *t)
+{
+  return t->num_cpu;
+}
+
+
+/* trace can be NULL
+ *
+ * Return value : 0 success, 1 bad tracefile
+ */
+int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
+{
+  guint32 *magic_number = (guint32*)header;
+  struct ltt_trace_header_any *any = (struct ltt_trace_header_any *)header;
+
+  if(*magic_number == LTT_MAGIC_NUMBER)
+    tf->reverse_bo = 0;
+  else if(*magic_number == LTT_REV_MAGIC_NUMBER)
+    tf->reverse_bo = 1;
+  else  /* invalid magic number, bad tracefile ! */
+    return 1;
+    
+  /* Get float byte order : might be different from int byte order
+   * (or is set to 0 if the trace has no float (kernel trace)) */
+  tf->float_word_order = any->float_word_order;
+
+  if(t) {
+    t->arch_type = ltt_get_uint32(LTT_GET_BO(tf),
+                          &any->arch_type);
+    t->arch_variant = ltt_get_uint32(LTT_GET_BO(tf),
+        &any->arch_variant);
+    t->arch_size = any->arch_size;
+    t->ltt_major_version = any->major_version;
+    t->ltt_minor_version = any->minor_version;
+    t->flight_recorder = any->flight_recorder;
+    t->has_heartbeat = any->has_heartbeat;
+    t->has_alignment = any->has_alignment;
+    t->has_tsc = any->has_tsc;
+  }
+
+  switch(any->major_version) {
+
+  case 0:
+    switch(any->minor_version) {
+    case 3:
+      {
+        struct ltt_trace_header_0_3 *header_0_3 = 
+                (struct ltt_trace_header_0_3 *)header;
+        tf->buffer_header_size =
+         sizeof(struct ltt_block_start_header) 
+            + sizeof(struct ltt_trace_header_0_3);
+      }
+      break;
+    default:
+        g_warning("Unsupported trace version : %hhu.%hhu",
+            any->major_version, any->minor_version);
+      return 1;
+    }
+    break;
+
+  default:
+    g_warning("Unsupported trace version : %hhu.%hhu",
+            any->major_version, any->minor_version);
+    return 1;
+  }
+
+
+  return 0;
+}
+
+
 
 /*****************************************************************************
  *Function name
@@ -219,7 +291,9 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   }
 
   // Is the file large enough to contain a trace 
-  if(lTDFStat.st_size < (off_t)(sizeof(struct ltt_block_start_header))){
+  if(lTDFStat.st_size <
+      (off_t)(sizeof(struct ltt_block_start_header 
+                     + sizeof(ltt_trace_header_any)))){
     g_print("The input data file %s does not contain a trace\n", fileName);
     goto close_file;
   }
@@ -227,7 +301,8 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   /* Temporarily map the buffer start header to get trace information */
   /* Multiple of pages aligned head */
   tf->buffer.head = mmap(0,
-      PAGE_ALIGN(sizeof(struct ltt_block_start_header)), PROT_READ, 
+      PAGE_ALIGN(sizeof(struct ltt_block_start_header
+          + sizeof(struct ltt_trace_header_any))), PROT_READ, 
       MAP_PRIVATE, tf->fd, 0);
   if(tf->buffer.head == MAP_FAILED) {
     perror("Error in allocating memory for buffer of tracefile");
@@ -237,12 +312,7 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   
   header = (struct ltt_block_start_header*)tf->buffer.head;
   
-  if(header->trace.magic_number == LTT_MAGIC_NUMBER)
-    tf->reverse_bo = 0;
-  else if(header->trace.magic_number == LTT_REV_MAGIC_NUMBER)
-    tf->reverse_bo = 1;
-  else  /* invalid magic number, bad tracefile ! */
-    goto unmap_file;
+  if(parse_trace_header(header->trace, tf, NULL)) goto unmap_file;
     
   //store the size of the file
   tf->file_size = lTDFStat.st_size;
@@ -250,9 +320,11 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   tf->num_blocks = tf->file_size / tf->buf_size;
 
   if(munmap(tf->buffer.head,
-        PAGE_ALIGN(sizeof(struct ltt_block_start_header)))) {
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header
+            + sizeof(struct ltt_trace_header_any))))) {
     g_warning("unmap size : %u\n",
-        PAGE_ALIGN(sizeof(struct ltt_block_start_header)));
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header
+            + sizeof(struct ltt_trace_header_any))));
     perror("munmap error");
     g_assert(0);
   }
@@ -269,9 +341,11 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   /* Error */
 unmap_file:
   if(munmap(tf->buffer.head,
-        PAGE_ALIGN(sizeof(struct ltt_block_start_header)))) {
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header
+            + sizeof(struct ltt_trace_header_any))))) {
     g_warning("unmap size : %u\n",
-        PAGE_ALIGN(sizeof(struct ltt_block_start_header)));
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header
+            + sizeof(struct ltt_trace_header_any))));
     perror("munmap error");
     g_assert(0);
   }
@@ -674,6 +748,8 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path,
                
                g_debug("Tracefile file or directory : %s\n", path);
                
+    if(strcmp(rel_path, "/eventdefs") == 0) continue;
+    
                if(S_ISDIR(stat_buf.st_mode)) {
 
                        g_debug("Entering subdirectory...\n");
@@ -966,8 +1042,14 @@ LttTrace *ltt_trace_open(const gchar *pathname)
   LttTrace  * t;
   LttTracefile *tf;
   GArray *group;
-  int i;
+  int i, ret;
   struct ltt_block_start_header *header;
+       DIR *dir;
+       struct dirent *entry;
+  guint control_found = 0;
+  guint eventdefs_found = 0;
+       struct stat stat_buf;
+  gchar path[PATH_MAX];
   
   t = g_new(LttTrace, 1);
   if(!t) goto alloc_error;
@@ -975,11 +1057,40 @@ LttTrace *ltt_trace_open(const gchar *pathname)
   get_absolute_pathname(pathname, abs_path);
   t->pathname = g_quark_from_string(abs_path);
 
-  /* Open all the tracefiles */
   g_datalist_init(&t->tracefiles);
+
+  /* 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;
+               }
+               if(S_ISDIR(stat_buf.st_mode)) {
+      if(strcmp(entry->d_name, "control") == 0) {
+        control_found = 1;
+      }
+      if(strcmp(entry->d_name, "eventdefs") == 0) {
+        eventdefs_found = 1;
+      }
+    }
+  }
+  closedir(dir);
+  
+  if(!control_found || !eventdefs_found) goto find_error;
+  
+  /* Open all the tracefiles */
   if(open_tracefiles(t, abs_path, "")) {
     g_warning("Error opening tracefile %s", abs_path);
-    goto open_error;
+    goto find_error;
   }
   
   /* Prepare the facilities containers : array and mapping */
@@ -1003,16 +1114,9 @@ LttTrace *ltt_trace_open(const gchar *pathname)
   g_assert(group->len > 0);
   tf = &g_array_index (group, LttTracefile, 0);
   header = (struct ltt_block_start_header*)tf->buffer.head;
-  t->arch_type = ltt_get_uint32(LTT_GET_BO(tf), &header->trace.arch_type);
-  t->arch_variant = ltt_get_uint32(LTT_GET_BO(tf), &header->trace.arch_variant);
-  t->arch_size = header->trace.arch_size;
-  t->ltt_major_version = header->trace.major_version;
-  t->ltt_minor_version = header->trace.minor_version;
-  t->flight_recorder = header->trace.flight_recorder;
-  t->has_heartbeat = header->trace.has_heartbeat;
-  t->has_alignment = header->trace.has_alignment;
-  t->has_tsc = header->trace.has_tsc;
-  
+  g_assert(parse_trace_header(header->trace, tf, t) == 0);
+
+  t->num_cpu = group->len;
   
   for(i=0; i<group->len; i++) {
     tf = &g_array_index (group, LttTracefile, i);
@@ -1026,8 +1130,9 @@ LttTrace *ltt_trace_open(const gchar *pathname)
 facilities_error:
   g_datalist_clear(&t->facilities_by_name);
   g_array_free(t->facilities_by_num, TRUE);
-open_error:
+find_error:
   g_datalist_clear(&t->tracefiles);
+open_error:
   g_free(t);
 alloc_error:
   return NULL;
@@ -1755,7 +1860,8 @@ static int ltt_seek_next_event(LttTracefile *tf)
   
   /* seek over the buffer header if we are at the buffer start */
   if(tf->event.offset == 0) {
-    tf->event.offset += sizeof(struct ltt_block_start_header);
+    tf->event.offset += sizeof(struct ltt_block_start_header 
+        + tf->buffer_header_size);
 
     if(tf->event.offset == tf->buf_size - tf->buffer.lost_size) {
       ret = ERANGE;
This page took 0.050756 seconds and 4 git commands to generate.