Fix: consumerd: crash occurs when taking snapshot of ust channel
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 30 Oct 2019 19:35:28 +0000 (15:35 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 30 Oct 2019 19:36:40 +0000 (15:36 -0400)
Commit 8e1ef46e8 added an acquisition of the metadata_stream's lock
during consumer_metadata_cache_flushed() as stream attributes are
used. However, when this function is called, the metadata channel's
stream can already be NULL, as indicated by the function's comments.

Check if the stream is NULL before attempting to acquire its lock.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/common/consumer/consumer-metadata-cache.c

index 5eee4014265f42566776ea34645a0f08504fbde0..3fffe53397b368f57e9ddc1e81257bfb50342e94 100644 (file)
@@ -274,16 +274,19 @@ int consumer_metadata_cache_flushed(struct lttng_consumer_channel *channel,
        }
        pthread_mutex_lock(&channel->timer_lock);
        metadata_stream = channel->metadata_stream;
-       pthread_mutex_lock(&metadata_stream->lock);
-       pthread_mutex_lock(&channel->metadata_cache->lock);
-
        if (!metadata_stream) {
                /*
                 * Having no metadata stream means the channel is being destroyed so there
                 * is no cache to flush anymore.
                 */
                ret = 0;
-       } else if (metadata_stream->ust_metadata_pushed >= offset) {
+               goto end_unlock_channel;
+       }
+
+       pthread_mutex_lock(&metadata_stream->lock);
+       pthread_mutex_lock(&channel->metadata_cache->lock);
+
+       if (metadata_stream->ust_metadata_pushed >= offset) {
                ret = 0;
        } else if (channel->metadata_stream->endpoint_status !=
                        CONSUMER_ENDPOINT_ACTIVE) {
@@ -296,6 +299,7 @@ int consumer_metadata_cache_flushed(struct lttng_consumer_channel *channel,
 
        pthread_mutex_unlock(&channel->metadata_cache->lock);
        pthread_mutex_unlock(&metadata_stream->lock);
+end_unlock_channel:
        pthread_mutex_unlock(&channel->timer_lock);
        if (!timer) {
                pthread_mutex_unlock(&channel->lock);
This page took 0.033786 seconds and 4 git commands to generate.