From 29c62722c4e1146fe6e7585308f3e4497e39e908 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 3 Nov 2014 15:52:36 -0500 Subject: [PATCH] Implement lttng-modules tracepoint wildcard support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Mathieu Desnoyers Signed-off-by: Jérémie Galarneau --- src/bin/lttng-sessiond/cmd.c | 232 +++---------------------- src/bin/lttng-sessiond/event.c | 84 +-------- src/bin/lttng-sessiond/event.h | 4 - src/bin/lttng/commands/enable_events.c | 11 +- src/common/kernel-ctl/kernel-ioctl.h | 2 +- 5 files changed, 38 insertions(+), 295 deletions(-) diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 4c1609fd2..31c3aff77 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -50,21 +50,6 @@ static pthread_mutex_t relayd_net_seq_idx_lock = PTHREAD_MUTEX_INITIALIZER; static uint64_t relayd_net_seq_idx; -/* - * Both functions below are special case for the Kernel domain when - * enabling/disabling all events. - */ -static -int enable_kevent_all(struct ltt_session *session, - struct lttng_domain *domain, char *channel_name, - struct lttng_event *event, - char *filter_expression, - struct lttng_filter_bytecode *filter, int wpipe); -static -int disable_kevent_all(struct ltt_session *session, int domain, - char *channel_name, - struct lttng_event *event); - /* * Create a session path used by list_lttng_sessions for the case that the * session consumer is on the network. @@ -1134,7 +1119,6 @@ end: return ret; } - /* * Command LTTNG_DISABLE_EVENT processed by the client thread. */ @@ -1154,10 +1138,6 @@ int cmd_disable_event(struct ltt_session *session, int domain, || event->pid || event->filter || event->exclusion) { return LTTNG_ERR_UNK; } - /* Special handling for kernel domain all events. */ - if (domain == LTTNG_DOMAIN_KERNEL && !strcmp(event_name, "*")) { - return disable_kevent_all(session, domain, channel_name, event); - } rcu_read_lock(); @@ -1187,8 +1167,17 @@ int cmd_disable_event(struct ltt_session *session, int domain, switch (event->type) { case LTTNG_EVENT_ALL: + ret = event_kernel_disable_all(kchan); + if (ret != LTTNG_OK) { + goto error; + } + break; case LTTNG_EVENT_TRACEPOINT: - ret = event_kernel_disable_tracepoint(kchan, event_name); + if (!strcmp(event_name, "*")) { + ret = event_kernel_disable_all_tracepoints(kchan); + } else { + ret = event_kernel_disable_tracepoint(kchan, event_name); + } if (ret != LTTNG_OK) { goto error; } @@ -1293,75 +1282,6 @@ error: return ret; } -/* - * Command LTTNG_DISABLE_EVENT for event "*" processed by the client thread. - */ -static -int disable_kevent_all(struct ltt_session *session, int domain, - char *channel_name, - struct lttng_event *event) -{ - int ret; - - rcu_read_lock(); - - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - { - struct ltt_kernel_session *ksess; - struct ltt_kernel_channel *kchan; - - ksess = session->kernel_session; - - /* - * If a non-default channel has been created in the - * session, explicitely require that -c chan_name needs - * to be provided. - */ - if (ksess->has_non_default_channel && channel_name[0] == '\0') { - ret = LTTNG_ERR_NEED_CHANNEL_NAME; - goto error; - } - - kchan = trace_kernel_get_channel_by_name(channel_name, ksess); - if (kchan == NULL) { - ret = LTTNG_ERR_KERN_CHAN_NOT_FOUND; - goto error; - } - - switch (event->type) { - case LTTNG_EVENT_ALL: - ret = event_kernel_disable_all(kchan); - if (ret != LTTNG_OK) { - goto error; - } - break; - case LTTNG_EVENT_SYSCALL: - ret = event_kernel_disable_syscall(kchan, ""); - if (ret != LTTNG_OK) { - goto error; - } - break; - default: - ret = LTTNG_ERR_UNK; - goto error; - } - - kernel_wait_quiescent(kernel_tracer_fd); - break; - } - default: - ret = LTTNG_ERR_UND; - goto error; - } - - ret = LTTNG_OK; - -error: - rcu_read_unlock(); - return ret; -} - /* * Command LTTNG_ADD_CONTEXT processed by the client thread. */ @@ -1504,12 +1424,6 @@ int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain, DBG("Enable event command for event \'%s\'", event->name); - /* Special handling for kernel domain all events. */ - if (domain->type == LTTNG_DOMAIN_KERNEL && !strcmp(event->name, "*")) { - return enable_kevent_all(session, domain, channel_name, event, - filter_expression, filter, wpipe); - } - ret = validate_event_name(event->name); if (ret) { goto error; @@ -1565,6 +1479,23 @@ int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain, switch (event->type) { case LTTNG_EVENT_ALL: + { + event->type = LTTNG_EVENT_TRACEPOINT; /* Hack */ + ret = event_kernel_enable_tracepoint(kchan, event); + if (ret != LTTNG_OK) { + if (channel_created) { + /* Let's not leak a useless channel. */ + kernel_destroy_channel(kchan); + } + goto error; + } + event->type = LTTNG_EVENT_SYSCALL; /* Hack */ + ret = event_kernel_enable_syscall(kchan, event->name); + if (ret != LTTNG_OK) { + goto error; + } + break; + } case LTTNG_EVENT_PROBE: case LTTNG_EVENT_FUNCTION: case LTTNG_EVENT_FUNCTION_ENTRY: @@ -1761,115 +1692,6 @@ error: return ret; } -/* - * Command LTTNG_ENABLE_EVENT for event "*" processed by the client thread. - */ -static -int enable_kevent_all(struct ltt_session *session, - struct lttng_domain *domain, char *channel_name, - struct lttng_event *event, - char *filter_expression, - struct lttng_filter_bytecode *filter, int wpipe) -{ - int ret; - struct lttng_channel *attr; - - assert(session); - assert(channel_name); - - rcu_read_lock(); - - switch (domain->type) { - case LTTNG_DOMAIN_KERNEL: - { - struct ltt_kernel_channel *kchan; - - assert(session->kernel_session); - - /* - * If a non-default channel has been created in the - * session, explicitely require that -c chan_name needs - * to be provided. - */ - if (session->kernel_session->has_non_default_channel - && channel_name[0] == '\0') { - ret = LTTNG_ERR_NEED_CHANNEL_NAME; - goto error; - } - - kchan = trace_kernel_get_channel_by_name(channel_name, - session->kernel_session); - if (kchan == NULL) { - /* Create default channel */ - attr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL, - LTTNG_BUFFER_GLOBAL); - if (attr == NULL) { - ret = LTTNG_ERR_FATAL; - goto error; - } - strncpy(attr->name, channel_name, sizeof(attr->name)); - - ret = cmd_enable_channel(session, domain, attr, wpipe); - if (ret != LTTNG_OK) { - free(attr); - goto error; - } - free(attr); - - /* Get the newly created kernel channel pointer */ - kchan = trace_kernel_get_channel_by_name(channel_name, - session->kernel_session); - assert(kchan); - } - - switch (event->type) { - case LTTNG_EVENT_SYSCALL: - ret = event_kernel_enable_syscall(kchan, ""); - if (ret != LTTNG_OK) { - goto error; - } - break; - case LTTNG_EVENT_TRACEPOINT: - /* - * This call enables all LTTNG_KERNEL_TRACEPOINTS and - * events already registered to the channel. - */ - ret = event_kernel_enable_all_tracepoints(kchan, kernel_tracer_fd); - break; - case LTTNG_EVENT_ALL: - /* Enable syscalls and tracepoints */ - ret = event_kernel_enable_all(kchan, kernel_tracer_fd); - break; - default: - ret = LTTNG_ERR_KERN_ENABLE_FAIL; - goto error; - } - - /* Manage return value */ - if (ret != LTTNG_OK) { - /* - * On error, cmd_enable_channel call will take care of destroying - * the created channel if it was needed. - */ - goto error; - } - - kernel_wait_quiescent(kernel_tracer_fd); - break; - } - default: - ret = LTTNG_ERR_UND; - goto error; - } - - ret = LTTNG_OK; - -error: - rcu_read_unlock(); - return ret; -} - - /* * Command LTTNG_LIST_TRACEPOINTS processed by the client thread. */ diff --git a/src/bin/lttng-sessiond/event.c b/src/bin/lttng-sessiond/event.c index a8e63896d..564cbb784 100644 --- a/src/bin/lttng-sessiond/event.c +++ b/src/bin/lttng-sessiond/event.c @@ -106,7 +106,7 @@ int event_kernel_enable_syscall(struct ltt_kernel_channel *kchan, goto error; } - DBG("Kernel event %s enable for channel %s.", + DBG("Kernel syscall %s enable for channel %s.", syscall_name, kchan->channel->name); ret = LTTNG_OK; @@ -132,7 +132,7 @@ int event_kernel_disable_syscall(struct ltt_kernel_channel *kchan, } DBG("Kernel syscall %s disable for channel %s.", - syscall_name[0] == '\0' ? "" : syscall_name, + !strcmp(syscall_name, "*") ? "" : syscall_name, kchan->channel->name); ret = LTTNG_OK; @@ -175,7 +175,7 @@ int event_kernel_disable_all(struct ltt_kernel_channel *kchan) ret = event_kernel_disable_all_tracepoints(kchan); if (ret != LTTNG_OK) return ret; - ret = event_kernel_disable_syscall(kchan, ""); + ret = event_kernel_disable_syscall(kchan, "*"); return ret; } @@ -226,84 +226,6 @@ end: return ret; } -/* - * Enable all kernel tracepoint events of a channel of the kernel session. - */ -int event_kernel_enable_all_tracepoints(struct ltt_kernel_channel *kchan, - int kernel_tracer_fd) -{ - int size, i, ret; - struct ltt_kernel_event *kevent; - struct lttng_event *event_list = NULL; - - assert(kchan); - - /* For each event in the kernel session */ - cds_list_for_each_entry(kevent, &kchan->events_list.head, list) { - if (kevent->enabled == 0) { - ret = kernel_enable_event(kevent); - if (ret < 0) { - /* Enable failed but still continue */ - continue; - } - } - } - - size = kernel_list_events(kernel_tracer_fd, &event_list); - if (size < 0) { - ret = LTTNG_ERR_KERN_LIST_FAIL; - goto end; - } - - for (i = 0; i < size; i++) { - kevent = trace_kernel_get_event_by_name(event_list[i].name, kchan); - if (kevent == NULL) { - /* Default event type for enable all */ - event_list[i].type = LTTNG_EVENT_TRACEPOINT; - /* Enable each single tracepoint event */ - ret = kernel_create_event(&event_list[i], kchan); - if (ret < 0) { - /* Ignore error here and continue */ - } - } - } - free(event_list); - - ret = LTTNG_OK; -end: - return ret; -} - -/* - * Enable all kernel events of a channel of the kernel session. - */ -int event_kernel_enable_all(struct ltt_kernel_channel *kchan, - int kernel_tracer_fd) -{ - int tp_ret; - - assert(kchan); - - tp_ret = event_kernel_enable_all_tracepoints(kchan, kernel_tracer_fd); - if (tp_ret != LTTNG_OK) { - goto end; - } - - /* - * Reaching this code path means that all tracepoints were enabled without - * errors so we ignore the error value of syscalls. - * - * At the moment, failing to enable syscalls on "lttng enable-event -a -k" - * is not considered an error that need to be returned to the client since - * tracepoints did not fail. Future work will allow us to send back - * multiple errors to the client in one API call. - */ - (void) event_kernel_enable_syscall(kchan, ""); - -end: - return tp_ret; -} - /* * ============================ * UST : The Ultimate Frontier! diff --git a/src/bin/lttng-sessiond/event.h b/src/bin/lttng-sessiond/event.h index 501ee02d1..4fa44560e 100644 --- a/src/bin/lttng-sessiond/event.h +++ b/src/bin/lttng-sessiond/event.h @@ -32,10 +32,6 @@ int event_kernel_enable_tracepoint(struct ltt_kernel_channel *kchan, struct lttng_event *event); int event_kernel_enable_syscall(struct ltt_kernel_channel *kchan, char *syscall_name); -int event_kernel_enable_all_tracepoints(struct ltt_kernel_channel *kchan, - int kernel_tracer_fd); -int event_kernel_enable_all(struct ltt_kernel_channel *kchan, - int kernel_tracer_fd); int event_ust_enable_tracepoint(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct lttng_event *event, diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c index 1b3d5f7cd..0de6c8d08 100644 --- a/src/bin/lttng/commands/enable_events.c +++ b/src/bin/lttng/commands/enable_events.c @@ -777,7 +777,7 @@ static int enable_events(char *session_name) /* Default setup for enable all */ if (opt_kernel) { ev.type = opt_event_type; - ev.name[0] = '\0'; + strcpy(ev.name, "*"); /* kernel loglevels not implemented */ ev.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; } else { @@ -1034,9 +1034,12 @@ static int enable_events(char *session_name) print_channel_name(channel_name)); switch (opt_event_type) { - case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */ - ev.type = LTTNG_EVENT_TRACEPOINT; - /* Fall-through */ + case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */ + /* If event name differs from *, select tracepoint. */ + if (strcmp(ev.name, "*")) { + ev.type = LTTNG_EVENT_TRACEPOINT; + } + break; case LTTNG_EVENT_TRACEPOINT: break; case LTTNG_EVENT_PROBE: diff --git a/src/common/kernel-ctl/kernel-ioctl.h b/src/common/kernel-ctl/kernel-ioctl.h index 528c8082b..671a76972 100644 --- a/src/common/kernel-ctl/kernel-ioctl.h +++ b/src/common/kernel-ctl/kernel-ioctl.h @@ -19,7 +19,7 @@ #ifndef _LTT_KERNEL_IOCTL_H #define _LTT_KERNEL_IOCTL_H -#define LTTNG_MODULES_ABI_MAJOR_VERSION 1 +#define LTTNG_MODULES_ABI_MAJOR_VERSION 2 #define LTTNG_MODULES_ABI_MINOR_VERSION 0 /* Get a snapshot of the current ring buffer producer and consumer positions */ -- 2.34.1