From: Philippe Proulx Date: Wed, 2 Sep 2015 16:55:47 +0000 (-0400) Subject: Fix: disable agent events by name X-Git-Tag: v2.8.0-rc1~367 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=e261a6cc54e9a5567bf12c963f96fe22e9cf345c Fix: disable agent events by name 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 Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-sessiond/agent.c b/src/bin/lttng-sessiond/agent.c index 33559c89a..bc72ff93f 100644 --- a/src/bin/lttng-sessiond/agent.c +++ b/src/bin/lttng-sessiond/agent.c @@ -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); } /* diff --git a/src/bin/lttng-sessiond/agent.h b/src/bin/lttng-sessiond/agent.h index 949c0d1d4..50a4fdab3 100644 --- a/src/bin/lttng-sessiond/agent.h +++ b/src/bin/lttng-sessiond/agent.h @@ -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); diff --git a/src/bin/lttng-sessiond/event.c b/src/bin/lttng-sessiond/event.c index 06a683658..d7034efa5 100644 --- a/src/bin/lttng-sessiond/event.c +++ b/src/bin/lttng-sessiond/event.c @@ -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. *