Filter iteration: iterate on list of filters
[lttng-ust.git] / liblttng-ust / ltt-events.c
index d9bf555a9869c52af3f0dc550b6d74ee45c320a1..ee82413db8f8707b30884287fc5723434227200a 100644 (file)
 
 #define _GNU_SOURCE
 #include <stdio.h>
-#include <endian.h>
 #include <urcu/list.h>
 #include <urcu/hlist.h>
 #include <pthread.h>
-#include <uuid/uuid.h>
 #include <errno.h>
 #include <sys/shm.h>
 #include <sys/ipc.h>
@@ -34,7 +32,7 @@
 #include <stddef.h>
 #include <inttypes.h>
 #include <time.h>
-#include <sys/prctl.h>
+#include <lttng/ust-endian.h>
 #include "clock.h"
 
 #include <urcu-bp.h>
@@ -48,6 +46,8 @@
 #include <usterr-signal-safe.h>
 #include <helper.h>
 #include "error.h"
+#include "compat.h"
+#include "lttng-ust-uuid.h"
 
 #include "tracepoint-internal.h"
 #include "ltt-tracer.h"
@@ -56,8 +56,6 @@
 #include "../libringbuffer/shm.h"
 #include "jhash.h"
 
-#define PROCNAME_LEN 17
-
 /*
  * The sessions mutex is the centralized mutex across UST tracing
  * control and probe registration. All operations within this file are
@@ -181,20 +179,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);
+       size_t name_len = strlen(name) + 1;
        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;
+       if (name_len > LTTNG_UST_SYM_NAME_LEN) {
+               WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN);
+               name_len = LTTNG_UST_SYM_NAME_LEN;
        }
-       hash = jhash(name, name_len, 0);
+       hash = jhash(name, name_len - 1, 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 + 1);
-       e->name[name_len] = '\0';
+       memcpy(&e->name[0], name, name_len);
+       e->name[name_len - 1] = '\0';
        e->loglevel_type = loglevel_type;
        e->loglevel = loglevel;
        cds_hlist_add_head(&e->node, head);
@@ -230,13 +228,16 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc)
        const char *name = desc->name;
        int ret = 0;
        struct lttng_ust_event event_param;
-       size_t name_len = strlen(name);
+       size_t name_len = strlen(name) + 1;
        uint32_t hash;
 
        /* Wildcard */
        {
                struct wildcard_entry *wildcard;
 
+               //FIXME: should iterate on all match for filter.
+               //FIXME: should re-use pending event if present rather
+               //than create duplicate.
                wildcard = match_wildcard(desc);
                if (strcmp(desc->name, "lttng_ust:metadata") && wildcard) {
                        struct session_wildcard *sw;
@@ -248,28 +249,30 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc)
 
                                memcpy(&event_param, &sw->event_param,
                                                sizeof(event_param));
-                               memcpy(event_param.name,
+                               strncpy(event_param.name,
                                        desc->name,
                                        sizeof(event_param.name));
+                               event_param.name[sizeof(event_param.name) - 1] = '\0';
                                /* create event */
                                ret = ltt_event_create(sw->chan,
-                                       &event_param, NULL,
-                                       &ev);
+                                       &event_param, &ev);
                                if (ret) {
                                        DBG("Error creating event");
                                        continue;
                                }
                                cds_list_add(&ev->wildcard_list,
                                        &sw->events);
+                               lttng_filter_event_link_wildcard_bytecode(ev,
+                                       sw);
                        }
                }
        }
 
-       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;
+       if (name_len > LTTNG_UST_SYM_NAME_LEN) {
+               WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN);
+               name_len = LTTNG_UST_SYM_NAME_LEN;
        }
-       hash = jhash(name, name_len, 0);
+       hash = jhash(name, name_len - 1, 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;
@@ -283,6 +286,8 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc)
                if (strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) {
                        continue;
                }
+               /* TODO: wildcard same as pending event: duplicate */
+               /* TODO: Should apply filter though */
                event = e->event;
                chan = event->chan;
                assert(!event->desc);
@@ -297,6 +302,7 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc)
                event->id = chan->free_event_id++;
                ret |= _ltt_event_metadata_statedump(chan->session, chan,
                                event);
+               lttng_filter_event_link_bytecode(event);
        }
        return ret;
 }
