X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fevent.c;h=dd2e4b382fa46ca76978898a2a0e1b38bd8ccf9c;hp=125adb9a058bf4fdedac31a1daaeaa02733c26c5;hb=refs%2Fheads%2Fsow-2020-0002-rev2;hpb=11f6ce94d8fb73f017888681aaba5d7df55fc735 diff --git a/src/bin/lttng-sessiond/event.c b/src/bin/lttng-sessiond/event.c index 125adb9a0..dd2e4b382 100644 --- a/src/bin/lttng-sessiond/event.c +++ b/src/bin/lttng-sessiond/event.c @@ -13,13 +13,14 @@ #include #include #include -#include +#include #include #include #include #include #include #include +#include #include #include "channel.h" @@ -38,7 +39,7 @@ * 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) + struct ltt_ust_event *event, struct lttng_map_key *map_key) { struct cds_lfht_node *node_ptr; struct ltt_ust_ht_key key; @@ -52,6 +53,7 @@ static void add_unique_ust_event(struct lttng_ht *ht, key.loglevel_type = event->attr.loglevel_type; key.loglevel_value = event->attr.loglevel; key.exclusion = event->exclusion; + key.key = map_key; node_ptr = cds_lfht_add_unique(ht->ht, ht->hash_fct(event->node.key, lttng_ht_seed), @@ -113,8 +115,8 @@ int event_kernel_enable_event(struct ltt_kernel_channel *kchan, assert(kchan); assert(event); - kevent = trace_kernel_find_event(event->name, kchan, - event->type, filter); + kevent = trace_kernel_find_event(&kchan->events_list, + 0, event->name, event->type, filter); if (kevent == NULL) { ret = kernel_create_event(event, kchan, filter_expression, filter); /* We have passed ownership */ @@ -142,6 +144,104 @@ end: return ret; } +/* + * Disable kernel tracepoint events for a map from the kernel session of + * a specified event_name and event type. + * On type LTTNG_EVENT_ALL all events with event_name are disabled. + * If event_name is NULL all events of the specified type are disabled. + */ +int map_event_kernel_disable_event(struct ltt_kernel_map *kmap, + uint64_t action_tracer_token) +{ + struct ltt_kernel_event_counter *kevent_counter; + struct lttng_ht_iter iter; + const struct lttng_ht_node_u64 *node; + enum lttng_error_code ret_code; + int ret; + + assert(kmap); + + lttng_ht_lookup(kmap->event_counters_ht, (void *) &action_tracer_token, &iter); + node = lttng_ht_iter_get_node_u64(&iter); + if (node){ + kevent_counter = caa_container_of(node, + struct ltt_kernel_event_counter, ht_node); + ret = kernctl_disable(kevent_counter->fd); + if (ret < 0) { + ret_code = LTTNG_ERR_KERN_DISABLE_FAIL; + goto end; + } + kevent_counter->enabled = false; + DBG("Disable kernel event counter"); + } else { + ret_code = LTTNG_ERR_NO_EVENT; + goto end; + } + + ret_code = LTTNG_OK; +end: + return ret_code; +} + +/* + * Enable kernel tracepoint event for a map from the kernel session. + * We own filter_expression and filter. + */ +int map_event_kernel_enable_event(struct ltt_kernel_map *kmap, + const struct lttng_credentials *creds, + uint64_t action_tracer_token, + const struct lttng_event_rule *event_rule, + struct lttng_map_key *key) +{ + int err; + enum lttng_error_code ret_code; + struct ltt_kernel_event_counter *kevent_counter; + struct lttng_ht_iter iter; + const struct lttng_ht_node_u64 *node; + + assert(kmap); + assert(event_rule); + assert(key); + + lttng_ht_lookup(kmap->event_counters_ht, (void *) &action_tracer_token, &iter); + node = lttng_ht_iter_get_node_u64(&iter); + if (node){ + kevent_counter = caa_container_of(node, + struct ltt_kernel_event_counter, ht_node); + if (kevent_counter->enabled) { + /* At this point, the event is considered enabled */ + ret_code = LTTNG_ERR_KERN_EVENT_EXIST; + goto end; + } + + err = kernctl_enable(kevent_counter->fd); + if (err < 0) { + switch (-err) { + case EEXIST: + ret_code = LTTNG_ERR_KERN_EVENT_EXIST; + break; + default: + PERROR("enable kernel event counter"); + ret_code = LTTNG_ERR_KERN_ENABLE_FAIL; + break; + } + goto end; + } + + } else { + + ret_code = kernel_create_event_counter(kmap, creds, + action_tracer_token, event_rule, key); + if (ret_code != LTTNG_OK) { + goto end; + } + } + + ret_code = LTTNG_OK; +end: + return ret_code; +} + /* * ============================ * UST : The Ultimate Frontier! @@ -162,18 +262,26 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int ret = LTTNG_OK, to_create = 0; struct ltt_ust_event *uevent; + /* + * FIXME: Frdeso. The tracer token should probably me set for regular + * events too. + */ + uint64_t tracer_token = 0; + assert(usess); assert(uchan); assert(event); rcu_read_lock(); - uevent = trace_ust_find_event(uchan->events, event->name, filter, + uevent = trace_ust_find_event(uchan->events, 0, event->name, filter, (enum lttng_ust_loglevel_type) event->loglevel_type, - event->loglevel, exclusion); + event->loglevel, exclusion, NULL); if (!uevent) { - ret = trace_ust_create_event(event, filter_expression, - filter, exclusion, internal_event, &uevent); + ret = trace_ust_create_event(tracer_token, event->name, NULL, event->type, + event->loglevel_type, event->loglevel, + filter_expression, filter, exclusion, + internal_event, &uevent); /* We have passed ownership */ filter_expression = NULL; filter = NULL; @@ -196,7 +304,7 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, uevent->enabled = 1; if (to_create) { /* Add ltt ust event to channel */ - add_unique_ust_event(uchan->events, uevent); + add_unique_ust_event(uchan->events, uevent, NULL); } if (!usess->active) { @@ -205,10 +313,10 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, if (to_create) { /* Create event on all UST registered apps for session */ - ret = ust_app_create_event_glb(usess, uchan, uevent); + ret = ust_app_create_channel_event_glb(usess, uchan, uevent); } else { /* Enable event on all UST registered apps for session */ - ret = ust_app_enable_event_glb(usess, uchan, uevent); + ret = ust_app_enable_channel_event_glb(usess, uchan, uevent); } if (ret < 0) { @@ -252,6 +360,140 @@ error: return ret; } +/* + * Enable UST tracepoint event for a map from a UST session. + */ +enum lttng_error_code map_event_ust_enable_tracepoint( + struct ltt_ust_session *usess, + struct ltt_ust_map *umap, + uint64_t tracer_token, + char *ev_name, + struct lttng_map_key *key, + enum lttng_event_type ev_type, + enum lttng_loglevel_type ev_loglevel_type, + int ev_loglevel_value, + char *_filter_expression, + struct lttng_bytecode *_filter, + struct lttng_event_exclusion *exclusion, + bool internal_event) +{ + enum lttng_error_code ret_code = LTTNG_OK; + int ret, to_create = 0; + struct ltt_ust_event *uevent; + struct lttng_bytecode *filter = NULL; + char *filter_expression = NULL; + + + assert(usess); + assert(umap); + + /* + * FIXME: FRDESO: this function was copied from ust-app.c + */ + if (_filter_expression) { + filter_expression = strdup(_filter_expression); + } + + if (_filter) { + filter = zmalloc(sizeof(*filter) + _filter->len); + if (!filter) { + PERROR("Failed to allocate lttng_ust_filter_bytecode: bytecode len = %" PRIu32 " bytes", _filter->len); + goto error; + } + + assert(sizeof(struct lttng_bytecode) == + sizeof(struct lttng_ust_filter_bytecode)); + memcpy(filter, _filter, sizeof(*filter) + _filter->len); + } + + rcu_read_lock(); + + uevent = trace_ust_find_event(umap->events, tracer_token, ev_name, filter, + (enum lttng_ust_loglevel_type) ev_loglevel_type, + ev_loglevel_value, exclusion, key); + if (!uevent) { + ret_code = trace_ust_create_event(tracer_token, ev_name, key, ev_type, + ev_loglevel_type, ev_loglevel_value, + filter_expression, filter, exclusion, + internal_event, &uevent); + /* We have passed ownership */ + filter_expression = NULL; + filter = NULL; + exclusion = NULL; + if (ret_code != LTTNG_OK) { + goto error; + } + + /* Valid to set it after the goto error since uevent is still NULL */ + to_create = 1; + } + + if (uevent->enabled) { + /* It's already enabled so everything is OK */ + assert(!to_create); + ret_code = LTTNG_ERR_UST_EVENT_ENABLED; + goto end; + } + + uevent->enabled = 1; + if (to_create) { + /* Add ltt ust event to map */ + add_unique_ust_event(umap->events, uevent, key); + } + + if (!usess->active) { + goto end; + } + + if (to_create) { + /* Create event on all UST registered apps for session */ + ret = ust_app_create_map_event_glb(usess, umap, uevent); + } else { + /* Enable event on all UST registered apps for session */ + ret = ust_app_enable_map_event_glb(usess, umap, uevent); + } + + if (ret < 0) { + if (ret == -LTTNG_UST_ERR_EXIST) { + ret_code = LTTNG_ERR_UST_EVENT_EXIST; + goto end; + } else { + ret_code = LTTNG_ERR_UST_ENABLE_FAIL; + goto error; + } + } + + DBG("Event UST %s %s in map %s", uevent->attr.name, + to_create ? "created" : "enabled", umap->name); + + ret_code = LTTNG_OK; + +end: + rcu_read_unlock(); + free(filter_expression); + free(filter); + free(exclusion); + return ret_code; + +error: + /* + * Only destroy event on creation time (not enabling time) because if the + * event is found in the map (to_create == 0), it means that at some + * point the enable_event worked and it's thus valid to keep it alive. + * Destroying it also implies that we also destroy it's shadow copy to sync + * everyone up. + */ + if (to_create) { + /* In this code path, the uevent was not added to the hash table */ + trace_ust_destroy_event(uevent); + } + rcu_read_unlock(); + free(filter_expression); + free(filter); + free(exclusion); + return ret_code; +} + /* * Disable UST tracepoint of a channel from a UST session. */ @@ -300,7 +542,7 @@ int event_ust_disable_tracepoint(struct ltt_ust_session *usess, if (!usess->active) { goto next; } - ret = ust_app_disable_event_glb(usess, uchan, uevent); + ret = ust_app_disable_channel_event_glb(usess, uchan, uevent); if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) { ret = LTTNG_ERR_UST_DISABLE_FAIL; goto error; @@ -319,6 +561,69 @@ error: return ret; } +/* + * Disable UST tracepoint of a map from a UST session. + */ +enum lttng_error_code map_event_ust_disable_tracepoint( + struct ltt_ust_session *usess, + struct ltt_ust_map *umap, + uint64_t tracer_token, + char *event_name, + struct lttng_map_key *key, + enum lttng_event_type ev_type, + enum lttng_loglevel_type ev_loglevel_type, + int ev_loglevel_value, + char *filter_expression, + struct lttng_bytecode *filter, + struct lttng_event_exclusion *exclusion, + bool internal_event) +{ + int ret; + enum lttng_error_code ret_code; + struct ltt_ust_event *uevent; + + assert(usess); + assert(umap); + assert(event_name); + + rcu_read_lock(); + + /* + * FIXME: frdeso: We need to pass all the parameters to find the right + * event. + */ + uevent = trace_ust_find_event(umap->events, tracer_token, event_name, filter, + (enum lttng_ust_loglevel_type) ev_loglevel_type, + ev_loglevel_value, exclusion, key); + assert(uevent); + + if (uevent->enabled == 0) { + ret_code = LTTNG_OK; + goto end; + } + + uevent->enabled = 0; + DBG2("Event UST %s disabled in map %s", uevent->attr.name, + umap->name); + + if (!usess->active) { + ret_code = LTTNG_OK; + goto end; + } + + ret = ust_app_disable_map_event_glb(usess, umap, uevent); + if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) { + ret_code = LTTNG_ERR_UST_DISABLE_FAIL; + goto end; + } + + ret_code = LTTNG_OK; + +end: + rcu_read_unlock(); + return ret_code; +} + /* * Disable all UST tracepoints for a channel from a UST session. */ @@ -372,6 +677,56 @@ error: return ret; } +/* + * Disable all UST tracepoints for a map from a UST session. + */ +int map_event_ust_disable_all_tracepoints(struct ltt_ust_session *usess, + struct ltt_ust_map *umap) +{ + int ret, error = 0; + struct lttng_ht_iter iter; + struct ltt_ust_event *uevent = NULL; + struct lttng_event *events = NULL; + + assert(usess); + assert(umap); + + rcu_read_lock(); + + /* Disabling existing events */ + cds_lfht_for_each_entry(umap->events->ht, &iter.iter, uevent, + node.node) { + if (uevent->enabled == 1) { + ret = map_event_ust_disable_tracepoint(usess, umap, + uevent->attr.token, + uevent->attr.name, + uevent->key, + uevent->attr.instrumentation, + (enum lttng_loglevel_type) uevent->attr.loglevel_type, + uevent->attr.loglevel, + uevent->filter_expression, + uevent->filter, + uevent->exclusion, + false); + if (ret < 0) { + error = LTTNG_ERR_UST_DISABLE_FAIL; + continue; + } + } + } + + /* + * FIXME: FRDESO: in the equivalent function + * event_ust_disable_all_tracepoints() (above ^) we also iterator over + * all lttng_event. Do we need to do this here too? + */ + + ret = error ? error : LTTNG_OK; + rcu_read_unlock(); + free(events); + return ret; +} + static void agent_enable_all(struct agent *agt) { struct agent_event *aevent; @@ -601,9 +956,9 @@ int trigger_agent_enable(const struct lttng_trigger *trigger, struct agent *agt) condition = lttng_trigger_get_const_condition(trigger); assert(lttng_condition_get_type(condition) == - LTTNG_CONDITION_TYPE_EVENT_RULE_HIT); + LTTNG_CONDITION_TYPE_ON_EVENT); - c_status = lttng_condition_event_rule_get_rule(condition, &rule); + c_status = lttng_condition_on_event_get_rule(condition, &rule); assert(c_status == LTTNG_CONDITION_STATUS_OK); assert(lttng_event_rule_get_type(rule) == @@ -779,13 +1134,15 @@ static int event_agent_disable_one(struct ltt_ust_session *usess, * happens thanks to an UST filter. The following -1 is actually * ignored since the type is LTTNG_UST_LOGLEVEL_ALL. */ - uevent = trace_ust_find_event(uchan->events, (char *) ust_event_name, - aevent->filter, LTTNG_UST_LOGLEVEL_ALL, -1, NULL); + /* TODO: JORAJ FRDESO: hmmm what to do with tracer token here? + */ + uevent = trace_ust_find_event(uchan->events, 0, (char *) ust_event_name, + aevent->filter, LTTNG_UST_LOGLEVEL_ALL, -1, NULL, NULL); /* If the agent event exists, it must be available on the UST side. */ assert(uevent); if (usess->active) { - ret = ust_app_disable_event_glb(usess, uchan, uevent); + ret = ust_app_disable_channel_event_glb(usess, uchan, uevent); if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) { ret = LTTNG_ERR_UST_DISABLE_FAIL; goto error;