consumer: fix: unaligned accesses to index fields
[lttng-tools.git] / src / common / kernel-consumer / kernel-consumer.c
index a5dcc663d68c67f4b465ecabe70004f682842f3f..61602dd103fadb279582ebe10ec3b5168997ada2 100644 (file)
@@ -60,7 +60,11 @@ int lttng_kconsumer_take_snapshot(struct lttng_consumer_stream *stream)
        int infd = stream->wait_fd;
 
        ret = kernctl_snapshot(infd);
-       if (ret != 0) {
+       /*
+        * -EAGAIN is not an error, it just means that there is no data to
+        *  be read.
+        */
+       if (ret != 0 && ret != -EAGAIN) {
                PERROR("Getting sub-buffer snapshot.");
        }
 
@@ -187,14 +191,6 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path,
                        DBG("Kernel consumer snapshot stream %s/%s (%" PRIu64 ")",
                                        path, stream->name, stream->key);
                }
-               if (relayd_id != -1ULL) {
-                       ret = consumer_send_relayd_streams_sent(relayd_id);
-                       if (ret < 0) {
-                               ERR("sending streams sent to relayd");
-                               goto end_unlock;
-                       }
-                       channel->streams_sent_to_relayd = true;
-               }
 
                ret = kernctl_buffer_flush_empty(stream->wait_fd);
                if (ret < 0) {
@@ -244,7 +240,7 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path,
                                produced_pos, nb_packets_per_stream,
                                stream->max_sb_size);
 
