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);
msg.u.trace_chunk_exists.chunk_id);
goto end_msg_sessiond;
}
+ case LTTNG_CONSUMER_OPEN_CHANNEL_PACKETS:
+ {
+ const uint64_t key = msg.u.open_channel_packets.key;
+ struct lttng_consumer_channel *channel =
+ consumer_find_channel(key);
+
+ if (channel) {
+ pthread_mutex_lock(&channel->lock);
+ ret_code = lttng_consumer_open_channel_packets(channel);
+ pthread_mutex_unlock(&channel->lock);
+ } else {
+ WARN("Channel %" PRIu64 " not found", key);
+ ret_code = LTTCOMM_CONSUMERD_CHAN_NOT_FOUND;
+ }
+
+ health_code_update();
+ goto end_msg_sessiond;
+ }
default:
goto end_nosignal;
}
* 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
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;
}
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;
}
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
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) {