Fix: consumer recv command error path
[lttng-tools.git] / src / common / ust-consumer / ust-consumer.c
index a8872aaf33481239df05e39c5b6c29851cd83586..2b8098835857106a811f03761fcafe7489f1ce1f 100644 (file)
@@ -92,6 +92,11 @@ int lttng_ustconsumer_get_produced_snapshot(
        return ret;
 }
 
+/*
+ * Receive command from session daemon and process it.
+ *
+ * Return 1 on success else a negative value or 0.
+ */
 int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                int sock, struct pollfd *consumer_sockpoll)
 {
@@ -102,7 +107,7 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
        if (ret != sizeof(msg)) {
                DBG("Consumer received unexpected message size %zd (expects %zu)",
                        ret, sizeof(msg));
-               lttng_consumer_send_error(ctx, CONSUMERD_ERROR_RECV_FD);
+               lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_ERROR_RECV_FD);
                return ret;
        }
        if (msg.cmd_type == LTTNG_CONSUMER_STOP) {
@@ -135,7 +140,7 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                }
                ret = lttcomm_recv_fds_unix_sock(sock, fds, nb_fd);
                if (ret != sizeof(fds)) {
-                       lttng_consumer_send_error(ctx, CONSUMERD_ERROR_RECV_FD);
+                       lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_ERROR_RECV_FD);
                        rcu_read_unlock();
                        return ret;
                }
@@ -147,7 +152,7 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                msg.u.channel.mmap_len,
                                msg.u.channel.max_sb_size);
                if (new_channel == NULL) {
-                       lttng_consumer_send_error(ctx, CONSUMERD_OUTFD_ERROR);
+                       lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
                        goto end_nosignal;
                }
                if (ctx->on_recv_channel != NULL) {
@@ -178,7 +183,7 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                }
                ret = lttcomm_recv_fds_unix_sock(sock, fds, nb_fd);
                if (ret != sizeof(fds)) {
-                       lttng_consumer_send_error(ctx, CONSUMERD_ERROR_RECV_FD);
+                       lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_ERROR_RECV_FD);
                        rcu_read_unlock();
                        return ret;
                }
@@ -200,7 +205,7 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                msg.u.stream.net_index,
                                msg.u.stream.metadata_flag);
                if (new_stream == NULL) {
-                       lttng_consumer_send_error(ctx, CONSUMERD_OUTFD_ERROR);
+                       lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
                        goto end_nosignal;
                }
 
@@ -241,25 +246,30 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
        }
        case LTTNG_CONSUMER_DESTROY_RELAYD:
        {
+               uint64_t index = msg.u.destroy_relayd.net_seq_idx;
                struct consumer_relayd_sock_pair *relayd;
 
-               DBG("UST consumer destroying relayd %" PRIu64,
-                               msg.u.destroy_relayd.net_seq_idx);
+               DBG("UST consumer destroying relayd %" PRIu64, index);
 
                /* Get relayd reference if exists. */
-               relayd = consumer_find_relayd(msg.u.destroy_relayd.net_seq_idx);
+               relayd = consumer_find_relayd(index);
                if (relayd == NULL) {
-                       ERR("Unable to find relayd %" PRIu64, msg.u.destroy_relayd.net_seq_idx);
+                       ERR("Unable to find relayd %" PRIu64, index);
                        goto end_nosignal;
                }
 
-               /* Set destroy flag for this object */
-               uatomic_set(&relayd->destroy_flag, 1);
+               /*
+                * Each relayd socket pair has a refcount of stream attached to it
+                * which tells if the relayd is still active or not depending on the
+                * refcount value.
+                *
+                * This will set the destroy flag of the relayd object and destroy it
+                * if the refcount reaches zero when called.
+                *
+                * The destroy can happen either here or when a stream fd hangs up.
+                */
+               consumer_flag_relayd_for_destroy(relayd);
 
-               /* Destroy the relayd if refcount is 0 else set the destroy flag. */
-               if (uatomic_read(&relayd->refcount) == 0) {
-                       consumer_destroy_relayd(relayd);
-               }
                goto end_nosignal;
        }
        case LTTNG_CONSUMER_UPDATE_STREAM:
@@ -300,9 +310,13 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                ret = write(ctx->consumer_poll_pipe[1], "", 1);
        } while (ret < 0 && errno == EINTR);
 end_nosignal:
-       /* XXX: At some point we might want to return something else than zero */
        rcu_read_unlock();
-       return 0;
+
+       /*
+        * Return 1 to indicate success since the 0 value can be a socket
+        * shutdown during the recv() or send() call.
+        */
+       return 1;
 }
 
 int lttng_ustconsumer_allocate_channel(struct lttng_consumer_channel *chan)
This page took 0.024718 seconds and 4 git commands to generate.