X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=formats%2Flttng-live%2Flttng-live-comm.c;h=842eae0840661f1b5ebf972a728e355db49a7e38;hp=f9c87221b9373b7911851d43adf80da7c1364fca;hb=7def295f1625bf793b85fb032f63f8a2925b8307;hpb=f8612f315230f2352982f4391e37f5b840af8b94 diff --git a/formats/lttng-live/lttng-live-comm.c b/formats/lttng-live/lttng-live-comm.c index f9c87221..842eae08 100644 --- a/formats/lttng-live/lttng-live-comm.c +++ b/formats/lttng-live/lttng-live-comm.c @@ -49,6 +49,8 @@ #include #include +#include + #include "lttng-live.h" #include "lttng-viewer-abi.h" @@ -66,6 +68,9 @@ static void ctf_live_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence); static void add_traces(gpointer key, gpointer value, gpointer user_data); static int del_traces(gpointer key, gpointer value, gpointer user_data); +static int get_new_metadata(struct lttng_live_ctx *ctx, + struct lttng_live_viewer_stream *viewer_stream, + char **metadata_buf); int lttng_live_connect_viewer(struct lttng_live_ctx *ctx) { @@ -123,7 +128,7 @@ int lttng_live_establish_connection(struct lttng_live_ctx *ctx) ret_len = send(ctx->control_sock, &cmd, sizeof(cmd), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending cmd\n"); + perror("[error] Error sending cmd"); ret = ret_len; goto error; } @@ -133,7 +138,7 @@ int lttng_live_establish_connection(struct lttng_live_ctx *ctx) ret_len = send(ctx->control_sock, &connect, sizeof(connect), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending version\n"); + perror("[error] Error sending version"); ret = ret_len; goto error; } @@ -148,7 +153,7 @@ int lttng_live_establish_connection(struct lttng_live_ctx *ctx) goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving version\n"); + perror("[error] Error receiving version"); ret = ret_len; goto error; } @@ -250,7 +255,7 @@ int lttng_live_list_sessions(struct lttng_live_ctx *ctx, const char *path) ret_len = send(ctx->control_sock, &cmd, sizeof(cmd), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending cmd\n"); + perror("[error] Error sending cmd"); ret = ret_len; goto error; } @@ -265,7 +270,7 @@ int lttng_live_list_sessions(struct lttng_live_ctx *ctx, const char *path) goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving session list\n"); + perror("[error] Error receiving session list"); ret = ret_len; goto error; } @@ -282,7 +287,7 @@ int lttng_live_list_sessions(struct lttng_live_ctx *ctx, const char *path) goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving session\n"); + perror("[error] Error receiving session"); ret = ret_len; goto error; } @@ -346,6 +351,22 @@ int lttng_live_ctf_trace_assign(struct lttng_live_viewer_stream *stream, return ret; } +static +int open_metadata_fp_write(struct lttng_live_viewer_stream *stream, + char **metadata_buf, size_t *size) +{ + int ret = 0; + + stream->metadata_fp_write = + babeltrace_open_memstream(metadata_buf, size); + if (!stream->metadata_fp_write) { + perror("Metadata open_memstream"); + ret = -1; + } + + return ret; +} + int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id) { struct lttng_viewer_cmd cmd; @@ -369,7 +390,7 @@ int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id) ret_len = send(ctx->control_sock, &cmd, sizeof(cmd), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending cmd\n"); + perror("[error] Error sending cmd"); ret = ret_len; goto error; } @@ -379,7 +400,7 @@ int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id) ret_len = send(ctx->control_sock, &rq, sizeof(rq), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending attach request\n"); + perror("[error] Error sending attach request"); ret = ret_len; goto error; } @@ -394,7 +415,7 @@ int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id) goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving attach response\n"); + perror("[error] Error receiving attach response"); ret = ret_len; goto error; } @@ -407,7 +428,7 @@ int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id) ret = -LTTNG_VIEWER_ATTACH_UNK; goto end; case LTTNG_VIEWER_ATTACH_ALREADY: - fprintf(stderr, "[error] Already a viewer attached\n"); + fprintf(stderr, "[error] There is already a viewer attached to this session\n"); ret = -1; goto end; case LTTNG_VIEWER_ATTACH_NOT_LIVE: @@ -453,7 +474,7 @@ int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id) goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving stream\n"); + perror("[error] Error receiving stream"); ret = ret_len; goto error; } @@ -471,35 +492,7 @@ int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id) ctx->session->streams[i].mmap_size = 0; if (be32toh(stream.metadata_flag)) { - char *path; - - path = strdup(LTTNG_METADATA_PATH_TEMPLATE); - if (!path) { - perror("strdup"); - ret = -1; - goto error; - } - if (!mkdtemp(path)) { - perror("mkdtemp"); - free(path); - ret = -1; - goto error; - } ctx->session->streams[i].metadata_flag = 1; - snprintf(ctx->session->streams[i].path, - sizeof(ctx->session->streams[i].path), - "%s/%s", path, - stream.channel_name); - ret = open(ctx->session->streams[i].path, - O_WRONLY | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (ret < 0) { - perror("open"); - free(path); - goto error; - } - ctx->session->streams[i].fd = ret; - free(path); } ret = lttng_live_ctf_trace_assign(&ctx->session->streams[i], be64toh(stream.ctf_trace_id)); @@ -553,6 +546,43 @@ end: return ret; } +static +int append_metadata(struct lttng_live_ctx *ctx, + struct lttng_live_viewer_stream *viewer_stream) +{ + int ret; + struct lttng_live_viewer_stream *metadata; + char *metadata_buf = NULL; + + printf_verbose("get_next_index: new metadata needed\n"); + ret = get_new_metadata(ctx, viewer_stream, &metadata_buf); + if (ret < 0) { + free(metadata_buf); + goto error; + } + + metadata = viewer_stream->ctf_trace->metadata_stream; + metadata->ctf_trace->metadata_fp = + babeltrace_fmemopen(metadata_buf, + metadata->metadata_len, "rb"); + if (!metadata->ctf_trace->metadata_fp) { + perror("Metadata fmemopen"); + free(metadata_buf); + ret = -1; + goto error; + } + ret = ctf_append_trace_metadata( + viewer_stream->ctf_trace->handle->td, + metadata->ctf_trace->metadata_fp); + if (ret != 0) { + fprintf(stderr, "[error] Appending metadata\n"); + goto error; + } + +error: + return ret; +} + static int get_data_packet(struct lttng_live_ctx *ctx, struct ctf_stream_pos *pos, @@ -565,6 +595,7 @@ int get_data_packet(struct lttng_live_ctx *ctx, ssize_t ret_len; int ret; +retry: cmd.cmd = htobe32(LTTNG_VIEWER_GET_PACKET); cmd.data_size = sizeof(rq); cmd.cmd_version = 0; @@ -579,7 +610,7 @@ int get_data_packet(struct lttng_live_ctx *ctx, ret_len = send(ctx->control_sock, &cmd, sizeof(cmd), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending cmd\n"); + perror("[error] Error sending cmd"); ret = ret_len; goto error; } @@ -589,7 +620,7 @@ int get_data_packet(struct lttng_live_ctx *ctx, ret_len = send(ctx->control_sock, &rq, sizeof(rq), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending get_data_packet request\n"); + perror("[error] Error sending get_data_packet request"); ret = ret_len; goto error; } @@ -604,7 +635,7 @@ int get_data_packet(struct lttng_live_ctx *ctx, goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving data response\n"); + perror("[error] Error receiving data response"); ret = ret_len; goto error; } @@ -631,8 +662,10 @@ int get_data_packet(struct lttng_live_ctx *ctx, case LTTNG_VIEWER_GET_PACKET_ERR: if (rp.flags & LTTNG_VIEWER_FLAG_NEW_METADATA) { printf_verbose("get_data_packet: new metadata needed\n"); - ret = 0; - goto end; + ret = append_metadata(ctx, stream); + if (ret) + goto error; + goto retry; } if (rp.flags & LTTNG_VIEWER_FLAG_NEW_STREAM) { ret = ask_new_streams(ctx); @@ -667,8 +700,7 @@ int get_data_packet(struct lttng_live_ctx *ctx, /* unmap old base */ ret = munmap_align(pos->base_mma); if (ret) { - fprintf(stderr, "[error] Unable to unmap old base: %s.\n", - strerror(errno)); + perror("[error] Unable to unmap old base"); ret = -1; goto error; } @@ -678,8 +710,7 @@ int get_data_packet(struct lttng_live_ctx *ctx, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (pos->base_mma == MAP_FAILED) { - fprintf(stderr, "[error] mmap error %s.\n", - strerror(errno)); + perror("[error] mmap error"); pos->base_mma = NULL; ret = -1; goto error; @@ -701,7 +732,7 @@ int get_data_packet(struct lttng_live_ctx *ctx, goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving trace packet\n"); + perror("[error] Error receiving trace packet"); ret = ret_len; goto error; } @@ -712,35 +743,28 @@ error: return ret; } -/* - * Return number of metadata bytes written or a negative value on error. - */ static -int get_new_metadata(struct lttng_live_ctx *ctx, - struct lttng_live_viewer_stream *viewer_stream, - uint64_t *metadata_len) +int get_one_metadata_packet(struct lttng_live_ctx *ctx, + struct lttng_live_viewer_stream *metadata_stream) { uint64_t len = 0; int ret; struct lttng_viewer_cmd cmd; struct lttng_viewer_get_metadata rq; struct lttng_viewer_metadata_packet rp; - struct lttng_live_viewer_stream *metadata_stream; char *data = NULL; ssize_t ret_len; + rq.stream_id = htobe64(metadata_stream->id); cmd.cmd = htobe32(LTTNG_VIEWER_GET_METADATA); cmd.data_size = sizeof(rq); cmd.cmd_version = 0; - metadata_stream = viewer_stream->ctf_trace->metadata_stream; - rq.stream_id = htobe64(metadata_stream->id); - do { ret_len = send(ctx->control_sock, &cmd, sizeof(cmd), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending cmd\n"); + perror("[error] Error sending cmd"); ret = ret_len; goto error; } @@ -750,7 +774,7 @@ int get_new_metadata(struct lttng_live_ctx *ctx, ret_len = send(ctx->control_sock, &rq, sizeof(rq), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending get_metadata request\n"); + perror("[error] Error sending get_metadata request"); ret = ret_len; goto error; } @@ -765,7 +789,7 @@ int get_new_metadata(struct lttng_live_ctx *ctx, goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving metadata response\n"); + perror("[error] Error receiving metadata response"); ret = ret_len; goto error; } @@ -777,7 +801,7 @@ int get_new_metadata(struct lttng_live_ctx *ctx, break; case LTTNG_VIEWER_NO_NEW_METADATA: printf_verbose("get_metadata : NO NEW\n"); - ret = -1; + ret = 0; goto end; case LTTNG_VIEWER_METADATA_ERR: printf_verbose("get_metadata : ERR\n"); @@ -812,7 +836,7 @@ int get_new_metadata(struct lttng_live_ctx *ctx, goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving trace packet\n"); + perror("[error] Error receiving trace packet"); ret = ret_len; free(data); goto error; @@ -820,24 +844,67 @@ int get_new_metadata(struct lttng_live_ctx *ctx, assert(ret_len == len); do { - ret_len = write(metadata_stream->fd, data, len); + ret_len = fwrite(data, 1, len, + metadata_stream->metadata_fp_write); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { + fprintf(stderr, "[error] Writing in the metadata fp\n"); free(data); ret = ret_len; goto error; } assert(ret_len == len); + metadata_stream->metadata_len += len; + ret = len; free(data); - *metadata_len = len; - ret = 0; end: error: return ret; } +/* + * Return 0 on success, a negative value on error. + */ +static +int get_new_metadata(struct lttng_live_ctx *ctx, + struct lttng_live_viewer_stream *viewer_stream, + char **metadata_buf) +{ + int ret = 0; + struct lttng_live_viewer_stream *metadata_stream; + size_t size; + + metadata_stream = viewer_stream->ctf_trace->metadata_stream; + if (!metadata_stream) { + fprintf(stderr, "[error] No metadata stream\n"); + ret = -1; + goto error; + } + metadata_stream->metadata_len = 0; + ret = open_metadata_fp_write(metadata_stream, metadata_buf, &size); + if (ret < 0) { + goto error; + } + + do { + /* + * get_one_metadata_packet returns the number of bytes + * received, 0 when we have received everything, a + * negative value on error. + */ + ret = get_one_metadata_packet(ctx, metadata_stream); + } while (ret > 0); + + if (fclose(metadata_stream->metadata_fp_write)) + perror("fclose"); + metadata_stream->metadata_fp_write = NULL; + +error: + return ret; +} + /* * Get one index for a stream. * @@ -852,7 +919,6 @@ int get_next_index(struct lttng_live_ctx *ctx, struct lttng_viewer_get_next_index rq; struct lttng_viewer_index rp; int ret; - uint64_t metadata_len; ssize_t ret_len; cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEXT_INDEX); @@ -867,7 +933,7 @@ retry: ret_len = send(ctx->control_sock, &cmd, sizeof(cmd), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending cmd\n"); + perror("[error] Error sending cmd"); ret = ret_len; goto error; } @@ -877,7 +943,7 @@ retry: ret_len = send(ctx->control_sock, &rq, sizeof(rq), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending get_next_index request\n"); + perror("[error] Error sending get_next_index request"); ret = ret_len; goto error; } @@ -892,7 +958,7 @@ retry: goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving index response\n"); + perror("[error] Error receiving index response"); ret = ret_len; goto error; } @@ -917,12 +983,9 @@ retry: index->events_discarded = be64toh(rp.events_discarded); if (rp.flags & LTTNG_VIEWER_FLAG_NEW_METADATA) { - printf_verbose("get_next_index: new metadata needed\n"); - ret = get_new_metadata(ctx, viewer_stream, - &metadata_len); - if (ret < 0) { + ret = append_metadata(ctx, viewer_stream); + if (ret) goto error; - } } if (rp.flags & LTTNG_VIEWER_FLAG_NEW_STREAM) { ret = ask_new_streams(ctx); @@ -939,7 +1002,6 @@ retry: case LTTNG_VIEWER_INDEX_HUP: printf_verbose("get_next_index: stream hung up\n"); viewer_stream->id = -1ULL; - viewer_stream->fd = -1; index->offset = EOF; ctx->session->stream_count--; break; @@ -1108,7 +1170,7 @@ int lttng_live_create_viewer_session(struct lttng_live_ctx *ctx) ret_len = send(ctx->control_sock, &cmd, sizeof(cmd), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending cmd\n"); + perror("[error] Error sending cmd"); ret = ret_len; goto error; } @@ -1123,7 +1185,7 @@ int lttng_live_create_viewer_session(struct lttng_live_ctx *ctx) goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving create session reply\n"); + perror("[error] Error receiving create session reply"); ret = ret_len; goto error; } @@ -1158,14 +1220,15 @@ int del_traces(gpointer key, gpointer value, gpointer user_data) static void add_traces(gpointer key, gpointer value, gpointer user_data) { - int i, ret, total_metadata = 0; - uint64_t metadata_len; + int i, ret; struct bt_context *bt_ctx = user_data; struct lttng_live_ctf_trace *trace = value; struct lttng_live_viewer_stream *stream; struct bt_mmap_stream *new_mmap_stream; struct bt_mmap_stream_list mmap_list; struct lttng_live_ctx *ctx = NULL; + struct bt_trace_descriptor *td; + struct bt_trace_handle *handle; /* * We don't know how many streams we will receive for a trace, so @@ -1191,15 +1254,29 @@ void add_traces(gpointer key, gpointer value, gpointer user_data) new_mmap_stream->fd = -1; bt_list_add(&new_mmap_stream->list, &mmap_list.head); } else { + char *metadata_buf = NULL; + /* Get all possible metadata before starting */ - do { - ret = get_new_metadata(ctx, stream, - &metadata_len); - if (ret == 0) { - total_metadata += metadata_len; - } - } while (ret == 0 || total_metadata == 0); - trace->metadata_fp = fopen(stream->path, "r"); + ret = get_new_metadata(ctx, stream, &metadata_buf); + if (ret) { + free(metadata_buf); + goto end_free; + } + if (!stream->metadata_len) { + fprintf(stderr, "[error] empty metadata\n"); + ret = -1; + free(metadata_buf); + goto end_free; + } + + trace->metadata_fp = babeltrace_fmemopen(metadata_buf, + stream->metadata_len, "rb"); + if (!trace->metadata_fp) { + perror("Metadata fmemopen"); + ret = -1; + free(metadata_buf); + goto end_free; + } } } @@ -1214,15 +1291,14 @@ void add_traces(gpointer key, gpointer value, gpointer user_data) fprintf(stderr, "[error] Error adding trace\n"); goto end_free; } + trace->metadata_stream->metadata_len = 0; + handle = (struct bt_trace_handle *) g_hash_table_lookup( + bt_ctx->trace_handles, + (gpointer) (unsigned long) ret); + td = handle->td; + trace->handle = handle; if (bt_ctx->current_iterator) { - struct bt_trace_descriptor *td; - struct bt_trace_handle *handle; - - handle = (struct bt_trace_handle *) g_hash_table_lookup( - bt_ctx->trace_handles, - (gpointer) (unsigned long) ret); - td = handle->td; bt_iter_add_trace(bt_ctx->current_iterator, td); } @@ -1258,7 +1334,7 @@ int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id) ret_len = send(ctx->control_sock, &cmd, sizeof(cmd), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending cmd\n"); + perror("[error] Error sending cmd"); ret = ret_len; goto error; } @@ -1268,7 +1344,7 @@ int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id) ret_len = send(ctx->control_sock, &rq, sizeof(rq), 0); } while (ret_len < 0 && errno == EINTR); if (ret_len < 0) { - fprintf(stderr, "[error] Error sending get_new_streams request\n"); + perror("[error] Error sending get_new_streams request"); ret = ret_len; goto error; } @@ -1283,7 +1359,7 @@ int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id) goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving get_new_streams response\n"); + perror("[error] Error receiving get_new_streams response"); ret = ret_len; goto error; } @@ -1334,7 +1410,7 @@ int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id) goto error; } if (ret_len < 0) { - fprintf(stderr, "[error] Error receiving stream\n"); + perror("[error] Error receiving stream"); ret = ret_len; goto error; } @@ -1352,35 +1428,7 @@ int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id) ctx->session->streams[i].mmap_size = 0; if (be32toh(stream.metadata_flag)) { - char *path; - - path = strdup(LTTNG_METADATA_PATH_TEMPLATE); - if (!path) { - perror("strdup"); - ret = -1; - goto error; - } - if (!mkdtemp(path)) { - perror("mkdtemp"); - free(path); - ret = -1; - goto error; - } ctx->session->streams[i].metadata_flag = 1; - snprintf(ctx->session->streams[i].path, - sizeof(ctx->session->streams[i].path), - "%s/%s", path, - stream.channel_name); - ret = open(ctx->session->streams[i].path, - O_WRONLY | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (ret < 0) { - perror("open"); - free(path); - goto error; - } - ctx->session->streams[i].fd = ret; - free(path); } ret = lttng_live_ctf_trace_assign(&ctx->session->streams[i], be64toh(stream.ctf_trace_id));