Fix: define _LGPL_SOURCE in C files
[lttng-tools.git] / src / bin / lttng-sessiond / trace-ust.c
index 996916558f8b3a0d5fd1c3d5945fe11783368d53..0e386aa0327f2f430806321766e2a4e2516b64dc 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #define _GNU_SOURCE
+#define _LGPL_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -199,6 +200,38 @@ error:
        return NULL;
 }
 
+/*
+ * Lookup an agent in the session agents hash table by domain type and return
+ * the object if found else NULL.
+ *
+ * RCU read side lock must be acquired before calling and only released
+ * once the agent is no longer in scope or being used.
+ */
+struct agent *trace_ust_find_agent(struct ltt_ust_session *session,
+               enum lttng_domain_type domain_type)
+{
+       struct agent *agt = NULL;
+       struct lttng_ht_node_u64 *node;
+       struct lttng_ht_iter iter;
+       uint64_t key;
+
+       assert(session);
+
+       DBG3("Trace ust agent lookup for domain %d", domain_type);
+
+       key = domain_type;
+
+       lttng_ht_lookup(session->agents, &key, &iter);
+       node = lttng_ht_iter_get_node_u64(&iter);
+       if (!node) {
+               goto end;
+       }
+       agt = caa_container_of(node, struct agent, node);
+
+end:
+       return agt;
+}
+
 /*
  * Allocate and initialize a ust session data structure.
  *
@@ -206,7 +239,6 @@ error:
  */
 struct ltt_ust_session *trace_ust_create_session(uint64_t session_id)
 {
-       int ret;
        struct ltt_ust_session *lus;
 
        /* Allocate a new ltt ust session */
@@ -218,7 +250,7 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id)
 
        /* Init data structure */
        lus->id = session_id;
-       lus->start_trace = 0;
+       lus->active = 0;
 
        /* Set default metadata channel attribute. */
        lus->metadata_attr.overwrite = DEFAULT_CHANNEL_OVERWRITE;
@@ -242,10 +274,8 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id)
 
        /* Alloc UST global domain channels' HT */
        lus->domain_global.channels = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
-       ret = jul_init_domain(&lus->domain_jul);
-       if (ret < 0) {
-               goto error_consumer;
-       }
+       /* Alloc agent hash table. */
+       lus->agents = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
 
        lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
        if (lus->consumer == NULL) {
@@ -266,7 +296,7 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id)
 
 error_consumer:
        ht_cleanup_push(lus->domain_global.channels);
-       jul_destroy_domain(&lus->domain_jul);
+       ht_cleanup_push(lus->agents);
        free(lus);
 error:
        return NULL;
@@ -340,6 +370,7 @@ error:
  * Return pointer to structure or NULL.
  */
 struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev,
+               char *filter_expression,
                struct lttng_filter_bytecode *filter,
                struct lttng_event_exclusion *exclusion)
 {
@@ -394,6 +425,7 @@ struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev,
        }
 
        /* Same layout. */
+       lue->filter_expression = filter_expression;
        lue->filter = (struct lttng_ust_filter_bytecode *) filter;
        lue->exclusion = (struct lttng_event_exclusion *) exclusion;
 
@@ -412,20 +444,12 @@ error:
        return NULL;
 }
 
