Fix: disable agent events by name
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 2 Sep 2015 16:55:47 +0000 (12:55 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 8 Sep 2015 14:00:49 +0000 (10:00 -0400)
The event_agent_disable() function only disables the first
agent event matching a given name. However, if multiple agent
events exist with different loglevels, but share the same name,
we want all of them to be disabled at once.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-sessiond/agent.c
src/bin/lttng-sessiond/agent.h
src/bin/lttng-sessiond/event.c

index 10e8b1f3a89ca859478a95c6855223ba5e069ced..eed7e68c6d264dfcd2f5a3c33f92d2804cd47def 100644 (file)
@@ -841,40 +841,47 @@ void agent_add_event(struct agent_event *event, struct agent *agt)
 }
 
 /*
- * Find a agent event in the given agent using name.
+ * Find multiple agent events sharing the given name.
  *
- * RCU read side lock MUST be acquired.
+ * RCU read side lock MUST be acquired. It must be held for the
+ * duration of the iteration.
  *
- * Return object if found else NULL.
+ * Sets the given iterator.
  */
-struct agent_event *agent_find_event_by_name(const char *name,
-               struct agent *agt)
+void agent_find_events_by_name(const char *name, struct agent *agt,
+               struct lttng_ht_iter* iter)
 {
-       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);
+       assert(iter);
 
        ht = agt->events;
        key.name = name;
 
        cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
-                       ht_match_event_by_name, &key, &iter.iter);
-       node = lttng_ht_iter_get_node_str(&iter);
-       if (node == NULL) {
-               goto error;
-       }
+                       ht_match_event_by_name, &key, &iter->iter);
+}
 
-       DBG3("Agent event found %s by name.", name);
-       return caa_container_of(node, struct agent_event, node);
+/*
+ * 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.
+ *
+ * The RCU read lock must be held during the iteration and for as long
+ * as the object the iterator points to remains in use.
+ */
+void agent_event_next_duplicate(const char *name,
+               struct agent *agt, struct lttng_ht_iter* iter)
+{
+       struct agent_ht_key key;
 
-error:
-       DBG3("Agent NOT found by name %s.", name);
-       return NULL;
+       key.name = name;
+
+       cds_lfht_next_duplicate(agt->events->ht, ht_match_event_by_name,
+               &key, &iter->iter);
 }
 
 /*
index fd1c47f3f1150e8f9950f51a3eadc0b77c0e732f..49393e8096202b82a4fb1f6e802201f4f796d8f4 100644 (file)
@@ -141,8 +141,10 @@ void agent_add_event(struct agent_event *event, struct agent *agt);
 struct agent_event *agent_find_event(const char *name,
                enum lttng_loglevel_type loglevel_type, int loglevel_value,
                struct agent *agt);
-struct agent_event *agent_find_event_by_name(const char *name,
-               struct agent *agt);
+void agent_find_events_by_name(const char *name, struct agent *agt,
+               struct lttng_ht_iter* iter);
+void agent_event_next_duplicate(const char *name,
+               struct agent *agt, struct lttng_ht_iter* iter);
 void agent_delete_event(struct agent_event *event, struct agent *agt);
 void agent_destroy_event(struct agent_event *event);
 
index 27ebc4ff3cb3fd86aa17c929247aa3b4b7a210e2..b0652bed00d783203e7c1e23c10c9636f558b3e6 100644 (file)
@@ -483,30 +483,26 @@ const char *event_get_default_agent_ust_name(enum lttng_domain_type domain)
 }
 
 /*
- * Disable a single agent event for a given UST session.
+ * Disable a given agent event for a given UST session.
  *
+ * Must be called with the RCU read lock held.
  * Return LTTNG_OK on success or else a LTTNG_ERR* code.
  */
-int event_agent_disable(struct ltt_ust_session *usess, struct agent *agt,
-               char *event_name)
+static int event_agent_disable_one(struct ltt_ust_session *usess,
+               struct agent *agt, struct agent_event *aevent)
 {
        int ret;
-       struct agent_event *aevent;
        struct ltt_ust_event *uevent = NULL;
        struct ltt_ust_channel *uchan = NULL;
        const char *ust_event_name, *ust_channel_name;
 
        assert(agt);
        assert(usess);
-       assert(event_name);
-
-       DBG("Event agent disabling %s for session %" PRIu64, event_name, usess->id);
+       assert(aevent);
 
-       aevent = agent_find_event_by_name(event_name, agt);
-       if (!aevent) {
-               ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
-               goto error;
-       }
+       DBG("Event agent disabling %s (loglevel type %d, loglevel value %d) for session %" PRIu64,
+               aevent->name, aevent->loglevel_type, aevent->loglevel_value,
+               usess->id);
 
        /* Already disabled? */
        if (!aevent->enabled) {
@@ -575,6 +571,52 @@ end:
 error:
        return ret;
 }
+
+/*
+ * Disable all agent events matching a given name for a given UST session.
+ *
+ * Return LTTNG_OK on success or else a LTTNG_ERR* code.
+ */
+int event_agent_disable(struct ltt_ust_session *usess, struct agent *agt,
+               char *event_name)
+{
+       int ret = LTTNG_OK;
+       struct agent_event *aevent;
+       struct lttng_ht_iter iter;
+       struct lttng_ht_node_str *node;
+
+       assert(agt);
+       assert(usess);
+       assert(event_name);
+
+       DBG("Event agent disabling %s (all loglevels) for session %" PRIu64, event_name, usess->id);
+
+       rcu_read_lock();
+       agent_find_events_by_name(event_name, agt, &iter);
+       node = lttng_ht_iter_get_node_str(&iter);
+
+       if (node == NULL) {
+               DBG2("Event agent NOT found by name %s", event_name);
+               ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
+               goto end;
+       }
+
+       do {
+               aevent = caa_container_of(node, struct agent_event, node);
+               ret = event_agent_disable_one(usess, agt, aevent);
+
+               if (ret != LTTNG_OK) {
+                       goto end;
+               }
+
+               /* Get next duplicate agent event by name. */
+               agent_event_next_duplicate(event_name, agt, &iter);
+               node = lttng_ht_iter_get_node_str(&iter);
+       } while (node);
+end:
+       rcu_read_unlock();
+       return ret;
+}
 /*
  * Disable all agent event for a given UST session.
  *
This page took 0.02916 seconds and 4 git commands to generate.