From: David Goulet Date: Tue, 6 Dec 2011 19:33:02 +0000 (-0500) Subject: Merge branch 'master' X-Git-Tag: v2.0-pre15~31 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=90192ee7cea425e30bd065576612156dd6cf5608;hp=4dbd54a14d42213c0b80fa6d797ddd416cd0330d Merge branch 'master' Signed-off-by: David Goulet --- 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 0a6319f35..86112f473 100644 --- a/lttng-sessiond/main.c +++ b/lttng-sessiond/main.c @@ -2713,11 +2713,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. @@ -2725,7 +2725,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); @@ -2742,8 +2742,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 bd4160b9a..904fcc3b9 100644 --- a/lttng-sessiond/ust-app.c +++ b/lttng-sessiond/ust-app.c @@ -2253,3 +2253,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 */ diff --git a/lttng/commands/enable_events.c b/lttng/commands/enable_events.c index 45cef9f60..a043eb43f 100644 --- a/lttng/commands/enable_events.c +++ b/lttng/commands/enable_events.c @@ -33,7 +33,7 @@ static char *opt_event_list; static int opt_event_type; -static char *opt_kernel; +static int opt_kernel; static char *opt_session_name; static int opt_pid_all; static int opt_userspace; @@ -119,9 +119,7 @@ static void usage(FILE *ofp) } /* - * parse_probe_addr - * - * Parse probe options. + * Parse probe options. */ static int parse_probe_opts(struct lttng_event *ev, char *opt) { @@ -188,9 +186,7 @@ end: } /* - * enable_events - * - * Enabling event using the lttng API. + * Enabling event using the lttng API. */ static int enable_events(char *session_name) { @@ -214,17 +210,23 @@ static int enable_events(char *session_name) ret = CMD_FATAL; goto error; } + /* Create lttng domain */ if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; - } - if (opt_userspace) { - /* TODO - * LTTNG_DOMAIN_UST_EXEC_NAME, - * LTTNG_DOMAIN_UST_PID, - * LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN - */ + } else if (opt_pid != 0) { + dom.type = LTTNG_DOMAIN_UST_PID; + dom.attr.pid = opt_pid; + DBG("PID %d set to lttng handle", opt_pid); + } else if (opt_userspace && opt_cmd_name == NULL) { dom.type = LTTNG_DOMAIN_UST; + } else if (opt_userspace && opt_cmd_name != NULL) { + dom.type = LTTNG_DOMAIN_UST_EXEC_NAME; + strncpy(dom.attr.exec_name, opt_cmd_name, NAME_MAX); + } else { + ERR("Please specify a tracer (--kernel or --userspace)"); + ret = CMD_NOT_IMPLEMENTED; + goto error; } handle = lttng_create_handle(session_name, &dom); @@ -260,9 +262,8 @@ static int enable_events(char *session_name) break; default: /* - * We should not be here since - * lttng_enable_event should have failed on the - * event type. + * We should not be here since lttng_enable_event should have + * failed on the event type. */ goto error; } @@ -272,14 +273,15 @@ static int enable_events(char *session_name) /* Strip event list */ event_name = strtok(opt_event_list, ","); while (event_name != NULL) { + /* Copy name and type of the event */ + strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN); + ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; + ev.type = opt_event_type; + /* Kernel tracer action */ if (opt_kernel) { DBG("Enabling kernel event %s for channel %s", event_name, channel_name); - /* Copy name and type of the event */ - strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN); - ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; - ev.type = opt_event_type; switch (opt_event_type) { case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */ @@ -304,37 +306,27 @@ static int enable_events(char *session_name) } break; case LTTNG_EVENT_FUNCTION_ENTRY: - strncpy(ev.attr.ftrace.symbol_name, - opt_function_entry_symbol, - LTTNG_SYMBOL_NAME_LEN); + strncpy(ev.attr.ftrace.symbol_name, opt_function_entry_symbol, + LTTNG_SYMBOL_NAME_LEN); ev.attr.ftrace.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; break; case LTTNG_EVENT_SYSCALL: - MSG("per-syscall selection not supported yet. Use \"-a\" for all syscalls."); - ret = CMD_NOT_IMPLEMENTED; - goto error; + MSG("per-syscall selection not supported yet. Use \"-a\" " + "for all syscalls."); default: ret = CMD_NOT_IMPLEMENTED; goto error; } - - ret = lttng_enable_event(handle, &ev, channel_name); - if (ret == 0) { - MSG("Kernel event %s created in channel %s", event_name, channel_name); - } } else if (opt_userspace) { /* User-space tracer action */ - /* - * TODO: only supporting pid_all tracing for - * now. Should have different domain based on - * opt_pid. - */ if (!opt_pid_all) { - MSG("Only supporting tracing all UST processes (-u --all) for now."); + MSG("Only supporting tracing all UST processes " + "(-u --all) for now."); ret = CMD_NOT_IMPLEMENTED; goto error; } - DBG("Enabling UST event %s for channel %s", - event_name, channel_name); + + DBG("Enabling UST event %s for channel %s", event_name, + channel_name); switch (opt_event_type) { case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */ @@ -359,16 +351,17 @@ static int enable_events(char *session_name) ret = CMD_NOT_IMPLEMENTED; goto error; } - - ret = lttng_enable_event(handle, &ev, channel_name); - if (ret == 0) { - MSG("UST event %s created in channel %s", event_name, channel_name); - } } else { ERR("Please specify a tracer (--kernel or --userspace)"); goto error; } + ret = lttng_enable_event(handle, &ev, channel_name); + if (ret == 0) { + MSG("%s event %s created in channel %s", + opt_kernel ? "kernel": "UST", event_name, channel_name); + } + /* Next event */ event_name = strtok(NULL, ","); } @@ -384,9 +377,7 @@ error: } /* - * cmd_enable_events - * - * Add event to trace session + * Add event to trace session */ int cmd_enable_events(int argc, const char **argv) {