1e73064907865e8e2e7cfbc396fd0fa1fe96c647
[lttng-ust.git] / src / lib / lttng-ust / lttng-probes.c
1 /*
2 * SPDX-License-Identifier: LGPL-2.1-only
3 *
4 * Copyright 2010-2012 (C) Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * Holds LTTng probes registry.
7 */
8
9 #define _LGPL_SOURCE
10 #include <string.h>
11 #include <errno.h>
12 #include <urcu/list.h>
13 #include <urcu/hlist.h>
14 #include <lttng/ust-events.h>
15 #include <lttng/tracepoint.h>
16 #include "common/tracepoint.h"
17 #include <assert.h>
18 #include "common/macros.h"
19 #include <ctype.h>
20
21 #include "lttng-tracer-core.h"
22 #include "common/jhash.h"
23 #include "lib/lttng-ust/events.h"
24
25 /*
26 * probe list is protected by ust_lock()/ust_unlock().
27 */
28 static CDS_LIST_HEAD(_probe_list);
29
30 /*
31 * List of probes registered by not yet processed.
32 */
33 static CDS_LIST_HEAD(lazy_probe_init);
34
35 /*
36 * lazy_nesting counter ensures we don't trigger lazy probe registration
37 * fixup while we are performing the fixup. It is protected by the ust
38 * mutex.
39 */
40 static int lazy_nesting;
41
42 /*
43 * Validate that each event within the probe provider refers to the
44 * right probe, and that the resulting name is not too long.
45 */
46 static
47 bool check_event_provider(const struct lttng_ust_probe_desc *probe_desc)
48 {
49 int i;
50
51 for (i = 0; i < probe_desc->nr_events; i++) {
52 const struct lttng_ust_event_desc *event_desc = probe_desc->event_desc[i];
53
54 if (event_desc->probe_desc != probe_desc) {
55 ERR("Error registering probe provider '%s'. Event '%s:%s' refers to the wrong provider descriptor.",
56 probe_desc->provider_name, probe_desc->provider_name, event_desc->event_name);
57 return false; /* provider mismatch */
58 }
59 if (!lttng_ust_validate_event_name(event_desc)) {
60 ERR("Error registering probe provider '%s'. Event '%s:%s' name is too long.",
61 probe_desc->provider_name, probe_desc->provider_name, event_desc->event_name);
62 return false; /* provider mismatch */
63 }
64 }
65 return true;
66 }
67
68 /*
69 * Called under ust lock.
70 */
71 static
72 void lttng_lazy_probe_register(struct lttng_ust_registered_probe *reg_probe)
73 {
74 struct lttng_ust_registered_probe *iter;
75 struct cds_list_head *probe_list;
76
77 /*
78 * The provider ensures there are no duplicate event names.
79 * Duplicated LTTNG_UST_TRACEPOINT_EVENT event names would generate a
80 * compile-time error due to duplicated symbol names.
81 */
82
83 /*
84 * We sort the providers by struct lttng_ust_probe_desc pointer
85 * address.
86 */
87 probe_list = &_probe_list;
88 cds_list_for_each_entry_reverse(iter, probe_list, head) {
89 BUG_ON(iter == reg_probe); /* Should never be in the list twice */
90 if (iter < reg_probe) {
91 /* We belong to the location right after iter. */
92 cds_list_add(&reg_probe->head, &iter->head);
93 goto probe_added;
94 }
95 }
96 /* We should be added at the head of the list */
97 cds_list_add(&reg_probe->head, probe_list);
98 probe_added:
99 DBG("just registered probe %s containing %u events",
100 reg_probe->desc->provider_name, reg_probe->desc->nr_events);
101 }
102
103 /*
104 * Called under ust lock.
105 */
106 static
107 void fixup_lazy_probes(void)
108 {
109 struct lttng_ust_registered_probe *iter, *tmp;
110 int ret;
111
112 lazy_nesting++;
113 cds_list_for_each_entry_safe(iter, tmp,
114 &lazy_probe_init, lazy_init_head) {
115 lttng_lazy_probe_register(iter);
116 iter->lazy = 0;
117 cds_list_del(&iter->lazy_init_head);
118 }
119 ret = lttng_fix_pending_events();
120 assert(!ret);
121 lazy_nesting--;
122 }
123
124 /*
125 * Called under ust lock.
126 */
127 struct cds_list_head *lttng_get_probe_list_head(void)
128 {
129 if (!lazy_nesting && !cds_list_empty(&lazy_probe_init))
130 fixup_lazy_probes();
131 return &_probe_list;
132 }
133
134 static
135 int check_provider_version(const struct lttng_ust_probe_desc *desc)
136 {
137 /*
138 * Check tracepoint provider version compatibility.
139 */
140 if (desc->major <= LTTNG_UST_PROVIDER_MAJOR) {
141 DBG("Provider \"%s\" accepted, version %u.%u is compatible "
142 "with LTTng UST provider version %u.%u.",
143 desc->provider_name, desc->major, desc->minor,
144 LTTNG_UST_PROVIDER_MAJOR,
145 LTTNG_UST_PROVIDER_MINOR);
146 if (desc->major < LTTNG_UST_PROVIDER_MAJOR) {
147 DBG("However, some LTTng UST features might not be "
148 "available for this provider unless it is "
149 "recompiled against a more recent LTTng UST.");
150 }
151 return 1; /* accept */
152 } else {
153 ERR("Provider \"%s\" rejected, version %u.%u is incompatible "
154 "with LTTng UST provider version %u.%u. Please upgrade "
155 "LTTng UST.",
156 desc->provider_name, desc->major, desc->minor,
157 LTTNG_UST_PROVIDER_MAJOR,
158 LTTNG_UST_PROVIDER_MINOR);
159 return 0; /* reject */
160 }
161 }
162
163 struct lttng_ust_registered_probe *lttng_ust_probe_register(const struct lttng_ust_probe_desc *desc)
164 {
165 struct lttng_ust_registered_probe *reg_probe = NULL;
166
167 lttng_ust_alloc_tls();
168
169 /*
170 * If version mismatch, don't register, but don't trigger assert
171 * on caller. The version check just prints an error.
172 */
173 if (!check_provider_version(desc))
174 return NULL;
175 if (!check_event_provider(desc))
176 return NULL;
177
178 ust_lock_nocheck();
179
180 reg_probe = zmalloc(sizeof(struct lttng_ust_registered_probe));
181 if (!reg_probe)
182 goto end;
183 reg_probe->desc = desc;
184 cds_list_add(&reg_probe->lazy_init_head, &lazy_probe_init);
185 reg_probe->lazy = 1;
186
187 DBG("adding probe %s containing %u events to lazy registration list",
188 desc->provider_name, desc->nr_events);
189 /*
190 * If there is at least one active session, we need to register
191 * the probe immediately, since we cannot delay event
192 * registration because they are needed ASAP.
193 */
194 if (lttng_session_active())
195 fixup_lazy_probes();
196
197 lttng_fix_pending_event_notifiers();
198 end:
199 ust_unlock();
200 return reg_probe;
201 }
202
203 void lttng_ust_probe_unregister(struct lttng_ust_registered_probe *reg_probe)
204 {
205 lttng_ust_alloc_tls();
206
207 if (!reg_probe)
208 return;
209 if (!check_provider_version(reg_probe->desc))
210 return;
211
212 ust_lock_nocheck();
213 if (!reg_probe->lazy)
214 cds_list_del(&reg_probe->head);
215 else
216 cds_list_del(&reg_probe->lazy_init_head);
217
218 lttng_probe_provider_unregister_events(reg_probe->desc);
219 DBG("just unregistered probes of provider %s", reg_probe->desc->provider_name);
220 ust_unlock();
221 free(reg_probe);
222 }
223
224 void lttng_probes_prune_event_list(struct lttng_ust_tracepoint_list *list)
225 {
226 struct tp_list_entry *list_entry, *tmp;
227
228 cds_list_for_each_entry_safe(list_entry, tmp, &list->head, head) {
229 cds_list_del(&list_entry->head);
230 free(list_entry);
231 }
232 }
233
234 /*
235 * called with UST lock held.
236 */
237 int lttng_probes_get_event_list(struct lttng_ust_tracepoint_list *list)
238 {
239 struct lttng_ust_registered_probe *reg_probe;
240 struct cds_list_head *probe_list;
241 int i;
242
243 probe_list = lttng_get_probe_list_head();
244 CDS_INIT_LIST_HEAD(&list->head);
245 cds_list_for_each_entry(reg_probe, probe_list, head) {
246 const struct lttng_ust_probe_desc *probe_desc = reg_probe->desc;
247
248 for (i = 0; i < probe_desc->nr_events; i++) {
249 const struct lttng_ust_event_desc *event_desc =
250 probe_desc->event_desc[i];
251 struct tp_list_entry *list_entry;
252
253 /* Skip event if name is too long. */
254 if (!lttng_ust_validate_event_name(event_desc))
255 continue;
256 list_entry = zmalloc(sizeof(*list_entry));
257 if (!list_entry)
258 goto err_nomem;
259 cds_list_add(&list_entry->head, &list->head);
260 lttng_ust_format_event_name(event_desc, list_entry->tp.name);
261 if (!event_desc->loglevel) {
262 list_entry->tp.loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT;
263 } else {
264 list_entry->tp.loglevel = *(*event_desc->loglevel);
265 }
266 }
267 }
268 if (cds_list_empty(&list->head))
269 list->iter = NULL;
270 else
271 list->iter =
272 cds_list_first_entry(&list->head, struct tp_list_entry, head);
273 return 0;
274
275 err_nomem:
276 lttng_probes_prune_event_list(list);
277 return -ENOMEM;
278 }
279
280 /*
281 * Return current iteration position, advance internal iterator to next.
282 * Return NULL if end of list.
283 */
284 struct lttng_ust_abi_tracepoint_iter *
285 lttng_ust_tracepoint_list_get_iter_next(struct lttng_ust_tracepoint_list *list)
286 {
287 struct tp_list_entry *entry;
288
289 if (!list->iter)
290 return NULL;
291 entry = list->iter;
292 if (entry->head.next == &list->head)
293 list->iter = NULL;
294 else
295 list->iter = cds_list_entry(entry->head.next,
296 struct tp_list_entry, head);
297 return &entry->tp;
298 }
299
300 void lttng_probes_prune_field_list(struct lttng_ust_field_list *list)
301 {
302 struct tp_field_list_entry *list_entry, *tmp;
303
304 cds_list_for_each_entry_safe(list_entry, tmp, &list->head, head) {
305 cds_list_del(&list_entry->head);
306 free(list_entry);
307 }
308 }
309
310 /*
311 * called with UST lock held.
312 */
313 int lttng_probes_get_field_list(struct lttng_ust_field_list *list)
314 {
315 struct lttng_ust_registered_probe *reg_probe;
316 struct cds_list_head *probe_list;
317 int i;
318
319 probe_list = lttng_get_probe_list_head();
320 CDS_INIT_LIST_HEAD(&list->head);
321 cds_list_for_each_entry(reg_probe, probe_list, head) {
322 const struct lttng_ust_probe_desc *probe_desc = reg_probe->desc;
323
324 for (i = 0; i < probe_desc->nr_events; i++) {
325 const struct lttng_ust_event_desc *event_desc =
326 probe_desc->event_desc[i];
327 int j;
328
329 if (event_desc->nr_fields == 0) {
330 /* Events without fields. */
331 struct tp_field_list_entry *list_entry;
332
333 /* Skip event if name is too long. */
334 if (!lttng_ust_validate_event_name(event_desc))
335 continue;
336 list_entry = zmalloc(sizeof(*list_entry));
337 if (!list_entry)
338 goto err_nomem;
339 cds_list_add(&list_entry->head, &list->head);
340 lttng_ust_format_event_name(event_desc, list_entry->field.event_name);
341 list_entry->field.field_name[0] = '\0';
342 list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
343 if (!event_desc->loglevel) {
344 list_entry->field.loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT;
345 } else {
346 list_entry->field.loglevel = *(*event_desc->loglevel);
347 }
348 list_entry->field.nowrite = 1;
349 }
350
351 for (j = 0; j < event_desc->nr_fields; j++) {
352 const struct lttng_ust_event_field *event_field =
353 event_desc->fields[j];
354 struct tp_field_list_entry *list_entry;
355
356 /* Skip event if name is too long. */
357 if (!lttng_ust_validate_event_name(event_desc))
358 continue;
359 list_entry = zmalloc(sizeof(*list_entry));
360 if (!list_entry)
361 goto err_nomem;
362 cds_list_add(&list_entry->head, &list->head);
363 lttng_ust_format_event_name(event_desc, list_entry->field.event_name);
364 strncpy(list_entry->field.field_name,
365 event_field->name,
366 LTTNG_UST_ABI_SYM_NAME_LEN);
367 list_entry->field.field_name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
368 switch (event_field->type->type) {
369 case lttng_ust_type_integer:
370 list_entry->field.type = LTTNG_UST_ABI_FIELD_INTEGER;
371 break;
372 case lttng_ust_type_string:
373 list_entry->field.type = LTTNG_UST_ABI_FIELD_STRING;
374 break;
375 case lttng_ust_type_array:
376 if (lttng_ust_get_type_array(event_field->type)->encoding == lttng_ust_string_encoding_none)
377 list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
378 else
379 list_entry->field.type = LTTNG_UST_ABI_FIELD_STRING;
380 break;
381 case lttng_ust_type_sequence:
382 if (lttng_ust_get_type_sequence(event_field->type)->encoding == lttng_ust_string_encoding_none)
383 list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
384 else
385 list_entry->field.type = LTTNG_UST_ABI_FIELD_STRING;
386 break;
387 case lttng_ust_type_float:
388 list_entry->field.type = LTTNG_UST_ABI_FIELD_FLOAT;
389 break;
390 case lttng_ust_type_enum:
391 list_entry->field.type = LTTNG_UST_ABI_FIELD_ENUM;
392 break;
393 default:
394 list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
395 }
396 if (!event_desc->loglevel) {
397 list_entry->field.loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT;
398 } else {
399 list_entry->field.loglevel = *(*event_desc->loglevel);
400 }
401 list_entry->field.nowrite = event_field->nowrite;
402 }
403 }
404 }
405 if (cds_list_empty(&list->head))
406 list->iter = NULL;
407 else
408 list->iter =
409 cds_list_first_entry(&list->head,
410 struct tp_field_list_entry, head);
411 return 0;
412
413 err_nomem:
414 lttng_probes_prune_field_list(list);
415 return -ENOMEM;
416 }
417
418 /*
419 * Return current iteration position, advance internal iterator to next.
420 * Return NULL if end of list.
421 */
422 struct lttng_ust_abi_field_iter *
423 lttng_ust_field_list_get_iter_next(struct lttng_ust_field_list *list)
424 {
425 struct tp_field_list_entry *entry;
426
427 if (!list->iter)
428 return NULL;
429 entry = list->iter;
430 if (entry->head.next == &list->head)
431 list->iter = NULL;
432 else
433 list->iter = cds_list_entry(entry->head.next,
434 struct tp_field_list_entry, head);
435 return &entry->field;
436 }
This page took 0.042326 seconds and 3 git commands to generate.