X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;ds=sidebyside;f=liblttng-ust%2Fltt-events.c;h=911bf2929bd6a7bde214e315113163fff255e5b4;hb=882a56d75d6054e1bf35d1bcddd668be4da4980f;hp=06d2f89714feeeaa3771361efd15bff5a003f2ad;hpb=df854e41ded4203a5b86bac062b8604bb038759a;p=lttng-ust.git diff --git a/liblttng-ust/ltt-events.c b/liblttng-ust/ltt-events.c index 06d2f897..911bf292 100644 --- a/liblttng-ust/ltt-events.c +++ b/liblttng-ust/ltt-events.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include "clock.h" #include #include @@ -31,6 +34,7 @@ #include #include +#include "error.h" #include "ltt-tracer.h" #include "ltt-tracer-core.h" @@ -73,6 +77,7 @@ struct ust_pending_probe { }; static void _ltt_event_destroy(struct ltt_event *event); +static void _ltt_wildcard_destroy(struct session_wildcard *sw); static void _ltt_channel_destroy(struct ltt_channel *chan); static int _ltt_event_unregister(struct ltt_event *event); static @@ -91,14 +96,20 @@ int add_pending_probe(struct ltt_event *event, const char *name) { struct cds_hlist_head *head; struct ust_pending_probe *e; - size_t name_len = strlen(name) + 1; - uint32_t hash = jhash(name, name_len - 1, 0); + size_t name_len = strlen(name); + uint32_t hash; + if (name_len > LTTNG_UST_SYM_NAME_LEN - 1) { + WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN - 1); + name_len = LTTNG_UST_SYM_NAME_LEN - 1; + } + hash = jhash(name, name_len, 0); head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)]; e = zmalloc(sizeof(struct ust_pending_probe) + name_len); if (!e) return -ENOMEM; - memcpy(&e->name[0], name, name_len); + memcpy(&e->name[0], name, name_len + 1); + e->name[name_len] = '\0'; cds_hlist_add_head(&e->node, head); e->event = event; event->pending_probe = e; @@ -130,16 +141,56 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc) struct cds_hlist_node *node, *p; struct ust_pending_probe *e; const char *name = desc->name; - size_t name_len = strlen(name) + 1; - uint32_t hash = jhash(name, name_len - 1, 0); int ret = 0; + struct lttng_ust_event event_param; + size_t name_len = strlen(name); + uint32_t hash; + + /* Wildcard */ + { + struct wildcard_entry *wildcard; + + /* TODO: check if loglevel match */ + wildcard = match_wildcard(desc->name); + if (strcmp(desc->name, "lttng_ust:metadata") && wildcard) { + struct session_wildcard *sw; + + cds_list_for_each_entry(sw, &wildcard->session_list, + session_list) { + struct ltt_event *ev; + int ret; + + memcpy(&event_param, &sw->event_param, + sizeof(event_param)); + memcpy(event_param.name, + desc->name, + sizeof(event_param.name)); + /* create event */ + ret = ltt_event_create(sw->chan, + &event_param, NULL, + &ev); + if (ret) { + DBG("Error creating event"); + continue; + } + cds_list_add(&ev->wildcard_list, + &sw->events); + } + } + } + if (name_len > LTTNG_UST_SYM_NAME_LEN - 1) { + WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN - 1); + name_len = LTTNG_UST_SYM_NAME_LEN - 1; + } + hash = jhash(name, name_len, 0); head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)]; cds_hlist_for_each_entry_safe(e, node, p, head, node) { struct ltt_event *event; struct ltt_channel *chan; - if (strcmp(name, e->name)) + /* TODO: check if loglevel match */ + if (strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) continue; event = e->event; chan = event->chan; @@ -173,6 +224,7 @@ struct ltt_session *ltt_session_create(void) return NULL; CDS_INIT_LIST_HEAD(&session->chan); CDS_INIT_LIST_HEAD(&session->events); + CDS_INIT_LIST_HEAD(&session->wildcards); uuid_generate(session->uuid); cds_list_add(&session->list, &sessions); return session; @@ -182,6 +234,7 @@ void ltt_session_destroy(struct ltt_session *session) { struct ltt_channel *chan, *tmpchan; struct ltt_event *event, *tmpevent; + struct session_wildcard *wildcard, *tmpwildcard; int ret; CMM_ACCESS_ONCE(session->active) = 0; @@ -190,6 +243,8 @@ void ltt_session_destroy(struct ltt_session *session) WARN_ON(ret); } synchronize_trace(); /* Wait for in-flight events to complete */ + cds_list_for_each_entry_safe(wildcard, tmpwildcard, &session->wildcards, list) + _ltt_wildcard_destroy(wildcard); cds_list_for_each_entry_safe(event, tmpevent, &session->events, list) _ltt_event_destroy(event); cds_list_for_each_entry_safe(chan, tmpchan, &session->chan, list) @@ -297,8 +352,8 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session, size_t subbuf_size, size_t num_subbuf, unsigned int switch_timer_interval, unsigned int read_timer_interval, - int *shm_fd, int *wait_fd, - uint64_t *memory_map_size, + int **shm_fd, int **wait_fd, + uint64_t **memory_map_size, struct ltt_channel *chan_priv_init) { struct ltt_channel *chan = NULL; @@ -347,6 +402,26 @@ void _ltt_channel_destroy(struct ltt_channel *chan) chan->ops->channel_destroy(chan); } +int ltt_wildcard_create(struct ltt_channel *chan, + struct lttng_ust_event *event_param, + struct session_wildcard **_sw) +{ + struct session_wildcard *sw; + + sw = add_wildcard(event_param->name, chan, event_param); + if (!sw || IS_ERR(sw)) { + return PTR_ERR(sw); + } + *_sw = sw; + return 0; +} + +static +void _ltt_wildcard_destroy(struct session_wildcard *sw) +{ + _remove_wildcard(sw); +} + /* * Supports event creation while tracing session is active. */ @@ -367,7 +442,9 @@ int ltt_event_create(struct ltt_channel *chan, * creation). Might require a hash if we have lots of events. */ cds_list_for_each_entry(event, &chan->session->events, list) { - if (event->desc && !strcmp(event->desc->name, event_param->name)) { + if (event->desc && !strncmp(event->desc->name, + event_param->name, + LTTNG_UST_SYM_NAME_LEN - 1)) { ret = -EEXIST; goto exist; } @@ -391,6 +468,7 @@ int ltt_event_create(struct ltt_channel *chan, switch (event_param->instrumentation) { case LTTNG_UST_TRACEPOINT: event->desc = ltt_event_get(event_param->name); + /* TODO: check if loglevel match */ if (event->desc) { ret = __tracepoint_probe_register(event_param->name, event->desc->probe_callback, @@ -409,13 +487,6 @@ int ltt_event_create(struct ltt_channel *chan, goto add_pending_error; } break; - case LTTNG_UST_TRACEPOINT_LOGLEVEL: - /* - * TODO: add tracepoint loglevel to hash table, with - * event info. Enable all events corresponding to - * loglevel. - */ - break; default: WARN_ON_ONCE(1); } @@ -748,6 +819,17 @@ int _ltt_event_metadata_statedump(struct ltt_session *session, if (ret) goto end; + if (event->desc->loglevel) { + const int *ll_entry; + + ll_entry = *event->desc->loglevel; + ret = lttng_metadata_printf(session, + " loglevel = %d;\n", + ll_entry); + if (ret) + goto end; + } + if (event->ctx) { ret = lttng_metadata_printf(session, " context := struct {\n"); @@ -842,8 +924,8 @@ int _ltt_stream_packet_context_declare(struct ltt_session *session) { return lttng_metadata_printf(session, "struct packet_context {\n" - " uint64_t timestamp_begin;\n" - " uint64_t timestamp_end;\n" + " uint64_clock_monotonic_t timestamp_begin;\n" + " uint64_clock_monotonic_t timestamp_end;\n" " uint32_t events_discarded;\n" " uint32_t content_size;\n" " uint32_t packet_size;\n" @@ -869,11 +951,11 @@ int _ltt_event_header_declare(struct ltt_session *session) " enum : uint5_t { compact = 0 ... 30, extended = 31 } id;\n" " variant {\n" " struct {\n" - " uint27_t timestamp;\n" + " uint27_clock_monotonic_t timestamp;\n" " } compact;\n" " struct {\n" " uint32_t id;\n" - " uint64_t timestamp;\n" + " uint64_clock_monotonic_t timestamp;\n" " } extended;\n" " } v;\n" "} align(%u);\n" @@ -882,11 +964,11 @@ int _ltt_event_header_declare(struct ltt_session *session) " enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;\n" " variant {\n" " struct {\n" - " uint32_t timestamp;\n" + " uint32_clock_monotonic_t timestamp;\n" " } compact;\n" " struct {\n" " uint32_t id;\n" - " uint64_t timestamp;\n" + " uint64_clock_monotonic_t timestamp;\n" " } extended;\n" " } v;\n" "} align(%u);\n\n", @@ -895,6 +977,31 @@ int _ltt_event_header_declare(struct ltt_session *session) ); } +/* + * Approximation of NTP time of day to clock monotonic correlation, + * taken at start of trace. + * Yes, this is only an approximation. Yes, we can (and will) do better + * in future versions. + */ +static +uint64_t measure_clock_offset(void) +{ + uint64_t offset, monotonic[2], realtime; + struct timespec rts = { 0, 0 }; + int ret; + + monotonic[0] = trace_clock_read64(); + ret = clock_gettime(CLOCK_REALTIME, &rts); + if (ret < 0) + return 0; + monotonic[1] = trace_clock_read64(); + offset = (monotonic[0] + monotonic[1]) >> 1; + realtime = rts.tv_sec * 1000000000ULL; + realtime += rts.tv_nsec; + offset = realtime - offset; + return offset; +} + /* * Output metadata into this session's metadata buffers. */ @@ -902,7 +1009,7 @@ static int _ltt_session_metadata_statedump(struct ltt_session *session) { unsigned char *uuid_c = session->uuid; - char uuid_s[37]; + char uuid_s[37], clock_uuid_s[CLOCK_UUID_LEN]; struct ltt_channel *chan; struct ltt_event *event; int ret = 0; @@ -958,6 +1065,56 @@ int _ltt_session_metadata_statedump(struct ltt_session *session) if (ret) goto end; + ret = lttng_metadata_printf(session, + "clock {\n" + " name = %s;\n", + "monotonic" + ); + if (ret) + goto end; + + if (!trace_clock_uuid(clock_uuid_s)) { + ret = lttng_metadata_printf(session, + " uuid = \"%s\";\n", + clock_uuid_s + ); + if (ret) + goto end; + } + + ret = lttng_metadata_printf(session, + " description = \"Monotonic Clock\";\n" + " freq = %" PRIu64 "; /* Frequency, in Hz */\n" + " /* clock value offset from Epoch is: offset * (1/freq) */\n" + " offset = %" PRIu64 ";\n" + "};\n\n", + trace_clock_freq(), + measure_clock_offset() + ); + if (ret) + goto end; + + ret = lttng_metadata_printf(session, + "typealias integer {\n" + " size = 27; align = 1; signed = false;\n" + " map = clock.monotonic.value;\n" + "} := uint27_clock_monotonic_t;\n" + "\n" + "typealias integer {\n" + " size = 32; align = %u; signed = false;\n" + " map = clock.monotonic.value;\n" + "} := uint32_clock_monotonic_t;\n" + "\n" + "typealias integer {\n" + " size = 64; align = %u; signed = false;\n" + " map = clock.monotonic.value;\n" + "} := uint64_clock_monotonic_t;\n\n", + lttng_alignof(uint32_t) * CHAR_BIT, + lttng_alignof(uint64_t) * CHAR_BIT + ); + if (ret) + goto end; + ret = _ltt_stream_packet_context_declare(session); if (ret) goto end;