@@ -309,6 +315,7 @@ void synchronize_trace(void)
 struct ltt_session *ltt_session_create(void)
 {
        struct ltt_session *session;
+       int ret;
 
        session = zmalloc(sizeof(struct ltt_session));
        if (!session)
@@ -316,7 +323,10 @@ struct ltt_session *ltt_session_create(void)
        CDS_INIT_LIST_HEAD(&session->chan);
        CDS_INIT_LIST_HEAD(&session->events);
        CDS_INIT_LIST_HEAD(&session->wildcards);
-       uuid_generate(session->uuid);
+       ret = lttng_ust_uuid_generate(session->uuid);
+       if (ret != 0) {
+               session->uuid[0] = '\0';
+       }
        cds_list_add(&session->list, &sessions);
        return session;
 }
@@ -498,7 +508,6 @@ void _ltt_channel_destroy(struct ltt_channel *chan)
  */
 int ltt_event_create(struct ltt_channel *chan,
                struct lttng_ust_event *event_param,
-               void *filter,
                struct ltt_event **_event)
 {
        const struct lttng_event_desc *desc = NULL;     /* silence gcc */
@@ -509,6 +518,8 @@ int ltt_event_create(struct ltt_channel *chan,
                ret = -ENOMEM;
                goto full;
        }
+       //FIXME: re-use event if already registered by wildcard or
+       //if we have a pending probe.... (CHECK)
        /*
         * This is O(n^2) (for each event, the loop is called at event
         * creation). Might require a hash if we have lots of events.
@@ -546,13 +557,14 @@ int ltt_event_create(struct ltt_channel *chan,
                goto cache_error;
        }
        event->chan = chan;
-       event->filter = filter;
        /*
         * used_event_id counts the maximum number of event IDs that can
         * register if all probes register.
         */
        chan->used_event_id++;
        event->enabled = 1;
+       CDS_INIT_LIST_HEAD(&event->filter_bytecode);
+       CDS_INIT_LIST_HEAD(&event->bytecode_runtime);
        event->instrumentation = event_param->instrumentation;
        /* Populate ltt_event structure before tracepoint registration. */
        cmm_smp_wmb();
@@ -651,6 +663,8 @@ void _ltt_event_destroy(struct ltt_event *event)
        }
        cds_list_del(&event->list);
        lttng_destroy_context(event->ctx);
+       lttng_free_event_filter_runtime(event);
+       lttng_free_event_filter_bytecode(event);
        free(event);
 }
 
