X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=ltt-probes.c;h=81dcbd715df08300b6bcfd9973418f853544e8d0;hb=9d7d747f10bab16b3d85915a5b87e10acd2374f0;hp=dbdb50d402a2f7bbecd06a203d03fe46a3b85300;hpb=85a9ca7ff30ef892e5865c5541fd11f6c6de33a3;p=lttng-modules.git diff --git a/ltt-probes.c b/ltt-probes.c index dbdb50d4..81dcbd71 100644 --- a/ltt-probes.c +++ b/ltt-probes.c @@ -4,11 +4,14 @@ * Copyright 2010 (c) - Mathieu Desnoyers * * Holds LTTng probes registry. + * + * Dual LGPL v2.1/GPL v2 license. */ #include #include #include +#include #include "ltt-events.h" @@ -23,18 +26,13 @@ const struct lttng_event_desc *find_event(const char *name) list_for_each_entry(probe_desc, &probe_list, head) { for (i = 0; i < probe_desc->nr_events; i++) { - if (!strcmp(probe_desc->event_desc[i].name, name)) - return &probe_desc->event_desc[i]; + if (!strcmp(probe_desc->event_desc[i]->name, name)) + return probe_desc->event_desc[i]; } } return NULL; } -/* - * TODO: registration of probe descriptions in dynamically allocated memory (not - * directly in a module memory) will require some care for refcounting: it's - * currently done by just refcounting the module in event_get/put. - */ int ltt_probe_register(struct lttng_probe_desc *desc) { int ret = 0; @@ -46,7 +44,7 @@ int ltt_probe_register(struct lttng_probe_desc *desc) * overhead becomes an issue. */ for (i = 0; i < desc->nr_events; i++) { - if (find_event(desc->event_desc[i].name)) { + if (find_event(desc->event_desc[i]->name)) { ret = -EEXIST; goto end; } @@ -73,18 +71,94 @@ const struct lttng_event_desc *ltt_event_get(const char *name) mutex_lock(&probe_mutex); event = find_event(name); + mutex_unlock(&probe_mutex); if (!event) - goto end; - ret = try_module_get(__module_text_address((unsigned long) event)); + return NULL; + ret = try_module_get(event->owner); WARN_ON_ONCE(!ret); -end: - mutex_unlock(&probe_mutex); return event; } EXPORT_SYMBOL_GPL(ltt_event_get); void ltt_event_put(const struct lttng_event_desc *event) { - module_put(__module_text_address((unsigned long) 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; + + mutex_lock(&probe_mutex); + 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) +{ + mutex_unlock(&probe_mutex); +} + +static +int tp_list_show(struct seq_file *m, void *p) +{ + const struct lttng_event_desc *probe_desc = p; + + /* + * Don't export lttng internal events (metadata). + */ + if (!strncmp(probe_desc->name, "lttng_", sizeof("lttng_") - 1)) + return 0; + 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 = { + .owner = THIS_MODULE, + .open = lttng_tracepoint_list_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +};