X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=src%2Flttng-events.c;h=3b9b907beb85196b36301cbb6df6456ab195b23b;hb=44df1a4dd8bb1bb9ead8901954a1edf765d0345f;hp=a85360912271c8725c4d59e329f4c3ea212ca6cf;hpb=cfa6cc1d0f01c2cfcc1a679abf3a6572d411c309;p=lttng-modules.git diff --git a/src/lttng-events.c b/src/lttng-events.c index a8536091..3b9b907b 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -1626,7 +1626,7 @@ void lttng_session_lazy_sync_enablers(struct lttng_session *session) * was written and a negative value on error. */ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, - struct channel *chan) + struct channel *chan, bool *coherent) { struct lib_ring_buffer_ctx ctx; int ret = 0; @@ -1665,6 +1665,7 @@ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, ret = stream->transport->ops.event_reserve(&ctx, 0); if (ret != 0) { printk(KERN_WARNING "LTTng: Metadata event reservation failed\n"); + stream->coherent = false; goto end; } stream->transport->ops.event_write(&ctx, @@ -1672,18 +1673,43 @@ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, reserve_len); stream->transport->ops.event_commit(&ctx); stream->metadata_in += reserve_len; + if (reserve_len < len || stream->metadata_cache->producing != 0) + stream->coherent = false; + else + stream->coherent = true; ret = reserve_len; end: + if (coherent) + *coherent = stream->coherent; mutex_unlock(&stream->metadata_cache->lock); return ret; } +static +void lttng_metadata_begin(struct lttng_session *session) +{ + mutex_lock(&session->metadata_cache->lock); + session->metadata_cache->producing++; + mutex_unlock(&session->metadata_cache->lock); +} + +static +void lttng_metadata_end(struct lttng_session *session) +{ + mutex_lock(&session->metadata_cache->lock); + WARN_ON_ONCE(!session->metadata_cache->producing); + session->metadata_cache->producing--; + mutex_unlock(&session->metadata_cache->lock); +} + /* * Write the metadata to the metadata cache. * Must be called with sessions_mutex held. * The metadata cache lock protects us from concurrent read access from * thread outputting metadata content to ring buffer. + * The content of the printf is printed as a single atomic metadata + * transaction. */ int lttng_metadata_printf(struct lttng_session *session, const char *fmt, ...) @@ -1703,6 +1729,7 @@ int lttng_metadata_printf(struct lttng_session *session, len = strlen(str); mutex_lock(&session->metadata_cache->lock); + session->metadata_cache->producing++; if (session->metadata_cache->metadata_written + len > session->metadata_cache->cache_alloc) { char *tmp_cache_realloc; @@ -1728,6 +1755,7 @@ int lttng_metadata_printf(struct lttng_session *session, session->metadata_cache->metadata_written, str, len); session->metadata_cache->metadata_written += len; + session->metadata_cache->producing--; mutex_unlock(&session->metadata_cache->lock); kfree(str); @@ -1737,6 +1765,7 @@ int lttng_metadata_printf(struct lttng_session *session, return 0; err: + session->metadata_cache->producing--; mutex_unlock(&session->metadata_cache->lock); kfree(str); return -ENOMEM; @@ -2312,6 +2341,8 @@ int _lttng_fields_metadata_statedump(struct lttng_session *session, /* * Must be called with sessions_mutex held. + * The entire event metadata is printed as a single atomic metadata + * transaction. */ static int _lttng_event_metadata_statedump(struct lttng_session *session, @@ -2325,6 +2356,8 @@ int _lttng_event_metadata_statedump(struct lttng_session *session, if (chan->channel_type == METADATA_CHANNEL) return 0; + lttng_metadata_begin(session); + ret = lttng_metadata_printf(session, "event {\n" " name = \"%s\";\n" @@ -2374,12 +2407,15 @@ int _lttng_event_metadata_statedump(struct lttng_session *session, event->metadata_dumped = 1; end: + lttng_metadata_end(session); return ret; } /* * Must be called with sessions_mutex held. + * The entire channel metadata is printed as a single atomic metadata + * transaction. */ static int _lttng_channel_metadata_statedump(struct lttng_session *session, @@ -2393,6 +2429,8 @@ int _lttng_channel_metadata_statedump(struct lttng_session *session, if (chan->channel_type == METADATA_CHANNEL) return 0; + lttng_metadata_begin(session); + WARN_ON_ONCE(!chan->header_type); ret = lttng_metadata_printf(session, "stream {\n" @@ -2426,6 +2464,7 @@ int _lttng_channel_metadata_statedump(struct lttng_session *session, chan->metadata_dumped = 1; end: + lttng_metadata_end(session); return ret; } @@ -2613,6 +2652,9 @@ int _lttng_session_metadata_statedump(struct lttng_session *session) if (!READ_ONCE(session->active)) return 0; + + lttng_metadata_begin(session); + if (session->metadata_dumped) goto skip_session; @@ -2785,6 +2827,7 @@ skip_session: } session->metadata_dumped = 1; end: + lttng_metadata_end(session); return ret; } @@ -3071,7 +3114,7 @@ static void __exit lttng_events_exit(void) module_exit(lttng_events_exit); -#include +#include #ifdef LTTNG_EXTRA_VERSION_GIT MODULE_INFO(extra_version_git, LTTNG_EXTRA_VERSION_GIT); #endif