X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng-sessiond%2Fevent.c;h=90b10ec3a64e6b4b5defa62e2ccc3a17f22df225;hp=1f90c1c73069d97c520d2c8670ef12fe7dd68c64;hb=be0406668cc2147087a38ac82d6029b8cc56ba79;hpb=322585731ced1adba36cddcb8bdd5d997d1b2e3e diff --git a/lttng-sessiond/event.c b/lttng-sessiond/event.c index 1f90c1c73..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 @@ -23,16 +24,14 @@ #include #include -#ifdef CONFIG_LTTNG_TOOLS_HAVE_UST -#include -#else -#include "lttng-ust-ctl.h" -#endif - #include "channel.h" #include "event.h" #include "hashtable.h" -#include "kernel-ctl.h" +#include "kernel.h" +#include "ust-ctl.h" +#include "ust-app.h" +#include "trace-kernel.h" +#include "trace-ust.h" /* * Setup a lttng_event used to enable *all* syscall tracing. @@ -163,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; + } } } @@ -193,6 +194,7 @@ int event_kernel_enable_all_tracepoints(struct ltt_kernel_session *ksession, } } free(event_list); + ret = LTTCOMM_OK; end: return ret; @@ -214,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; @@ -238,59 +246,295 @@ 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. */ -#ifdef DISABLE -int event_ust_enable_tracepoint(struct ltt_ust_session *usess, - struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent) +int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain, + struct ltt_ust_channel *uchan, struct lttng_event *event) { - int ret; - struct lttng_ust_event ltt_uevent; - struct object_data *obj_event; + int ret, to_create = 0; + struct ltt_ust_event *uevent; + + uevent = trace_ust_find_event_by_name(uchan->events, event->name); + if (uevent == NULL) { + uevent = trace_ust_create_event(event); + if (uevent == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + to_create = 1; + } + + if (uevent->enabled) { + /* It's already enabled so everything is OK */ + goto end; + } - strncpy(ltt_uevent.name, uevent->attr.name, sizeof(ltt_uevent.name)); - ltt_uevent.name[sizeof(ltt_uevent.name) - 1] = '\0'; - /* TODO: adjust to other instrumentation types */ - ltt_uevent.instrumentation = LTTNG_UST_TRACEPOINT; + switch (domain) { + case LTTNG_DOMAIN_UST: + { + if (to_create) { + /* Create event on all UST registered apps for session */ + ret = ust_app_create_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 = ustctl_create_event(app->key.sock, <t_uevent, - uchan->obj, &obj_event); - if (ret < 0) { - DBG("Error ustctl create event %s for app pid: %d, sock: %d ret %d", - uevent->attr.name, app->key.pid, app->key.sock, ret); - goto next; + if (ret < 0) { + if (ret == -EEXIST) { + ret = LTTCOMM_UST_EVENT_EXIST; + goto end; + } else { + ret = LTTCOMM_UST_ENABLE_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 end; } - uevent->obj = obj_event; - uevent->handle = obj_event->handle; uevent->enabled = 1; - ret = LTTCOMM_OK; + /* Add ltt ust event to channel */ + 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: + trace_ust_destroy_event(uevent); return ret; } -#endif -#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