This set of functions allows a client to open a trace that is not stored on tracefiles but instead is in memory. Since the parameters required for such an operation are really different than typical traces, we define the open_mmap_trace function. This patch also introduces the mmap_subbuf_info structure that represents a list of FDs readable by mmap.
Signed-off-by: Julien Desfossez <[email protected]> --- formats/ctf/ctf.c | 158 +++++++++++++++++++++++++++++++++++++++++++ include/babeltrace/format.h | 13 ++++ 2 files changed, 171 insertions(+), 0 deletions(-) diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index f9f9e47..81152a2 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -59,6 +59,12 @@ struct trace_descriptor *ctf_open_trace(const char *path, int flags, void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, int whence), FILE *metadata_fp); static +struct trace_descriptor *ctf_open_mmap_trace( + struct mmap_subbuf_info_list *mmap_list, + void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, int whence), + FILE *metadata_fp); + +static void ctf_close_trace(struct trace_descriptor *descriptor); static @@ -88,6 +94,7 @@ rw_dispatch write_dispatch_table[] = { static struct format ctf_format = { .open_trace = ctf_open_trace, + .open_mmap_trace = ctf_open_mmap_trace, .close_trace = ctf_close_trace, }; @@ -1256,6 +1263,157 @@ error: return NULL; } + +void ctf_init_mmap_pos(struct ctf_stream_pos *pos, + struct mmap_subbuf_info *mmap_info) +{ + pos->mmap_offset = 0; + pos->packet_size = 0; + pos->content_size = 0; + pos->content_size_loc = NULL; + pos->fd = mmap_info->fd; + pos->base = 0; + pos->offset = 0; + pos->dummy = false; + pos->cur_index = 0; + pos->packet_index = NULL; + pos->prot = PROT_READ; + pos->flags = MAP_PRIVATE; + pos->parent.rw_table = read_dispatch_table; + pos->parent.event_cb = ctf_read_event; +} + +/* FIXME : function name, not really index */ +static +int create_stream_mmap_packet_index(struct ctf_trace *td, + struct ctf_file_stream *file_stream) +{ + struct ctf_stream_class *stream; + uint64_t stream_id = 0; + int ret; + + file_stream->parent.stream_id = stream_id; + if (stream_id >= td->streams->len) { + fprintf(stdout, "[error] Stream %" PRIu64 " is not declared " + "in metadata.\n", stream_id); + ret = -EINVAL; + goto end; + } + stream = g_ptr_array_index(td->streams, stream_id); + if (!stream) { + fprintf(stdout, "[error] Stream %" PRIu64 " is not declared " + "in metadata.\n", stream_id); + ret = -EINVAL; + goto end; + } + file_stream->parent.stream_class = stream; + ret = create_stream_definitions(td, &file_stream->parent); + +end: + return ret; +} + +static +int ctf_open_mmap_stream_read(struct ctf_trace *td, + struct mmap_subbuf_info *mmap_info, + void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, + int whence)) +{ + int ret; + struct ctf_file_stream *file_stream; + + 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; + + ret = create_trace_definitions(td, &file_stream->parent); + if (ret) { + goto error_def; + } + + ret = create_stream_mmap_packet_index(td, file_stream); + if (ret) + goto error_index; + + /* Add stream file to stream class */ + g_ptr_array_add(file_stream->parent.stream_class->streams, + &file_stream->parent); + return 0; + +error_index: + if (file_stream->parent.trace_packet_header) + definition_unref(&file_stream->parent.trace_packet_header->p); +error_def: + g_free(file_stream); + return ret; +} + +int ctf_open_mmap_trace_read(struct ctf_trace *td, + struct mmap_subbuf_info_list *mmap_list, + void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, + int whence), + FILE *metadata_fp) +{ + int ret; + struct mmap_subbuf_info *mmap_info; + + ret = ctf_open_trace_metadata_read(td, ctf_move_pos_slow, metadata_fp); + if (ret) { + goto error; + } + + /* + * 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); + if (ret) { + fprintf(stdout, "[error] Open file mmap stream error.\n"); + goto error; + } + } + + return 0; + +error: + return ret; +} + +static +struct trace_descriptor *ctf_open_mmap_trace( + struct mmap_subbuf_info_list *mmap_list, + void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, int whence), + FILE *metadata_fp) +{ + struct ctf_trace *td; + int ret; + + td = g_new0(struct ctf_trace, 1); + + if (!metadata_fp) { + fprintf(stderr, "[error] No metadata file pointer associated, " + "required for mmap parsing\n"); + goto error; + } + + if (!move_pos_slow) { + fprintf(stderr, "[error] move_pos_slow function undefined.\n"); + goto error; + } + + ret = ctf_open_mmap_trace_read(td, mmap_list, move_pos_slow, metadata_fp); + if (ret) + goto error; + + return &td->parent; +error: + g_free(td); + return NULL; +} + + static void ctf_close_file_stream(struct ctf_file_stream *file_stream) { diff --git a/include/babeltrace/format.h b/include/babeltrace/format.h index 5b2f694..f54b253 100644 --- a/include/babeltrace/format.h +++ b/include/babeltrace/format.h @@ -31,12 +31,25 @@ struct trace_descriptor { }; +struct mmap_subbuf_info { + int fd; + struct cds_list_head list; +}; + +struct mmap_subbuf_info_list { + struct cds_list_head head; +}; + struct format { GQuark name; struct trace_descriptor *(*open_trace)(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 *(*open_mmap_trace)( + struct mmap_subbuf_info_list *mmap_list, + void (*move_pos_slow)(struct ctf_stream_pos *pos, size_t offset, + int whence), FILE *metadata_fp); void (*close_trace)(struct trace_descriptor *descriptor); }; -- 1.7.5.4 _______________________________________________ ltt-dev mailing list [email protected] http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
