From 2ef84c95c5158ce40e77229fb5705524ff22be7b Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 30 May 2011 18:06:50 -0400 Subject: [PATCH] Add listing kernel event support Introduce the --list-events option which list all tracing event of the kernel or/and an application. Only kernel support here. User-space integration is coming. Signed-off-by: David Goulet --- include/lttng/lttng.h | 1 + liblttngctl/liblttngctl.c | 13 ++++++ liblttsessiondcomm/liblttsessiondcomm.c | 1 + liblttsessiondcomm/liblttsessiondcomm.h | 2 + ltt-sessiond/kernel-ctl.c | 60 +++++++++++++++++++++++++ ltt-sessiond/kernel-ctl.h | 9 ++++ ltt-sessiond/main.c | 30 +++++++++++++ lttng/lttng.c | 48 +++++++++++++++++++- lttng/options.c | 3 ++ lttng/options.h | 1 + 10 files changed, 167 insertions(+), 1 deletion(-) diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index a9955f8d4..d76340dc8 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -92,6 +92,7 @@ extern int lttng_kernel_create_session(void); extern int lttng_kernel_create_stream(void); extern int lttng_kernel_disable_event(char *event_name); extern int lttng_kernel_enable_event(char *event_name); +extern int lttng_kernel_list_events(char **event_list); extern int lttng_kernel_open_metadata(void); extern int lttng_kernel_start_tracing(void); extern int lttng_kernel_stop_tracing(void); diff --git a/liblttngctl/liblttngctl.c b/liblttngctl/liblttngctl.c index 31edc982e..d8230c618 100644 --- a/liblttngctl/liblttngctl.c +++ b/liblttngctl/liblttngctl.c @@ -290,6 +290,19 @@ int lttng_kernel_create_stream(void) return ask_sessiond(KERNEL_CREATE_STREAM, NULL); } +/* + * lttng_kernel_list_events + * + * List all available events in the kernel. + * + * Return the size (bytes) of the list and set the event_list array. + * On error, return negative value. + */ +int lttng_kernel_list_events(char **event_list) +{ + return ask_sessiond(KERNEL_LIST_EVENTS, (void **) event_list); +} + /* * lttng_kernel_start_tracing * diff --git a/liblttsessiondcomm/liblttsessiondcomm.c b/liblttsessiondcomm/liblttsessiondcomm.c index ff14d7879..ce7bd9145 100644 --- a/liblttsessiondcomm/liblttsessiondcomm.c +++ b/liblttsessiondcomm/liblttsessiondcomm.c @@ -61,6 +61,7 @@ static const char *lttcomm_readable_code[] = { [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_DIR_FAIL) ] = "Kernel trace directory creation failed", [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_DIR_EXIST) ] = "Kernel trace directory already exist", [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_NO_SESSION) ] = "No kernel session found", + [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_LIST_FAIL) ] = "Listing kernel events failed", [ LTTCOMM_ERR_INDEX(KCONSUMERD_COMMAND_SOCK_READY) ] = "Kconsumerd command socket ready", [ LTTCOMM_ERR_INDEX(KCONSUMERD_SUCCESS_RECV_FD) ] = "Kconsumerd success on receiving fds", [ LTTCOMM_ERR_INDEX(KCONSUMERD_ERROR_RECV_FD) ] = "Kconsumerd error on receiving fds", diff --git a/liblttsessiondcomm/liblttsessiondcomm.h b/liblttsessiondcomm/liblttsessiondcomm.h index d63f9b62c..b563f6a7b 100644 --- a/liblttsessiondcomm/liblttsessiondcomm.h +++ b/liblttsessiondcomm/liblttsessiondcomm.h @@ -46,6 +46,7 @@ enum lttcomm_sessiond_command { KERNEL_CREATE_STREAM, KERNEL_DISABLE_EVENT, KERNEL_ENABLE_EVENT, + KERNEL_LIST_EVENTS, KERNEL_OPEN_METADATA, KERNEL_START_TRACE, KERNEL_STOP_TRACE, @@ -108,6 +109,7 @@ enum lttcomm_return_code { LTTCOMM_KERN_DIR_FAIL, /* Kernel trace directory creation failed */ LTTCOMM_KERN_DIR_EXIST, /* Kernel trace directory exist */ LTTCOMM_KERN_NO_SESSION, /* No kernel session found */ + LTTCOMM_KERN_LIST_FAIL, /* Kernel listing events failed */ KCONSUMERD_COMMAND_SOCK_READY, /* when kconsumerd command socket ready */ KCONSUMERD_SUCCESS_RECV_FD, /* success on receiving fds */ KCONSUMERD_ERROR_RECV_FD, /* error on receiving fds */ diff --git a/ltt-sessiond/kernel-ctl.c b/ltt-sessiond/kernel-ctl.c index a4d8099f9..f3fdc0e72 100644 --- a/ltt-sessiond/kernel-ctl.c +++ b/ltt-sessiond/kernel-ctl.c @@ -281,3 +281,63 @@ int kernel_create_metadata_stream(struct ltt_kernel_session *session) error: return -1; } + +/* + * kernel_list_events + * + * Get the event list from the kernel tracer and return that list in the CTF + * format. + */ +ssize_t kernel_list_events(int tracer_fd, char **list) +{ + int fd; + char *buf, *line = NULL; + size_t nb, nbmem, total = 0; + ssize_t size; + FILE *fp; + + fd = kernctl_tracepoint_list(tracer_fd); + if (fd < 0) { + perror("kernel tracepoint list"); + goto error; + } + + fp = fdopen(fd, "r"); + if (fp == NULL) { + perror("kernel tracepoint list fdopen"); + goto error; + } + + /* + * Init memory size counter + * See kernel-ctl.h for explanation of this value + */ + nbmem = KERNEL_EVENT_LIST_SIZE; + buf = malloc(nbmem); + + while ((size = getline(&line, &nb, fp)) != -1) { + if (total + size > nbmem) { + DBG("Reallocating event list from %ld to %ld bytes", nbmem, + total + size + KERNEL_EVENT_LIST_SIZE); + /* Adding the default size again */ + nbmem = total + size + KERNEL_EVENT_LIST_SIZE; + buf = realloc(buf, nbmem); + if (buf == NULL) { + perror("realloc list events"); + goto error; + } + } + memcpy(buf + total, line, size); + total += size; + } + + *list = buf; + + DBG("Kernel list events done"); + + return total; + +error: + return -1; +} + diff --git a/ltt-sessiond/kernel-ctl.h b/ltt-sessiond/kernel-ctl.h index 00388c7dd..3b18fe8e0 100644 --- a/ltt-sessiond/kernel-ctl.h +++ b/ltt-sessiond/kernel-ctl.h @@ -22,6 +22,14 @@ #include "session.h" #include "trace.h" +/* + * Default size for the event list when kernel_list_events is called. This size + * value is based on the initial LTTng 2.0 version set of tracepoints. This is + * NOT an upper bound because if the real event list size is bigger, dynamic + * reallocation is performed. + */ +#define KERNEL_EVENT_LIST_SIZE 2000 + int kernel_create_session(struct ltt_session *session, int tracer_fd); int kernel_create_channel(struct ltt_kernel_session *session); int kernel_enable_event(struct ltt_kernel_session *session, char *name); @@ -30,5 +38,6 @@ int kernel_create_metadata_stream(struct ltt_kernel_session *session); int kernel_create_channel_stream(struct ltt_kernel_channel *channel); int kernel_start_session(struct ltt_kernel_session *session); int kernel_stop_session(struct ltt_kernel_session *session); +ssize_t kernel_list_events(int tracer_fd, char **event_list); #endif /* _LTT_KERNEL_CTL_H */ diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index 68481146e..e65e8198b 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -658,6 +658,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->cmd_type) { case LTTNG_CREATE_SESSION: case LTTNG_LIST_SESSIONS: + case KERNEL_LIST_EVENTS: case UST_LIST_APPS: break; default: @@ -676,6 +677,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) case KERNEL_CREATE_STREAM: case KERNEL_DISABLE_EVENT: case KERNEL_ENABLE_EVENT: + case KERNEL_LIST_EVENTS: case KERNEL_OPEN_METADATA: case KERNEL_START_TRACE: case KERNEL_STOP_TRACE: @@ -761,6 +763,34 @@ static int process_client_msg(struct command_ctx *cmd_ctx) ret = LTTCOMM_OK; break; } + case KERNEL_LIST_EVENTS: + { + char *event_list; + ssize_t size; + + size = kernel_list_events(kernel_tracer_fd, &event_list); + if (size < 0) { + ret = LTTCOMM_KERN_LIST_FAIL; + goto error; + } + + /* + * Setup lttng message with payload size set to the event list size in + * bytes and then copy list into the llm payload. + */ + ret = setup_lttng_msg(cmd_ctx, size); + if (ret < 0) { + goto setup_error; + } + + /* Copy event list into message payload */ + memcpy(cmd_ctx->llm->payload, event_list, size); + + free(event_list); + + ret = LTTCOMM_OK; + break; + } case KERNEL_OPEN_METADATA: { /* Setup lttng message with no payload */ diff --git a/lttng/lttng.c b/lttng/lttng.c index 75cb1b473..9c34d2c62 100644 --- a/lttng/lttng.c +++ b/lttng/lttng.c @@ -47,6 +47,7 @@ static int process_client_opt(void); static int process_opt_list_apps(void); static int process_opt_list_sessions(void); static int process_opt_list_traces(void); +static int process_opt_kernel_list_events(void); static int process_opt_create_session(void); static int process_kernel_create_trace(void); static int process_opt_kernel_event(void); @@ -87,6 +88,18 @@ static int process_client_opt(void) goto error; } + if (opt_list_events) { + if (opt_trace_kernel) { + ret = process_opt_kernel_list_events(); + if (ret < 0) { + goto end; + } + } else if (opt_trace_pid != 0) { + // TODO + } + goto error; + } + /* Session creation or auto session set on */ if (auto_session || opt_create_session) { DBG("Creating a new session"); @@ -253,7 +266,40 @@ error: } /* - * process_kernel_event + * process_opt_kernel_list_events + * + * Ask for all trace events in the kernel and pretty print them. + */ +static int process_opt_kernel_list_events(void) +{ + int ret, pos, size; + char *event_list, *event, *ptr; + + DBG("Getting all tracing events"); + + ret = lttng_kernel_list_events(&event_list); + if (ret < 0) { + ERR("Unable to list events."); + return ret; + } + + MSG("Kernel tracepoints:\n-------------"); + + ptr = event_list; + while ((size = sscanf(ptr, "event { name = %m[^;]; };%n\n", &event, &pos)) == 1) { + MSG(" - %s", event); + /* Move pointer to the next line */ + ptr += pos + 1; + free(event); + } + + free(event_list); + + return 0; +} + +/* + * process_opt_kernel_event * * Enable kernel event from the command line list given. */ diff --git a/lttng/options.c b/lttng/options.c index 5b9e0c858..fe7e400f8 100644 --- a/lttng/options.c +++ b/lttng/options.c @@ -34,6 +34,7 @@ int opt_trace_kernel; int opt_quiet; int opt_verbose; int opt_list_apps; +int opt_list_events; int opt_no_sessiond; int opt_list_session; int opt_list_traces; @@ -70,6 +71,7 @@ static struct poptOption long_options[] = { {"kernel", 'k', POPT_ARG_VAL, &opt_trace_kernel, 1, 0, 0}, {"kern-create-channel",0, POPT_ARG_VAL, &opt_kern_create_channel, 1, 0, 0}, {"list-apps", 'L', POPT_ARG_VAL, &opt_list_apps, 1, 0, 0}, + {"list-events", 0, POPT_ARG_VAL, &opt_list_events, 1, 0, 0}, {"list-sessions", 'l', POPT_ARG_VAL, &opt_list_session, 1, 0, 0}, {"list-traces", 't', POPT_ARG_VAL, &opt_list_traces, 1, 0, 0}, {"no-kernel", 0, POPT_ARG_VAL, &opt_trace_kernel, 0, 0, 0}, @@ -112,6 +114,7 @@ static void usage(FILE *ofp) fprintf(ofp, "Tracing options:\n"); fprintf(ofp, " -p, --pid PID Specify action on user-space tracer for PID\n"); fprintf(ofp, " -k, --kernel Specify action on kernel tracer\n"); + fprintf(ofp, " --list-events List all available tracing events\n"); fprintf(ofp, " -e, --enable-event LIST Enable tracing event (support marker and tracepoint)\n"); fprintf(ofp, " --disable-event LIST Disable tracing event (support marker and tracepoint)\n"); fprintf(ofp, " -C, --create-trace Create a trace. Allocate and setup a trace\n"); diff --git a/lttng/options.h b/lttng/options.h index d5c0b5372..45a76c77e 100644 --- a/lttng/options.h +++ b/lttng/options.h @@ -39,6 +39,7 @@ extern int opt_destroy_session; extern int opt_create_session; extern int opt_kern_create_channel; extern int opt_list_apps; +extern int opt_list_events; extern int opt_no_sessiond; extern int opt_list_session; extern int opt_list_traces; -- 2.34.1