X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng-sessiond%2Fevent.c;h=90b10ec3a64e6b4b5defa62e2ccc3a17f22df225;hp=c7331956f91e486a5f2a06caf3f8b20f71d53f26;hb=be0406668cc2147087a38ac82d6029b8cc56ba79;hpb=e0b03593613331103ad4c15a95f5495a31289225 diff --git a/lttng-sessiond/event.c b/lttng-sessiond/event.c index c7331956f..90b10ec3a 100644 --- a/lttng-sessiond/event.c +++ b/lttng-sessiond/event.c @@ -15,6 +15,7 @@ * Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define _GNU_SOURCE #include #include #include @@ -161,14 +162,16 @@ int event_kernel_enable_all_tracepoints(struct ltt_kernel_session *ksession, { int size, i, ret; struct ltt_kernel_event *kevent; - struct lttng_event *event_list; + struct lttng_event *event_list = NULL; /* For each event in the kernel session */ cds_list_for_each_entry(kevent, &kchan->events_list.head, list) { - ret = kernel_enable_event(kevent); - if (ret < 0) { - /* Enable failed but still continue */ - continue; + if (kevent->enabled == 0) { + ret = kernel_enable_event(kevent); + if (ret < 0) { + /* Enable failed but still continue */ + continue; + } } } @@ -191,6 +194,7 @@ int event_kernel_enable_all_tracepoints(struct ltt_kernel_session *ksession, } } free(event_list); + ret = LTTCOMM_OK; end: return ret; @@ -212,8 +216,14 @@ int event_kernel_enable_all_syscalls(struct ltt_kernel_session *ksession, ret = kernel_create_event(&event, kchan); if (ret < 0) { + if (ret == -EEXIST) { + ret = LTTCOMM_KERN_EVENT_EXIST; + } else { + ret = LTTCOMM_KERN_ENABLE_FAIL; + } goto end; } + ret = LTTCOMM_OK; end: return ret; @@ -236,6 +246,112 @@ end: return ret; } +/* + * ============================ + * UST : The Ultimate Frontier! + * ============================ + */ + +/* + * 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) +{ + int ret, i; + size_t size; + struct cds_lfht_iter iter; + struct ltt_ust_event *uevent = NULL; + struct lttng_event *events = NULL; + + switch (domain) { + case LTTNG_DOMAIN_UST: + { + /* Enable existing events */ + cds_lfht_for_each_entry(uchan->events, &iter, uevent, node) { + if (uevent->enabled == 0) { + ret = ust_app_enable_event_glb(usess, uchan, uevent); + if (ret < 0) { + continue; + } + uevent->enabled = 1; + } + } + + /* 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++) { + /* + * Check if event exist and if so, continue since it was enable + * previously. + */ + uevent = trace_ust_find_event_by_name(uchan->events, + events[i].name); + if (uevent != NULL) { + ret = ust_app_enable_event_pid(usess, uchan, uevent, + events[i].pid); + if (ret < 0) { + if (ret != -EEXIST) { + ret = LTTCOMM_UST_ENABLE_FAIL; + goto error; + } + } + continue; + } + + /* Create ust event */ + uevent = trace_ust_create_event(&events[i]); + if (uevent == NULL) { + ret = LTTCOMM_FATAL; + goto error_destroy; + } + + /* Create event for the specific PID */ + ret = ust_app_enable_event_pid(usess, uchan, uevent, + events[i].pid); + if (ret < 0) { + if (ret == -EEXIST) { + ret = LTTCOMM_UST_EVENT_EXIST; + goto error; + } else { + ret = LTTCOMM_UST_ENABLE_FAIL; + goto error_destroy; + } + } + + uevent->enabled = 1; + /* Add ltt ust event to channel */ + rcu_read_lock(); + hashtable_add_unique(uchan->events, &uevent->node); + rcu_read_unlock(); + } + + 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_destroy: + trace_ust_destroy_event(uevent); + +error: + free(events); + return ret; +} + /* * Enable UST tracepoint event for a channel from a UST session. */ @@ -255,6 +371,11 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain, to_create = 1; } + if (uevent->enabled) { + /* It's already enabled so everything is OK */ + goto end; + } + switch (domain) { case LTTNG_DOMAIN_UST: { @@ -269,14 +390,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: @@ -284,15 +403,21 @@ 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(); + hashtable_add_unique(uchan->events, &uevent->node); + rcu_read_unlock(); + } + DBG("Event UST %s %s in channel %s", uevent->attr.name, + to_create ? "created" : "enabled", uchan->name); + +end: return LTTCOMM_OK; error: @@ -300,26 +425,116 @@ error: 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 cds_lfht_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, &iter, uevent, 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