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>
Sun, 6 Sep 2015 23:45:11 +0000 (19:45 -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 33559c89a9423ea13b322d90c5db9995269d9f21..bc72ff93f61ed16c7fa43c8a236c2d8464d7401c 100644 (file)
@@ -874,40 +874,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 949c0d1d47ff79727c1e77b4e895018dcf6d67cc..50a4fdab353b658a1ea8e0cc62a89ee3fcf1b665 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 06a683658510d7db5ea6f4d63aba317f37d75886..d7034efa5fc20175c019bd4426a1d3c4f0af1d6b 100644 (file)
@@ -476,30 +476,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) {
@@ -568,6 +564,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.028204 seconds and 4 git commands to generate.