From: David Goulet Date: Wed, 24 Oct 2012 16:40:59 +0000 (-0400) Subject: Fix: Delete stream on write error in consumer X-Git-Tag: v2.1.0-rc6~26 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=ab1027f48fa7e2dd29b3c85548ec42f26d06be25;p=lttng-tools.git Fix: Delete stream on write error in consumer Whenever a write() error occured, both on network or local trace file, the consumer thread just died considering the error a fatal one. This commit fixes that by simply deleting the stream, removing it from the poll set of the thread and freeing it. Furthermore, on a write() error, a SIGPIPE is usually raised if the FD is invalid. The consumer is catching this signal but was initiating a should exit action thus ultimately cleaning all threads. We now still catch SIGPIPE but don't set the should quit flag so normal cleanup can be done by the threads. Signed-off-by: David Goulet --- diff --git a/src/bin/lttng-consumerd/lttng-consumerd.c b/src/bin/lttng-consumerd/lttng-consumerd.c index 1cc11d2d5..4d02c8427 100644 --- a/src/bin/lttng-consumerd/lttng-consumerd.c +++ b/src/bin/lttng-consumerd/lttng-consumerd.c @@ -79,6 +79,14 @@ static void sighandler(int sig) return; } + /* + * Ignore SIGPIPE because it should not stop the consumer whenever a + * SIGPIPE is catched through a FD operation. + */ + if (sig == SIGPIPE) { + return; + } + lttng_consumer_should_exit(ctx); } diff --git a/src/common/consumer.c b/src/common/consumer.c index 295e7be5d..53c618067 100644 --- a/src/common/consumer.c +++ b/src/common/consumer.c @@ -923,6 +923,8 @@ void lttng_consumer_should_exit(struct lttng_consumer_local_data *ctx) if (ret < 0) { PERROR("write consumer quit"); } + + DBG("Consumer flag that it should quit"); } void lttng_consumer_sync_trace_file(struct lttng_consumer_stream *stream, @@ -1084,6 +1086,8 @@ void lttng_consumer_destroy(struct lttng_consumer_local_data *ctx) { int ret; + DBG("Consumer destroying it. Closing everything."); + ret = close(ctx->consumer_error_socket); if (ret) { PERROR("close"); @@ -1916,8 +1920,9 @@ restart: len = ctx->on_buffer_ready(stream, ctx); /* It's ok to have an unavailable sub-buffer */ if (len < 0 && len != -EAGAIN && len != -ENODATA) { - rcu_read_unlock(); - goto end; + /* Clean up stream from consumer and free it. */ + lttng_poll_del(&events, stream->wait_fd); + consumer_del_metadata_stream(stream, metadata_ht); } else if (len > 0) { stream->data_read = 1; } @@ -2084,7 +2089,8 @@ void *consumer_thread_data_poll(void *data) len = ctx->on_buffer_ready(local_stream[i], ctx); /* it's ok to have an unavailable sub-buffer */ if (len < 0 && len != -EAGAIN && len != -ENODATA) { - goto end; + /* Clean the stream and free it. */ + consumer_del_stream(local_stream[i], data_ht); } else if (len > 0) { local_stream[i]->data_read = 1; } @@ -2107,7 +2113,8 @@ void *consumer_thread_data_poll(void *data) len = ctx->on_buffer_ready(local_stream[i], ctx); /* it's ok to have an unavailable sub-buffer */ if (len < 0 && len != -EAGAIN && len != -ENODATA) { - goto end; + /* Clean the stream and free it. */ + consumer_del_stream(local_stream[i], data_ht); } else if (len > 0) { local_stream[i]->data_read = 1; }