}
/*
- * 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);
}
/*
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);
}
/*
- * 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) {
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.
*