ctf.fs: bt_ctf_notif_iter_create(): assert() that all medops exist
[babeltrace.git] / formats / lttng-live / lttng-live-comm.c
index a3a02a2cc19ad1bc9741b8340d83fb92978136f6..6c5d4fd296f55fc9f23f4bba506432c3889f367c 100644 (file)
 #include <netinet/in.h>
 #include <netdb.h>
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <fcntl.h>
-#include <sys/mman.h>
 #include <poll.h>
 
 #include <babeltrace/ctf/ctf-index.h>
 
 #include <babeltrace/endian.h>
 #include <babeltrace/compat/memstream.h>
+#include <babeltrace/compat/send.h>
+#include <babeltrace/compat/string.h>
+#include <babeltrace/compat/mman.h>
+#include <babeltrace/babeltrace-internal.h>
 
 #include "lttng-live.h"
 #include "lttng-viewer-abi.h"
 
 #define ACTIVE_POLL_DELAY      100     /* ms */
 
-/*
- * Memory allocation zeroed
- */
-#define zmalloc(x) calloc(1, x)
-
-#ifndef max_t
-#define max_t(type, a, b)      \
-       ((type) (a) > (type) (b) ? (type) (a) : (type) (b))
-#endif
-
 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 add_traces(struct lttng_live_ctx *ctx);
 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,
@@ -103,7 +95,7 @@ ssize_t lttng_live_send(int fd, const void *buf, size_t len)
        ssize_t ret;
 
        do {
-               ret = send(fd, buf, len, MSG_NOSIGNAL);
+               ret = bt_send_nosigpipe(fd, buf, len);
        } while (ret < 0 && errno == EINTR);
        return ret;
 }
@@ -134,7 +126,7 @@ int lttng_live_connect_viewer(struct lttng_live_ctx *ctx)
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(ctx->port);
        server_addr.sin_addr = *((struct in_addr *) host->h_addr);
-       bzero(&(server_addr.sin_zero), 8);
+       memset(&(server_addr.sin_zero), 0, 8);
 
        if (connect(ctx->control_sock, (struct sockaddr *) &server_addr,
                                sizeof(struct sockaddr)) == -1) {
@@ -165,8 +157,8 @@ int lttng_live_establish_connection(struct lttng_live_ctx *ctx)
        }
 
        cmd.cmd = htobe32(LTTNG_VIEWER_CONNECT);
-       cmd.data_size = sizeof(connect);
-       cmd.cmd_version = 0;
+       cmd.data_size = htobe64((uint64_t) sizeof(connect));
+       cmd.cmd_version = htobe32(0);
 
        connect.viewer_session_id = -1ULL;      /* will be set on recv */
        connect.major = htobe32(LTTNG_LIVE_MAJOR);
