Fix: kernel consumer: issue put_subbuf on error
[lttng-tools.git] / src / common / kernel-consumer / kernel-consumer.c
index ab4f604d7a5c525447cdf23453633ef0baa4318a..e5595a1c3c106973bbbd285997612b98d422bca0 100644 (file)
@@ -35,6 +35,7 @@
 #include <common/sessiond-comm/sessiond-comm.h>
 #include <common/sessiond-comm/relayd.h>
 #include <common/compat/fcntl.h>
+#include <common/compat/endian.h>
 #include <common/pipe.h>
 #include <common/relayd/relayd.h>
 #include <common/utils.h>
@@ -561,7 +562,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                         * happens while tearing down.
                         */
                        ERR("Unable to find channel key %" PRIu64, msg.u.stream.channel_key);
-                       ret_code = LTTNG_ERR_KERN_CHAN_NOT_FOUND;
+                       ret_code = LTTCOMM_CONSUMERD_CHAN_NOT_FOUND;
                }
 
                health_code_update();
@@ -764,7 +765,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                         */
                        ERR("Unable to find channel key %" PRIu64,
                                        msg.u.sent_streams.channel_key);
-                       ret_code = LTTNG_ERR_KERN_CHAN_NOT_FOUND;
+                       ret_code = LTTCOMM_CONSUMERD_CHAN_NOT_FOUND;
                }
 
                health_code_update();
@@ -815,7 +816,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                relayd = consumer_find_relayd(index);
                if (relayd == NULL) {
                        DBG("Unable to find relayd %" PRIu64, index);
-                       ret_code = LTTNG_ERR_NO_CONSUMER;
+                       ret_code = LTTCOMM_CONSUMERD_RELAYD_FAIL;
                }
 
                /*
@@ -874,7 +875,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                        msg.u.snapshot_channel.relayd_id, ctx);
                        if (ret < 0) {
                                ERR("Snapshot metadata failed");
-                               ret_code = LTTNG_ERR_KERN_META_FAIL;
+                               ret_code = LTTCOMM_CONSUMERD_ERROR_METADATA;
                        }
                } else {
                        ret = lttng_kconsumer_snapshot_channel(msg.u.snapshot_channel.key,
@@ -884,7 +885,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                        ctx);
                        if (ret < 0) {
                                ERR("Snapshot channel failed");
-                               ret_code = LTTNG_ERR_KERN_CHAN_FAIL;
+                               ret_code = LTTCOMM_CONSUMERD_CHAN_NOT_FOUND;
                        }
                }
 
@@ -905,7 +906,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                channel = consumer_find_channel(key);
                if (!channel) {
                        ERR("Kernel consumer destroy channel %" PRIu64 " not found", key);
-                       ret_code = LTTNG_ERR_KERN_CHAN_NOT_FOUND;
+                       ret_code = LTTCOMM_CONSUMERD_CHAN_NOT_FOUND;
                }
 
                health_code_update();
@@ -918,6 +919,11 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
 
                health_code_update();
 
+               /* Stop right now if no channel was found. */
+               if (!channel) {
+                       goto end_nosignal;
+               }
+
                /*
                 * This command should ONLY be issued for channel with streams set in
                 * no monitor mode.
@@ -1078,6 +1084,17 @@ ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
        err = kernctl_get_padded_subbuf_size(infd, &len);
        if (err != 0) {
                perror("Getting sub-buffer len failed.");
+               err = kernctl_put_subbuf(infd);
+               if (err != 0) {
+                       if (errno == EFAULT) {
+                               perror("Error in unreserving sub buffer\n");
+                       } else if (errno == EIO) {
+                               /* Should never happen with newer LTTng versions */
+                               perror("Reader has been pushed by the writer, last sub-buffer corrupted.");
+                       }
+                       ret = -errno;
+                       goto end;
+               }
                ret = -errno;
                goto end;
        }
@@ -1085,6 +1102,17 @@ ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
        if (!stream->metadata_flag) {
                ret = get_index_values(&index, infd);
                if (ret < 0) {
+                       err = kernctl_put_subbuf(infd);
+                       if (err != 0) {
+                               if (errno == EFAULT) {
+                                       perror("Error in unreserving sub buffer\n");
+                               } else if (errno == EIO) {
+                                       /* Should never happen with newer LTTng versions */
+                                       perror("Reader has been pushed by the writer, last sub-buffer corrupted.");
+                               }
+                               ret = -errno;
+                               goto end;
+                       }
                        goto end;
                }
        } else {
@@ -1123,6 +1151,17 @@ ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
                err = kernctl_get_subbuf_size(infd, &subbuf_size);
                if (err != 0) {
                        perror("Getting sub-buffer len failed.");
+                       err = kernctl_put_subbuf(infd);
+                       if (err != 0) {
+                               if (errno == EFAULT) {
+                                       perror("Error in unreserving sub buffer\n");
+                               } else if (errno == EIO) {
+                                       /* Should never happen with newer LTTng versions */
+                                       perror("Reader has been pushed by the writer, last sub-buffer corrupted.");
+                               }
+                               ret = -errno;
+                               goto end;
+                       }
                        ret = -errno;
                        goto end;
                }
This page took 0.025414 seconds and 4 git commands to generate.