Fix UST channel/stream output assignation
[lttng-tools.git] / src / common / ust-consumer / ust-consumer.c
index cd6277f1aa42995735c95cbdf296e3cec55386cf..432f43a60c92d78aff436370e717ca382231d466 100644 (file)
@@ -114,13 +114,15 @@ error:
 static struct lttng_consumer_channel *allocate_channel(uint64_t session_id,
                const char *pathname, const char *name, uid_t uid, gid_t gid,
                int relayd_id, uint64_t key, enum lttng_event_output output,
-               uint64_t tracefile_size, uint64_t tracefile_count)
+               uint64_t tracefile_size, uint64_t tracefile_count,
+               uint64_t session_id_per_pid, unsigned int monitor)
 {
        assert(pathname);
        assert(name);
 
-       return consumer_allocate_channel(key, session_id, pathname, name, uid, gid,
-                       relayd_id, output, tracefile_size, tracefile_count);
+       return consumer_allocate_channel(key, session_id, pathname, name, uid,
+                       gid, relayd_id, output, tracefile_size,
+                       tracefile_count, session_id_per_pid, monitor);
 }
 
 /*
@@ -394,7 +396,7 @@ static int send_sessiond_channel(int sock,
                struct lttng_consumer_channel *channel,
                struct lttng_consumer_local_data *ctx, int *relayd_error)
 {
-       int ret;
+       int ret, ret_code = LTTNG_OK;
        struct lttng_consumer_stream *stream;
 
        assert(channel);
@@ -403,18 +405,6 @@ static int send_sessiond_channel(int sock,
 
        DBG("UST consumer sending channel %s to sessiond", channel->name);
 
-       /* Send channel to sessiond. */
-       ret = ustctl_send_channel_to_sessiond(sock, channel->uchan);
-       if (ret < 0) {
-               goto error;
-       }
-
-       ret = ustctl_channel_close_wakeup_fd(channel->uchan);
-       if (ret < 0) {
-               goto error;
-       }
-
-       /* The channel was sent successfully to the sessiond at this point. */
        cds_list_for_each_entry(stream, &channel->streams.head, send_node) {
                /* Try to send the stream to the relayd if one is available. */
                ret = send_stream_to_relayd(stream);
@@ -426,9 +416,33 @@ static int send_sessiond_channel(int sock,
                        if (relayd_error) {
                                *relayd_error = 1;
                        }
-                       goto error;
+                       ret_code = LTTNG_ERR_RELAYD_CONNECT_FAIL;
                }
+       }
+
+       /* Inform sessiond that we are about to send channel and streams. */
+       ret = consumer_send_status_msg(sock, ret_code);
+       if (ret < 0 || ret_code != LTTNG_OK) {
+               /*
+                * Either the session daemon is not responding or the relayd died so we
+                * stop now.
+                */
+               goto error;
+       }
+
+       /* Send channel to sessiond. */
+       ret = ustctl_send_channel_to_sessiond(sock, channel->uchan);
+       if (ret < 0) {
+               goto error;
+       }
+
+       ret = ustctl_channel_close_wakeup_fd(channel->uchan);
+       if (ret < 0) {
+               goto error;
+       }
 
+       /* The channel was sent successfully to the sessiond at this point. */
+       cds_list_for_each_entry(stream, &channel->streams.head, send_node) {
                /* Send stream to session daemon. */
                ret = send_sessiond_stream(sock, stream);
                if (ret < 0) {
@@ -447,6 +461,9 @@ static int send_sessiond_channel(int sock,
        return 0;
 
 error:
+       if (ret_code != LTTNG_OK) {
+               ret = -1;
+       }
        return ret;
 }
 
@@ -624,7 +641,13 @@ static int close_metadata(uint64_t chan_key)
 
        channel = consumer_find_channel(chan_key);
        if (!channel) {
-               ERR("UST consumer close metadata %" PRIu64 " not found", chan_key);
+               /*
+                * This is possible if the metadata thread has issue a delete because
+                * the endpoint point of the stream hung up. There is no way the
+                * session daemon can know about it thus use a DBG instead of an actual
+                * error.
+                */
+               DBG("UST consumer close metadata %" PRIu64 " not found", chan_key);
                ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
                goto error;
        }
@@ -671,7 +694,7 @@ static int setup_metadata(struct lttng_consumer_local_data *ctx, uint64_t key)
        if (!metadata) {
                ERR("UST consumer push metadata %" PRIu64 " not found", key);
                ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
-               goto error;
+               goto error_find;
        }
 
        /*
@@ -703,9 +726,17 @@ static int setup_metadata(struct lttng_consumer_local_data *ctx, uint64_t key)
        /* List MUST be empty after or else it could be reused. */
        assert(cds_list_empty(&metadata->streams.head));
 
-       ret = 0;
+       return 0;
 
 error:
+       /*
+        * Delete metadata channel on error. At this point, the metadata stream can
+        * NOT be monitored by the metadata thread thus having the guarantee that
+        * the stream is still in the local stream list of the channel. This call
+        * will make sure to clean that list.
+        */
+       consumer_del_channel(metadata);
+error_find:
        return ret;
 }
 
@@ -895,7 +926,9 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                msg.u.ask_channel.relayd_id, msg.u.ask_channel.key,
                                (enum lttng_event_output) msg.u.ask_channel.output,
                                msg.u.ask_channel.tracefile_size,
-                               msg.u.ask_channel.tracefile_count);
+                               msg.u.ask_channel.tracefile_count,
+                               msg.u.ask_channel.session_id_per_pid,
+                               msg.u.ask_channel.monitor);
                if (!channel) {
                        goto end_channel_error;
                }
