+ } else {
+ ret = consumer_add_channel(new_channel, ctx);
+ }
+ if (CONSUMER_CHANNEL_TYPE_DATA) {
+ consumer_timer_live_start(new_channel,
+ msg.u.channel.live_timer_interval);
+ }
+
+ 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 = LTTNG_ERR_KERN_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 < 0) {
+ rcu_read_unlock();
+ return -EINTR;
+ }
+
+ 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();
+
+ /*
+ * Send status code to session daemon only if the recv works. If the
+ * above recv() failed, the session daemon is notified through the
+ * error socket and the teardown is eventually done.
+ */
+ ret = consumer_send_status_msg(sock, ret_code);
+ if (ret < 0) {
+ /* Somehow, the session daemon is not responding anymore. */
+ goto end_nosignal;
+ }
+
+ health_code_update();
+
+ new_stream = consumer_allocate_stream(channel->key,
+ fd,
+ LTTNG_CONSUMER_ACTIVE_STREAM,
+ channel->name,
+ channel->uid,
+ channel->gid,
+ channel->relayd_id,
+ channel->session_id,
+ msg.u.stream.cpu,
+ &alloc_ret,
+ channel->type,
+ channel->monitor);
+ if (new_stream == NULL) {
+ switch (alloc_ret) {
+ case -ENOMEM:
+ case -EINVAL:
+ default:
+ lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
+ break;
+ }
+ goto end_nosignal;