Rename all 'fixup_tls' functions to 'alloc_tls'
[lttng-ust.git] / src / lib / lttng-ust / lttng-probes.c
CommitLineData
ce5aef0b 1/*
c0c0989a 2 * SPDX-License-Identifier: LGPL-2.1-only
ce5aef0b 3 *
c0c0989a 4 * Copyright 2010-2012 (C) Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
e92f3e28 5 *
c0c0989a 6 * Holds LTTng probes registry.
ce5aef0b
MD
7 */
8
3fbec7dc 9#define _LGPL_SOURCE
8d8a24c8
MD
10#include <string.h>
11#include <errno.h>
12#include <urcu/list.h>
1f18504e 13#include <urcu/hlist.h>
4318ae1b 14#include <lttng/ust-events.h>
902e1379 15#include <lttng/tracepoint.h>
8f51c684 16#include "common/tracepoint.h"
a3bb4b27 17#include <assert.h>
9d315d6d 18#include "common/macros.h"
48740cab 19#include <ctype.h>
ce5aef0b 20
7dd08bec 21#include "lttng-tracer-core.h"
e58e5ad5 22#include "common/jhash.h"
36c52fff 23#include "lib/lttng-ust/events.h"
8165c8da
MD
24
25/*
17dfb34b 26 * probe list is protected by ust_lock()/ust_unlock().
8165c8da 27 */
ac69b35b 28static CDS_LIST_HEAD(_probe_list);
e58095ef 29
6715d7d1
MD
30/*
31 * List of probes registered by not yet processed.
32 */
33static CDS_LIST_HEAD(lazy_probe_init);
df854e41 34
6715d7d1
MD
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 */
40static int lazy_nesting;
df854e41 41
6715d7d1 42/*
5b4c6da4
MD
43 * Validate that each event within the probe provider refers to the
44 * right probe, and that the resulting name is not too long.
6715d7d1 45 */
ce5aef0b 46static
4e48b5d2 47bool check_event_provider(const struct lttng_ust_probe_desc *probe_desc)
ce5aef0b 48{
ce5aef0b 49 int i;
5b4c6da4
MD
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 }
ce5aef0b 64 }
5b4c6da4 65 return true;
ce5aef0b
MD
66}
67
6715d7d1
MD
68/*
69 * Called under ust lock.
70 */
71static
4e48b5d2 72void lttng_lazy_probe_register(struct lttng_ust_registered_probe *reg_probe)
ce5aef0b 73{
4e48b5d2 74 struct lttng_ust_registered_probe *iter;
ac69b35b 75 struct cds_list_head *probe_list;
48205d60 76
48205d60
MD
77 /*
78 * The provider ensures there are no duplicate event names.
7f2f82c3 79 * Duplicated LTTNG_UST_TRACEPOINT_EVENT event names would generate a
48205d60 80 * compile-time error due to duplicated symbol names.
ce5aef0b 81 */
df854e41
MD
82
83 /*
dc11f93f 84 * We sort the providers by struct lttng_ust_probe_desc pointer
df854e41
MD
85 * address.
86 */
6715d7d1 87 probe_list = &_probe_list;
ac69b35b 88 cds_list_for_each_entry_reverse(iter, probe_list, head) {
4e48b5d2
MD
89 BUG_ON(iter == reg_probe); /* Should never be in the list twice */
90 if (iter < reg_probe) {
df854e41 91 /* We belong to the location right after iter. */
4e48b5d2
MD
92 cds_list_add(&reg_probe->head, &iter->head);
93 goto probe_added;
df854e41
MD
94 }
95 }
96 /* We should be added at the head of the list */
4e48b5d2
MD
97 cds_list_add(&reg_probe->head, probe_list);
98probe_added:
e81a53af 99 DBG("just registered probe %s containing %u events",
4e48b5d2 100 reg_probe->desc->provider_name, reg_probe->desc->nr_events);
6715d7d1
MD
101}
102
103/*
104 * Called under ust lock.
105 */
106static
107void fixup_lazy_probes(void)
108{
4e48b5d2 109 struct lttng_ust_registered_probe *iter, *tmp;
5f733922 110 int ret;
6715d7d1
MD
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 }
5f733922
MD
119 ret = lttng_fix_pending_events();
120 assert(!ret);
6715d7d1
MD
121 lazy_nesting--;
122}
123
124/*
125 * Called under ust lock.
126 */
127struct 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
71d31690 134static
4e48b5d2 135int check_provider_version(const struct lttng_ust_probe_desc *desc)
71d31690
MD
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.",
5b4c6da4 143 desc->provider_name, desc->major, desc->minor,
71d31690
MD
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.",
5b4c6da4 156 desc->provider_name, desc->major, desc->minor,
71d31690
MD
157 LTTNG_UST_PROVIDER_MAJOR,
158 LTTNG_UST_PROVIDER_MINOR);
159 return 0; /* reject */
160 }
161}
162
4e48b5d2 163struct lttng_ust_registered_probe *lttng_ust_probe_register(const struct lttng_ust_probe_desc *desc)
6715d7d1 164{
4e48b5d2 165 struct lttng_ust_registered_probe *reg_probe = NULL;
6715d7d1 166
a9fd951a 167 lttng_ust_alloc_tls();
c362addf 168
71d31690
MD
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))
4e48b5d2 174 return NULL;
5b4c6da4 175 if (!check_event_provider(desc))
4e48b5d2 176 return NULL;
71d31690 177
3327ac33 178 ust_lock_nocheck();
6715d7d1 179
4e48b5d2
MD
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
6715d7d1 187 DBG("adding probe %s containing %u events to lazy registration list",
5b4c6da4 188 desc->provider_name, desc->nr_events);
6715d7d1
MD
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();
0fdd0b89 196
d8d2416d 197 lttng_fix_pending_event_notifiers();
4e48b5d2 198end:
17dfb34b 199 ust_unlock();
4e48b5d2 200 return reg_probe;
ce5aef0b 201}
ce5aef0b 202
4e48b5d2 203void lttng_ust_probe_unregister(struct lttng_ust_registered_probe *reg_probe)
ce5aef0b 204{
a9fd951a 205 lttng_ust_alloc_tls();
c362addf 206
4e48b5d2
MD
207 if (!reg_probe)
208 return;
209 if (!check_provider_version(reg_probe->desc))
71d31690
MD
210 return;
211
3327ac33 212 ust_lock_nocheck();
4e48b5d2
MD
213 if (!reg_probe->lazy)
214 cds_list_del(&reg_probe->head);
6715d7d1 215 else
4e48b5d2 216 cds_list_del(&reg_probe->lazy_init_head);
2c05c691 217
4e48b5d2
MD
218 lttng_probe_provider_unregister_events(reg_probe->desc);
219 DBG("just unregistered probes of provider %s", reg_probe->desc->provider_name);
17dfb34b 220 ust_unlock();
4e48b5d2 221 free(reg_probe);
ce5aef0b 222}
ce5aef0b 223
7dd08bec 224void lttng_probes_prune_event_list(struct lttng_ust_tracepoint_list *list)
c8fcf224
MD
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 */
7dd08bec 237int lttng_probes_get_event_list(struct lttng_ust_tracepoint_list *list)
c8fcf224 238{
4e48b5d2 239 struct lttng_ust_registered_probe *reg_probe;
ac69b35b 240 struct cds_list_head *probe_list;
4e48b5d2 241 int i;
c8fcf224 242
ac69b35b 243 probe_list = lttng_get_probe_list_head();
c8fcf224 244 CDS_INIT_LIST_HEAD(&list->head);
4e48b5d2
MD
245 cds_list_for_each_entry(reg_probe, probe_list, head) {
246 const struct lttng_ust_probe_desc *probe_desc = reg_probe->desc;
247
c8fcf224 248 for (i = 0; i < probe_desc->nr_events; i++) {
5b4c6da4
MD
249 const struct lttng_ust_event_desc *event_desc =
250 probe_desc->event_desc[i];
c8fcf224
MD
251 struct tp_list_entry *list_entry;
252
5b4c6da4
MD
253 /* Skip event if name is too long. */
254 if (!lttng_ust_validate_event_name(event_desc))
255 continue;
c8fcf224
MD
256 list_entry = zmalloc(sizeof(*list_entry));
257 if (!list_entry)
258 goto err_nomem;
259 cds_list_add(&list_entry->head, &list->head);
5b4c6da4
MD
260 lttng_ust_format_event_name(event_desc, list_entry->tp.name);
261 if (!event_desc->loglevel) {
612e9ce4 262 list_entry->tp.loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT;
c8fcf224 263 } else {
5b4c6da4 264 list_entry->tp.loglevel = *(*event_desc->loglevel);
c8fcf224
MD
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
275err_nomem:
7dd08bec 276 lttng_probes_prune_event_list(list);
c8fcf224
MD
277 return -ENOMEM;
278}
279
280/*
281 * Return current iteration position, advance internal iterator to next.
282 * Return NULL if end of list.
283 */
fd17d7ce 284struct lttng_ust_abi_tracepoint_iter *
c8fcf224
MD
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}
1f18504e 299
7dd08bec 300void lttng_probes_prune_field_list(struct lttng_ust_field_list *list)
06d4f27e
MD
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 */
7dd08bec 313int lttng_probes_get_field_list(struct lttng_ust_field_list *list)
06d4f27e 314{
4e48b5d2 315 struct lttng_ust_registered_probe *reg_probe;
ac69b35b 316 struct cds_list_head *probe_list;
4e48b5d2 317 int i;
06d4f27e 318
ac69b35b 319 probe_list = lttng_get_probe_list_head();
06d4f27e 320 CDS_INIT_LIST_HEAD(&list->head);
4e48b5d2
MD
321 cds_list_for_each_entry(reg_probe, probe_list, head) {
322 const struct lttng_ust_probe_desc *probe_desc = reg_probe->desc;
323
06d4f27e 324 for (i = 0; i < probe_desc->nr_events; i++) {
dc11f93f 325 const struct lttng_ust_event_desc *event_desc =
06d4f27e
MD
326 probe_desc->event_desc[i];
327 int j;
328
26329f26
MD
329 if (event_desc->nr_fields == 0) {
330 /* Events without fields. */
331 struct tp_field_list_entry *list_entry;
332
5b4c6da4
MD
333 /* Skip event if name is too long. */
334 if (!lttng_ust_validate_event_name(event_desc))
335 continue;
26329f26
MD
336 list_entry = zmalloc(sizeof(*list_entry));
337 if (!list_entry)
338 goto err_nomem;
339 cds_list_add(&list_entry->head, &list->head);
5b4c6da4 340 lttng_ust_format_event_name(event_desc, list_entry->field.event_name);
26329f26 341 list_entry->field.field_name[0] = '\0';
fd17d7ce 342 list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
26329f26 343 if (!event_desc->loglevel) {
612e9ce4 344 list_entry->field.loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT;
26329f26
MD
345 } else {
346 list_entry->field.loglevel = *(*event_desc->loglevel);
347 }
348 list_entry->field.nowrite = 1;
349 }
350
06d4f27e 351 for (j = 0; j < event_desc->nr_fields; j++) {
25cff019
MD
352 const struct lttng_ust_event_field *event_field =
353 event_desc->fields[j];
06d4f27e
MD
354 struct tp_field_list_entry *list_entry;
355
5b4c6da4
MD
356 /* Skip event if name is too long. */
357 if (!lttng_ust_validate_event_name(event_desc))
358 continue;
06d4f27e
MD
359 list_entry = zmalloc(sizeof(*list_entry));
360 if (!list_entry)
361 goto err_nomem;
362 cds_list_add(&list_entry->head, &list->head);
5b4c6da4 363 lttng_ust_format_event_name(event_desc, list_entry->field.event_name);
06d4f27e
MD
364 strncpy(list_entry->field.field_name,
365 event_field->name,
fd17d7ce
MD
366 LTTNG_UST_ABI_SYM_NAME_LEN);
367 list_entry->field.field_name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
a084756d
MD
368 switch (event_field->type->type) {
369 case lttng_ust_type_integer:
fd17d7ce 370 list_entry->field.type = LTTNG_UST_ABI_FIELD_INTEGER;
40003310 371 break;
a084756d 372 case lttng_ust_type_string:
fd17d7ce 373 list_entry->field.type = LTTNG_UST_ABI_FIELD_STRING;
40003310 374 break;
a084756d
MD
375 case lttng_ust_type_array:
376 if (lttng_ust_get_type_array(event_field->type)->encoding == lttng_ust_string_encoding_none)
fd17d7ce 377 list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
40003310 378 else
fd17d7ce 379 list_entry->field.type = LTTNG_UST_ABI_FIELD_STRING;
40003310 380 break;
a084756d
MD
381 case lttng_ust_type_sequence:
382 if (lttng_ust_get_type_sequence(event_field->type)->encoding == lttng_ust_string_encoding_none)
fd17d7ce 383 list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
40003310 384 else
fd17d7ce 385 list_entry->field.type = LTTNG_UST_ABI_FIELD_STRING;
40003310 386 break;
a084756d 387 case lttng_ust_type_float:
fd17d7ce 388 list_entry->field.type = LTTNG_UST_ABI_FIELD_FLOAT;
40003310 389 break;
a084756d 390 case lttng_ust_type_enum:
fd17d7ce 391 list_entry->field.type = LTTNG_UST_ABI_FIELD_ENUM;
40003310
MD
392 break;
393 default:
fd17d7ce 394 list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
40003310 395 }
06d4f27e 396 if (!event_desc->loglevel) {
612e9ce4 397 list_entry->field.loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT;
06d4f27e
MD
398 } else {
399 list_entry->field.loglevel = *(*event_desc->loglevel);
400 }
180901e6 401 list_entry->field.nowrite = event_field->nowrite;
06d4f27e
MD
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
413err_nomem:
7dd08bec 414 lttng_probes_prune_field_list(list);
06d4f27e
MD
415 return -ENOMEM;
416}
417
418/*
419 * Return current iteration position, advance internal iterator to next.
420 * Return NULL if end of list.
421 */
fd17d7ce 422struct lttng_ust_abi_field_iter *
06d4f27e
MD
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.061883 seconds and 4 git commands to generate.