Fix: tests: fix unused-but-set warning in test_fd_tracker.c
[lttng-tools.git] / src / bin / lttng-sessiond / agent.c
index 310a7e8e1f7513dba73bd9d8d6a07ed16998eead..77846b4f2251e7891d4f32b5ad196da4f4535f53 100644 (file)
@@ -1,26 +1,25 @@
 /*
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License, version 2 only, as
- * published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
  *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #define _LGPL_SOURCE
-#include <assert.h>
 #include <urcu/uatomic.h>
 #include <urcu/rculist.h>
 
+#include <lttng/event-rule/event-rule.h>
+#include <lttng/event-rule/event-rule-internal.h>
+#include <lttng/event-rule/jul-logging.h>
+#include <lttng/event-rule/log4j-logging.h>
+#include <lttng/event-rule/python-logging.h>
+#include <lttng/condition/condition.h>
+#include <lttng/condition/event-rule-matches.h>
+#include <lttng/domain-internal.h>
+#include <lttng/log-level-rule-internal.h>
+
 #include <common/common.h>
 #include <common/sessiond-comm/agent.h>
 
 
 #define AGENT_RET_CODE_INDEX(code) (code - AGENT_RET_CODE_SUCCESS)
 
+typedef enum lttng_event_rule_status (*event_rule_logging_get_name_pattern)(
+               const struct lttng_event_rule *rule, const char **pattern);
+typedef enum lttng_event_rule_status (*event_rule_logging_get_log_level_rule)(
+               const struct lttng_event_rule *rule,
+               const struct lttng_log_level_rule **log_level_rule);
+
 /*
  * Agent application context representation.
  */
@@ -91,8 +96,8 @@ static int ht_match_event_by_name(struct cds_lfht_node *node,
        struct agent_event *event;
        const struct agent_ht_key *key;
 
-       assert(node);
-       assert(_key);
+       LTTNG_ASSERT(node);
+       LTTNG_ASSERT(_key);
 
        event = caa_container_of(node, struct agent_event, node.node);
        key = _key;
@@ -111,7 +116,8 @@ no_match:
 }
 
 /*
- * Match function for the events hash table lookup by name and loglevel.
+ * Match function for the events hash table lookup by name, log level and
+ * filter expression.
  */
 static int ht_match_event(struct cds_lfht_node *node,
                const void *_key)
