From 76d45b4000137cff321b29800e11cc5d4a299a98 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 6 Dec 2011 14:02:54 -0500 Subject: [PATCH] Add support for UST enable all tracepoints Support to enable all tracepoints for UST global domain Signed-off-by: David Goulet --- lttng-sessiond/event.c | 96 ++++++++++++++++++++++++++++++++++++++++ lttng-sessiond/event.h | 2 + lttng-sessiond/main.c | 69 +++++++++++++++++++++++++++-- lttng-sessiond/ust-app.c | 58 ++++++++++++++++++++++++ lttng-sessiond/ust-app.h | 10 +++++ 5 files changed, 231 insertions(+), 4 deletions(-) diff --git a/lttng-sessiond/event.c b/lttng-sessiond/event.c index 247a4c6d7..4e6ac03bf 100644 --- a/lttng-sessiond/event.c +++ b/lttng-sessiond/event.c @@ -245,6 +245,102 @@ end: return ret; } +/* + * 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; + + 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; + } + + /* 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; + } else { + ret = LTTCOMM_UST_ENABLE_FAIL; + } + goto error; + } + + 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: + trace_ust_destroy_event(uevent); + return ret; +} + /* * Enable UST tracepoint event for a channel from a UST session. */ diff --git a/lttng-sessiond/event.h b/lttng-sessiond/event.h index 2a7d8c2c3..2eafeccae 100644 --- a/lttng-sessiond/event.h +++ b/lttng-sessiond/event.h @@ -44,5 +44,7 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain, struct ltt_ust_channel *uchan, struct lttng_event *event); int event_ust_disable_tracepoint(struct ltt_ust_session *ustsession, struct ltt_ust_channel *ustchan, char *event_name); +int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess, int domain, + struct ltt_ust_channel *uchan); #endif /* _LTT_EVENT_H */ diff --git a/lttng-sessiond/main.c b/lttng-sessiond/main.c index 46fcba939..4091bb090 100644 --- a/lttng-sessiond/main.c +++ b/lttng-sessiond/main.c @@ -2715,11 +2715,11 @@ static int cmd_enable_event_all(struct ltt_session *session, int domain, } switch (event_type) { - case LTTNG_KERNEL_SYSCALL: + case LTTNG_EVENT_SYSCALL: ret = event_kernel_enable_all_syscalls(session->kernel_session, kchan, kernel_tracer_fd); break; - case LTTNG_KERNEL_TRACEPOINT: + case LTTNG_EVENT_TRACEPOINT: /* * This call enables all LTTNG_KERNEL_TRACEPOINTS and * events already registered to the channel. @@ -2727,7 +2727,7 @@ static int cmd_enable_event_all(struct ltt_session *session, int domain, ret = event_kernel_enable_all_tracepoints(session->kernel_session, kchan, kernel_tracer_fd); break; - case LTTNG_KERNEL_ALL: + case LTTNG_EVENT_ALL: /* Enable syscalls and tracepoints */ ret = event_kernel_enable_all(session->kernel_session, kchan, kernel_tracer_fd); @@ -2744,8 +2744,69 @@ static int cmd_enable_event_all(struct ltt_session *session, int domain, kernel_wait_quiescent(kernel_tracer_fd); break; + case LTTNG_DOMAIN_UST: + { + struct lttng_channel *attr; + struct ltt_ust_channel *uchan; + struct ltt_ust_session *usess = session->ust_session; + + /* Get channel from global UST domain */ + uchan = trace_ust_find_channel_by_name(usess->domain_global.channels, + channel_name); + if (uchan == NULL) { + /* Create default channel */ + attr = channel_new_default_attr(domain); + if (attr == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + snprintf(attr->name, NAME_MAX, "%s", channel_name); + attr->name[NAME_MAX - 1] = '\0'; + + /* Use the internal command enable channel */ + ret = cmd_enable_channel(session, domain, attr); + if (ret != LTTCOMM_OK) { + free(attr); + goto error; + } + free(attr); + + /* Get the newly created channel reference back */ + uchan = trace_ust_find_channel_by_name( + usess->domain_global.channels, channel_name); + if (uchan == NULL) { + /* Something is really wrong */ + ret = LTTCOMM_FATAL; + goto error; + } + } + + /* At this point, the session and channel exist on the tracer */ + + switch (event_type) { + case LTTNG_EVENT_ALL: + case LTTNG_EVENT_TRACEPOINT: + ret = event_ust_enable_all_tracepoints(usess, domain, uchan); + if (ret != LTTCOMM_OK) { + goto error; + } + break; + default: + ret = LTTCOMM_UST_ENABLE_FAIL; + goto error; + } + + /* Manage return value */ + if (ret != LTTCOMM_OK) { + goto error; + } + + break; + } + case LTTNG_DOMAIN_UST_EXEC_NAME: + case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: default: - /* TODO: Userspace tracing */ ret = LTTCOMM_NOT_IMPLEMENTED; goto error; } diff --git a/lttng-sessiond/ust-app.c b/lttng-sessiond/ust-app.c index f5dfb110b..9a20d5d45 100644 --- a/lttng-sessiond/ust-app.c +++ b/lttng-sessiond/ust-app.c @@ -2252,3 +2252,61 @@ int ust_app_add_ctx_event_glb(struct ltt_ust_session *usess, rcu_read_unlock(); return ret; } + +/* + * Enable event for a channel from a UST session for a specific PID. + */ +int ust_app_enable_event_pid(struct ltt_ust_session *usess, + struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, pid_t pid) +{ + int ret = 0; + struct cds_lfht_iter iter; + struct cds_lfht_node *ua_chan_node, *ua_event_node; + struct ust_app *app; + struct ust_app_session *ua_sess; + struct ust_app_channel *ua_chan; + struct ust_app_event *ua_event; + + DBG("UST app enabling event %s for PID %d", uevent->attr.name, pid); + + rcu_read_lock(); + + app = ust_app_find_by_pid(pid); + if (app == NULL) { + ERR("UST app enable event per PID %d not found", pid); + ret = -1; + goto error; + } + + ua_sess = lookup_session_by_app(usess, app); + /* If ua_sess is NULL, there is a code flow error */ + assert(ua_sess); + + /* Lookup channel in the ust app session */ + ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name, + strlen(uchan->name), &iter); + /* If the channel is not found, there is a code flow error */ + assert(ua_chan_node); + + ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node); + + ua_event_node = hashtable_lookup(ua_sess->channels, + (void*)uevent->attr.name, strlen(uevent->attr.name), &iter); + if (ua_event_node == NULL) { + ret = create_ust_app_event(ua_sess, ua_chan, uevent, app); + if (ret < 0) { + goto error; + } + } else { + ua_event = caa_container_of(ua_event_node, struct ust_app_event, node); + + ret = enable_ust_app_event(ua_sess, ua_event, app); + if (ret < 0) { + goto error; + } + } + +error: + rcu_read_unlock(); + return ret; +} diff --git a/lttng-sessiond/ust-app.h b/lttng-sessiond/ust-app.h index 1dc0e8ba2..9fb4df1a7 100644 --- a/lttng-sessiond/ust-app.h +++ b/lttng-sessiond/ust-app.h @@ -129,6 +129,9 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan); int ust_app_create_event_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent); +int ust_app_enable_event_pid(struct ltt_ust_session *usess, + struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, + pid_t pid); int ust_app_disable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan); int ust_app_enable_channel_glb(struct ltt_ust_session *usess, @@ -288,6 +291,13 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess, { return 0; } +static inline +int ust_app_enable_event_pid(struct ltt_ust_session *usess, + struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, + pid_t pid) +{ + return 0; +} #endif /* HAVE_LIBLTTNG_UST_CTL */ -- 2.34.1