-               while (consumed_pos < produced_pos) {
+               while ((long) (consumed_pos - produced_pos) < 0) {
                        ssize_t read_len;
                        unsigned long len, padded_len;
 
@@ -340,7 +336,7 @@ end:
  *
  * Returns 0 on success, < 0 on error
  */
-int lttng_kconsumer_snapshot_metadata(uint64_t key, char *path,
+static int lttng_kconsumer_snapshot_metadata(uint64_t key, char *path,
                uint64_t relayd_id, struct lttng_consumer_local_data *ctx)
 {
        int ret, use_relayd = 0;
@@ -359,11 +355,12 @@ int lttng_kconsumer_snapshot_metadata(uint64_t key, char *path,
        if (!metadata_channel) {
                ERR("Kernel snapshot metadata not found for key %" PRIu64, key);
                ret = -1;
-               goto error;
+               goto error_no_channel;
        }
 
        metadata_stream = metadata_channel->metadata_stream;
        assert(metadata_stream);
+       pthread_mutex_lock(&metadata_stream->lock);
 
        /* Flag once that we have a valid relayd for the stream. */
        if (relayd_id != (uint64_t) -1ULL) {
@@ -373,7 +370,7 @@ int lttng_kconsumer_snapshot_metadata(uint64_t key, char *path,
        if (use_relayd) {
                ret = consumer_send_relayd_stream(metadata_stream, path);
                if (ret < 0) {
-                       goto error;
+                       goto error_snapshot;
                }
        } else {
                ret = utils_create_stream_file(path, metadata_stream->name,
@@ -381,7 +378,7 @@ int lttng_kconsumer_snapshot_metadata(uint64_t key, char *path,
                                metadata_stream->tracefile_count_current,
                                metadata_stream->uid, metadata_stream->gid, NULL);
                if (ret < 0) {
-                       goto error;
+                       goto error_snapshot;
                }
                metadata_stream->out_fd = ret;
        }
@@ -394,7 +391,8 @@ int lttng_kconsumer_snapshot_metadata(uint64_t key, char *path,
                        if (ret_read != -EAGAIN) {
                                ERR("Kernel snapshot reading metadata subbuffer (ret: %zd)",
                                                ret_read);
-                               goto error;
+                               ret = ret_read;
+                               goto error_snapshot;
                        }
                        /* ret_read is negative at this point so we will exit the loop. */
                        continue;
@@ -419,11 +417,12 @@ int lttng_kconsumer_snapshot_metadata(uint64_t key, char *path,
        }
 
        ret = 0;
-
+error_snapshot:
+       pthread_mutex_unlock(&metadata_stream->lock);
        cds_list_del(&metadata_stream->send_node);
        consumer_stream_destroy(metadata_stream, NULL);
        metadata_channel->metadata_stream = NULL;
-error:
+error_no_channel:
        rcu_read_unlock();
        return ret;
 }
@@ -1120,66 +1119,62 @@ error_fatal:
 static int get_index_values(struct ctf_packet_index *index, int infd)
 {
        int ret;
+       uint64_t packet_size, content_size, timestamp_begin, timestamp_end,
+                       events_discarded, stream_id, stream_instance_id,
+                       packet_seq_num;
 
-       ret = kernctl_get_timestamp_begin(infd, &index->timestamp_begin);
+       ret = kernctl_get_timestamp_begin(infd, &timestamp_begin);
        if (ret < 0) {
                PERROR("kernctl_get_timestamp_begin");
                goto error;
        }
-       index->timestamp_begin = htobe64(index->timestamp_begin);
 
-       ret = kernctl_get_timestamp_end(infd, &index->timestamp_end);
+       ret = kernctl_get_timestamp_end(infd, &timestamp_end);
        if (ret < 0) {
                PERROR("kernctl_get_timestamp_end");
                goto error;
        }
-       index->timestamp_end = htobe64(index->timestamp_end);
 
-       ret = kernctl_get_events_discarded(infd, &index->events_discarded);
+       ret = kernctl_get_events_discarded(infd, &events_discarded);
        if (ret < 0) {
                PERROR("kernctl_get_events_discarded");
                goto error;
        }
-       index->events_discarded = htobe64(index->events_discarded);
 
-       ret = kernctl_get_content_size(infd, &index->content_size);
+       ret = kernctl_get_content_size(infd, &content_size);
        if (ret < 0) {
                PERROR("kernctl_get_content_size");
                goto error;
        }
-       index->content_size = htobe64(index->content_size);
 
-       ret = kernctl_get_packet_size(infd, &index->packet_size);
+       ret = kernctl_get_packet_size(infd, &packet_size);
        if (ret < 0) {
                PERROR("kernctl_get_packet_size");
                goto error;
        }
-       index->packet_size = htobe64(index->packet_size);
 
-       ret = kernctl_get_stream_id(infd, &index->stream_id);
+       ret = kernctl_get_stream_id(infd, &stream_id);
        if (ret < 0) {
                PERROR("kernctl_get_stream_id");
                goto error;
        }
-       index->stream_id = htobe64(index->stream_id);
 
-       ret = kernctl_get_instance_id(infd, &index->stream_instance_id);
+       ret = kernctl_get_instance_id(infd, &stream_instance_id);
        if (ret < 0) {
                if (ret == -ENOTTY) {
                        /* Command not implemented by lttng-modules. */
-                       index->stream_instance_id = -1ULL;
+                       stream_instance_id = -1ULL;
                } else {
                        PERROR("kernctl_get_instance_id");
                        goto error;
                }
        }
-       index->stream_instance_id = htobe64(index->stream_instance_id);
 
-       ret = kernctl_get_sequence_number(infd, &index->packet_seq_num);
+       ret = kernctl_get_sequence_number(infd, &packet_seq_num);
        if (ret < 0) {
                if (ret == -ENOTTY) {
                        /* Command not implemented by lttng-modules. */
-                       index->packet_seq_num = -1ULL;
+                       packet_seq_num = -1ULL;
                        ret = 0;
                } else {
                        PERROR("kernctl_get_sequence_number");
@@ -1188,6 +1183,18 @@ static int get_index_values(struct ctf_packet_index *index, int infd)
        }
        index->packet_seq_num = htobe64(index->packet_seq_num);
 
+       *index = (typeof(*index)) {
+               .offset = index->offset,
+               .packet_size = htobe64(packet_size),
+               .content_size = htobe64(content_size),
+               .timestamp_begin = htobe64(timestamp_begin),
+               .timestamp_end = htobe64(timestamp_end),
+               .events_discarded = htobe64(events_discarded),
+               .stream_id = htobe64(stream_id),
+               .stream_instance_id = htobe64(stream_instance_id),
+               .packet_seq_num = htobe64(packet_seq_num),
+       };
+
 error:
        return ret;
 }
This page took 0.026851 seconds and 4 git commands to generate.