X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=ltt%2Ftracefile.c;h=012ce10801ec27cf63819614a477ccf5fa173e3d;hb=caa44fe6ed9d848a52f712fbe900ad3e932d7da4;hp=2ac0fa5865a15a1ef10acf234045c95c935992ca;hpb=9c9bf2d4c123db7e0d53714410d642388c8ae8e9;p=lttv.git diff --git a/ltt/tracefile.c b/ltt/tracefile.c index 2ac0fa58..012ce108 100644 --- a/ltt/tracefile.c +++ b/ltt/tracefile.c @@ -55,6 +55,8 @@ /* from marker.c */ extern long marker_update_fields_offsets(struct marker_info *info, const char *data); +extern void marker_update_event_fields_offsets(GArray *fields_offsets, + struct marker_info *info); /* Tracefile names used in this file */ @@ -148,9 +150,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; @@ -333,7 +335,13 @@ static gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf) perror("Cannot map block for tracefile"); goto close_file; } - + + /* Create fields offset table */ + tf->event.fields_offsets = g_array_sized_new(FALSE, FALSE, + sizeof(struct LttField), 1); + if (!tf->event.fields_offsets) + goto close_file; + return 0; /* Error */ @@ -376,6 +384,7 @@ static void ltt_tracefile_close(LttTracefile *t) close(t->fd); if (t->buf_index) g_array_free(t->buf_index, TRUE); + g_array_free(t->event.fields_offsets, TRUE); } /**************************************************************************** @@ -1085,8 +1094,11 @@ int ltt_tracefile_seek_time(LttTracefile *tf, LttTime time) } } else if(ltt_time_compare(time, tf->buffer.begin.timestamp) < 0) { - /* go to lower part */ - high = block_num - 1; + /* + * Go to lower part. We don't want block_num - 1 since block_num + * can equal low , in which case high < low. + */ + high = block_num; } else if(ltt_time_compare(time, tf->buffer.end.timestamp) > 0) { /* go to higher part */ low = block_num + 1; @@ -1593,8 +1605,9 @@ void ltt_update_event_size(LttTracefile *tf) if (info->size != -1) size = info->size; else - size = marker_update_fields_offsets(marker_get_info_from_id(tf->mdata, - tf->event.event_id), tf->event.data); + size = marker_update_fields_offsets(info, tf->event.data); + /* Update per-tracefile offsets */ + marker_update_event_fields_offsets(tf->event.fields_offsets, info); } tf->event.data_size = size; @@ -1790,3 +1803,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; +}