+ switch (msg.cmd_type) {
+ case LTTNG_CONSUMER_ADD_RELAYD_SOCKET:
+ {
+ /* Session daemon status message are handled in the following call. */
+ consumer_add_relayd_socket(msg.u.relayd_sock.net_index,
+ msg.u.relayd_sock.type, ctx, sock, consumer_sockpoll,
+ &msg.u.relayd_sock.sock, msg.u.relayd_sock.session_id,
+ msg.u.relayd_sock.relayd_session_id);
+ goto end_nosignal;
+ }
+ case LTTNG_CONSUMER_ADD_CHANNEL:
+ {
+ struct lttng_consumer_channel *new_channel;
+ int ret_recv;
+
+ health_code_update();
+
+ /* First send a status message before receiving the fds. */
+ ret = consumer_send_status_msg(sock, ret_code);
+ if (ret < 0) {
+ /* Somehow, the session daemon is not responding anymore. */
+ goto error_fatal;
+ }
+
+ health_code_update();
+
+ DBG("consumer_add_channel %" PRIu64, msg.u.channel.channel_key);
+ new_channel = consumer_allocate_channel(msg.u.channel.channel_key,
+ msg.u.channel.session_id, msg.u.channel.pathname,
+ msg.u.channel.name, msg.u.channel.uid, msg.u.channel.gid,
+ msg.u.channel.relayd_id, msg.u.channel.output,
+ msg.u.channel.tracefile_size,
+ msg.u.channel.tracefile_count, 0,
+ msg.u.channel.monitor,
+ msg.u.channel.live_timer_interval,
+ NULL, NULL);
+ if (new_channel == NULL) {
+ lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
+ goto end_nosignal;
+ }
+ new_channel->nb_init_stream_left = msg.u.channel.nb_init_streams;
+ switch (msg.u.channel.output) {
+ case LTTNG_EVENT_SPLICE:
+ new_channel->output = CONSUMER_CHANNEL_SPLICE;
+ break;
+ case LTTNG_EVENT_MMAP:
+ new_channel->output = CONSUMER_CHANNEL_MMAP;
+ break;
+ default:
+ ERR("Channel output unknown %d", msg.u.channel.output);
+ goto end_nosignal;
+ }
+
+ /* Translate and save channel type. */
+ switch (msg.u.channel.type) {
+ case CONSUMER_CHANNEL_TYPE_DATA:
+ case CONSUMER_CHANNEL_TYPE_METADATA:
+ new_channel->type = msg.u.channel.type;
+ break;
+ default:
+ assert(0);
+ goto end_nosignal;
+ };
+
+ health_code_update();
+
+ if (ctx->on_recv_channel != NULL) {
+ ret_recv = ctx->on_recv_channel(new_channel);
+ if (ret_recv == 0) {
+ ret = consumer_add_channel(new_channel, ctx);
+ } else if (ret_recv < 0) {
+ goto end_nosignal;
+ }
+ } else {
+ ret = consumer_add_channel(new_channel, ctx);
+ }
+ if (msg.u.channel.type == CONSUMER_CHANNEL_TYPE_DATA && !ret) {
+ int monitor_start_ret;
+
+ DBG("Consumer starting monitor timer");
+ consumer_timer_live_start(new_channel,
+ msg.u.channel.live_timer_interval);
+ monitor_start_ret = consumer_timer_monitor_start(
+ new_channel,
+ msg.u.channel.monitor_timer_interval);
+ if (monitor_start_ret < 0) {
+ ERR("Starting channel monitoring timer failed");
+ goto end_nosignal;
+ }
+
+ }
+
+ health_code_update();
+
+ /* If we received an error in add_channel, we need to report it. */
+ if (ret < 0) {
+ ret = consumer_send_status_msg(sock, ret);
+ if (ret < 0) {
+ goto error_fatal;
+ }
+ goto end_nosignal;
+ }
+
+ goto end_nosignal;
+ }
+ case LTTNG_CONSUMER_ADD_STREAM:
+ {
+ int fd;
+ struct lttng_pipe *stream_pipe;
+ struct lttng_consumer_stream *new_stream;
+ struct lttng_consumer_channel *channel;
+ int alloc_ret = 0;
+
+ /*
+ * Get stream's channel reference. Needed when adding the stream to the
+ * global hash table.
+ */
+ channel = consumer_find_channel(msg.u.stream.channel_key);
+ if (!channel) {
+ /*
+ * We could not find the channel. Can happen if cpu hotplug
+ * happens while tearing down.
+ */
+ ERR("Unable to find channel key %" PRIu64, msg.u.stream.channel_key);
+ ret_code = LTTCOMM_CONSUMERD_CHAN_NOT_FOUND;
+ }
+
+ health_code_update();
+
+ /* First send a status message before receiving the fds. */
+ ret = consumer_send_status_msg(sock, ret_code);
+ if (ret < 0) {
+ /* Somehow, the session daemon is not responding anymore. */
+ goto error_fatal;
+ }
+
+ health_code_update();
+
+ if (ret_code != LTTCOMM_CONSUMERD_SUCCESS) {
+ /* Channel was not found. */
+ goto end_nosignal;
+ }
+
+ /* Blocking call */
+ health_poll_entry();
+ ret = lttng_consumer_poll_socket(consumer_sockpoll);
+ health_poll_exit();
+ if (ret) {
+ goto error_fatal;
+ }
+
+ health_code_update();
+
+ /* Get stream file descriptor from socket */
+ ret = lttcomm_recv_fds_unix_sock(sock, &fd, 1);
+ if (ret != sizeof(fd)) {
+ lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_ERROR_RECV_FD);
+ rcu_read_unlock();
+ return ret;
+ }
+
+ health_code_update();
+