X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fctf.c;h=c503eca1a6879753cf741487556708562ca10a7a;hb=f0c3ee5976ee0ebf89c9e9e81cc0803b736ddc87;hp=515bbe1a2c256aea19efefc3c1af9bfe35ac82d9;hpb=b5a1fa45f7cfaccf73b21712047775ab8f957bb0;p=babeltrace.git diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index 515bbe1a..c503eca1 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -887,9 +887,12 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence) return; } assert(pos->cur_index < pos->packet_index->len); - if (index > 0) { + packet_index = &g_array_index(pos->packet_index, + struct packet_index, pos->cur_index); + if (pos->cur_index > 0) { prev_index = &g_array_index(pos->packet_index, - struct packet_index, index - 1); + struct packet_index, + pos->cur_index - 1); } ctf_update_current_packet_index(&file_stream->parent, prev_index, packet_index); @@ -1046,7 +1049,7 @@ warning: } static -int ctf_open_trace_metadata_packet_read(struct ctf_trace *td, FILE *in, +int ctf_trace_metadata_packet_read(struct ctf_trace *td, FILE *in, FILE *out) { struct metadata_packet_header header; @@ -1136,7 +1139,7 @@ read_padding: } static -int ctf_open_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp, +int ctf_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp, char **buf) { FILE *in, *out; @@ -1155,7 +1158,7 @@ int ctf_open_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp, return -errno; } for (;;) { - ret = ctf_open_trace_metadata_packet_read(td, in, out); + ret = ctf_trace_metadata_packet_read(td, in, out); if (ret) { break; } @@ -1196,11 +1199,9 @@ 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 (*packet_seek)(struct bt_stream_pos *pos, size_t index, - int whence), FILE *metadata_fp) +int ctf_trace_metadata_read(struct ctf_trace *td, FILE *metadata_fp, + struct ctf_scanner *scanner, int append) { - struct ctf_scanner *scanner; struct ctf_file_stream *metadata_stream; FILE *fp; char *buf = NULL; @@ -1209,14 +1210,6 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, metadata_stream = g_new0(struct ctf_file_stream, 1); metadata_stream->pos.last_offset = LAST_OFFSET_POISON; - if (packet_seek) { - metadata_stream->pos.packet_seek = packet_seek; - } else { - fprintf(stderr, "[error] packet_seek function undefined.\n"); - ret = -1; - goto end_free; - } - if (metadata_fp) { fp = metadata_fp; metadata_stream->pos.fd = -1; @@ -1243,38 +1236,34 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, yydebug = 1; if (packet_metadata(td, fp)) { - ret = ctf_open_trace_metadata_stream_read(td, &fp, &buf); + ret = ctf_trace_metadata_stream_read(td, &fp, &buf); if (ret) { /* Warn about empty metadata */ fprintf(stderr, "[warning] Empty metadata.\n"); - goto end_packet_read; + goto end; } td->metadata_string = buf; td->metadata_packetized = 1; } else { - unsigned int major, minor; - ssize_t nr_items; - - td->byte_order = BYTE_ORDER; - - /* Check text-only metadata header and version */ - nr_items = fscanf(fp, "/* CTF %u.%u", &major, &minor); - if (nr_items < 2) - fprintf(stderr, "[warning] Ill-shapen or missing \"/* CTF x.y\" header for text-only metadata.\n"); - if (check_version(major, minor) < 0) { - ret = -EINVAL; - goto end_packet_read; + if (!append) { + unsigned int major, minor; + ssize_t nr_items; + + td->byte_order = BYTE_ORDER; + + /* Check text-only metadata header and version */ + nr_items = fscanf(fp, "/* CTF %10u.%10u", &major, &minor); + if (nr_items < 2) + fprintf(stderr, "[warning] Ill-shapen or missing \"/* CTF x.y\" header for text-only metadata.\n"); + if (check_version(major, minor) < 0) { + ret = -EINVAL; + goto end; + } + rewind(fp); } - rewind(fp); } - scanner = ctf_scanner_alloc(fp); - if (!scanner) { - fprintf(stderr, "[error] Error allocating scanner\n"); - ret = -ENOMEM; - goto end_scanner_alloc; - } - ret = ctf_scanner_append_ast(scanner); + ret = ctf_scanner_append_ast(scanner, fp); if (ret) { fprintf(stderr, "[error] Error creating AST\n"); goto end; @@ -1300,9 +1289,6 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, goto end; } end: - ctf_scanner_free(scanner); -end_scanner_alloc: -end_packet_read: if (fp) { closeret = fclose(fp); if (closeret) { @@ -1364,6 +1350,36 @@ error: return NULL; } +static +int copy_event_declarations_stream_class_to_stream(struct ctf_trace *td, + struct ctf_stream_declaration *stream_class, + struct ctf_stream_definition *stream) +{ + size_t def_size, class_size, i; + int ret = 0; + + def_size = stream->events_by_id->len; + class_size = stream_class->events_by_id->len; + + g_ptr_array_set_size(stream->events_by_id, class_size); + for (i = def_size; i < class_size; i++) { + struct ctf_event_declaration *event = + g_ptr_array_index(stream_class->events_by_id, i); + struct ctf_event_definition *stream_event; + + if (!event) + continue; + stream_event = create_event_definitions(td, stream, event); + if (!stream_event) { + ret = -EINVAL; + goto error; + } + g_ptr_array_index(stream->events_by_id, i) = stream_event; + } +error: + return ret; +} + static int create_stream_definitions(struct ctf_trace *td, struct ctf_stream_definition *stream) { @@ -1413,20 +1429,10 @@ int create_stream_definitions(struct ctf_trace *td, struct ctf_stream_definition stream->parent_def_scope = stream->stream_event_context->p.scope; } stream->events_by_id = g_ptr_array_new(); - g_ptr_array_set_size(stream->events_by_id, stream_class->events_by_id->len); - for (i = 0; i < stream->events_by_id->len; i++) { - struct ctf_event_declaration *event = g_ptr_array_index(stream_class->events_by_id, i); - struct ctf_event_definition *stream_event; - - if (!event) - continue; - stream_event = create_event_definitions(td, stream, event); - if (!stream_event) { - ret = -EINVAL; - goto error_event; - } - g_ptr_array_index(stream->events_by_id, i) = stream_event; - } + ret = copy_event_declarations_stream_class_to_stream(td, + stream_class, stream); + if (ret) + goto error_event; return 0; error_event: @@ -1808,9 +1814,8 @@ static int import_stream_packet_index(struct ctf_trace *td, struct ctf_file_stream *file_stream) { - struct ctf_stream_declaration *stream; struct ctf_stream_pos *pos; - struct ctf_packet_index ctf_index; + struct ctf_packet_index *ctf_index = NULL; struct ctf_packet_index_file_hdr index_hdr; struct packet_index index; int ret = 0; @@ -1845,21 +1850,26 @@ int import_stream_packet_index(struct ctf_trace *td, ret = -1; goto error; } - - while (fread(&ctf_index, index_hdr.packet_index_len, 1, + /* + * Allocate the index length found in header, not internal + * representation. + */ + ctf_index = g_malloc0(index_hdr.packet_index_len); + while (fread(ctf_index, index_hdr.packet_index_len, 1, pos->index_fp) == 1) { uint64_t stream_id; + struct ctf_stream_declaration *stream = NULL; memset(&index, 0, sizeof(index)); - index.offset = be64toh(ctf_index.offset); - index.packet_size = be64toh(ctf_index.packet_size); - index.content_size = be64toh(ctf_index.content_size); - index.ts_cycles.timestamp_begin = be64toh(ctf_index.timestamp_begin); - index.ts_cycles.timestamp_end = be64toh(ctf_index.timestamp_end); - index.events_discarded = be64toh(ctf_index.events_discarded); + index.offset = be64toh(ctf_index->offset); + index.packet_size = be64toh(ctf_index->packet_size); + index.content_size = be64toh(ctf_index->content_size); + index.ts_cycles.timestamp_begin = be64toh(ctf_index->timestamp_begin); + index.ts_cycles.timestamp_end = be64toh(ctf_index->timestamp_end); + index.events_discarded = be64toh(ctf_index->events_discarded); index.events_discarded_len = 64; index.data_offset = -1; - stream_id = be64toh(ctf_index.stream_id); + stream_id = be64toh(ctf_index->stream_id); if (!first_packet) { /* add index to packet array */ @@ -1868,7 +1878,9 @@ int import_stream_packet_index(struct ctf_trace *td, } file_stream->parent.stream_id = stream_id; - stream = g_ptr_array_index(td->streams, stream_id); + if (stream_id < td->streams->len) { + stream = g_ptr_array_index(td->streams, stream_id); + } if (!stream) { fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", @@ -1894,6 +1906,7 @@ int import_stream_packet_index(struct ctf_trace *td, ret = 0; error: + g_free(ctf_index); return ret; } @@ -2040,6 +2053,7 @@ int ctf_open_trace_read(struct ctf_trace *td, void (*packet_seek)(struct bt_stream_pos *pos, size_t index, int whence), FILE *metadata_fp) { + struct ctf_scanner *scanner; int ret, closeret; struct dirent *dirent; struct dirent *diriter; @@ -2068,9 +2082,17 @@ int ctf_open_trace_read(struct ctf_trace *td, /* * Keep the metadata file separate. + * Keep scanner object local to the open. We don't support + * incremental metadata append for on-disk traces. */ - - ret = ctf_open_trace_metadata_read(td, packet_seek, metadata_fp); + scanner = ctf_scanner_alloc(); + if (!scanner) { + fprintf(stderr, "[error] Error allocating scanner\n"); + ret = -ENOMEM; + goto error_metadata; + } + ret = ctf_trace_metadata_read(td, metadata_fp, scanner, 0); + ctf_scanner_free(scanner); if (ret) { fprintf(stderr, "[warning] Unable to open trace metadata for path \"%s\".\n", path); goto error_metadata; @@ -2281,7 +2303,13 @@ int ctf_open_mmap_trace_read(struct ctf_trace *td, int ret; struct bt_mmap_stream *mmap_info; - ret = ctf_open_trace_metadata_read(td, ctf_packet_seek, metadata_fp); + td->scanner = ctf_scanner_alloc(); + if (!td->scanner) { + fprintf(stderr, "[error] Error allocating scanner\n"); + ret = -ENOMEM; + goto error; + } + ret = ctf_trace_metadata_read(td, metadata_fp, td->scanner, 0); if (ret) { goto error; } @@ -2297,10 +2325,10 @@ int ctf_open_mmap_trace_read(struct ctf_trace *td, goto error; } } - return 0; error: + ctf_scanner_free(td->scanner); return ret; } @@ -2337,6 +2365,41 @@ error: return NULL; } +int ctf_append_trace_metadata(struct bt_trace_descriptor *tdp, + FILE *metadata_fp) +{ + struct ctf_trace *td = container_of(tdp, struct ctf_trace, parent); + int i, j; + int ret; + + if (!td->scanner) + return -EINVAL; + ret = ctf_trace_metadata_read(td, metadata_fp, td->scanner, 1); + if (ret) + return ret; + /* for each stream_class */ + for (i = 0; i < td->streams->len; i++) { + struct ctf_stream_declaration *stream_class; + + stream_class = g_ptr_array_index(td->streams, i); + if (!stream_class) + continue; + /* for each stream */ + for (j = 0; j < stream_class->streams->len; j++) { + struct ctf_stream_definition *stream; + + stream = g_ptr_array_index(stream_class->streams, j); + if (!stream) + continue; + ret = copy_event_declarations_stream_class_to_stream(td, + stream_class, stream); + if (ret) + return ret; + } + } + return 0; +} + static int ctf_convert_index_timestamp(struct bt_trace_descriptor *tdp) { @@ -2429,6 +2492,7 @@ int ctf_close_trace(struct bt_trace_descriptor *tdp) } } ctf_destroy_metadata(td); + ctf_scanner_free(td->scanner); if (td->dirfd >= 0) { ret = close(td->dirfd); if (ret) {