@@ -120,8 +126,8 @@ static int ht_match_event(struct cds_lfht_node *node,
        const struct agent_ht_key *key;
        int ll_match;
 
-       assert(node);
-       assert(_key);
+       LTTNG_ASSERT(node);
+       LTTNG_ASSERT(_key);
 
        event = caa_container_of(node, struct agent_event, node.node);
        key = _key;
@@ -143,7 +149,7 @@ static int ht_match_event(struct cds_lfht_node *node,
        }
 
        /* Filter expression */
-       if (!!event->filter_expression ^ !!key->filter_expression) {
+       if (!!event->filter_expression != !!key->filter_expression) {
                /* One has a filter expression, the other does not */
                goto no_match;
        }
@@ -170,9 +176,9 @@ static void add_unique_agent_event(struct lttng_ht *ht,
        struct cds_lfht_node *node_ptr;
        struct agent_ht_key key;
 
-       assert(ht);
-       assert(ht->ht);
-       assert(event);
+       LTTNG_ASSERT(ht);
+       LTTNG_ASSERT(ht->ht);
+       LTTNG_ASSERT(event);
 
        key.name = event->name;
        key.loglevel_value = event->loglevel_value;
@@ -182,7 +188,7 @@ static void add_unique_agent_event(struct lttng_ht *ht,
        node_ptr = cds_lfht_add_unique(ht->ht,
                        ht->hash_fct(event->node.key, lttng_ht_seed),
                        ht_match_event, &key, &event->node.node);
-       assert(node_ptr == &event->node.node);
+       LTTNG_ASSERT(node_ptr == &event->node.node);
 }
 
 /*
@@ -224,7 +230,7 @@ static int send_header(struct lttcomm_sock *sock, uint64_t data_size,
        ssize_t size;
        struct lttcomm_agent_hdr msg;
 
-       assert(sock);
+       LTTNG_ASSERT(sock);
 
        memset(&msg, 0, sizeof(msg));
        msg.data_size = htobe64(data_size);
@@ -254,8 +260,8 @@ static int send_payload(struct lttcomm_sock *sock, const void *data,
        int ret;
        ssize_t len;
 
-       assert(sock);
-       assert(data);
+       LTTNG_ASSERT(sock);
+       LTTNG_ASSERT(data);
 
        len = sock->ops->sendmsg(sock, data, size, 0);
        if (len < size) {
@@ -279,8 +285,8 @@ static int recv_reply(struct lttcomm_sock *sock, void *buf, size_t size)
        int ret;
        ssize_t len;
 
-       assert(sock);
-       assert(buf);
+       LTTNG_ASSERT(sock);
+       LTTNG_ASSERT(buf);
 
        len = sock->ops->recvmsg(sock, buf, size, 0);
        if (len < size) {
@@ -310,9 +316,9 @@ static ssize_t list_events(struct agent_app *app, struct lttng_event **events)
        struct lttcomm_agent_list_reply *reply = NULL;
        struct lttcomm_agent_list_reply_hdr reply_hdr;
 
-       assert(app);
-       assert(app->sock);
-       assert(events);
+       LTTNG_ASSERT(app);
+       LTTNG_ASSERT(app->sock);
+       LTTNG_ASSERT(events);
 
        DBG2("Agent listing events for app pid: %d and socket %d", app->pid,
                        app->sock->fd);
@@ -390,7 +396,7 @@ error:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR* code.
  */
-static int enable_event(struct agent_app *app, struct agent_event *event)
+static int enable_event(const struct agent_app *app, struct agent_event *event)
 {
        int ret;
        char *bytes_to_send;
@@ -400,9 +406,9 @@ static int enable_event(struct agent_app *app, struct agent_event *event)
        struct lttcomm_agent_enable_event msg;
        struct lttcomm_agent_generic_reply reply;
 
-       assert(app);
-       assert(app->sock);
-       assert(event);
+       LTTNG_ASSERT(app);
+       LTTNG_ASSERT(app->sock);
+       LTTNG_ASSERT(event);
 
        DBG2("Agent enabling event %s for app pid: %d and socket %d", event->name,
                        app->pid, app->sock->fd);
@@ -505,18 +511,18 @@ end:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR* code.
  */
-static int app_context_op(struct agent_app *app,
-               struct agent_app_ctx *ctx, enum lttcomm_agent_command cmd)
+static int app_context_op(const struct agent_app *app,
+               const struct agent_app_ctx *ctx, enum lttcomm_agent_command cmd)
 {
        int ret;
        uint32_t reply_ret_code;
        struct lttcomm_agent_generic_reply reply;
        size_t app_ctx_provider_name_len, app_ctx_name_len, data_size;
 
-       assert(app);
-       assert(app->sock);
-       assert(ctx);
-       assert(cmd == AGENT_CMD_APP_CTX_ENABLE ||
+       LTTNG_ASSERT(app);
+       LTTNG_ASSERT(app->sock);
+       LTTNG_ASSERT(ctx);
+       LTTNG_ASSERT(cmd == AGENT_CMD_APP_CTX_ENABLE ||
                        cmd == AGENT_CMD_APP_CTX_DISABLE);
 
        DBG2("Agent %s application %s:%s for app pid: %d and socket %d",
@@ -596,9 +602,9 @@ static int disable_event(struct agent_app *app, struct agent_event *event)
        struct lttcomm_agent_disable_event msg;
        struct lttcomm_agent_generic_reply reply;
 
-       assert(app);
-       assert(app->sock);
-       assert(event);
+       LTTNG_ASSERT(app);
+       LTTNG_ASSERT(app->sock);
+       LTTNG_ASSERT(event);
 
        DBG2("Agent disabling event %s for app pid: %d and socket %d", event->name,
                        app->pid, app->sock->fd);
@@ -653,8 +659,8 @@ error:
  */
 int agent_send_registration_done(struct agent_app *app)
 {
-       assert(app);
-       assert(app->sock);
+       LTTNG_ASSERT(app);
+       LTTNG_ASSERT(app->sock);
 
        DBG("Agent sending registration done to app socket %d", app->sock->fd);
 
@@ -674,11 +680,11 @@ int agent_enable_event(struct agent_event *event,
        struct agent_app *app;
        struct lttng_ht_iter iter;
 
-       assert(event);
+       LTTNG_ASSERT(event);
 
        rcu_read_lock();
 
-       cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, app,
+       cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
                        node.node) {
                if (app->domain != domain) {
                        continue;
@@ -691,7 +697,7 @@ int agent_enable_event(struct agent_event *event,
                }
        }
 
-       event->enabled = 1;
+       event->enabled_count++;
        ret = LTTNG_OK;
 
 error:
@@ -708,7 +714,7 @@ void destroy_app_ctx(struct agent_app_ctx *ctx)
 }
 
 static
-struct agent_app_ctx *create_app_ctx(struct lttng_event_context *ctx)
+struct agent_app_ctx *create_app_ctx(const struct lttng_event_context *ctx)
 {
        struct agent_app_ctx *agent_ctx = NULL;
 
@@ -716,7 +722,7 @@ struct agent_app_ctx *create_app_ctx(struct lttng_event_context *ctx)
                goto end;
        }
 
-       assert(ctx->ctx == LTTNG_EVENT_CONTEXT_APP_CONTEXT);
+       LTTNG_ASSERT(ctx->ctx == LTTNG_EVENT_CONTEXT_APP_CONTEXT);
        agent_ctx = zmalloc(sizeof(*ctx));
        if (!agent_ctx) {
                goto end;
@@ -738,14 +744,14 @@ end:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR* code.
  */
-int agent_enable_context(struct lttng_event_context *ctx,
+int agent_enable_context(const struct lttng_event_context *ctx,
                enum lttng_domain_type domain)
 {
        int ret;
        struct agent_app *app;
        struct lttng_ht_iter iter;
 
-       assert(ctx);
+       LTTNG_ASSERT(ctx);
        if (ctx->ctx != LTTNG_EVENT_CONTEXT_APP_CONTEXT) {
                ret = LTTNG_ERR_INVALID;
                goto error;
@@ -753,7 +759,7 @@ int agent_enable_context(struct lttng_event_context *ctx,
 
        rcu_read_lock();
 
-       cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, app,
+       cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
                        node.node) {
                struct agent_app_ctx *agent_ctx;
 
@@ -796,14 +802,24 @@ int agent_disable_event(struct agent_event *event,
        struct agent_app *app;
        struct lttng_ht_iter iter;
 
-       assert(event);
-       if (!event->enabled) {
+       LTTNG_ASSERT(event);
+       if (!AGENT_EVENT_IS_ENABLED(event)) {
+               goto end;
+       }
+
+       if (--event->enabled_count != 0) {
+               /*
+                * Agent event still enabled. Disable the agent event only when
+                * all "users" have disabled it (event notifiers, event rules,
+                * etc.).
+                */
+               ret = LTTNG_OK;
                goto end;
        }
 
        rcu_read_lock();
 
-       cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, app,
+       cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
                        node.node) {
                if (app->domain != domain) {
                        continue;
@@ -816,7 +832,8 @@ int agent_disable_event(struct agent_event *event,
                }
        }
 
-       event->enabled = 0;
+       /* event->enabled_count is now 0. */
+       LTTNG_ASSERT(!AGENT_EVENT_IS_ENABLED(event));
 
 error:
        rcu_read_unlock();
@@ -830,18 +847,19 @@ end:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR* code.
  */
-int disable_context(struct agent_app_ctx *ctx, enum lttng_domain_type domain)
+static int disable_context(struct agent_app_ctx *ctx,
+               enum lttng_domain_type domain)
 {
        int ret = LTTNG_OK;
        struct agent_app *app;
        struct lttng_ht_iter iter;
 
-       assert(ctx);
+       LTTNG_ASSERT(ctx);
 
        rcu_read_lock();
        DBG2("Disabling agent application context %s:%s",
                        ctx->provider_name, ctx->ctx_name);
-       cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, app,
+       cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
                        node.node) {
                if (app->domain != domain) {
                        continue;
@@ -872,7 +890,7 @@ int agent_list_events(struct lttng_event **events,
        struct lttng_event *tmp_events = NULL;
        struct lttng_ht_iter iter;
 
-       assert(events);
+       LTTNG_ASSERT(events);
 
        DBG2("Agent listing events for domain %d", domain);
 
@@ -885,7 +903,7 @@ int agent_list_events(struct lttng_event **events,
        }
 
        rcu_read_lock();
-       cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, app,
+       cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
                        node.node) {
                ssize_t nb_ev;
                struct lttng_event *agent_events;
@@ -951,11 +969,11 @@ struct agent_app *agent_create_app(pid_t pid, enum lttng_domain_type domain,
 {
        struct agent_app *app;
 
-       assert(sock);
+       LTTNG_ASSERT(sock);
 
        app = zmalloc(sizeof(*app));
        if (!app) {
-               PERROR("zmalloc agent create");
+               PERROR("Failed to allocate agent application instance");
                goto error;
        }
 
@@ -981,9 +999,10 @@ struct agent_app *agent_find_app_by_sock(int sock)
        struct lttng_ht_iter iter;
        struct agent_app *app;
 
-       assert(sock >= 0);
+       LTTNG_ASSERT(sock >= 0);
 
-       lttng_ht_lookup(agent_apps_ht_by_sock, (void *)((unsigned long) sock), &iter);
+       lttng_ht_lookup(the_agent_apps_ht_by_sock,
+                       (void *) ((unsigned long) sock), &iter);
        node = lttng_ht_iter_get_node_ulong(&iter);
        if (node == NULL) {
                goto error;
@@ -1003,10 +1022,10 @@ error:
  */
 void agent_add_app(struct agent_app *app)
 {
-       assert(app);
+       LTTNG_ASSERT(app);
 
        DBG3("Agent adding app sock: %d and pid: %d to ht", app->sock->fd, app->pid);
-       lttng_ht_add_unique_ulong(agent_apps_ht_by_sock, &app->node);
+       lttng_ht_add_unique_ulong(the_agent_apps_ht_by_sock, &app->node);
 }
 
 /*
@@ -1019,13 +1038,13 @@ void agent_delete_app(struct agent_app *app)
        int ret;
        struct lttng_ht_iter iter;
 
-       assert(app);
+       LTTNG_ASSERT(app);
 
        DBG3("Agent deleting app pid: %d and sock: %d", app->pid, app->sock->fd);
 
        iter.iter.node = &app->node.node;
-       ret = lttng_ht_del(agent_apps_ht_by_sock, &iter);
-       assert(!ret);
+       ret = lttng_ht_del(the_agent_apps_ht_by_sock, &iter);
+       LTTNG_ASSERT(!ret);
 }
 
 /*
@@ -1035,7 +1054,7 @@ void agent_delete_app(struct agent_app *app)
  */
 void agent_destroy_app(struct agent_app *app)
 {
-       assert(app);
+       LTTNG_ASSERT(app);
 
        if (app->sock) {
                app->sock->ops->close(app->sock);
@@ -1054,7 +1073,7 @@ int agent_init(struct agent *agt)
 {
        int ret;
 
-       assert(agt);
+       LTTNG_ASSERT(agt);
 
        agt->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
        if (!agt->events) {
@@ -1075,8 +1094,8 @@ error:
  */
 void agent_add(struct agent *agt, struct lttng_ht *ht)
 {
-       assert(agt);
-       assert(ht);
+       LTTNG_ASSERT(agt);
+       LTTNG_ASSERT(ht);
 
        DBG3("Agent adding from domain %d", agt->domain);
 
@@ -1118,7 +1137,7 @@ error:
  */
 struct agent_event *agent_create_event(const char *name,
                enum lttng_loglevel_type loglevel_type, int loglevel_value,
-               struct lttng_filter_bytecode *filter, char *filter_expression)
+               struct lttng_bytecode *filter, char *filter_expression)
 {
        struct agent_event *event = NULL;
 
@@ -1154,9 +1173,9 @@ error:
  */
 void agent_add_event(struct agent_event *event, struct agent *agt)
 {
-       assert(event);
-       assert(agt);
-       assert(agt->events);
+       LTTNG_ASSERT(event);
+       LTTNG_ASSERT(agt);
+       LTTNG_ASSERT(agt->events);
 
        DBG3("Agent adding event %s", event->name);
        add_unique_agent_event(agt->events, event);
@@ -1166,15 +1185,15 @@ void agent_add_event(struct agent_event *event, struct agent *agt)
 /*
  * Unique add of a agent context to an agent object.
  */
-int agent_add_context(struct lttng_event_context *ctx, struct agent *agt)
+int agent_add_context(const struct lttng_event_context *ctx, struct agent *agt)
 {
        int ret = LTTNG_OK;
        struct agent_app_ctx *agent_ctx = NULL;
 
-       assert(ctx);
-       assert(agt);
-       assert(agt->events);
-       assert(ctx->ctx == LTTNG_EVENT_CONTEXT_APP_CONTEXT);
+       LTTNG_ASSERT(ctx);
+       LTTNG_ASSERT(agt);
+       LTTNG_ASSERT(agt->events);
+       LTTNG_ASSERT(ctx->ctx == LTTNG_EVENT_CONTEXT_APP_CONTEXT);
 
        agent_ctx = create_app_ctx(ctx);
        if (!agent_ctx) {
@@ -1203,10 +1222,10 @@ void agent_find_events_by_name(const char *name, struct agent *agt,
        struct lttng_ht *ht;
        struct agent_ht_key key;
 
-       assert(name);
-       assert(agt);
-       assert(agt->events);
-       assert(iter);
+       LTTNG_ASSERT(name);
+       LTTNG_ASSERT(agt);
+       LTTNG_ASSERT(agt->events);
+       LTTNG_ASSERT(iter);
 
        ht = agt->events;
        key.name = name;
@@ -1215,6 +1234,93 @@ void agent_find_events_by_name(const char *name, struct agent *agt,
                        ht_match_event_by_name, &key, &iter->iter);
 }
 
+/*
+ * Find the agent event matching a trigger.
+ *
+ * RCU read side lock MUST be acquired. It must be held for as long as
+ * the returned agent_event is used.
+ *
+ * Return object if found else NULL.
+ */
+struct agent_event *agent_find_event_by_trigger(
+               const struct lttng_trigger *trigger, struct agent *agt)
+{
+       enum lttng_condition_status c_status;
+       enum lttng_event_rule_status er_status;
+       enum lttng_domain_type domain;
+       const struct lttng_condition *condition;
+       const struct lttng_event_rule *rule;
+       const char *name;
+       const char *filter_expression;
+       const struct lttng_log_level_rule *log_level_rule;
+       /* Unused when loglevel_type is 'ALL'. */
+       int loglevel_value = 0;
+       enum lttng_loglevel_type loglevel_type;
+       event_rule_logging_get_name_pattern logging_get_name_pattern;
+       event_rule_logging_get_log_level_rule logging_get_log_level_rule;
+
+       LTTNG_ASSERT(agt);
+       LTTNG_ASSERT(agt->events);
+
+       condition = lttng_trigger_get_const_condition(trigger);
+
+       LTTNG_ASSERT(lttng_condition_get_type(condition) ==
+                       LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES);
+
+       c_status = lttng_condition_event_rule_matches_get_rule(
+                       condition, &rule);
+       LTTNG_ASSERT(c_status == LTTNG_CONDITION_STATUS_OK);
+
+       switch (lttng_event_rule_get_type(rule)) {
+       case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
+               logging_get_name_pattern =
+                               lttng_event_rule_jul_logging_get_name_pattern;
+               logging_get_log_level_rule =
+                               lttng_event_rule_jul_logging_get_log_level_rule;
+               break;
+       case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
+               logging_get_name_pattern =
+                               lttng_event_rule_log4j_logging_get_name_pattern;
+               logging_get_log_level_rule =
+                               lttng_event_rule_log4j_logging_get_log_level_rule;
+               break;
+       case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
+               logging_get_name_pattern =
+                               lttng_event_rule_python_logging_get_name_pattern;
+               logging_get_log_level_rule =
+                               lttng_event_rule_python_logging_get_log_level_rule;
+               break;
+       default:
+               abort();
+               break;
+       }
+
+       domain = lttng_event_rule_get_domain_type(rule);
+       LTTNG_ASSERT(domain == LTTNG_DOMAIN_JUL || domain == LTTNG_DOMAIN_LOG4J ||
+                       domain == LTTNG_DOMAIN_PYTHON);
+
+       /* Get the event's pattern name ('name' in the legacy terminology). */
+       er_status = logging_get_name_pattern(rule, &name);
+       LTTNG_ASSERT(er_status == LTTNG_EVENT_RULE_STATUS_OK);
+
+       /* Get the internal filter expression. */
+       filter_expression = lttng_event_rule_get_filter(rule);
+
+       /* Map log_level_rule to loglevel value. */
+       er_status = logging_get_log_level_rule(rule, &log_level_rule);
+       if (er_status == LTTNG_EVENT_RULE_STATUS_UNSET) {
+               loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
+               loglevel_value = 0;
+       } else if (er_status == LTTNG_EVENT_RULE_STATUS_OK) {
+               lttng_log_level_rule_to_loglevel(log_level_rule, &loglevel_type, &loglevel_value);
+       } else {
+               abort();
+       }
+
+       return agent_find_event(name, loglevel_type, loglevel_value,
+                       filter_expression, agt);
+}
+
 /*
  * Get the next agent event duplicate by name. This should be called
  * after a call to agent_find_events_by_name() to iterate on events.
@@ -1242,17 +1348,19 @@ void agent_event_next_duplicate(const char *name,
  * Return object if found else NULL.
  */
 struct agent_event *agent_find_event(const char *name,
-               enum lttng_loglevel_type loglevel_type, int loglevel_value,
-               char *filter_expression, struct agent *agt)
+               enum lttng_loglevel_type loglevel_type,
+               int loglevel_value,
+               const char *filter_expression,
+               struct agent *agt)
 {
        struct lttng_ht_node_str *node;
        struct lttng_ht_iter iter;
        struct lttng_ht *ht;
        struct agent_ht_key key;
 
-       assert(name);
-       assert(agt);
-       assert(agt->events);
+       LTTNG_ASSERT(name);
+       LTTNG_ASSERT(agt);
+       LTTNG_ASSERT(agt->events);
 
        ht = agt->events;
        key.name = name;
@@ -1282,7 +1390,7 @@ error:
  */
 void agent_destroy_event(struct agent_event *event)
 {
-       assert(event);
+       LTTNG_ASSERT(event);
 
        free(event->filter);
        free(event->filter_expression);
@@ -1308,7 +1416,7 @@ void agent_destroy(struct agent *agt)
        struct lttng_ht_iter iter;
        struct agent_app_ctx *ctx;
 
-       assert(agt);
+       LTTNG_ASSERT(agt);
 
        DBG3("Agent destroy");
 
@@ -1327,7 +1435,7 @@ void agent_destroy(struct agent *agt)
                (void) agent_disable_event(event, agt->domain);
 
                ret = lttng_ht_del(agt->events, &iter);
-               assert(!ret);
+               LTTNG_ASSERT(!ret);
                call_rcu(&node->head, destroy_event_agent_rcu);
        }
 
@@ -1346,14 +1454,8 @@ void agent_destroy(struct agent *agt)
  */
 int agent_app_ht_alloc(void)
 {
-       int ret = 0;
-
-       agent_apps_ht_by_sock = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
-       if (!agent_apps_ht_by_sock) {
-               ret = -1;
-       }
-
-       return ret;
+       the_agent_apps_ht_by_sock = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
+       return the_agent_apps_ht_by_sock ? 0 : -1;
 }
 
 /*
@@ -1363,7 +1465,7 @@ void agent_destroy_app_by_sock(int sock)
 {
        struct agent_app *app;
 
-       assert(sock >= 0);
+       LTTNG_ASSERT(sock >= 0);
 
        /*
         * Not finding an application is a very important error that should NEVER
@@ -1372,7 +1474,7 @@ void agent_destroy_app_by_sock(int sock)
         */
        rcu_read_lock();
        app = agent_find_app_by_sock(sock);
-       assert(app);
+       LTTNG_ASSERT(app);
 
        /* RCU read side lock is assumed to be held by this function. */
        agent_delete_app(app);
@@ -1390,11 +1492,12 @@ void agent_app_ht_clean(void)
        struct lttng_ht_node_ulong *node;
        struct lttng_ht_iter iter;
 
-       if (!agent_apps_ht_by_sock) {
+       if (!the_agent_apps_ht_by_sock) {
                return;
        }
        rcu_read_lock();
-       cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, node, node) {
+       cds_lfht_for_each_entry(
+                       the_agent_apps_ht_by_sock->ht, &iter.iter, node, node) {
                struct agent_app *app;
 
                app = caa_container_of(node, struct agent_app, node);
@@ -1402,7 +1505,7 @@ void agent_app_ht_clean(void)
        }
        rcu_read_unlock();
 
-       lttng_ht_destroy(agent_apps_ht_by_sock);
+       lttng_ht_destroy(the_agent_apps_ht_by_sock);
 }
 
 /*
@@ -1411,29 +1514,27 @@ void agent_app_ht_clean(void)
  * Note that this function is most likely to be used with a tracing session
  * thus the caller should make sure to hold the appropriate lock(s).
  */
-void agent_update(struct agent *agt, int sock)
+void agent_update(const struct agent *agt, const struct agent_app *app)
 {
        int ret;
-       struct agent_app *app;
        struct agent_event *event;
        struct lttng_ht_iter iter;
        struct agent_app_ctx *ctx;
 
-       assert(agt);
-       assert(sock >= 0);
+       LTTNG_ASSERT(agt);
+       LTTNG_ASSERT(app);
 
-       DBG("Agent updating app socket %d", sock);
+       DBG("Agent updating app: pid = %ld", (long) app->pid);
 
        rcu_read_lock();
-       app = agent_find_app_by_sock(sock);
        /*
         * We are in the registration path thus if the application is gone,
         * there is a serious code flow error.
         */
-       assert(app);
+
        cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) {
                /* Skip event if disabled. */
-               if (!event->enabled) {
+               if (!AGENT_EVENT_IS_ENABLED(event)) {
                        continue;
                }
 
@@ -1458,3 +1559,66 @@ void agent_update(struct agent *agt, int sock)
 
        rcu_read_unlock();
 }
+
+/*
+ * Allocate the per-event notifier domain agent hash table. It is lazily
+ * populated as domains are used.
+ */
+int agent_by_event_notifier_domain_ht_create(void)
+{
+       the_trigger_agents_ht_by_domain = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+       return the_trigger_agents_ht_by_domain ? 0 : -1;
+}
+
+/*
+ * Clean-up the per-event notifier domain agent hash table and destroy it.
+ */
+void agent_by_event_notifier_domain_ht_destroy(void)
+{
+       struct lttng_ht_node_u64 *node;
+       struct lttng_ht_iter iter;
+
+       if (!the_trigger_agents_ht_by_domain) {
+               return;
+       }
+
+       rcu_read_lock();
+       cds_lfht_for_each_entry(the_trigger_agents_ht_by_domain->ht,
+                       &iter.iter, node, node) {
+               struct agent *agent =
+                               caa_container_of(node, struct agent, node);
+               const int ret = lttng_ht_del(
+                               the_trigger_agents_ht_by_domain, &iter);
+
+               LTTNG_ASSERT(ret == 0);
+               agent_destroy(agent);
+       }
+
+       rcu_read_unlock();
+       lttng_ht_destroy(the_trigger_agents_ht_by_domain);
+}
+
+struct agent *agent_find_by_event_notifier_domain(
+               enum lttng_domain_type domain_type)
+{
+       struct agent *agt = NULL;
+       struct lttng_ht_node_u64 *node;
+       struct lttng_ht_iter iter;
+       const uint64_t key = (uint64_t) domain_type;
+
+       LTTNG_ASSERT(the_trigger_agents_ht_by_domain);
+
+       DBG3("Per-event notifier domain agent lookup for domain '%s'",
+                       lttng_domain_type_str(domain_type));
+
+       lttng_ht_lookup(the_trigger_agents_ht_by_domain, &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;
+}
This page took 0.035344 seconds and 4 git commands to generate.