From: Mathieu Desnoyers Date: Fri, 30 Apr 2021 16:02:47 +0000 (-0400) Subject: Fix: kernel consumer: get next subbuffer EAGAIN handling X-Git-Tag: v2.12.4~6 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=bc93eeca040cab99277daf1bffe87416b62e2532;p=lttng-tools.git Fix: kernel consumer: get next subbuffer EAGAIN handling The caller of get next subbuffer (data and metadata) callbacks only expects -ENODATA when there is no data to read. However, the kernel tracer distinguishes between no data for a finalized stream (-ENODATA) and no data for a non-finalized stream (-EAGAIN). Given that the consumer daemon uses the POLLHUP returned by epoll to detect stream end of life, it does not care about the distinction between -EAGAIN and -ENODATA when streaming. However, taking a snapshot of a metadata stream uses the distinction between nodata and again. Change this so it considers a return value of 0 from lttng_consumer_read_subbuffer to mean there is no more data to read, so we can combine -EAGAIN and -ENODATA within get next subbuffer callbacks and return -ENODATA for both. Signed-off-by: Mathieu Desnoyers Signed-off-by: Jérémie Galarneau Change-Id: Ifb157dbe28498279dce30e9efa3b5aedcf3f9b1d --- diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index c0d8e0972..245f4ee46 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -403,16 +403,12 @@ static int lttng_kconsumer_snapshot_metadata( ret_read = lttng_consumer_read_subbuffer(metadata_stream, ctx, true); if (ret_read < 0) { - if (ret_read != -EAGAIN) { - ERR("Kernel snapshot reading metadata subbuffer (ret: %zd)", - ret_read); - ret = ret_read; - goto error_snapshot; - } - /* ret_read is negative at this point so we will exit the loop. */ - continue; + ERR("Kernel snapshot reading metadata subbuffer (ret: %zd)", + ret_read); + ret = ret_read; + goto error_snapshot; } - } while (ret_read >= 0); + } while (ret_read > 0); if (use_relayd) { close_relayd_stream(metadata_stream); @@ -1531,6 +1527,17 @@ int get_subbuffer_common(struct lttng_consumer_stream *stream, ret = kernctl_get_next_subbuf(stream->wait_fd); if (ret) { + /* + * The caller only expects -ENODATA when there is no data to + * read, but the kernel tracer returns -EAGAIN when there is + * currently no data for a non-finalized stream, and -ENODATA + * when there is no data for a finalized stream. Those can be + * combined into a -ENODATA return value. + */ + if (ret == -EAGAIN) { + ret = -ENODATA; + } + goto end; } @@ -1612,6 +1619,16 @@ int get_next_subbuffer_metadata_check(struct lttng_consumer_stream *stream, subbuffer->info.metadata.padded_subbuf_size, coherent ? "true" : "false"); end: + /* + * The caller only expects -ENODATA when there is no data to read, but + * the kernel tracer returns -EAGAIN when there is currently no data + * for a non-finalized stream, and -ENODATA when there is no data for a + * finalized stream. Those can be combined into a -ENODATA return value. + */ + if (ret == -EAGAIN) { + ret = -ENODATA; + } + return ret; }