Fix: Metadata stream leak when received in consumer
[lttng-tools.git] / src / common / ust-consumer / ust-consumer.c
index e7d6dd4e780084879759055fe839e018f6d02048..f57e2e602f1d6bcf7b2f017fbdc0c933ae7830a8 100644 (file)
@@ -150,7 +150,8 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                new_channel = consumer_allocate_channel(msg.u.channel.channel_key,
                                fds[0], -1,
                                msg.u.channel.mmap_len,
-                               msg.u.channel.max_sb_size);
+                               msg.u.channel.max_sb_size,
+                               msg.u.channel.nb_init_streams);
                if (new_channel == NULL) {
                        lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
                        goto end_nosignal;
@@ -173,6 +174,7 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                int fds[2];
                size_t nb_fd = 2;
                struct consumer_relayd_sock_pair *relayd = NULL;
+               int alloc_ret = 0;
 
                DBG("UST Consumer adding stream");
 
@@ -203,9 +205,23 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                msg.u.stream.uid,
                                msg.u.stream.gid,
                                msg.u.stream.net_index,
-                               msg.u.stream.metadata_flag);
+                               msg.u.stream.metadata_flag,
+                               &alloc_ret);
                if (new_stream == NULL) {
-                       lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
+                       switch (alloc_ret) {
+                       case -ENOMEM:
+                       case -EINVAL:
+                       default:
+                               lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
+                               break;
+                       case -ENOENT:
+                               /*
+                                * We could not find the channel. Can happen if cpu hotplug
+                                * happens while tearing down.
+                                */
+                               DBG3("Could not find channel");
+                               break;
+                       }
                        goto end_nosignal;
                }
 
@@ -228,29 +244,24 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                        goto end_nosignal;
                }
 
-               /* Send stream to the metadata thread */
-               if (new_stream->metadata_flag) {
-                       if (ctx->on_recv_stream) {
-                               ret = ctx->on_recv_stream(new_stream);
-                               if (ret < 0) {
-                                       goto end_nosignal;
-                               }
+               /* Do actions once stream has been received. */
+               if (ctx->on_recv_stream) {
+                       ret = ctx->on_recv_stream(new_stream);
+                       if (ret < 0) {
+                               goto end_nosignal;
                        }
+               }
 
+               /* Send stream to the metadata thread */
+               if (new_stream->metadata_flag) {
                        do {
-                               ret = write(ctx->consumer_metadata_pipe[1], new_stream,
-                                               sizeof(struct lttng_consumer_stream));
+                               ret = write(ctx->consumer_metadata_pipe[1], &new_stream,
+                                               sizeof(new_stream));
                        } while (ret < 0 && errno == EINTR);
                        if (ret < 0) {
                                PERROR("write metadata pipe");
                        }
                } else {
-                       if (ctx->on_recv_stream) {
-                               ret = ctx->on_recv_stream(new_stream);
-                               if (ret < 0) {
-                                       goto end_nosignal;
-                               }
-                       }
                        consumer_add_stream(new_stream);
                }
 
@@ -452,12 +463,19 @@ int lttng_ustconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
        padding = len - subbuf_size;
        /* write the subbuffer to the tracefile */
        ret = lttng_consumer_on_read_subbuffer_mmap(ctx, stream, subbuf_size, padding);
-       if (ret != subbuf_size) {
+       /*
+        * The mmap operation should write subbuf_size amount of data when network
+        * streaming or the full padding (len) size when we are _not_ streaming.
+        */
+       if ((ret != subbuf_size && stream->net_seq_idx != -1) ||
+                       (ret != len && stream->net_seq_idx == -1)) {
                /*
-                * display the error but continue processing to try
-                * to release the subbuffer
+                * Display the error but continue processing to try to release the
+                * subbuffer
                 */
-               ERR("Error writing to tracefile (expected: %ld, got: %ld)", ret, len);
+               ERR("Error writing to tracefile "
+                               "(ret: %zd != len: %lu != subbuf_size: %lu)",
+                               ret, len, subbuf_size);
        }
        err = ustctl_put_next_subbuf(handle, buf);
        assert(err == 0);
This page took 0.024706 seconds and 4 git commands to generate.