Fix: add missing UST perf counter support check
[lttng-tools.git] / src / bin / lttng-sessiond / trace-ust.c
index 96225a21b4846e974ffb1f900c054202759e3b5a..4f06f1b06d149635080e99edc616978cca3ae7ba 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 */
@@ -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;
@@ -336,6 +366,7 @@ error:
 
 /*
  * Allocate and initialize a ust event. Set name and event type.
+ * We own filter_expression, filter, and exclusion.
  *
  * Return pointer to structure or NULL.
  */
@@ -411,6 +442,9 @@ struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev,
 error_free_event:
        free(lue);
 error:
+       free(filter_expression);
+       free(filter);
+       free(exclusion);
        return NULL;
 }
 
@@ -436,7 +470,12 @@ int trace_ust_context_type_event_to_ust(enum lttng_event_context_type type)
                utype = LTTNG_UST_CONTEXT_IP;
                break;
        case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
-               utype = LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER;
+               if (!ustctl_has_perf_counters()) {
+                       utype = -1;
+                       WARN("Perf counters not implemented in UST");
+               } else {
+                       utype = LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER;
+               }
                break;
        default:
                ERR("Invalid UST context");
@@ -712,7 +751,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);
 
@@ -720,7 +761,17 @@ 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) {
+               int ret = lttng_ht_del(session->agents, &iter);
+
+               assert(!ret);
+               agent_destroy(agt);
+       }
+       rcu_read_unlock();
+
+       ht_cleanup_push(session->agents);
 
        /* Cleanup UID buffer registry object(s). */
        cds_list_for_each_entry_safe(reg, sreg, &session->buffer_reg_uid_list,
This page took 0.02555 seconds and 4 git commands to generate.