X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Fltt%2Ftracefile.c;h=6fe13f1dbd13ee9311885c49037de55db9c57612;hb=b56dcdf2c3128db9165e0de6476ca5b799338486;hp=e6117b3461fc081b27bfdb16bd440982aee95fb0;hpb=cb03932ac8527313696af07dba4404603620c844;p=lttv.git diff --git a/ltt/branches/poly/ltt/tracefile.c b/ltt/branches/poly/ltt/tracefile.c index e6117b34..6fe13f1d 100644 --- a/ltt/branches/poly/ltt/tracefile.c +++ b/ltt/branches/poly/ltt/tracefile.c @@ -76,11 +76,6 @@ GQuark LTT_TRACEFILE_NAME_FACILITIES; #define PAGE_MASK (~(page_size-1)) #define PAGE_ALIGN(addr) (((addr)+page_size-1)&PAGE_MASK) -/* obtain the time of an event */ - -static inline LttTime getEventTime(LttTracefile * tf); - - /* set the offset of the fields belonging to the event, need the information of the archecture */ void set_fields_offsets(LttTracefile *tf, LttEventType *event_type); @@ -190,6 +185,11 @@ LttFacility *ltt_trace_get_facility_by_num(LttTrace *t, } +guint ltt_trace_get_num_cpu(LttTrace *t) +{ + return t->num_cpu; +} + /***************************************************************************** *Function name @@ -209,7 +209,7 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf) int page_size = getpagesize(); //open the file - tf->name = g_quark_from_string(fileName); + tf->long_name = g_quark_from_string(fileName); tf->trace = t; tf->fd = open(fileName, O_RDONLY); if(tf->fd < 0){ @@ -251,10 +251,16 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf) //store the size of the file tf->file_size = lTDFStat.st_size; - tf->block_size = ltt_get_uint32(LTT_GET_BO(tf), &header->buf_size); - tf->num_blocks = tf->file_size / tf->block_size; - - munmap(tf->buffer.head, PAGE_ALIGN(sizeof(struct ltt_block_start_header))); + tf->buf_size = ltt_get_uint32(LTT_GET_BO(tf), &header->buf_size); + tf->num_blocks = tf->file_size / tf->buf_size; + + if(munmap(tf->buffer.head, + PAGE_ALIGN(sizeof(struct ltt_block_start_header)))) { + g_warning("unmap size : %u\n", + PAGE_ALIGN(sizeof(struct ltt_block_start_header))); + perror("munmap error"); + g_assert(0); + } tf->buffer.head = NULL; //read the first block @@ -267,13 +273,24 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf) /* Error */ unmap_file: - munmap(tf->buffer.head, PAGE_ALIGN(sizeof(struct ltt_block_start_header))); + if(munmap(tf->buffer.head, + PAGE_ALIGN(sizeof(struct ltt_block_start_header)))) { + g_warning("unmap size : %u\n", + PAGE_ALIGN(sizeof(struct ltt_block_start_header))); + perror("munmap error"); + g_assert(0); + } close_file: close(tf->fd); end: return -1; } +LttTrace *ltt_tracefile_get_trace(LttTracefile *tf) +{ + return tf->trace; +} + #if 0 /***************************************************************************** *Open control and per cpu tracefiles @@ -351,8 +368,16 @@ gint ltt_tracefile_open_control(LttTrace *t, gchar * control_name) void ltt_tracefile_close(LttTracefile *t) { + int page_size = getpagesize(); + if(t->buffer.head != NULL) - munmap(t->buffer.head, t->buf_size); + if(munmap(t->buffer.head, PAGE_ALIGN(t->buf_size))) { + g_warning("unmap size : %u\n", + PAGE_ALIGN(t->buf_size)); + perror("munmap error"); + g_assert(0); + } + close(t->fd); } @@ -515,7 +540,6 @@ int get_tracefile_name_number(const gchar *raw_name, { guint raw_name_len = strlen(raw_name); gchar char_name[PATH_MAX]; - gchar *digit_begin; int i; int underscore_pos; long int cpu_num; @@ -537,6 +561,8 @@ int get_tracefile_name_number(const gchar *raw_name, strncpy(char_name, raw_name, underscore_pos); + char_name[underscore_pos] = '\0'; + *name = g_quark_from_string(char_name); *num = cpu_num; @@ -604,21 +630,21 @@ gboolean ltt_tracefile_group_has_cpu_online(gpointer data) * A tracefile group is simply an array where all the per cpu tracefiles sits. */ -static int open_tracefiles(LttTrace *trace, char *root_path, - char *relative_path) +static int open_tracefiles(LttTrace *trace, gchar *root_path, + gchar *relative_path) { DIR *dir = opendir(root_path); struct dirent *entry; struct stat stat_buf; int ret; - char path[PATH_MAX]; + gchar path[PATH_MAX]; int path_len; - char *path_ptr; + gchar *path_ptr; int rel_path_len; - char rel_path[PATH_MAX]; - char *rel_path_ptr; + gchar rel_path[PATH_MAX]; + gchar *rel_path_ptr; LttTracefile tmp_tf; if(dir == NULL) { @@ -662,8 +688,6 @@ static int open_tracefiles(LttTrace *trace, char *root_path, GQuark name; guint num; GArray *group; - LttTracefile *tf; - guint len; if(get_tracefile_name_number(rel_path, &name, &num)) continue; /* invalid name */ @@ -680,6 +704,7 @@ static int open_tracefiles(LttTrace *trace, char *root_path, tmp_tf.cpu_online = 1; tmp_tf.cpu_num = num; + tmp_tf.name = name; group = g_datalist_id_get_data(&trace->tracefiles, name); if(group == NULL) { @@ -931,7 +956,6 @@ static int ltt_process_facility_tracefile(LttTracefile *tf) return 0; /* Error handling */ -facility_error: event_id_error: fac_id_error: update_error: @@ -947,8 +971,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; @@ -956,10 +986,41 @@ 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); - if(open_tracefiles(t, abs_path, "")) - goto open_error; + + /* 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 find_error; + } /* Prepare the facilities containers : array and mapping */ /* Array is zeroed : the "exists" field is set to false by default */ @@ -991,7 +1052,8 @@ LttTrace *ltt_trace_open(const gchar *pathname) t->has_heartbeat = header->trace.has_heartbeat; t->has_alignment = header->trace.has_alignment; t->has_tsc = header->trace.has_tsc; - + + t->num_cpu = group->len; for(i=0; ilen; i++) { tf = &g_array_index (group, LttTracefile, i); @@ -1005,15 +1067,16 @@ 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; } -GQuark ltt_trace_name(LttTrace *t) +GQuark ltt_trace_name(const LttTrace *t) { return t->pathname; } @@ -1127,7 +1190,6 @@ LttTracefile *ltt_trace_find_tracefile(LttTrace *t, const gchar *name) static void ltt_tracefile_time_span_get(LttTracefile *tf, LttTime *start, LttTime *end) { - struct ltt_block_start_header * header; int err; err = map_block(tf, 0); @@ -1195,6 +1257,12 @@ GQuark ltt_tracefile_name(LttTracefile *tf) return tf->name; } + +guint ltt_tracefile_num(LttTracefile *tf) +{ + return tf->cpu_num; +} + /***************************************************************************** * Get the number of blocks in the tracefile ****************************************************************************/ @@ -1209,12 +1277,12 @@ guint ltt_tracefile_block_number(LttTracefile *tf) * the time passed in parameter. * * If the time parameter is outside the tracefile time span, seek to the first - * or the last event of the tracefile. + * event or if after, return ERANGE. * * If the time parameter is before the first event, we have to seek specially to * there. * - * If the time is after the end of the trace, get the last event. + * If the time is after the end of the trace, return ERANGE. * * Do a binary search to find the right block, then a sequential search in the * block to find the event. @@ -1229,6 +1297,7 @@ guint ltt_tracefile_block_number(LttTracefile *tf) * you will jump over an event if you do. * * Return value : 0 : no error, the tf->event can be used + * ERANGE : time if after the last event of the trace * otherwise : this is an error. * * */ @@ -1250,6 +1319,8 @@ int ltt_tracefile_seek_time(LttTracefile *tf, LttTime time) * go to the first event. */ if(ltt_time_compare(time, tf->buffer.begin.timestamp) <= 0) { ret = ltt_tracefile_read(tf); + if(ret == ERANGE) goto range; + else if (ret) goto fail; goto found; /* There is either no event in the trace or the event points to the first event in the trace */ } @@ -1260,16 +1331,9 @@ int ltt_tracefile_seek_time(LttTracefile *tf, LttTime time) goto fail; } - /* If the time is after the end of the trace, get the last event. */ - if(ltt_time_compare(time, tf->buffer.end.timestamp) >= 0) { - /* While the ltt_tracefile_read doesn't return ERANGE or EPERM, - * continue reading. - */ - while(1) { - ret = ltt_tracefile_read(tf); - if(ret == ERANGE) goto found; /* ERANGE or EPERM */ - else if(ret) goto fail; - } + /* If the time is after the end of the trace, return ERANGE. */ + if(ltt_time_compare(time, tf->buffer.end.timestamp) > 0) { + goto range; } /* Binary search the block */ @@ -1293,14 +1357,14 @@ int ltt_tracefile_seek_time(LttTracefile *tf, LttTime time) * (or in the next buffer first event) */ while(1) { ret = ltt_tracefile_read(tf); - if(ret == ERANGE) goto found; /* ERANGE or EPERM */ + if(ret == ERANGE) goto range; /* ERANGE or EPERM */ else if(ret) goto fail; if(ltt_time_compare(time, tf->event.event_time) >= 0) - break; + goto found; } - } if(ltt_time_compare(time, tf->buffer.begin.timestamp) < 0) { + } else if(ltt_time_compare(time, tf->buffer.begin.timestamp) < 0) { /* go to lower part */ high = block_num; } else if(ltt_time_compare(time, tf->buffer.end.timestamp) > 0) { @@ -1309,8 +1373,8 @@ int ltt_tracefile_seek_time(LttTracefile *tf, LttTime time) } else {/* The event is right in the buffer! (or in the next buffer first event) */ while(1) { - ltt_tracefile_read(tf); - if(ret == ERANGE) goto found; /* ERANGE or EPERM */ + ret = ltt_tracefile_read(tf); + if(ret == ERANGE) goto range; /* ERANGE or EPERM */ else if(ret) goto fail; if(ltt_time_compare(time, tf->event.event_time) >= 0) @@ -1322,6 +1386,8 @@ int ltt_tracefile_seek_time(LttTracefile *tf, LttTime time) found: return 0; +range: + return ERANGE; /* Error handling */ fail: @@ -1352,11 +1418,12 @@ int ltt_tracefile_seek_position(LttTracefile *tf, const LttEventPosition *ep) { err = ltt_tracefile_read_op(tf); if(err) goto fail; - return; + return 0; fail: g_error("ltt_tracefile_seek_time failed on tracefile %s", g_quark_to_string(tf->name)); + return 1; } /* Calculate the real event time based on the buffer boundaries */ @@ -1367,7 +1434,8 @@ LttTime ltt_interpolate_time(LttTracefile *tf, LttEvent *event) g_assert(tf->trace->has_tsc); time = ltt_time_from_uint64( - (guint64)tf->buffer.tsc*tf->buffer.nsecs_per_cycle); + (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count) * + tf->buffer.nsecs_per_cycle); time = ltt_time_add(tf->buffer.begin.timestamp, time); return time; @@ -1390,7 +1458,8 @@ LttEvent *ltt_tracefile_get_event(LttTracefile *tf) *Return value * * Returns 0 if an event can be used in tf->event. - * Returns ERANGE on end of trace. The event in tf->event still can be used. + * Returns ERANGE on end of trace. The event in tf->event still can be used + * (if the last block was not empty). * Returns EPERM on error. * * This function does make the tracefile event structure point to the event @@ -1450,9 +1519,6 @@ int ltt_tracefile_read_seek(LttTracefile *tf) /* do specific operation on events */ int ltt_tracefile_read_op(LttTracefile *tf) { - int err; - LttFacility *f; - void * pos; LttEvent *event; event = &tf->event; @@ -1472,8 +1538,6 @@ int ltt_tracefile_read_op(LttTracefile *tf) * event specific operation. */ int ltt_tracefile_read_update_event(LttTracefile *tf) { - int err; - LttFacility *f; void * pos; LttEvent *event; @@ -1559,14 +1623,21 @@ static gint map_block(LttTracefile * tf, guint block_num) g_assert(block_num < tf->num_blocks); - if(tf->buffer.head != NULL) - munmap(tf->buffer.head, PAGE_ALIGN(tf->buf_size)); + if(tf->buffer.head != NULL) { + if(munmap(tf->buffer.head, PAGE_ALIGN(tf->buf_size))) { + g_warning("unmap size : %u\n", + PAGE_ALIGN(tf->buf_size)); + perror("munmap error"); + g_assert(0); + } + } + /* Multiple of pages aligned head */ tf->buffer.head = mmap(0, - PAGE_ALIGN(tf->block_size), + PAGE_ALIGN(tf->buf_size), PROT_READ, MAP_PRIVATE, tf->fd, - PAGE_ALIGN((off_t)tf->block_size * (off_t)block_num)); + PAGE_ALIGN((off_t)tf->buf_size * (off_t)block_num)); if(tf->buffer.head == MAP_FAILED) { perror("Error in allocating memory for buffer of tracefile"); @@ -1583,11 +1654,15 @@ static gint map_block(LttTracefile * tf, guint block_num) tf->buffer.begin.timestamp = ltt_get_time(LTT_GET_BO(tf), &header->begin.timestamp); tf->buffer.begin.timestamp.tv_nsec *= NSEC_PER_USEC; + g_debug("block %u begin : %lu.%lu", block_num, + tf->buffer.begin.timestamp.tv_sec, tf->buffer.begin.timestamp.tv_nsec); tf->buffer.begin.cycle_count = ltt_get_uint64(LTT_GET_BO(tf), &header->begin.cycle_count); tf->buffer.end.timestamp = ltt_get_time(LTT_GET_BO(tf), &header->end.timestamp); tf->buffer.end.timestamp.tv_nsec *= NSEC_PER_USEC; + g_debug("block %u end : %lu.%lu", block_num, + tf->buffer.end.timestamp.tv_sec, tf->buffer.end.timestamp.tv_nsec); tf->buffer.end.cycle_count = ltt_get_uint64(LTT_GET_BO(tf), &header->end.cycle_count); tf->buffer.lost_size = ltt_get_uint32(LTT_GET_BO(tf), @@ -1599,7 +1674,7 @@ static gint map_block(LttTracefile * tf, guint block_num) /* FIXME * eventually support variable buffer size : will need a partial pre-read of * the headers to create an index when we open the trace... eventually. */ - g_assert(tf->block_size == ltt_get_uint32(LTT_GET_BO(tf), + g_assert(tf->buf_size == ltt_get_uint32(LTT_GET_BO(tf), &header->buf_size)); /* Now that the buffer is mapped, calculate the time interpolation for the @@ -1678,10 +1753,15 @@ void ltt_update_event_size(LttTracefile *tf) g_quark_to_string(tf->name)); goto event_type_error; } + + if(event_type->root_field) + size = get_field_type_size(tf, event_type, + 0, 0, event_type->root_field, tf->event.data); + else + size = 0; - size = get_field_type_size(tf, event_type, - 0, 0, event_type->root_field, tf->event.data); - g_debug("Event root field : f.e %hhu.%hhu size %lu", tf->event.facility_id, + g_debug("Event root field : f.e %hhu.%hhu size %zd", + tf->event.facility_id, tf->event.event_id, size); } @@ -1689,7 +1769,7 @@ void ltt_update_event_size(LttTracefile *tf) /* Check consistency between kernel and LTTV structure sizes */ g_assert(tf->event.data_size == tf->event.event_size); - + return; facility_error: @@ -1714,13 +1794,12 @@ static int ltt_seek_next_event(LttTracefile *tf) { int ret = 0; void *pos; - ssize_t event_size; /* 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); - if(tf->event.offset == tf->block_size - tf->buffer.lost_size) { + if(tf->event.offset == tf->buf_size - tf->buffer.lost_size) { ret = ERANGE; } goto found; @@ -1735,7 +1814,7 @@ static int ltt_seek_next_event(LttTracefile *tf) tf->event.offset = pos - tf->buffer.head; - if(tf->event.offset == tf->block_size - tf->buffer.lost_size) { + if(tf->event.offset == tf->buf_size - tf->buffer.lost_size) { ret = ERANGE; goto found; } @@ -1764,14 +1843,12 @@ static double calc_nsecs_per_cycle(LttTracefile * tf) LttCycleCount lBufTotalCycle;/* Total cycles for this buffer */ /* Calculate the total time for this buffer */ - lBufTotalTime = ltt_time_sub( - ltt_get_time(LTT_GET_BO(tf), &tf->buffer.end.timestamp), - ltt_get_time(LTT_GET_BO(tf), &tf->buffer.begin.timestamp)); + lBufTotalTime = ltt_time_sub(tf->buffer.end.timestamp, + tf->buffer.begin.timestamp); /* Calculate the total cycles for this bufffer */ - lBufTotalCycle = ltt_get_uint64(LTT_GET_BO(tf), &tf->buffer.end.cycle_count); - lBufTotalCycle -= ltt_get_uint64(LTT_GET_BO(tf), - &tf->buffer.begin.cycle_count); + lBufTotalCycle = tf->buffer.end.cycle_count; + lBufTotalCycle -= tf->buffer.begin.cycle_count; /* Convert the total time to double */ lBufTotalNSec = ltt_time_to_double(lBufTotalTime); @@ -1888,10 +1965,14 @@ void preset_field_type_size(LttTracefile *tf, LttEventType *event_type, field->child[0]); field->fixed_size = FIELD_VARIABLE; field->field_size = 0; + *fixed_root = FIELD_VARIABLE; + *fixed_parent = FIELD_VARIABLE; break; case LTT_STRING: field->fixed_size = FIELD_VARIABLE; field->field_size = 0; + *fixed_root = FIELD_VARIABLE; + *fixed_parent = FIELD_VARIABLE; break; case LTT_ARRAY: local_fixed_root = FIELD_VARIABLE; @@ -1901,10 +1982,13 @@ void preset_field_type_size(LttTracefile *tf, LttEventType *event_type, &local_fixed_root, &local_fixed_parent, field->child[0]); field->fixed_size = field->child[0]->fixed_size; - if(field->fixed_size == FIELD_FIXED) + if(field->fixed_size == FIELD_FIXED) { field->field_size = type->element_number * field->child[0]->field_size; - else + } else { field->field_size = 0; + *fixed_root = FIELD_VARIABLE; + *fixed_parent = FIELD_VARIABLE; + } break; case LTT_STRUCT: current_root_offset = field->offset_root; @@ -1981,7 +2065,6 @@ gint check_fields_compatibility(LttEventType *event_type1, LttField *field1, LttField *field2) { guint different = 0; - enum field_status local_fixed_root, local_fixed_parent; guint i; LttType *type1; LttType *type2; @@ -2007,11 +2090,6 @@ gint check_fields_compatibility(LttEventType *event_type1, type1 = field1->field_type; type2 = field2->field_type; - size_t current_root_offset; - size_t current_offset; - enum field_status current_child_status, final_child_status; - size_t max_size; - if(type1->type_class != type2->type_class) { different = 1; goto end;