From 271b66812595fb4be4ce1cb2b8277d97b13d795e Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 24 May 2011 12:20:48 -0400 Subject: [PATCH] Add tracepoint listing ABI Signed-off-by: Mathieu Desnoyers --- ltt-debugfs-abi.c | 37 +++++++++++++++++++++++-- ltt-debugfs-abi.h | 1 + ltt-events.h | 3 ++ ltt-probes.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 2 deletions(-) diff --git a/ltt-debugfs-abi.c b/ltt-debugfs-abi.c index db2aebc3..c5ca6325 100644 --- a/ltt-debugfs-abi.c +++ b/ltt-debugfs-abi.c @@ -84,6 +84,33 @@ fd_error: return ret; } +static +int lttng_abi_tracepoint_list(void) +{ + struct file *tracepoint_list_file; + int file_fd, ret; + + file_fd = get_unused_fd(); + if (file_fd < 0) { + ret = file_fd; + goto fd_error; + } + tracepoint_list_file = anon_inode_getfile("[lttng_session]", + <tng_tracepoint_list_fops, + NULL, O_RDWR); + if (IS_ERR(tracepoint_list_file)) { + ret = PTR_ERR(tracepoint_list_file); + goto file_error; + } + fd_install(file_fd, tracepoint_list_file); + return file_fd; + +file_error: + put_unused_fd(file_fd); +fd_error: + return ret; +} + static long lttng_abi_tracer_version(struct file *file, struct lttng_kernel_tracer_version __user *uversion_param) @@ -109,6 +136,10 @@ long lttng_abi_tracer_version(struct file *file, * This ioctl implements lttng commands: * LTTNG_KERNEL_SESSION * Returns a LTTng trace session file descriptor + * LTTNG_KERNEL_TRACER_VERSION + * Returns the LTTng kernel tracer version + * LTTNG_KERNEL_TRACEPOINT_LIST + * Returns a file descriptor listing available tracepoints * * The returned session will be deleted when its file descriptor is closed. */ @@ -121,6 +152,8 @@ long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case LTTNG_KERNEL_TRACER_VERSION: return lttng_abi_tracer_version(file, (struct lttng_kernel_tracer_version __user *) arg); + case LTTNG_KERNEL_TRACEPOINT_LIST: + return lttng_abi_tracepoint_list(); default: return -ENOIOCTLCMD; } @@ -155,8 +188,8 @@ void lttng_metadata_create_events(struct file *channel_file) */ event = ltt_event_create(channel, &metadata_params, NULL); if (!event) { - goto create_error; ret = -EINVAL; + goto create_error; } return; @@ -389,7 +422,7 @@ int lttng_abi_create_event(struct file *channel_file, */ event = ltt_event_create(channel, &event_param, NULL); if (!event) { - ret = -EEXIST; + ret = -EINVAL; goto event_error; } event_file->private_data = event; diff --git a/ltt-debugfs-abi.h b/ltt-debugfs-abi.h index c6edce31..d0c2dd1a 100644 --- a/ltt-debugfs-abi.h +++ b/ltt-debugfs-abi.h @@ -69,6 +69,7 @@ struct lttng_kernel_tracer_version { #define LTTNG_KERNEL_SESSION _IO(0xF6, 0x40) #define LTTNG_KERNEL_TRACER_VERSION \ _IOR(0xF6, 0x41, struct lttng_kernel_tracer_version) +#define LTTNG_KERNEL_TRACEPOINT_LIST _IO(0xF6, 0x42) /* Session FD ioctl */ #define LTTNG_KERNEL_METADATA \ diff --git a/ltt-events.h b/ltt-events.h index 9baf660d..4179fb7c 100644 --- a/ltt-events.h +++ b/ltt-events.h @@ -305,4 +305,7 @@ void lttng_ftrace_unregister(struct ltt_event *event) { } #endif + +extern const struct file_operations lttng_tracepoint_list_fops; + #endif /* _LTT_EVENTS_H */ diff --git a/ltt-probes.c b/ltt-probes.c index 0efc23c5..e1ed2a31 100644 --- a/ltt-probes.c +++ b/ltt-probes.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "ltt-events.h" @@ -82,3 +83,72 @@ void ltt_event_put(const struct lttng_event_desc *event) module_put(event->owner); } EXPORT_SYMBOL_GPL(ltt_event_put); + +static +void *tp_list_start(struct seq_file *m, loff_t *pos) +{ + struct lttng_probe_desc *probe_desc; + int iter = 0, i; + + list_for_each_entry(probe_desc, &probe_list, head) { + for (i = 0; i < probe_desc->nr_events; i++) { + if (iter++ >= *pos) + return (void *) &probe_desc->event_desc[i]; + } + } + /* End of list */ + return NULL; +} + +static +void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos) +{ + struct lttng_probe_desc *probe_desc; + int iter = 0, i; + + (*ppos)++; + list_for_each_entry(probe_desc, &probe_list, head) { + for (i = 0; i < probe_desc->nr_events; i++) { + if (iter++ >= *ppos) + return (void *) &probe_desc->event_desc[i]; + } + } + /* End of list */ + return NULL; +} + +static +void tp_list_stop(struct seq_file *m, void *p) +{ +} + +static +int tp_list_show(struct seq_file *m, void *p) +{ + const struct lttng_event_desc *probe_desc = p; + + seq_printf(m, "event { name = %s; };\n", + probe_desc->name); + return 0; +} + +static +const struct seq_operations lttng_tracepoint_list_seq_ops = { + .start = tp_list_start, + .next = tp_list_next, + .stop = tp_list_stop, + .show = tp_list_show, +}; + +static +int lttng_tracepoint_list_open(struct inode *inode, struct file *file) +{ + return seq_open(file, <tng_tracepoint_list_seq_ops); +} + +const struct file_operations lttng_tracepoint_list_fops = { + .open = lttng_tracepoint_list_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; -- 2.34.1