From d9a2e16ee3abce83801f58473831330aa8a5463b Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Mon, 11 Dec 2017 16:17:48 -0500 Subject: [PATCH] Keep read-only copies of fields from the channel to the stream MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit In the consumer, we sometimes need to read the channel pathname or tracefile_size from a stream, but we cannot always access those values safely. So we now keep a copy of those values when we add or allocate streams. Signed-off-by: Julien Desfossez Signed-off-by: Jérémie Galarneau --- src/common/consumer/consumer.c | 10 ++++++++++ src/common/consumer/consumer.h | 19 +++++++++++++++++++ src/common/kernel-consumer/kernel-consumer.c | 2 ++ src/common/ust-consumer/ust-consumer.c | 1 + 4 files changed, 32 insertions(+) diff --git a/src/common/consumer/consumer.c b/src/common/consumer/consumer.c index 6b920b6b1..2fa65f4d4 100644 --- a/src/common/consumer/consumer.c +++ b/src/common/consumer/consumer.c @@ -541,6 +541,16 @@ void consumer_del_stream_for_metadata(struct lttng_consumer_stream *stream) consumer_stream_destroy(stream, metadata_ht); } +void consumer_stream_update_channel_attributes( + struct lttng_consumer_stream *stream, + struct lttng_consumer_channel *channel) +{ + stream->channel_read_only_attributes.tracefile_size = + channel->tracefile_size; + memcpy(stream->channel_read_only_attributes.path, channel->pathname, + sizeof(stream->channel_read_only_attributes.path)); +} + struct lttng_consumer_stream *consumer_allocate_stream(uint64_t channel_key, uint64_t stream_key, enum lttng_consumer_stream_state state, diff --git a/src/common/consumer/consumer.h b/src/common/consumer/consumer.h index eb2958e20..a7d0ee1a7 100644 --- a/src/common/consumer/consumer.h +++ b/src/common/consumer/consumer.h @@ -415,6 +415,17 @@ struct lttng_consumer_stream { pthread_cond_t metadata_rdv; pthread_mutex_t metadata_rdv_lock; + /* + * Read-only copies of channel values. We cannot safely access the + * channel from a stream, so we need to have a local copy of these + * fields in the stream object. These fields should be removed from + * the stream objects when we introduce refcounting. + */ + struct { + char path[LTTNG_PATH_MAX]; + uint64_t tracefile_size; + } channel_read_only_attributes; + /* Indicate if the stream still has some data to be read. */ unsigned int has_data:1; /* @@ -662,6 +673,14 @@ void lttng_consumer_cleanup(void); */ int lttng_consumer_poll_socket(struct pollfd *kconsumer_sockpoll); +/* + * Copy the fields from the channel that need to be accessed (read-only) + * directly from the stream. + */ +void consumer_stream_update_channel_attributes( + struct lttng_consumer_stream *stream, + struct lttng_consumer_channel *channel); + struct lttng_consumer_stream *consumer_allocate_stream(uint64_t channel_key, uint64_t stream_key, enum lttng_consumer_stream_state state, diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index 103df665a..539d80b0b 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -658,6 +658,8 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, new_stream->chan = channel; new_stream->wait_fd = fd; + consumer_stream_update_channel_attributes(new_stream, + channel); switch (channel->output) { case CONSUMER_CHANNEL_SPLICE: new_stream->output = LTTNG_EVENT_SPLICE; diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index ec078fb47..00937a44d 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -184,6 +184,7 @@ static struct lttng_consumer_stream *allocate_stream(int cpu, int key, goto error; } + consumer_stream_update_channel_attributes(stream, channel); stream->chan = channel; error: -- 2.34.1