@@ -721,6 +735,9 @@ int _ltt_field_statedump(struct ltt_session *session,
 {
        int ret = 0;
 
+       if (field->nowrite)
+               return 0;
+
        switch (field->type.atype) {
        case atype_integer:
                ret = lttng_metadata_printf(session,
@@ -922,6 +939,14 @@ int _ltt_event_metadata_statedump(struct ltt_session *session,
        if (ret)
                goto end;
 
+       if (event->desc->u.ext.model_emf_uri) {
+               ret = lttng_metadata_printf(session,
+                       "       model.emf.uri = \"%s\";\n",
+                       *(event->desc->u.ext.model_emf_uri));
+               if (ret)
+                       goto end;
+       }
+
        if (event->ctx) {
                ret = lttng_metadata_printf(session,
                        "       context := struct {\n");
@@ -1018,9 +1043,9 @@ int _ltt_stream_packet_context_declare(struct ltt_session *session)
                "struct packet_context {\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"
+               "       uint64_t content_size;\n"
+               "       uint64_t packet_size;\n"
+               "       unsigned long events_discarded;\n"
                "       uint32_t cpu_id;\n"
                "};\n\n"
                );
@@ -1088,7 +1113,7 @@ uint64_t measure_clock_offset(void)
                return 0;
        monotonic[1] = trace_clock_read64();
        offset = (monotonic[0] + monotonic[1]) >> 1;
-       realtime = rts.tv_sec * 1000000000ULL;
+       realtime = (uint64_t) rts.tv_sec * 1000000000ULL;
        realtime += rts.tv_nsec;
        offset = realtime - offset;
        return offset;
@@ -1101,11 +1126,13 @@ static
 int _ltt_session_metadata_statedump(struct ltt_session *session)
 {
        unsigned char *uuid_c = session->uuid;
-       char uuid_s[37], clock_uuid_s[CLOCK_UUID_LEN];
+       char uuid_s[LTTNG_UST_UUID_STR_LEN],
+               clock_uuid_s[LTTNG_UST_UUID_STR_LEN];
        struct ltt_channel *chan;
        struct ltt_event *event;
        int ret = 0;
-       char procname[PROCNAME_LEN] = "";
+       char procname[LTTNG_UST_PROCNAME_LEN] = "";
+       char hostname[HOST_NAME_MAX];
 
        if (!CMM_ACCESS_ONCE(session->active))
                return 0;
@@ -1128,6 +1155,7 @@ int _ltt_session_metadata_statedump(struct ltt_session *session)
                "typealias integer { size = 16; align = %u; signed = false; } := uint16_t;\n"
                "typealias integer { size = 32; align = %u; signed = false; } := uint32_t;\n"
                "typealias integer { size = 64; align = %u; signed = false; } := uint64_t;\n"
+               "typealias integer { size = %u; align = %u; signed = false; } := unsigned long;\n"
                "typealias integer { size = 5; align = 1; signed = false; } := uint5_t;\n"
                "typealias integer { size = 27; align = 1; signed = false; } := uint27_t;\n"
                "\n"
@@ -1146,6 +1174,8 @@ int _ltt_session_metadata_statedump(struct ltt_session *session)
                lttng_alignof(uint16_t) * CHAR_BIT,
                lttng_alignof(uint32_t) * CHAR_BIT,
                lttng_alignof(uint64_t) * CHAR_BIT,
+               sizeof(unsigned long) * CHAR_BIT,
+               lttng_alignof(unsigned long) * CHAR_BIT,
                CTF_SPEC_MAJOR,
                CTF_SPEC_MINOR,
                uuid_s,
@@ -1159,10 +1189,15 @@ int _ltt_session_metadata_statedump(struct ltt_session *session)
                goto end;
 
        /* ignore error, just use empty string if error. */
-       (void) prctl(PR_GET_NAME, (unsigned long) procname, 0, 0, 0);
-       procname[PROCNAME_LEN - 1] = '\0';
+       hostname[0] = '\0';
+       ret = gethostname(hostname, sizeof(hostname));
+       if (ret && errno == ENAMETOOLONG)
+               hostname[HOST_NAME_MAX - 1] = '\0';
+       lttng_ust_getprocname(procname);
+       procname[LTTNG_UST_PROCNAME_LEN - 1] = '\0';
        ret = lttng_metadata_printf(session,
                "env {\n"
+               "       hostname = \"%s\";\n"
                "       vpid = %d;\n"
                "       procname = \"%s\";\n"
                "       domain = \"ust\";\n"
@@ -1171,6 +1206,7 @@ int _ltt_session_metadata_statedump(struct ltt_session *session)
                "       tracer_minor = %u;\n"
                "       tracer_patchlevel = %u;\n"
                "};\n\n",
+               hostname,
                (int) getpid(),
                procname,
                LTTNG_UST_MAJOR_VERSION,
@@ -1329,6 +1365,9 @@ struct session_wildcard *add_wildcard(struct ltt_channel *chan,
        size_t name_len = strlen(event_param->name) + 1;
        int found = 0;
 
+       //FIXME: ensure that wildcard re-use pending events, or
+       //re-use actual events, applying its filter on top.
+
        /*
         * Try to find global wildcard entry. Given that this is shared
         * across all sessions, we need to check for exact loglevel
@@ -1356,6 +1395,9 @@ struct session_wildcard *add_wildcard(struct ltt_channel *chan,
                if (!e)
                        return ERR_PTR(-ENOMEM);
                memcpy(&e->name[0], event_param->name, name_len);
+               e->loglevel_type = event_param->loglevel_type;
+               e->loglevel = event_param->loglevel;
+               CDS_INIT_LIST_HEAD(&e->filter_bytecode);
                cds_list_add(&e->list, &wildcard_list);
                CDS_INIT_LIST_HEAD(&e->session_list);
        }
@@ -1377,6 +1419,7 @@ struct session_wildcard *add_wildcard(struct ltt_channel *chan,
        sw->event_param.instrumentation = LTTNG_UST_TRACEPOINT;
        sw->event_param.loglevel_type = event_param->loglevel_type;
        sw->event_param.loglevel = event_param->loglevel;
+       CDS_INIT_LIST_HEAD(&sw->filter_bytecode);
        CDS_INIT_LIST_HEAD(&sw->events);
        cds_list_add(&sw->list, &chan->session->wildcards);
        cds_list_add(&sw->session_list, &e->session_list);
@@ -1409,6 +1452,7 @@ void _remove_wildcard(struct session_wildcard *wildcard)
                cds_list_del(&wildcard->entry->list);
                free(wildcard->entry);
        }
+       lttng_free_wildcard_filter_bytecode(wildcard);
        free(wildcard);
 }
 
@@ -1476,7 +1520,7 @@ int ltt_wildcard_disable(struct session_wildcard *wildcard)
  */
 void lttng_fixup_event_tls(void)
 {
-       unsigned char uuid[37];
+       unsigned char uuid[LTTNG_UST_UUID_STR_LEN];
 
-       (void) uuid_generate(uuid);
+       (void) lttng_ust_uuid_generate(uuid);
 }
This page took 0.028036 seconds and 4 git commands to generate.