@@ -909,16 +942,6 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                attr.chan_id = msg.u.ask_channel.chan_id;
                memcpy(attr.uuid, msg.u.ask_channel.uuid, sizeof(attr.uuid));
 
-               /* Translate the event output type to UST. */
-               switch (channel->output) {
-               case LTTNG_EVENT_SPLICE:
-                       /* Splice not supported so fallback on mmap(). */
-               case LTTNG_EVENT_MMAP:
-               default:
-                       attr.output = CONSUMER_CHANNEL_MMAP;
-                       break;
-               };
-
                /* Translate and save channel type. */
                switch (msg.u.ask_channel.type) {
                case LTTNG_UST_CHAN_PER_CPU:
@@ -1001,13 +1024,6 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                        goto end_msg_sessiond;
                }
 
-               /* Inform sessiond that we are about to send channel and streams. */
-               ret = consumer_send_status_msg(sock, LTTNG_OK);
-               if (ret < 0) {
-                       /* Somehow, the session daemon is not responding anymore. */
-                       goto error_fatal;
-               }
-
                /* Send everything to sessiond. */
                ret = send_sessiond_channel(sock, channel, ctx, &relayd_err);
                if (ret < 0) {
@@ -1015,10 +1031,10 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                /*
                                 * We were unable to send to the relayd the stream so avoid
                                 * sending back a fatal error to the thread since this is OK
-                                * and the consumer can continue its work.
+                                * and the consumer can continue its work. The above call
+                                * has sent the error status message to the sessiond.
                                 */
-                               ret_code = LTTNG_ERR_RELAYD_CONNECT_FAIL;
-                               goto end_msg_sessiond;
+                               goto end_nosignal;
                        }
                        /*
                         * The communicaton was broken hence there is a bad state between
@@ -1124,6 +1140,15 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                }
                goto end_msg_sessiond;
        }
+       case LTTNG_CONSUMER_SNAPSHOT_CHANNEL:
+       {
+               ret = consumer_send_status_msg(sock, ret_code);
+               if (ret < 0) {
+                       /* Somehow, the session daemon is not responding anymore. */
+                       goto end_nosignal;
+               }
+               break;
+       }
        default:
                break;
        }
@@ -1478,10 +1503,13 @@ int lttng_ustconsumer_request_metadata(struct lttng_consumer_local_data *ctx,
        }
 
        request.session_id = channel->session_id;
+       request.session_id_per_pid = channel->session_id_per_pid;
        request.uid = channel->uid;
        request.key = channel->key;
-       DBG("Sending metadata request to sessiond, session %" PRIu64,
-                       channel->session_id);
+       DBG("Sending metadata request to sessiond, session id %" PRIu64
+                       ", per-pid %" PRIu64,
+                       channel->session_id,
+                       channel->session_id_per_pid);
 
        ret = lttcomm_send_unix_sock(ctx->consumer_metadata_socket, &request,
                        sizeof(request));
@@ -1538,7 +1566,13 @@ int lttng_ustconsumer_request_metadata(struct lttng_consumer_local_data *ctx,
 
        ret_code = lttng_ustconsumer_recv_metadata(ctx->consumer_metadata_socket,
                        key, offset, len, channel);
-       (void) consumer_send_status_msg(ctx->consumer_metadata_socket, ret_code);
+       if (ret_code >= 0) {
+               /*
+                * Only send the status msg if the sessiond is alive meaning a positive
+                * ret code.
+                */
+               (void) consumer_send_status_msg(ctx->consumer_metadata_socket, ret_code);
+       }
        ret = 0;
 
 end:
This page took 0.02595 seconds and 4 git commands to generate.