X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng-sessiond%2Fevent.c;h=1068707438082e2758e80105599c050967d3e581;hp=4e6ac03bf19f58a4761b63c973ba6bac6bf25a24;hb=f851868f8c7195682d13762719ce8f13293fd794;hpb=76d45b4000137cff321b29800e11cc5d4a299a98 diff --git a/lttng-sessiond/event.c b/lttng-sessiond/event.c index 4e6ac03bf..106870743 100644 --- a/lttng-sessiond/event.c +++ b/lttng-sessiond/event.c @@ -15,17 +15,18 @@ * Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define _GNU_SOURCE #include #include #include #include +#include #include #include #include "channel.h" #include "event.h" -#include "hashtable.h" #include "kernel.h" #include "ust-ctl.h" #include "ust-app.h" @@ -245,6 +246,12 @@ end: return ret; } +/* + * ============================ + * UST : The Ultimate Frontier! + * ============================ + */ + /* * Enable all UST tracepoints for a channel from a UST session. */ @@ -253,15 +260,16 @@ int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, { int ret, i; size_t size; - struct cds_lfht_iter iter; + struct lttng_ht_iter iter; struct ltt_ust_event *uevent = NULL; - struct lttng_event *events; + struct lttng_event *events = NULL; switch (domain) { case LTTNG_DOMAIN_UST: { /* Enable existing events */ - cds_lfht_for_each_entry(uchan->events, &iter, uevent, node) { + cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent, + node.node) { if (uevent->enabled == 0) { ret = ust_app_enable_event_glb(usess, uchan, uevent); if (ret < 0) { @@ -301,7 +309,7 @@ int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, uevent = trace_ust_create_event(&events[i]); if (uevent == NULL) { ret = LTTCOMM_FATAL; - goto error; + goto error_destroy; } /* Create event for the specific PID */ @@ -310,16 +318,17 @@ int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, if (ret < 0) { if (ret == -EEXIST) { ret = LTTCOMM_UST_EVENT_EXIST; + goto error; } else { ret = LTTCOMM_UST_ENABLE_FAIL; + goto error_destroy; } - goto error; } uevent->enabled = 1; /* Add ltt ust event to channel */ rcu_read_lock(); - hashtable_add_unique(uchan->events, &uevent->node); + lttng_ht_add_unique_str(uchan->events, &uevent->node); rcu_read_unlock(); } @@ -336,8 +345,11 @@ int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, return LTTCOMM_OK; -error: +error_destroy: trace_ust_destroy_event(uevent); + +error: + free(events); return ret; } @@ -347,7 +359,7 @@ error: int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain, struct ltt_ust_channel *uchan, struct lttng_event *event) { - int ret, to_create = 0; + int ret = LTTCOMM_OK, to_create = 0; struct ltt_ust_event *uevent; uevent = trace_ust_find_event_by_name(uchan->events, event->name); @@ -357,9 +369,17 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain, ret = LTTCOMM_FATAL; 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 */ + goto end; + } + + uevent->enabled = 1; + switch (domain) { case LTTNG_DOMAIN_UST: { @@ -374,14 +394,12 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain, if (ret < 0) { if (ret == -EEXIST) { ret = LTTCOMM_UST_EVENT_EXIST; + goto end; } else { ret = LTTCOMM_UST_ENABLE_FAIL; + goto error; } - goto error; } - - DBG("Event UST %s added to channel %s", uevent->attr.name, - uchan->name); break; } case LTTNG_DOMAIN_UST_EXEC_NAME: @@ -389,42 +407,150 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain, case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: default: ret = LTTCOMM_NOT_IMPLEMENTED; - goto error; + goto end; } - uevent->enabled = 1; - /* Add ltt ust event to channel */ - rcu_read_lock(); - hashtable_add_unique(uchan->events, &uevent->node); - rcu_read_unlock(); + if (to_create) { + rcu_read_lock(); + /* Add ltt ust event to channel */ + lttng_ht_add_unique_str(uchan->events, &uevent->node); + rcu_read_unlock(); + } - return LTTCOMM_OK; + DBG("Event UST %s %s in channel %s", uevent->attr.name, + to_create ? "created" : "enabled", uchan->name); + + ret = LTTCOMM_OK; + +end: + return ret; error: - trace_ust_destroy_event(uevent); + /* + * Only destroy event on creation time (not enabling time) because if the + * event is found in the channel (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); + } return ret; } -#ifdef DISABLE -int event_ust_disable_tracepoint(struct ltt_ust_session *ustsession, - struct ltt_ust_channel *ustchan, char *event_name) +/* + * Disable UST tracepoint of a channel from a UST session. + */ +int event_ust_disable_tracepoint(struct ltt_ust_session *usess, int domain, + struct ltt_ust_channel *uchan, char *event_name) { int ret; - struct ltt_ust_event *ustevent; + struct ltt_ust_event *uevent; - ustevent = trace_ust_find_event_by_name(ustchan->events, event_name); - if (ustevent == NULL) { - ret = LTTCOMM_NO_EVENT; - goto end; + uevent = trace_ust_find_event_by_name(uchan->events, event_name); + if (uevent == NULL) { + ret = LTTCOMM_UST_EVENT_NOT_FOUND; + goto error; } - //ret = ustctl_disable(ustsession->sock, ustevent->obj); - if (ret < 0) { - ret = LTTCOMM_UST_ENABLE_FAIL; + + if (uevent->enabled == 0) { + /* It's already enabled so everything is OK */ + ret = LTTCOMM_OK; goto end; } - ustevent->enabled = 0; + + switch (domain) { + case LTTNG_DOMAIN_UST: + ret = ust_app_disable_event_glb(usess, uchan, uevent); + if (ret < 0 && ret != -EEXIST) { + ret = LTTCOMM_UST_DISABLE_FAIL; + goto error; + } + break; + case LTTNG_DOMAIN_UST_EXEC_NAME: + case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: + default: + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; + } + + uevent->enabled = 0; ret = LTTCOMM_OK; + end: + DBG2("Event UST %s disabled in channel %s", uevent->attr.name, + uchan->name); + +error: + return ret; +} + +/* + * Disable all UST tracepoints for a channel from a UST session. + */ +int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess, int domain, + struct ltt_ust_channel *uchan) +{ + int ret, i; + size_t size; + struct lttng_ht_iter iter; + struct ltt_ust_event *uevent = NULL; + struct lttng_event *events = NULL; + + switch (domain) { + case LTTNG_DOMAIN_UST: + { + /* Disabling existing events */ + 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); + if (ret < 0) { + continue; + } + uevent->enabled = 0; + } + } + + /* Get all UST available events */ + size = ust_app_list_events(&events); + if (size < 0) { + ret = LTTCOMM_UST_LIST_FAIL; + goto error; + } + + for (i = 0; i < size; i++) { + uevent = trace_ust_find_event_by_name(uchan->events, + events[i].name); + if (uevent != NULL && uevent->enabled == 1) { + ret = ust_app_disable_event_pid(usess, uchan, uevent, + events[i].pid); + if (ret < 0 && ret != -EEXIST) { + ret = LTTCOMM_UST_DISABLE_FAIL; + goto error; + } + uevent->enabled = 0; + continue; + } + } + + free(events); + break; + } + case LTTNG_DOMAIN_UST_EXEC_NAME: + case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: + default: + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; + } + + return LTTCOMM_OK; + +error: + free(events); return ret; } -#endif