#include "trace-kernel.h"
#include "trace-ust.h"
+/*
+ * Add unique UST event based on the event name, filter bytecode and loglevel.
+ */
static void add_unique_ust_event(struct lttng_ht *ht,
struct ltt_ust_event *event)
{
event->type = LTTNG_EVENT_SYSCALL;
}
-/*
- * Return 1 if loglevels match or 0 on failure.
- */
-static int loglevel_match(struct ltt_ust_event *uevent,
- enum lttng_ust_loglevel_type log_type, int loglevel)
-{
- /*
- * For the loglevel type ALL, the loglevel is set to -1 but the event
- * received by the session daemon is 0 which does not match the negative
- * value in the existing event.
- */
- if (log_type == LTTNG_UST_LOGLEVEL_ALL) {
- loglevel = -1;
- }
-
- if (uevent == NULL || uevent->attr.loglevel_type != log_type ||
- uevent->attr.loglevel != loglevel) {
- goto no_match;
- }
-
- return 1;
-
-no_match:
- return 0;
-}
-
/*
* Disable kernel tracepoint event for a channel from the kernel session.
*/
* Enable all UST tracepoints for a channel from a UST session.
*/
int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain,
- struct ltt_ust_channel *uchan)
+ struct ltt_ust_channel *uchan, struct lttng_filter_bytecode *filter)
{
int ret, i, size;
struct lttng_ht_iter iter;
struct ltt_ust_event *uevent = NULL;
struct lttng_event *events = NULL;
+ rcu_read_lock();
+
switch (domain) {
case LTTNG_DOMAIN_UST:
{
* Check if event exist and if so, continue since it was enable
* previously.
*/
- uevent = trace_ust_find_event(uchan->events, events[i].name, NULL,
+ uevent = trace_ust_find_event(uchan->events, events[i].name, filter,
events[i].loglevel);
if (uevent != NULL) {
ret = ust_app_enable_event_pid(usess, uchan, uevent,
}
/* Create ust event */
- uevent = trace_ust_create_event(&events[i]);
+ uevent = trace_ust_create_event(&events[i], filter);
if (uevent == NULL) {
ret = LTTNG_ERR_FATAL;
goto error_destroy;
goto error;
}
+ rcu_read_unlock();
return LTTNG_OK;
error_destroy:
error:
free(events);
+ rcu_read_unlock();
return ret;
}
* Enable UST tracepoint event for a channel from a UST session.
*/
int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain,
- struct ltt_ust_channel *uchan, struct lttng_event *event)
+ struct ltt_ust_channel *uchan, struct lttng_event *event,
+ struct lttng_filter_bytecode *filter)
{
int ret = LTTNG_OK, to_create = 0;
struct ltt_ust_event *uevent;
- DBG3("Enable ust: %s l:%d f:%p", event->name, event->loglevel, NULL);
-
rcu_read_lock();
- uevent = trace_ust_find_event(uchan->events, event->name, NULL,
+ uevent = trace_ust_find_event(uchan->events, event->name, filter,
event->loglevel);
if (uevent == NULL) {
- uevent = trace_ust_create_event(event);
+ uevent = trace_ust_create_event(event, filter);
if (uevent == NULL) {
ret = LTTNG_ERR_UST_ENABLE_FAIL;
goto error;
}
+
/* Valid to set it after the goto error since uevent is still NULL */
to_create = 1;
}
- /* Check loglevels */
- ret = loglevel_match(uevent, event->loglevel_type, event->loglevel);
- if (ret == 0) {
- /*
- * No match meaning that the user tried to enable a known event but
- * with a different loglevel.
- */
- DBG("Enable event %s does not match existing event %s with loglevel "
- "respectively of %d and %d", event->name, uevent->attr.name,
- uevent->attr.loglevel, event->loglevel);
- ret = LTTNG_ERR_EVENT_EXIST_LOGLEVEL;
- goto error;
- }
-
if (uevent->enabled) {
/* It's already enabled so everything is OK */
- ret = LTTNG_OK;
+ ret = LTTNG_ERR_UST_EVENT_ENABLED;
goto end;
}
struct ltt_ust_event *uevent;
struct lttng_ht_node_str *node;
struct lttng_ht_iter iter;
- void *orig_match_fct;
struct lttng_ht *ht;
ht = uchan->events;
- /* Save match function so we can use the event by name match. */
- orig_match_fct = (void *) ht->match_fct;
- ht->match_fct = trace_ust_ht_match_event_by_name;
-
rcu_read_lock();
- lttng_ht_lookup(ht, (void *) event_name, &iter);
+
+ /*
+ * We use a custom lookup since we need the iterator for the next_duplicate
+ * call in the do while loop below.
+ */
+ cds_lfht_lookup(ht->ht, ht->hash_fct((void *) event_name, lttng_ht_seed),
+ trace_ust_ht_match_event_by_name, event_name, &iter.iter);
node = lttng_ht_iter_get_node_str(&iter);
if (node == NULL) {
DBG2("Trace UST event NOT found by name %s", event_name);
do {
uevent = caa_container_of(node, struct ltt_ust_event, node);
+ assert(uevent);
+
if (uevent->enabled == 0) {
/* It's already disabled so everything is OK */
ret = LTTNG_OK;
uevent->enabled = 0;
+ DBG2("Event UST %s disabled in channel %s", uevent->attr.name,
+ uchan->name);
+
/* Get next duplicate event by name. */
cds_lfht_next_duplicate(ht->ht, trace_ust_ht_match_event_by_name,
event_name, &iter.iter);
ret = LTTNG_OK;
- DBG2("Event UST %s disabled in channel %s", uevent->attr.name,
- uchan->name);
error:
- ht->match_fct = orig_match_fct;
rcu_read_unlock();
return ret;
}
struct ltt_ust_event *uevent = NULL;
struct lttng_event *events = NULL;
+ rcu_read_lock();
+
switch (domain) {
case LTTNG_DOMAIN_UST:
{
cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent,
node.node) {
if (uevent->enabled == 1) {
- ret = ust_app_disable_event_glb(usess, uchan, uevent);
+ ret = event_ust_disable_tracepoint(usess, domain, uchan,
+ uevent->attr.name);
if (ret < 0) {
continue;
}
- uevent->enabled = 0;
}
}
goto error;
}
+ rcu_read_unlock();
return LTTNG_OK;
error:
free(events);
+ rcu_read_unlock();
return ret;
}