-/*
- * Allocate and initialize an UST context.
- *
- * Return pointer to structure or NULL.
- */
-struct ltt_ust_context *trace_ust_create_context(
-               struct lttng_event_context *ctx)
+static
+int trace_ust_context_type_event_to_ust(enum lttng_event_context_type type)
 {
-       struct ltt_ust_context *uctx;
-       enum lttng_ust_context_type utype;
-
-       assert(ctx);
+       int utype;
 
-       switch (ctx->ctx) {
+       switch (type) {
        case LTTNG_EVENT_CONTEXT_VTID:
                utype = LTTNG_UST_CONTEXT_VTID;
                break;
@@ -441,8 +465,70 @@ struct ltt_ust_context *trace_ust_create_context(
        case LTTNG_EVENT_CONTEXT_IP:
                utype = LTTNG_UST_CONTEXT_IP;
                break;
+       case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
+               utype = LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER;
+               break;
        default:
                ERR("Invalid UST context");
+               utype = -1;
+               break;
+       }
+       return utype;
+}
+
+/*
+ * Return 1 if contexts match, 0 otherwise.
+ */
+int trace_ust_match_context(struct ltt_ust_context *uctx,
+               struct lttng_event_context *ctx)
+{
+       int utype;
+
+       utype = trace_ust_context_type_event_to_ust(ctx->ctx);
+       if (utype < 0) {
+               return 0;
+       }
+       if (uctx->ctx.ctx != utype) {
+               return 0;
+       }
+       switch (utype) {
+       case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
+               if (uctx->ctx.u.perf_counter.type
+                               != ctx->u.perf_counter.type) {
+                       return 0;
+               }
+               if (uctx->ctx.u.perf_counter.config
+                               != ctx->u.perf_counter.config) {
+                       return 0;
+               }
+               if (strncmp(uctx->ctx.u.perf_counter.name,
+                               ctx->u.perf_counter.name,
+                               LTTNG_UST_SYM_NAME_LEN)) {
+                       return 0;
+               }
+               break;
+       default:
+               break;
+
+       }
+       return 1;
+}
+
+/*
+ * Allocate and initialize an UST context.
+ *
+ * Return pointer to structure or NULL.
+ */
+struct ltt_ust_context *trace_ust_create_context(
+               struct lttng_event_context *ctx)
+{
+       struct ltt_ust_context *uctx;
+       int utype;
+
+       assert(ctx);
+
+       utype = trace_ust_context_type_event_to_ust(ctx->ctx);
+       if (utype < 0) {
                return NULL;
        }
 
@@ -452,9 +538,19 @@ struct ltt_ust_context *trace_ust_create_context(
                goto error;
        }
 
-       uctx->ctx.ctx = utype;
+       uctx->ctx.ctx = (enum lttng_ust_context_type) utype;
+       switch (utype) {
+       case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
+               uctx->ctx.u.perf_counter.type = ctx->u.perf_counter.type;
+               uctx->ctx.u.perf_counter.config = ctx->u.perf_counter.config;
+               strncpy(uctx->ctx.u.perf_counter.name, ctx->u.perf_counter.name,
+                               LTTNG_UST_SYM_NAME_LEN);
+               uctx->ctx.u.perf_counter.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+               break;
+       default:
+               break;
+       }
        lttng_ht_node_init_ulong(&uctx->node, (unsigned long) uctx->ctx.ctx);
-       CDS_INIT_LIST_HEAD(&uctx->list);
 
        return uctx;
 
@@ -511,6 +607,7 @@ void trace_ust_destroy_event(struct ltt_ust_event *event)
        assert(event);
 
        DBG2("Trace destroy UST event %s", event->attr.name);
+       free(event->filter_expression);
        free(event->filter);
        free(event->exclusion);
        free(event);
@@ -645,7 +742,9 @@ static void destroy_domain_global(struct ltt_ust_domain_global *dom)
  */
 void trace_ust_destroy_session(struct ltt_ust_session *session)
 {
+       struct agent *agt;
        struct buffer_reg_uid *reg, *sreg;
+       struct lttng_ht_iter iter;
 
        assert(session);
 
@@ -653,7 +752,13 @@ void trace_ust_destroy_session(struct ltt_ust_session *session)
 
        /* Cleaning up UST domain */
        destroy_domain_global(&session->domain_global);
-       jul_destroy_domain(&session->domain_jul);
+
+       rcu_read_lock();
+       cds_lfht_for_each_entry(session->agents->ht, &iter.iter, agt, node.node) {
+               lttng_ht_del(session->agents, &iter);
+               agent_destroy(agt);
+       }
+       rcu_read_unlock();
 
        /* Cleanup UID buffer registry object(s). */
        cds_list_for_each_entry_safe(reg, sreg, &session->buffer_reg_uid_list,
This page took 0.027775 seconds and 5 git commands to generate.