@@ -245,7 +237,7 @@ void print_session_list(GPtrArray *session_list, const char *path)
 
        for (i = 0; i < session_list->len; i++) {
                relay_session = g_ptr_array_index(session_list, i);
-               fprintf(stdout, "%s/host/%s/%s (timer = %u, "
+               fprintf(LTTNG_LIVE_OUTPUT_FP, "%s/host/%s/%s (timer = %u, "
                                "%u stream(s), %u client(s) connected)\n",
                                path, relay_session->hostname,
                                relay_session->name, relay_session->timer,
@@ -263,9 +255,9 @@ void update_session_list(GPtrArray *session_list, char *hostname,
 
        for (i = 0; i < session_list->len; i++) {
                relay_session = g_ptr_array_index(session_list, i);
-               if ((strncmp(relay_session->hostname, hostname, NAME_MAX) == 0) &&
+               if ((strncmp(relay_session->hostname, hostname, MAXNAMLEN) == 0) &&
                                strncmp(relay_session->name,
-                                       session_name, NAME_MAX) == 0) {
+                                       session_name, MAXNAMLEN) == 0) {
                        relay_session->streams += streams;
                        if (relay_session->clients < clients)
                                relay_session->clients = clients;
@@ -277,8 +269,8 @@ void update_session_list(GPtrArray *session_list, char *hostname,
                return;
 
        relay_session = g_new0(struct lttng_live_relay_session, 1);
-       relay_session->hostname = strndup(hostname, NAME_MAX);
-       relay_session->name = strndup(session_name, NAME_MAX);
+       relay_session->hostname = bt_strndup(hostname, MAXNAMLEN);
+       relay_session->name = bt_strndup(session_name, MAXNAMLEN);
        relay_session->clients = clients;
        relay_session->streams = streams;
        relay_session->timer = timer;
@@ -306,8 +298,8 @@ int lttng_live_list_sessions(struct lttng_live_ctx *ctx, const char *path)
        }
 
        cmd.cmd = htobe32(LTTNG_VIEWER_LIST_SESSIONS);
-       cmd.data_size = 0;
-       cmd.cmd_version = 0;
+       cmd.data_size = htobe64((uint64_t) 0);
+       cmd.cmd_version = htobe32(0);
 
        ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
        if (ret_len < 0) {
@@ -352,8 +344,8 @@ int lttng_live_list_sessions(struct lttng_live_ctx *ctx, const char *path)
                                        be32toh(lsession.live_timer));
                } else {
                        if ((strncmp(lsession.session_name, ctx->session_name,
-                               NAME_MAX) == 0) && (strncmp(lsession.hostname,
-                                       ctx->traced_hostname, NAME_MAX) == 0)) {
+                               MAXNAMLEN) == 0) && (strncmp(lsession.hostname,
+                                       ctx->traced_hostname, MAXNAMLEN) == 0)) {
                                printf_verbose("Reading from session %" PRIu64 "\n",
                                                session_id);
                                g_array_append_val(ctx->session_ids,
@@ -382,13 +374,13 @@ int lttng_live_ctf_trace_assign(struct lttng_live_viewer_stream *stream,
        int ret = 0;
 
        trace = g_hash_table_lookup(stream->session->ctf_traces,
-                       (gpointer) ctf_trace_id);
+                       &ctf_trace_id);
        if (!trace) {
                trace = g_new0(struct lttng_live_ctf_trace, 1);
                trace->ctf_trace_id = ctf_trace_id;
                trace->streams = g_ptr_array_new();
                g_hash_table_insert(stream->session->ctf_traces,
-                               (gpointer) ctf_trace_id,
+                               &trace->ctf_trace_id,
                                trace);
        }
        if (stream->metadata_flag)
@@ -407,7 +399,7 @@ int open_metadata_fp_write(struct lttng_live_viewer_stream *stream,
        int ret = 0;
 
        stream->metadata_fp_write =
-               babeltrace_open_memstream(metadata_buf, size);
+               bt_open_memstream(metadata_buf, size);
        if (!stream->metadata_fp_write) {
                perror("Metadata open_memstream");
                ret = -1;
@@ -431,8 +423,8 @@ int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id)
        }
 
        cmd.cmd = htobe32(LTTNG_VIEWER_ATTACH_SESSION);
-       cmd.data_size = sizeof(rq);
-       cmd.cmd_version = 0;
+       cmd.data_size = htobe64((uint64_t) sizeof(rq));
+       cmd.cmd_version = htobe32(0);
 
        memset(&rq, 0, sizeof(rq));
        rq.session_id = htobe64(id);
@@ -609,7 +601,7 @@ int append_metadata(struct lttng_live_ctx *ctx,
 
        metadata = viewer_stream->ctf_trace->metadata_stream;
        metadata->ctf_trace->metadata_fp =
-               babeltrace_fmemopen(metadata_buf,
+               bt_fmemopen(metadata_buf,
                                metadata->metadata_len, "rb");
        if (!metadata->ctf_trace->metadata_fp) {
                perror("Metadata fmemopen");
@@ -648,9 +640,10 @@ retry:
                ret = -1;
                goto end;
        }
+
        cmd.cmd = htobe32(LTTNG_VIEWER_GET_PACKET);
-       cmd.data_size = sizeof(rq);
-       cmd.cmd_version = 0;
+       cmd.data_size = htobe64((uint64_t) sizeof(rq));
+       cmd.cmd_version = htobe32(0);
 
        memset(&rq, 0, sizeof(rq));
        rq.stream_id = htobe64(stream->id);
@@ -681,8 +674,8 @@ retry:
                goto error;
        }
        if (ret_len != sizeof(rp)) {
-               fprintf(stderr, "[error] get_data_packet: expected %" PRId64
-                               ", received %" PRId64 "\n", sizeof(rp),
+               fprintf(stderr, "[error] get_data_packet: expected %zu"
+                               ", received %zd\n", sizeof(rp),
                                ret_len);
                goto error;
        }
@@ -709,11 +702,14 @@ retry:
                if (rp.flags & LTTNG_VIEWER_FLAG_NEW_STREAM) {
                        printf_verbose("get_data_packet: new streams needed\n");
                        ret = ask_new_streams(ctx);
-                       if (ret < 0)
+                       if (ret < 0) {
                                goto error;
-                       else if (ret > 0)
-                               g_hash_table_foreach(ctx->session->ctf_traces,
-                                               add_traces, ctx->bt_ctx);
+                       } else if (ret > 0) {
+                               ret = add_traces(ctx);
+                               if (ret < 0) {
+                                       goto error;
+                               }
+                       }
                }
                if (rp.flags & (LTTNG_VIEWER_FLAG_NEW_METADATA
                                | LTTNG_VIEWER_FLAG_NEW_STREAM)) {
@@ -798,8 +794,8 @@ int get_one_metadata_packet(struct lttng_live_ctx *ctx,
 
        rq.stream_id = htobe64(metadata_stream->id);
        cmd.cmd = htobe32(LTTNG_VIEWER_GET_METADATA);
-       cmd.data_size = sizeof(rq);
-       cmd.cmd_version = 0;
+       cmd.data_size = htobe64((uint64_t) sizeof(rq));
+       cmd.cmd_version = htobe32(0);
 
        ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
        if (ret_len < 0) {
@@ -910,6 +906,10 @@ int get_new_metadata(struct lttng_live_ctx *ctx,
        }
 
        do {
+               if (lttng_live_should_quit()) {
+                       ret = -1;
+                       goto error;
+               }
                /*
                 * get_one_metadata_packet returns the number of bytes
                 * received, 0 when we have received everything, a
@@ -924,8 +924,10 @@ int get_new_metadata(struct lttng_live_ctx *ctx,
                }
        } while (ret > 0 || !len_read);
 
-       if (fclose(metadata_stream->metadata_fp_write))
-               perror("fclose");
+       if (bt_close_memstream(metadata_buf, &size,
+                       metadata_stream->metadata_fp_write)) {
+               perror("bt_close_memstream");
+       }
        metadata_stream->metadata_fp_write = NULL;
 
 error:
@@ -967,8 +969,8 @@ int get_next_index(struct lttng_live_ctx *ctx,
        struct lttng_viewer_index *rp = &viewer_stream->current_index;
 
        cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEXT_INDEX);
-       cmd.data_size = sizeof(rq);
-       cmd.cmd_version = 0;
+       cmd.data_size = htobe64((uint64_t) sizeof(rq));
+       cmd.cmd_version = htobe32(0);
 
        memset(&rq, 0, sizeof(rq));
        rq.stream_id = htobe64(viewer_stream->id);
@@ -1027,11 +1029,14 @@ retry:
                if (rp->flags & LTTNG_VIEWER_FLAG_NEW_STREAM) {
                        printf_verbose("get_next_index: need new streams\n");
                        ret = ask_new_streams(ctx);
-                       if (ret < 0)
+                       if (ret < 0) {
                                goto error;
-                       else if (ret > 0)
-                               g_hash_table_foreach(ctx->session->ctf_traces,
-                                               add_traces, ctx->bt_ctx);
+                       } else if (ret > 0) {
+                               ret = add_traces(ctx);
+                               if (ret < 0) {
+                                       goto error;
+                               }
+                       }
                }
                break;
        case LTTNG_VIEWER_INDEX_RETRY:
@@ -1066,7 +1071,8 @@ void read_packet_header(struct ctf_stream_pos *pos,
        int ret;
 
        /* update trace_packet_header and stream_packet_context */
-       if (pos->prot != PROT_WRITE && file_stream->parent.trace_packet_header) {
+       if (!(pos->prot & PROT_WRITE) &&
+               file_stream->parent.trace_packet_header) {
                /* Read packet header */
                ret = generic_rw(&pos->parent,
                                &file_stream->parent.trace_packet_header->p);
@@ -1077,7 +1083,8 @@ void read_packet_header(struct ctf_stream_pos *pos,
                        goto end;
                }
        }
-       if (pos->prot != PROT_WRITE && file_stream->parent.stream_packet_context) {
+       if (!(pos->prot & PROT_WRITE) &&
+               file_stream->parent.stream_packet_context) {
                /* Read packet context */
                ret = generic_rw(&pos->parent,
                                &file_stream->parent.stream_packet_context->p);
@@ -1105,7 +1112,7 @@ int handle_seek_position(size_t index, int whence,
                struct ctf_stream_pos *pos,
                struct ctf_file_stream *file_stream)
 {
-       int ret;
+       int ret = 0;
 
        switch (whence) {
        case SEEK_CUR:
@@ -1266,6 +1273,17 @@ retry:
                                cur_index->ts_real.timestamp_begin;
        }
 
+       /*
+        * Flush the output between attempts to grab a packet, thus
+        * ensuring we flush at least at the periodical timer period.
+        * This ensures the output remains reactive for interactive users and
+        * that the output is flushed when redirected to a file by the shell.
+        */
+       if (fflush(LTTNG_LIVE_OUTPUT_FP) < 0) {
+               perror("fflush");
+               goto end;
+       }
+
        if (pos->packet_size == 0 || pos->offset == EOF) {
                goto end;
        }
@@ -1305,8 +1323,8 @@ int lttng_live_create_viewer_session(struct lttng_live_ctx *ctx)
        }
 
        cmd.cmd = htobe32(LTTNG_VIEWER_CREATE_SESSION);
-       cmd.data_size = 0;
-       cmd.cmd_version = 0;
+       cmd.data_size = htobe64((uint64_t) 0);
+       cmd.cmd_version = htobe32(0);
 
        ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
        if (ret_len < 0) {
@@ -1354,15 +1372,14 @@ int del_traces(gpointer key, gpointer value, gpointer user_data)
 }
 
 static
-void add_traces(gpointer key, gpointer value, gpointer user_data)
+int add_one_trace(struct lttng_live_ctx *ctx,
+               struct lttng_live_ctf_trace *trace)
 {
        int i, ret;
-       struct bt_context *bt_ctx = user_data;
-       struct lttng_live_ctf_trace *trace = value;
+       struct bt_context *bt_ctx = ctx->bt_ctx;
        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;
 
@@ -1375,14 +1392,15 @@ void add_traces(gpointer key, gpointer value, gpointer user_data)
         * times the same traces.
         * If a trace is already in the context, we just skip this function.
         */
-       if (trace->in_use)
-               return;
+       if (trace->in_use) {
+               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);
-               ctx = stream->session->ctx;
 
                if (!stream->metadata_flag) {
                        new_mmap_stream = zmalloc(sizeof(struct bt_mmap_stream));
@@ -1405,7 +1423,7 @@ void add_traces(gpointer key, gpointer value, gpointer user_data)
                                goto end_free;
                        }
 
-                       trace->metadata_fp = babeltrace_fmemopen(metadata_buf,
+                       trace->metadata_fp = bt_fmemopen(metadata_buf,
                                        stream->metadata_len, "rb");
                        if (!trace->metadata_fp) {
                                perror("Metadata fmemopen");
@@ -1418,6 +1436,7 @@ void add_traces(gpointer key, gpointer value, gpointer user_data)
 
        if (!trace->metadata_fp) {
                fprintf(stderr, "[error] No metadata stream opened\n");
+               ret = -1;
                goto end_free;
        }
 
@@ -1425,6 +1444,7 @@ void add_traces(gpointer key, gpointer value, gpointer user_data)
                        ctf_live_packet_seek, &mmap_list, trace->metadata_fp);
        if (ret < 0) {
                fprintf(stderr, "[error] Error adding trace\n");
+               ret = -1;
                goto end_free;
        }
        trace->metadata_stream->metadata_len = 0;
@@ -1446,7 +1466,31 @@ void add_traces(gpointer key, gpointer value, gpointer user_data)
 end_free:
        bt_context_put(bt_ctx);
 end:
-       return;
+       return ret;
+}
+
+static
+int add_traces(struct lttng_live_ctx *ctx)
+{
+       int ret;
+       struct lttng_live_ctf_trace *trace;
+       GHashTableIter it;
+       gpointer key;
+       gpointer value;
+
+       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;
+               ret = add_one_trace(ctx, trace);
+               if (ret < 0) {
+                       goto end;
+               }
+       }
+
+       ret = 0;
+
+end:
+       return ret;
 }
 
 /*
@@ -1469,8 +1513,8 @@ int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id)
        }
 
        cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEW_STREAMS);
-       cmd.data_size = sizeof(rq);
-       cmd.cmd_version = 0;
+       cmd.data_size = htobe64((uint64_t) sizeof(rq));
+       cmd.cmd_version = htobe32(0);
 
        memset(&rq, 0, sizeof(rq));
        rq.session_id = htobe64(id);
@@ -1593,7 +1637,7 @@ int lttng_live_read(struct lttng_live_ctx *ctx)
                goto end;
        }
 
-       fmt_write = bt_lookup_format(g_quark_from_static_string("text"));
+       fmt_write = bt_lookup_format(g_quark_from_string("text"));
        if (!fmt_write) {
                fprintf(stderr, "[error] ctf-text error\n");
                goto end;
@@ -1618,7 +1662,7 @@ int lttng_live_read(struct lttng_live_ctx *ctx)
 
        for (i = 0; i < ctx->session_ids->len; i++) {
                id = g_array_index(ctx->session_ids, uint64_t, i);
-               printf_verbose("Attaching to session %lu\n", id);
+               printf_verbose("Attaching to session %" PRIu64 "\n", id);
                ret = lttng_live_attach_session(ctx, id);
                printf_verbose("Attaching session returns %d\n", ret);
                if (ret < 0) {
@@ -1655,8 +1699,10 @@ int lttng_live_read(struct lttng_live_ctx *ctx)
                        }
                }
 
-               g_hash_table_foreach(ctx->session->ctf_traces, add_traces,
-                               ctx->bt_ctx);
+               ret = add_traces(ctx);
+               if (ret < 0) {
+                       goto end_free;
+               }
 
                begin_pos.type = BT_SEEK_BEGIN;
                iter = bt_ctf_iter_create(ctx->bt_ctx, &begin_pos, NULL);
This page took 0.030859 seconds and 4 git commands to generate.