X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Flttng-live%2Flttng-live-comm.c;h=b61371fc5dba65523eb46f5f1e69b391d2103990;hb=8817e4924b6a74512413556b808373683934ea82;hp=ec0a0123ecda35c7f3a19fe4c0f89e73285b048c;hpb=b5e7994d62027cadcb2fb1b1f43c191f269b5e3f;p=babeltrace.git diff --git a/formats/lttng-live/lttng-live-comm.c b/formats/lttng-live/lttng-live-comm.c index ec0a0123..b61371fc 100644 --- a/formats/lttng-live/lttng-live-comm.c +++ b/formats/lttng-live/lttng-live-comm.c @@ -390,7 +390,8 @@ int lttng_live_ctf_trace_assign(struct lttng_live_viewer_stream *stream, if (!trace) { trace = g_new0(struct lttng_live_ctf_trace, 1); trace->ctf_trace_id = ctf_trace_id; - trace->streams = g_ptr_array_new(); + printf_verbose("Create trace ctf_trace_id %" PRIu64 "\n", ctf_trace_id); + BT_INIT_LIST_HEAD(&trace->stream_list); g_hash_table_insert(stream->session->ctf_traces, &trace->ctf_trace_id, trace); @@ -398,8 +399,10 @@ int lttng_live_ctf_trace_assign(struct lttng_live_viewer_stream *stream, if (stream->metadata_flag) trace->metadata_stream = stream; + assert(!stream->in_trace); + stream->in_trace = 1; stream->ctf_trace = trace; - g_ptr_array_add(trace->streams, stream); + bt_list_add(&stream->trace_stream_node, &trace->stream_list); return ret; } @@ -546,7 +549,7 @@ int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id) g_free(lvstream); goto error; } - bt_list_add(&lvstream->stream_node, + bt_list_add(&lvstream->session_stream_node, &ctx->session->stream_list); } ret = 0; @@ -842,6 +845,9 @@ int get_one_metadata_packet(struct lttng_live_ctx *ctx, memcpy(cmd_buf, &cmd, sizeof(cmd)); memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + printf_verbose("get_metadata for trace_id: %d, ctf_trace_id: %" PRIu64 "\n", + metadata_stream->ctf_trace->trace_id, + metadata_stream->ctf_trace->ctf_trace_id); ret_len = lttng_live_send(ctx->control_sock, cmd_buf, cmd_buf_len); if (ret_len < 0) { perror("[error] Error sending get_metadata cmd and request"); @@ -1095,10 +1101,14 @@ retry: goto retry; case LTTNG_VIEWER_INDEX_HUP: printf_verbose("get_next_index: stream hung up\n"); - /* TODO: remove stream from session list and trace ptr array */ viewer_stream->id = -1ULL; index->offset = EOF; ctx->session->stream_count--; + viewer_stream->in_trace = 0; + bt_list_del(&viewer_stream->trace_stream_node); + bt_list_del(&viewer_stream->session_stream_node); + g_free(viewer_stream); + *stream_id = be64toh(rp->stream_id); break; case LTTNG_VIEWER_INDEX_ERR: fprintf(stderr, "[error] get_next_index: error\n"); @@ -1439,10 +1449,22 @@ int del_traces(gpointer key, gpointer value, gpointer user_data) struct bt_context *bt_ctx = user_data; struct lttng_live_ctf_trace *trace = value; int ret; + struct lttng_live_viewer_stream *lvstream, *tmp; - ret = bt_context_remove_trace(bt_ctx, trace->trace_id); - if (ret < 0) - fprintf(stderr, "[error] removing trace from context\n"); + /* + * We don't have ownership of the live viewer stream, just + * remove them from our list. + */ + bt_list_for_each_entry_safe(lvstream, tmp, &trace->stream_list, + trace_stream_node) { + lvstream->in_trace = 0; + bt_list_del(&lvstream->trace_stream_node); + } + if (trace->in_use) { + ret = bt_context_remove_trace(bt_ctx, trace->trace_id); + if (ret < 0) + fprintf(stderr, "[error] removing trace from context\n"); + } /* remove the key/value pair from the HT. */ return 1; @@ -1452,7 +1474,7 @@ static int add_one_trace(struct lttng_live_ctx *ctx, struct lttng_live_ctf_trace *trace) { - int i, ret; + int ret; struct bt_context *bt_ctx = ctx->bt_ctx; struct lttng_live_viewer_stream *stream; struct bt_mmap_stream *new_mmap_stream; @@ -1460,6 +1482,9 @@ int add_one_trace(struct lttng_live_ctx *ctx, struct bt_trace_descriptor *td; struct bt_trace_handle *handle; + printf_verbose("Add one trace ctf_trace_id: %" PRIu64 + " (metadata_stream: %p)\n", + trace->ctf_trace_id, trace->metadata_stream); /* * We don't know how many streams we will receive for a trace, so * once we are done receiving the traces, we add all the traces @@ -1470,15 +1495,14 @@ int add_one_trace(struct lttng_live_ctx *ctx, * If a trace is already in the context, we just skip this function. */ if (trace->in_use) { + printf_verbose("Trace already in use\n"); ret = 0; goto end; } BT_INIT_LIST_HEAD(&mmap_list.head); - for (i = 0; i < trace->streams->len; i++) { - stream = g_ptr_array_index(trace->streams, i); - + bt_list_for_each_entry(stream, &trace->stream_list, trace_stream_node) { if (!stream->metadata_flag) { new_mmap_stream = zmalloc(sizeof(struct bt_mmap_stream)); new_mmap_stream->priv = (void *) stream; @@ -1500,6 +1524,7 @@ int add_one_trace(struct lttng_live_ctx *ctx, goto end_free; } + printf_verbose("Metadata stream found\n"); trace->metadata_fp = babeltrace_fmemopen(metadata_buf, stream->metadata_len, "rb"); if (!trace->metadata_fp) { @@ -1537,6 +1562,7 @@ int add_one_trace(struct lttng_live_ctx *ctx, trace->trace_id = ret; trace->in_use = 1; + printf_verbose("Trace now in use, id = %d\n", trace->trace_id); goto end; @@ -1546,6 +1572,56 @@ end: return ret; } +/* + * Make sure all the traces we know have a metadata stream or loop on + * ask_new_streams until it is done. This must be called before we call + * add_one_trace. + * + * Return 0 when all known traces have a metadata stream, a negative value + * on error. + */ +static +int check_traces_metadata(struct lttng_live_ctx *ctx) +{ + int ret; + struct lttng_live_ctf_trace *trace; + GHashTableIter it; + gpointer key; + gpointer value; + +retry: + g_hash_table_iter_init(&it, ctx->session->ctf_traces); + while (g_hash_table_iter_next(&it, &key, &value)) { + trace = (struct lttng_live_ctf_trace *) value; + printf_verbose("Check trace %" PRIu64 " metadata\n", trace->ctf_trace_id); + while (!trace->metadata_stream) { + printf_verbose("Waiting for metadata stream\n"); + if (lttng_live_should_quit()) { + ret = 0; + goto end; + } + ret = ask_new_streams(ctx); + if (ret < 0) { + goto end; + } else if (ret == 0) { + (void) poll(NULL, 0, ACTIVE_POLL_DELAY); + } else { + /* + * If ask_new_stream got streams from a trace we did not know + * about until now, we have to reinitialize the iterator. + */ + goto retry; + } + } + } + + ret = 0; + +end: + printf_verbose("End check traces metadata\n"); + return ret; +} + static int add_traces(struct lttng_live_ctx *ctx) { @@ -1555,6 +1631,13 @@ int add_traces(struct lttng_live_ctx *ctx) gpointer key; gpointer value; + printf_verbose("Begin add traces\n"); + + ret = check_traces_metadata(ctx); + if (ret < 0) { + goto end; + } + g_hash_table_iter_init(&it, ctx->session->ctf_traces); while (g_hash_table_iter_next(&it, &key, &value)) { trace = (struct lttng_live_ctf_trace *) value; @@ -1567,6 +1650,7 @@ int add_traces(struct lttng_live_ctx *ctx) ret = 0; end: + printf_verbose("End add traces\n"); return ret; } @@ -1694,7 +1778,7 @@ int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id) goto error; } nb_streams++; - bt_list_add(&lvstream->stream_node, + bt_list_add(&lvstream->session_stream_node, &ctx->session->stream_list); } ret = nb_streams; @@ -1726,7 +1810,7 @@ int lttng_live_read(struct lttng_live_ctx *ctx) fmt_write = bt_lookup_format(g_quark_from_static_string("text")); if (!fmt_write) { fprintf(stderr, "[error] ctf-text error\n"); - goto end; + goto end_free; } td_write = fmt_write->open_trace(NULL, O_RDWR, NULL, NULL); @@ -1796,10 +1880,10 @@ int lttng_live_read(struct lttng_live_ctx *ctx) if (!iter) { if (lttng_live_should_quit()) { ret = 0; - goto end; + goto end_free; } fprintf(stderr, "[error] Iterator creation error\n"); - goto end; + goto end_free; } for (;;) { if (lttng_live_should_quit()) { @@ -1832,6 +1916,8 @@ int lttng_live_read(struct lttng_live_ctx *ctx) } end_free: + g_hash_table_foreach_remove(ctx->session->ctf_traces, + del_traces, ctx->bt_ctx); bt_context_put(ctx->bt_ctx); end: if (lttng_live_should_quit()) {