X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=src%2Fcommon%2Fkernel-consumer%2Fkernel-consumer.c;h=70ca8b21e50714982b9d23dc5b32a92d6f11b2a3;hb=24cb9f69c5b6247c8c955252f7e468d4c473d4f1;hp=7e0b36540f306b99deabeb551f1940a341352722;hpb=8d18bcaede97b6d87e434310da9c13d269983c77;p=lttng-tools.git diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index 7e0b36540..70ca8b21e 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -413,16 +413,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); @@ -1341,36 +1337,38 @@ end: * metadata thread can consumer them. * * Metadata stream lock MUST be acquired. - * - * Return 0 if new metadatda is available, EAGAIN if the metadata stream - * is empty or a negative value on error. */ -int lttng_kconsumer_sync_metadata(struct lttng_consumer_stream *metadata) +enum sync_metadata_status lttng_kconsumer_sync_metadata( + struct lttng_consumer_stream *metadata) { int ret; + enum sync_metadata_status status; assert(metadata); ret = kernctl_buffer_flush(metadata->wait_fd); if (ret < 0) { ERR("Failed to flush kernel stream"); + status = SYNC_METADATA_STATUS_ERROR; goto end; } ret = kernctl_snapshot(metadata->wait_fd); if (ret < 0) { - if (ret != -EAGAIN) { + if (errno == EAGAIN) { + /* No new metadata, exit. */ + DBG("Sync metadata, no new kernel metadata"); + status = SYNC_METADATA_STATUS_NO_DATA; + } else { ERR("Sync metadata, taking kernel snapshot failed."); - goto end; + status = SYNC_METADATA_STATUS_ERROR; } - DBG("Sync metadata, no new kernel metadata"); - /* No new metadata, exit. */ - ret = ENODATA; - goto end; + } else { + status = SYNC_METADATA_STATUS_NEW_DATA; } end: - return ret; + return status; } static @@ -1504,6 +1502,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; } @@ -1585,6 +1594,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; } @@ -1609,8 +1628,23 @@ int put_next_subbuffer(struct lttng_consumer_stream *stream, static bool is_get_next_check_metadata_available(int tracer_fd) { - return kernctl_get_next_subbuf_metadata_check(tracer_fd, NULL) != - -ENOTTY; + const int ret = kernctl_get_next_subbuf_metadata_check(tracer_fd, NULL); + const bool available = ret != -ENOTTY; + + if (ret == 0) { + /* get succeeded, make sure to put the subbuffer. */ + kernctl_put_subbuf(tracer_fd); + } + + return available; +} + +static +int signal_metadata(struct lttng_consumer_stream *stream, + struct lttng_consumer_local_data *ctx) +{ + ASSERT_LOCKED(stream->metadata_rdv_lock); + return pthread_cond_broadcast(&stream->metadata_rdv) ? -errno : 0; } static @@ -1643,6 +1677,8 @@ int lttng_kconsumer_set_stream_ops( metadata_bucket_destroy(stream->metadata_bucket); stream->metadata_bucket = NULL; } + + stream->read_subbuffer_ops.on_sleep = signal_metadata; } if (!stream->read_subbuffer_ops.get_next_subbuffer) {