Commit | Line | Data |
---|---|---|
ce5aef0b MD |
1 | /* |
2 | * ltt-probes.c | |
3 | * | |
4 | * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
5 | * | |
6 | * Holds LTTng probes registry. | |
7 | * | |
8 | * Dual LGPL v2.1/GPL v2 license. | |
9 | */ | |
10 | ||
8d8a24c8 MD |
11 | #include <string.h> |
12 | #include <errno.h> | |
13 | #include <urcu/list.h> | |
14 | #include <ust/core.h> | |
f4681817 | 15 | #include <ust/lttng-events.h> |
ce5aef0b | 16 | |
8165c8da MD |
17 | #include "ltt-tracer-core.h" |
18 | ||
19 | /* | |
20 | * probe list is protected by lock_ust()/unlock_ust(). | |
21 | */ | |
8d8a24c8 | 22 | static CDS_LIST_HEAD(probe_list); |
ce5aef0b MD |
23 | |
24 | static | |
25 | const struct lttng_event_desc *find_event(const char *name) | |
26 | { | |
27 | struct lttng_probe_desc *probe_desc; | |
28 | int i; | |
29 | ||
8d8a24c8 | 30 | cds_list_for_each_entry(probe_desc, &probe_list, head) { |
ce5aef0b MD |
31 | for (i = 0; i < probe_desc->nr_events; i++) { |
32 | if (!strcmp(probe_desc->event_desc[i].name, name)) | |
33 | return &probe_desc->event_desc[i]; | |
34 | } | |
35 | } | |
36 | return NULL; | |
37 | } | |
38 | ||
39 | int ltt_probe_register(struct lttng_probe_desc *desc) | |
40 | { | |
41 | int ret = 0; | |
42 | int i; | |
43 | ||
8165c8da | 44 | lock_ust(); |
ce5aef0b MD |
45 | /* |
46 | * TODO: This is O(N^2). Turn into a hash table when probe registration | |
47 | * overhead becomes an issue. | |
48 | */ | |
49 | for (i = 0; i < desc->nr_events; i++) { | |
50 | if (find_event(desc->event_desc[i].name)) { | |
51 | ret = -EEXIST; | |
52 | goto end; | |
53 | } | |
54 | } | |
8d8a24c8 | 55 | cds_list_add(&desc->head, &probe_list); |
8165c8da MD |
56 | |
57 | /* | |
58 | * fix the events awaiting probe load. | |
59 | */ | |
60 | for (i = 0; i < desc->nr_events; i++) { | |
61 | ret = pending_probe_fix_events(&desc->event_desc[i]); | |
62 | assert(!ret); | |
63 | } | |
ce5aef0b | 64 | end: |
8165c8da | 65 | unlock_ust(); |
ce5aef0b MD |
66 | return ret; |
67 | } | |
ce5aef0b MD |
68 | |
69 | void ltt_probe_unregister(struct lttng_probe_desc *desc) | |
70 | { | |
8165c8da | 71 | lock_ust(); |
8d8a24c8 | 72 | cds_list_del(&desc->head); |
8165c8da | 73 | unlock_ust(); |
ce5aef0b | 74 | } |
ce5aef0b | 75 | |
8165c8da MD |
76 | /* |
77 | * called with UST lock held. | |
78 | */ | |
ce5aef0b MD |
79 | const struct lttng_event_desc *ltt_event_get(const char *name) |
80 | { | |
81 | const struct lttng_event_desc *event; | |
ce5aef0b | 82 | |
ce5aef0b | 83 | event = find_event(name); |
ce5aef0b MD |
84 | if (!event) |
85 | return NULL; | |
ce5aef0b MD |
86 | return event; |
87 | } | |
ce5aef0b MD |
88 | |
89 | void ltt_event_put(const struct lttng_event_desc *event) | |
90 | { | |
ce5aef0b | 91 | } |
ce5aef0b | 92 | |
8d8a24c8 | 93 | #if 0 |
ce5aef0b MD |
94 | static |
95 | void *tp_list_start(struct seq_file *m, loff_t *pos) | |
96 | { | |
97 | struct lttng_probe_desc *probe_desc; | |
98 | int iter = 0, i; | |
99 | ||
8d8a24c8 MD |
100 | pthread_mutex_lock(&probe_mutex); |
101 | cds_list_for_each_entry(probe_desc, &probe_list, head) { | |
ce5aef0b MD |
102 | for (i = 0; i < probe_desc->nr_events; i++) { |
103 | if (iter++ >= *pos) | |
104 | return (void *) &probe_desc->event_desc[i]; | |
105 | } | |
106 | } | |
107 | /* End of list */ | |
108 | return NULL; | |
109 | } | |
110 | ||
111 | static | |
112 | void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos) | |
113 | { | |
114 | struct lttng_probe_desc *probe_desc; | |
115 | int iter = 0, i; | |
116 | ||
117 | (*ppos)++; | |
8d8a24c8 | 118 | cds_list_for_each_entry(probe_desc, &probe_list, head) { |
ce5aef0b MD |
119 | for (i = 0; i < probe_desc->nr_events; i++) { |
120 | if (iter++ >= *ppos) | |
121 | return (void *) &probe_desc->event_desc[i]; | |
122 | } | |
123 | } | |
124 | /* End of list */ | |
125 | return NULL; | |
126 | } | |
127 | ||
128 | static | |
129 | void tp_list_stop(struct seq_file *m, void *p) | |
130 | { | |
8d8a24c8 | 131 | pthread_mutex_unlock(&probe_mutex); |
ce5aef0b MD |
132 | } |
133 | ||
134 | static | |
135 | int tp_list_show(struct seq_file *m, void *p) | |
136 | { | |
137 | const struct lttng_event_desc *probe_desc = p; | |
138 | ||
139 | /* | |
140 | * Don't export lttng internal events (metadata). | |
141 | */ | |
142 | if (!strncmp(probe_desc->name, "lttng_", sizeof("lttng_") - 1)) | |
143 | return 0; | |
144 | seq_printf(m, "event { name = %s; };\n", | |
145 | probe_desc->name); | |
146 | return 0; | |
147 | } | |
148 | ||
149 | static | |
150 | const struct seq_operations lttng_tracepoint_list_seq_ops = { | |
151 | .start = tp_list_start, | |
152 | .next = tp_list_next, | |
153 | .stop = tp_list_stop, | |
154 | .show = tp_list_show, | |
155 | }; | |
156 | ||
157 | static | |
158 | int lttng_tracepoint_list_open(struct inode *inode, struct file *file) | |
159 | { | |
160 | return seq_open(file, <tng_tracepoint_list_seq_ops); | |
161 | } | |
162 | ||
163 | const struct file_operations lttng_tracepoint_list_fops = { | |
164 | .open = lttng_tracepoint_list_open, | |
165 | .read = seq_read, | |
166 | .llseek = seq_lseek, | |
167 | .release = seq_release, | |
168 | }; | |
8d8a24c8 | 169 | #endif //0 |