X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=formats%2Fctf%2Fctf.c;h=4f14d7a0b8a45a1994e46d355aabb7af0a930734;hp=ab4945dddcff18b8c41c6df91798096b4940695b;hb=43e34335c78d923564d369e9af46b634ce9ad55f;hpb=0716bb06f1a2995aedf7df46b0ed00a126fc8f29 diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index ab4945dd..4f14d7a0 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -22,12 +22,13 @@ #include #include #include +#include +#include +#include #include #include -#include #include #include -#include #include #include #include @@ -39,6 +40,7 @@ #include "metadata/ctf-scanner.h" #include "metadata/ctf-parser.h" #include "metadata/ctf-ast.h" +#include "events-private.h" /* * We currently simply map a page to read the packet header and packet @@ -46,7 +48,6 @@ */ #define MAX_PACKET_HEADER_LEN (getpagesize() * CHAR_BIT) #define WRITE_PACKET_LEN (getpagesize() * 8 * CHAR_BIT) -#define UUID_LEN 16 /* uuid by value len */ #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) @@ -64,13 +65,15 @@ uint64_t opt_clock_offset; extern int yydebug; static -struct trace_descriptor *ctf_open_trace(const char *collection_path, const char *path, int flags, - void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, - int whence), FILE *metadata_fp); +struct trace_descriptor *ctf_open_trace(const char *path, int flags, + void (*packet_seek)(struct stream_pos *pos, size_t index, + int whence), + FILE *metadata_fp); static struct trace_descriptor *ctf_open_mmap_trace( struct mmap_stream_list *mmap_list, - void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, int whence), + void (*packet_seek)(struct stream_pos *pos, size_t index, + int whence), FILE *metadata_fp); static @@ -107,6 +110,9 @@ struct format ctf_format = { .close_trace = ctf_close_trace, }; +/* + * Update stream current timestamp, keep at clock frequency. + */ static void ctf_update_timestamp(struct ctf_stream *stream, struct definition_integer *integer_definition) @@ -134,21 +140,23 @@ void ctf_update_timestamp(struct ctf_stream *stream, stream->timestamp = updateval; } +/* + * Print timestamp, rescaling clock frequency to nanoseconds and + * applying offsets as needed (unix time). + */ void ctf_print_timestamp(FILE *fp, struct ctf_stream *stream, uint64_t timestamp) { uint64_t ts_sec = 0, ts_nsec; - struct ctf_trace *trace = stream->stream_class->trace; - struct trace_collection *tc = trace->collection; - uint64_t tc_offset = tc->single_clock_offset_avg; - ts_nsec = timestamp; - - /* Add offsets */ - if (!opt_clock_raw) { - ts_nsec += tc_offset; + if (opt_clock_raw) { + ts_nsec = ctf_get_timestamp_raw(stream, timestamp); + } else { + ts_nsec = ctf_get_timestamp(stream, timestamp); } + + /* Add command-line offset */ ts_sec += opt_clock_offset; ts_sec += ts_nsec / NSEC_PER_SEC; @@ -217,6 +225,11 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream *stream) ctf_pos_get_event(pos); + /* save the current position as a restore point */ + pos->last_offset = pos->offset; + /* we just read the event, it is consumed when used by the caller */ + stream->consumed = 0; + /* * This is the EOF check after we've advanced the position in * ctf_pos_get_event. @@ -394,7 +407,7 @@ void ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags) pos->parent.rw_table = write_dispatch_table; pos->parent.event_cb = ctf_write_event; if (fd >= 0) - ctf_move_pos_slow(pos, 0, SEEK_SET); /* position for write */ + ctf_packet_seek(&pos->parent, 0, SEEK_SET); /* position for write */ break; default: assert(0); @@ -419,13 +432,19 @@ void ctf_fini_pos(struct ctf_stream_pos *pos) (void) g_array_free(pos->packet_index, TRUE); } -void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence) +/* + * for SEEK_CUR: go to next packet. + * for SEEK_POS: go to packet numer (index). + */ +void ctf_packet_seek(struct stream_pos *stream_pos, size_t index, int whence) { + struct ctf_stream_pos *pos = + container_of(stream_pos, struct ctf_stream_pos, parent); struct ctf_file_stream *file_stream = container_of(pos, struct ctf_file_stream, pos); int ret; off_t off; - struct packet_index *index; + struct packet_index *packet_index; if (pos->prot == PROT_WRITE && pos->content_size_loc) *pos->content_size_loc = pos->offset; @@ -449,11 +468,10 @@ void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence) switch (whence) { case SEEK_CUR: /* The writer will add padding */ - assert(pos->offset + offset == pos->packet_size); pos->mmap_offset += WRITE_PACKET_LEN / CHAR_BIT; break; case SEEK_SET: - assert(offset == 0); /* only seek supported for now */ + assert(index == 0); /* only seek supported for now */ pos->cur_index = 0; break; default: @@ -476,27 +494,25 @@ void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence) return; } /* For printing discarded event count */ - index = &g_array_index(pos->packet_index, + packet_index = &g_array_index(pos->packet_index, struct packet_index, pos->cur_index); - events_discarded_diff = index->events_discarded; + events_discarded_diff = packet_index->events_discarded; file_stream->parent.prev_timestamp_end = - index->timestamp_end; + packet_index->timestamp_end; if (pos->cur_index > 0) { - index = &g_array_index(pos->packet_index, + packet_index = &g_array_index(pos->packet_index, struct packet_index, pos->cur_index - 1); - events_discarded_diff -= index->events_discarded; + events_discarded_diff -= packet_index->events_discarded; } file_stream->parent.events_discarded = events_discarded_diff; file_stream->parent.prev_timestamp = file_stream->parent.timestamp; /* The reader will expect us to skip padding */ - assert(pos->offset + offset == pos->content_size); ++pos->cur_index; break; } case SEEK_SET: - assert(offset == 0); /* only seek supported for now */ - pos->cur_index = 0; + pos->cur_index = index; file_stream->parent.prev_timestamp = 0; file_stream->parent.prev_timestamp_end = 0; break; @@ -512,35 +528,43 @@ void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence) * be printed in the output. */ if (file_stream->parent.events_discarded) { - fflush(stdout); - fprintf(stderr, "[warning] Tracer discarded %d events at end of stream between [", - file_stream->parent.events_discarded); - ctf_print_timestamp(stderr, &file_stream->parent, - file_stream->parent.prev_timestamp); - fprintf(stderr, "] and ["); - ctf_print_timestamp(stderr, &file_stream->parent, - file_stream->parent.prev_timestamp_end); - fprintf(stderr, "]. You should consider increasing the buffer size.\n"); - fflush(stderr); + /* + * We need to check if we are in trace + * read or called from packet indexing. + * In this last case, the collection is + * not there, so we cannot print the + * timestamps. + */ + if ((&file_stream->parent)->stream_class->trace->collection) { + fflush(stdout); + fprintf(stderr, "[warning] Tracer discarded %d events at end of stream between [", + file_stream->parent.events_discarded); + ctf_print_timestamp(stderr, &file_stream->parent, + file_stream->parent.prev_timestamp); + fprintf(stderr, "] and ["); + ctf_print_timestamp(stderr, &file_stream->parent, + file_stream->parent.prev_timestamp_end); + fprintf(stderr, "]. You should consider increasing the buffer size.\n"); + fflush(stderr); + } file_stream->parent.events_discarded = 0; } pos->offset = EOF; return; } - index = &g_array_index(pos->packet_index, struct packet_index, + packet_index = &g_array_index(pos->packet_index, struct packet_index, pos->cur_index); - pos->mmap_offset = index->offset; + pos->mmap_offset = packet_index->offset; /* Lookup context/packet size in index */ - file_stream->parent.timestamp = index->timestamp_begin; - pos->content_size = index->content_size; - pos->packet_size = index->packet_size; - if (index->data_offset < index->content_size) { + file_stream->parent.timestamp = packet_index->timestamp_begin; + pos->content_size = packet_index->content_size; + pos->packet_size = packet_index->packet_size; + if (packet_index->data_offset < packet_index->content_size) { pos->offset = 0; /* will read headers */ - } else if (index->data_offset == index->content_size) { + } else if (packet_index->data_offset == packet_index->content_size) { /* empty packet */ - pos->offset = index->data_offset; - offset = 0; + pos->offset = packet_index->data_offset; whence = SEEK_CUR; goto read_next_packet; } else { @@ -664,7 +688,7 @@ int ctf_open_trace_metadata_packet_read(struct ctf_trace *td, FILE *in, memcpy(td->uuid, header.uuid, sizeof(header.uuid)); CTF_TRACE_SET_FIELD(td, uuid); } else { - if (uuid_compare(header.uuid, td->uuid)) + if (babeltrace_uuid_compare(header.uuid, td->uuid)) return -EINVAL; } @@ -751,7 +775,7 @@ int ctf_open_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp, static int ctf_open_trace_metadata_read(struct ctf_trace *td, - void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, + void (*packet_seek)(struct stream_pos *pos, size_t index, int whence), FILE *metadata_fp) { struct ctf_scanner *scanner; @@ -762,10 +786,10 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, metadata_stream = g_new0(struct ctf_file_stream, 1); - if (move_pos_slow) { - metadata_stream->pos.move_pos_slow = move_pos_slow; + if (packet_seek) { + metadata_stream->pos.packet_seek = packet_seek; } else { - fprintf(stderr, "[error] move_pos_slow function undefined.\n"); + fprintf(stderr, "[error] packet_seek function undefined.\n"); ret = -1; goto end_stream; } @@ -1052,20 +1076,20 @@ int create_stream_packet_index(struct ctf_trace *td, struct definition_array *defarray; struct definition *field; uint64_t i; - uint8_t uuidval[UUID_LEN]; + uint8_t uuidval[BABELTRACE_UUID_LEN]; field = struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); assert(field->declaration->id == CTF_TYPE_ARRAY); defarray = container_of(field, struct definition_array, p); - assert(array_len(defarray) == UUID_LEN); + assert(array_len(defarray) == BABELTRACE_UUID_LEN); - for (i = 0; i < UUID_LEN; i++) { + for (i = 0; i < BABELTRACE_UUID_LEN; i++) { struct definition *elem; elem = array_index(defarray, i); uuidval[i] = get_unsigned_int(elem); } - ret = uuid_compare(td->uuid, uuidval); + ret = babeltrace_uuid_compare(td->uuid, uuidval); if (ret) { fprintf(stderr, "[error] Unique Universal Identifiers do not match.\n"); return -EINVAL; @@ -1168,14 +1192,14 @@ int create_stream_packet_index(struct ctf_trace *td, /* Validate content size and packet size values */ if (packet_index.content_size > packet_index.packet_size) { - fprintf(stderr, "[error] Content size (%zu bits) is larger than packet size (%zu bits).\n", + fprintf(stderr, "[error] Content size (%" PRIu64 " bits) is larger than packet size (%" PRIu64 " bits).\n", packet_index.content_size, packet_index.packet_size); return -EINVAL; } - if (packet_index.packet_size > (filestats.st_size - packet_index.offset) * CHAR_BIT) { - fprintf(stderr, "[error] Packet size (%zu bits) is larger than remaining file size (%zu bits).\n", - packet_index.content_size, (size_t) (filestats.st_size - packet_index.offset) * CHAR_BIT); + if (packet_index.packet_size > ((uint64_t)filestats.st_size - packet_index.offset) * CHAR_BIT) { + fprintf(stderr, "[error] Packet size (%" PRIu64 " bits) is larger than remaining file size (%" PRIu64 " bits).\n", + packet_index.content_size, ((uint64_t)filestats.st_size - packet_index.offset) * CHAR_BIT); return -EINVAL; } @@ -1189,7 +1213,7 @@ int create_stream_packet_index(struct ctf_trace *td, } /* Move pos back to beginning of file */ - ctf_move_pos_slow(pos, 0, SEEK_SET); /* position for write */ + ctf_packet_seek(&pos->parent, 0, SEEK_SET); /* position for write */ return 0; } @@ -1224,7 +1248,7 @@ error: */ static int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags, - void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, + void (*packet_seek)(struct stream_pos *pos, size_t index, int whence)) { int ret; @@ -1237,10 +1261,10 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags, } file_stream = g_new0(struct ctf_file_stream, 1); - if (move_pos_slow) { - file_stream->pos.move_pos_slow = move_pos_slow; + if (packet_seek) { + file_stream->pos.packet_seek = packet_seek; } else { - fprintf(stderr, "[error] move_pos_slow function undefined.\n"); + fprintf(stderr, "[error] packet_seek function undefined.\n"); ret = -1; goto error_def; } @@ -1249,6 +1273,10 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags, ret = create_trace_definitions(td, &file_stream->parent); if (ret) goto error_def; + /* + * For now, only a single slock is supported. + */ + file_stream->parent.current_clock = td->single_clock; ret = create_stream_packet_index(td, file_stream); if (ret) goto error_index; @@ -1268,106 +1296,16 @@ error: return ret; } -static void -init_domain_name(struct ctf_trace *td) -{ - char *start, *end; - - start = td->path + strlen(td->collection_path); - while (start[0] == '/') - start++; /* skip / */ - end = strchr(start, '/'); - if (!end) - end = start + strlen(start); - memcpy(td->domain, start, end - start); - td->domain[end - start] = '\0'; -} - -static void -init_proc_name(struct ctf_trace *td) -{ - char buf[PATH_MAX]; - char *start, *end; - - if (td->domain[0] == '\0') - return; - memcpy(buf, td->path, PATH_MAX); - start = buf + strlen(td->collection_path); - while (start[0] == '/') - start++; /* skip / */ - start = strchr(start, '/'); /* get begin of domain content */ - if (!start) - return; - while (start[0] == '/') - start++; /* skip / */ - /* find last -, skips time */ - end = strrchr(start, '-'); - if (!end) - return; - *end = '\0'; - /* find previous -, skips date */ - end = strrchr(start, '-'); - if (!end) - return; - *end = '\0'; - /* find previous -, skips pid */ - end = strrchr(start, '-'); - if (!end) - return; - *end = '\0'; - - memcpy(td->procname, start, end - start); - td->procname[end - start] = '\0'; -} - -static void -init_vpid(struct ctf_trace *td) -{ - char buf[PATH_MAX]; - char *start, *end; - - if (td->domain[0] == '\0') - return; - memcpy(buf, td->path, PATH_MAX); - start = buf + strlen(td->collection_path); - while (start[0] == '/') - start++; /* skip / */ - start = strchr(start, '/'); /* get begin of domain content */ - if (!start) - return; - while (start[0] == '/') - start++; /* skip / */ - /* find last -, skips time */ - end = strrchr(start, '-'); - if (!end) - return; - *end = '\0'; - /* find previous -, skips date */ - end = strrchr(start, '-'); - if (!end) - return; - *end = '\0'; - /* find previous -, skips pid */ - start = strrchr(start, '-'); - if (!start) - return; - start++; /* skip - */ - - memcpy(td->vpid, start, end - start); - td->vpid[end - start] = '\0'; -} - static -int ctf_open_trace_read(struct ctf_trace *td, const char *collection_path, +int ctf_open_trace_read(struct ctf_trace *td, const char *path, int flags, - void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, + void (*packet_seek)(struct stream_pos *pos, size_t index, int whence), FILE *metadata_fp) { int ret; struct dirent *dirent; struct dirent *diriter; size_t dirent_len; - char *respath, *rescolpath; td->flags = flags; @@ -1386,25 +1324,14 @@ int ctf_open_trace_read(struct ctf_trace *td, const char *collection_path, ret = -errno; goto error_dirfd; } - rescolpath = realpath(collection_path, td->collection_path); - if (!rescolpath) { - fprintf(stderr, "[error] collection path resolution failure\n"); - return -EINVAL; - } - respath = realpath(path, td->path); - if (!respath) { - fprintf(stderr, "[error] path resolution failure\n"); - return -EINVAL; - } - init_domain_name(td); - init_proc_name(td); - init_vpid(td); + strncpy(td->path, path, sizeof(td->path)); + td->path[sizeof(td->path) - 1] = '\0'; /* * Keep the metadata file separate. */ - ret = ctf_open_trace_metadata_read(td, move_pos_slow, metadata_fp); + ret = ctf_open_trace_metadata_read(td, packet_seek, metadata_fp); if (ret) { goto error_metadata; } @@ -1433,7 +1360,8 @@ int ctf_open_trace_read(struct ctf_trace *td, const char *collection_path, || !strcmp(diriter->d_name, "..") || !strcmp(diriter->d_name, "metadata")) continue; - ret = ctf_open_file_stream_read(td, diriter->d_name, flags, move_pos_slow); + ret = ctf_open_file_stream_read(td, diriter->d_name, + flags, packet_seek); if (ret) { fprintf(stderr, "[error] Open file stream error.\n"); goto readdir_error; @@ -1454,13 +1382,19 @@ error: } static -struct trace_descriptor *ctf_open_trace(const char *collection_path, const char *path, int flags, - void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, +struct trace_descriptor *ctf_open_trace(const char *path, int flags, + void (*packet_seek)(struct stream_pos *pos, size_t index, int whence), FILE *metadata_fp) { struct ctf_trace *td; int ret; + /* + * If packet_seek is NULL, we provide our default version. + */ + if (!packet_seek) + packet_seek = ctf_packet_seek; + td = g_new0(struct ctf_trace, 1); switch (flags & O_ACCMODE) { @@ -1469,7 +1403,7 @@ struct trace_descriptor *ctf_open_trace(const char *collection_path, const char fprintf(stderr, "[error] Path missing for input CTF trace.\n"); goto error; } - ret = ctf_open_trace_read(td, collection_path, path, flags, move_pos_slow, metadata_fp); + ret = ctf_open_trace_read(td, path, flags, packet_seek, metadata_fp); if (ret) goto error; break; @@ -1538,7 +1472,7 @@ end: static int ctf_open_mmap_stream_read(struct ctf_trace *td, struct mmap_stream *mmap_info, - void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, + void (*packet_seek)(struct stream_pos *pos, size_t index, int whence)) { int ret; @@ -1547,7 +1481,7 @@ int ctf_open_mmap_stream_read(struct ctf_trace *td, file_stream = g_new0(struct ctf_file_stream, 1); ctf_init_mmap_pos(&file_stream->pos, mmap_info); - file_stream->pos.move_pos_slow = move_pos_slow; + file_stream->pos.packet_seek = packet_seek; ret = create_trace_definitions(td, &file_stream->parent); if (ret) { @@ -1573,14 +1507,14 @@ error_def: int ctf_open_mmap_trace_read(struct ctf_trace *td, struct mmap_stream_list *mmap_list, - void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, + void (*packet_seek)(struct stream_pos *pos, size_t index, int whence), FILE *metadata_fp) { int ret; struct mmap_stream *mmap_info; - ret = ctf_open_trace_metadata_read(td, ctf_move_pos_slow, metadata_fp); + ret = ctf_open_trace_metadata_read(td, ctf_packet_seek, metadata_fp); if (ret) { goto error; } @@ -1589,8 +1523,8 @@ int ctf_open_mmap_trace_read(struct ctf_trace *td, * for each stream, try to open, check magic number, and get the * stream ID to add to the right location in the stream array. */ - cds_list_for_each_entry(mmap_info, &mmap_list->head, list) { - ret = ctf_open_mmap_stream_read(td, mmap_info, move_pos_slow); + bt_list_for_each_entry(mmap_info, &mmap_list->head, list) { + ret = ctf_open_mmap_stream_read(td, mmap_info, packet_seek); if (ret) { fprintf(stderr, "[error] Open file mmap stream error.\n"); goto error; @@ -1606,7 +1540,8 @@ error: static struct trace_descriptor *ctf_open_mmap_trace( struct mmap_stream_list *mmap_list, - void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, int whence), + void (*packet_seek)(struct stream_pos *pos, size_t index, + int whence), FILE *metadata_fp) { struct ctf_trace *td; @@ -1617,12 +1552,12 @@ struct trace_descriptor *ctf_open_mmap_trace( "required for mmap parsing\n"); goto error; } - if (!move_pos_slow) { - fprintf(stderr, "[error] move_pos_slow function undefined.\n"); + if (!packet_seek) { + fprintf(stderr, "[error] packet_seek function undefined.\n"); goto error; } td = g_new0(struct ctf_trace, 1); - ret = ctf_open_mmap_trace_read(td, mmap_list, move_pos_slow, metadata_fp); + ret = ctf_open_mmap_trace_read(td, mmap_list, packet_seek, metadata_fp); if (ret) goto error_free;