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);
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
*
[ 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",
KERNEL_CREATE_STREAM,
KERNEL_DISABLE_EVENT,
KERNEL_ENABLE_EVENT,
+ KERNEL_LIST_EVENTS,
KERNEL_OPEN_METADATA,
KERNEL_START_TRACE,
KERNEL_STOP_TRACE,
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 */
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;
+}
+
#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);
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 */
switch (cmd_ctx->lsm->cmd_type) {
case LTTNG_CREATE_SESSION:
case LTTNG_LIST_SESSIONS:
+ case KERNEL_LIST_EVENTS:
case UST_LIST_APPS:
break;
default:
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:
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 */
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);
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");
}
/*
- * 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.
*/
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;
{"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},
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");
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;