Fix: consumer recv command error path
[lttng-tools.git] / src / common / kernel-consumer / kernel-consumer.c
index 86ccddfd09e80672fbca3fb1ab6f772fb41bcc81..47463c6501eddb48c4963d99c15b3d3c510c035c 100644 (file)
@@ -92,7 +92,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
 
        ret = lttcomm_recv_unix_sock(sock, &msg, sizeof(msg));
        if (ret != sizeof(msg)) {
-               lttng_consumer_send_error(ctx, CONSUMERD_ERROR_RECV_CMD);
+               lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_ERROR_RECV_CMD);
                return ret;
        }
        if (msg.cmd_type == LTTNG_CONSUMER_STOP) {
@@ -120,7 +120,7 @@ int lttng_kconsumer_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) {
@@ -150,7 +150,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                /* Get stream file descriptor from socket */
                ret = lttcomm_recv_fds_unix_sock(sock, &fd, 1);
                if (ret != sizeof(fd)) {
-                       lttng_consumer_send_error(ctx, CONSUMERD_ERROR_RECV_FD);
+                       lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_ERROR_RECV_FD);
                        rcu_read_unlock();
                        return ret;
                }
@@ -167,7 +167,7 @@ int lttng_kconsumer_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;
                }
 
@@ -211,26 +211,30 @@ int lttng_kconsumer_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("Kernel consumer destroying relayd %" PRIu64,
-                               msg.u.destroy_relayd.net_seq_idx);
+               DBG("Kernel 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;
        }
        default:
@@ -253,7 +257,12 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
        } while (ret < 0 && errno == EINTR);
 end_nosignal:
        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;
 }
 
 /*
This page took 0.024036 seconds and 4 git commands to generate.