SoW-2020-0003: Trace Hit Counters
[lttng-tools.git] / src / bin / lttng-sessiond / trace-ust.c
1 /*
2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9 #define _LGPL_SOURCE
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <inttypes.h>
15
16 #include <common/common.h>
17 #include <common/defaults.h>
18 #include <common/trace-chunk.h>
19 #include <common/utils.h>
20
21 #include <lttng/map-key-internal.h>
22 #include <lttng/map/map-internal.h>
23
24 #include "buffer-registry.h"
25 #include "map.h"
26 #include "trace-ust.h"
27 #include "utils.h"
28 #include "ust-app.h"
29 #include "agent.h"
30
31 /*
32 * Match function for the events hash table lookup.
33 *
34 * Matches by name only. Used by the disable command.
35 */
36 int trace_ust_ht_match_event_by_name(struct cds_lfht_node *node,
37 const void *_key)
38 {
39 struct ltt_ust_event *event;
40 const char *name;
41
42 assert(node);
43 assert(_key);
44
45 event = caa_container_of(node, struct ltt_ust_event, node.node);
46 name = _key;
47
48 /* Event name */
49 if (strncmp(event->attr.name, name, sizeof(event->attr.name)) != 0) {
50 goto no_match;
51 }
52
53 /* Match */
54 return 1;
55
56 no_match:
57 return 0;
58 }
59
60 /*
61 * Match function for the hash table lookup.
62 *
63 * It matches an ust event based on three attributes which are the event name,
64 * the filter bytecode and the loglevel.
65 */
66 int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key)
67 {
68 struct ltt_ust_event *event;
69 const struct ltt_ust_ht_key *key;
70 int ev_loglevel_value;
71 int ll_match;
72
73 assert(node);
74 assert(_key);
75
76 event = caa_container_of(node, struct ltt_ust_event, node.node);
77 key = _key;
78 ev_loglevel_value = event->attr.loglevel;
79
80 /* Match the 6 elements of the key: tracer_token, map_key, name, filter, loglevel, exclusions. */
81 if (event->attr.token != key->tracer_token) {
82 goto no_match;
83 }
84
85 if (!lttng_map_key_is_equal(event->key, key->key)) {
86 goto no_match;
87 }
88
89 /* Event name */
90 if (strncmp(event->attr.name, key->name, sizeof(event->attr.name)) != 0) {
91 goto no_match;
92 }
93
94 /* Event loglevel value and type. */
95 ll_match = loglevels_match(event->attr.loglevel_type,
96 ev_loglevel_value, key->loglevel_type,
97 key->loglevel_value, LTTNG_UST_LOGLEVEL_ALL);
98
99 if (!ll_match) {
100 goto no_match;
101 }
102
103 /* Only one of the filters is NULL, fail. */
104 if ((key->filter && !event->filter) || (!key->filter && event->filter)) {
105 goto no_match;
106 }
107
108 if (key->filter && event->filter) {
109 /* Both filters exists, check length followed by the bytecode. */
110 if (event->filter->len != key->filter->len ||
111 memcmp(event->filter->data, key->filter->data,
112 event->filter->len) != 0) {
113 goto no_match;
114 }
115 }
116
117 /* If only one of the exclusions is NULL, fail. */
118 if ((key->exclusion && !event->exclusion) || (!key->exclusion && event->exclusion)) {
119 goto no_match;
120 }
121
122 if (key->exclusion && event->exclusion) {
123 size_t i;
124
125 /* Check exclusion counts first. */
126 if (event->exclusion->count != key->exclusion->count) {
127 goto no_match;
128 }
129
130 /* Compare names individually. */
131 for (i = 0; i < event->exclusion->count; ++i) {
132 size_t j;
133 bool found = false;
134 const char *name_ev =
135 LTTNG_EVENT_EXCLUSION_NAME_AT(
136 event->exclusion, i);
137
138 /*
139 * Compare this exclusion name to all the key's
140 * exclusion names.
141 */
142 for (j = 0; j < key->exclusion->count; ++j) {
143 const char *name_key =
144 LTTNG_EVENT_EXCLUSION_NAME_AT(
145 key->exclusion, j);
146
147 if (!strncmp(name_ev, name_key,
148 LTTNG_SYMBOL_NAME_LEN)) {
149 /* Names match! */
150 found = true;
151 break;
152 }
153 }
154
155 /*
156 * If the current exclusion name was not found amongst
157 * the key's exclusion names, then there's no match.
158 */
159 if (!found) {
160 goto no_match;
161 }
162 }
163 }
164 /* Match. */
165 return 1;
166
167 no_match:
168 return 0;
169 }
170
171 /*
172 * Find the channel in the hashtable and return channel pointer. RCU read side
173 * lock MUST be acquired before calling this.
174 */
175 struct ltt_ust_channel *trace_ust_find_channel_by_name(struct lttng_ht *ht,
176 const char *name)
177 {
178 struct lttng_ht_node_str *node;
179 struct lttng_ht_iter iter;
180
181 /*
182 * If we receive an empty string for channel name, it means the
183 * default channel name is requested.
184 */
185 if (name[0] == '\0')
186 name = DEFAULT_CHANNEL_NAME;
187
188 lttng_ht_lookup(ht, (void *)name, &iter);
189 node = lttng_ht_iter_get_node_str(&iter);
190 if (node == NULL) {
191 goto error;
192 }
193
194 DBG2("Trace UST channel %s found by name", name);
195
196 return caa_container_of(node, struct ltt_ust_channel, node);
197
198 error:
199 DBG2("Trace UST channel %s not found by name", name);
200 return NULL;
201 }
202
203 /*
204 * Find the map in the hashtable and return map pointer. RCU read side
205 * lock MUST be acquired before calling this.
206 */
207 struct ltt_ust_map *trace_ust_find_map_by_name(struct lttng_ht *ht,
208 const char *name)
209 {
210 struct lttng_ht_node_str *node;
211 struct lttng_ht_iter iter;
212
213 if (name[0] == '\0') {
214 goto error;
215 }
216
217 lttng_ht_lookup(ht, (void *)name, &iter);
218 node = lttng_ht_iter_get_node_str(&iter);
219 if (node == NULL) {
220 goto error;
221 }
222
223 DBG2("Trace UST map %s found by name", name);
224
225 return caa_container_of(node, struct ltt_ust_map, node);
226
227 error:
228 DBG2("Trace UST map %s not found by name", name);
229 return NULL;
230 }
231
232 /*
233 * Find the event in the hashtable and return event pointer. RCU read side lock
234 * MUST be acquired before calling this.
235 */
236 struct ltt_ust_event *trace_ust_find_event(struct lttng_ht *ht,
237 uint64_t tracer_token, char *name, struct lttng_bytecode *filter,
238 enum lttng_ust_loglevel_type loglevel_type, int loglevel_value,
239 struct lttng_event_exclusion *exclusion,
240 struct lttng_map_key *map_key)
241 {
242 struct lttng_ht_node_str *node;
243 struct lttng_ht_iter iter;
244 struct ltt_ust_ht_key key;
245
246 assert(name);
247 assert(ht);
248
249 key.tracer_token = tracer_token;
250 key.name = name;
251 key.filter = filter;
252 key.loglevel_type = loglevel_type;
253 key.loglevel_value = loglevel_value;
254 key.exclusion = exclusion;
255 key.key = map_key;
256
257 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
258 trace_ust_ht_match_event, &key, &iter.iter);
259 node = lttng_ht_iter_get_node_str(&iter);
260 if (node == NULL) {
261 goto error;
262 }
263
264 DBG2("Trace UST event %s found", key.name);
265
266 return caa_container_of(node, struct ltt_ust_event, node);
267
268 error:
269 DBG2("Trace UST event %s NOT found", key.name);
270 return NULL;
271 }
272
273 /*
274 * Lookup an agent in the session agents hash table by domain type and return
275 * the object if found else NULL.
276 *
277 * RCU read side lock must be acquired before calling and only released
278 * once the agent is no longer in scope or being used.
279 */
280 struct agent *trace_ust_find_agent(struct ltt_ust_session *session,
281 enum lttng_domain_type domain_type)
282 {
283 struct agent *agt = NULL;
284 struct lttng_ht_node_u64 *node;
285 struct lttng_ht_iter iter;
286 uint64_t key;
287
288 assert(session);
289
290 DBG3("Trace ust agent lookup for domain %d", domain_type);
291
292 key = domain_type;
293
294 lttng_ht_lookup(session->agents, &key, &iter);
295 node = lttng_ht_iter_get_node_u64(&iter);
296 if (!node) {
297 goto end;
298 }
299 agt = caa_container_of(node, struct agent, node);
300
301 end:
302 return agt;
303 }
304
305 /*
306 * Allocate and initialize a ust session data structure.
307 *
308 * Return pointer to structure or NULL.
309 */
310 struct ltt_ust_session *trace_ust_create_session(uint64_t session_id)
311 {
312 struct ltt_ust_session *lus;
313
314 /* Allocate a new ltt ust session */
315 lus = zmalloc(sizeof(struct ltt_ust_session));
316 if (lus == NULL) {
317 PERROR("create ust session zmalloc");
318 goto error_alloc;
319 }
320
321 /* Init data structure */
322 lus->id = session_id;
323 lus->active = 0;
324
325 /* Set default metadata channel attribute. */
326 lus->metadata_attr.overwrite = DEFAULT_CHANNEL_OVERWRITE;
327 lus->metadata_attr.subbuf_size = default_get_metadata_subbuf_size();
328 lus->metadata_attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM;
329 lus->metadata_attr.switch_timer_interval = DEFAULT_METADATA_SWITCH_TIMER;
330 lus->metadata_attr.read_timer_interval = DEFAULT_METADATA_READ_TIMER;
331 lus->metadata_attr.output = LTTNG_UST_MMAP;
332
333 /*
334 * Default buffer type. This can be changed through an enable channel
335 * requesting a different type. Note that this can only be changed once
336 * during the session lifetime which is at the first enable channel and
337 * only before start. The flag buffer_type_changed indicates the status.
338 */
339 lus->buffer_type = LTTNG_BUFFER_PER_UID;
340 /* Once set to 1, the buffer_type is immutable for the session. */
341 lus->buffer_type_changed = 0;
342 /* Init it in case it get used after allocation. */
343 CDS_INIT_LIST_HEAD(&lus->buffer_reg_uid_list);
344
345 /* Alloc UST global domain channels' HT */
346 lus->domain_global.channels = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
347 /* Alloc UST global domain maps' HT */
348 lus->domain_global.maps = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
349 /* Alloc agent hash table. */
350 lus->agents = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
351
352 lus->tracker_vpid = process_attr_tracker_create();
353 if (!lus->tracker_vpid) {
354 goto error;
355 }
356 lus->tracker_vuid = process_attr_tracker_create();
357 if (!lus->tracker_vuid) {
358 goto error;
359 }
360 lus->tracker_vgid = process_attr_tracker_create();
361 if (!lus->tracker_vgid) {
362 goto error;
363 }
364 lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
365 if (lus->consumer == NULL) {
366 goto error;
367 }
368
369 DBG2("UST trace session create successful");
370
371 return lus;
372
373 error:
374 process_attr_tracker_destroy(lus->tracker_vpid);
375 process_attr_tracker_destroy(lus->tracker_vuid);
376 process_attr_tracker_destroy(lus->tracker_vgid);
377 ht_cleanup_push(lus->domain_global.channels);
378 ht_cleanup_push(lus->domain_global.maps);
379 ht_cleanup_push(lus->agents);
380 free(lus);
381 error_alloc:
382 return NULL;
383 }
384
385 /*
386 * Allocate and initialize a ust channel data structure.
387 *
388 * Return pointer to structure or NULL.
389 */
390 struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan,
391 enum lttng_domain_type domain)
392 {
393 struct ltt_ust_channel *luc;
394
395 assert(chan);
396
397 luc = zmalloc(sizeof(struct ltt_ust_channel));
398 if (luc == NULL) {
399 PERROR("ltt_ust_channel zmalloc");
400 goto error;
401 }
402
403 luc->domain = domain;
404
405 /* Copy UST channel attributes */
406 luc->attr.overwrite = chan->attr.overwrite;
407 luc->attr.subbuf_size = chan->attr.subbuf_size;
408 luc->attr.num_subbuf = chan->attr.num_subbuf;
409 luc->attr.switch_timer_interval = chan->attr.switch_timer_interval;
410 luc->attr.read_timer_interval = chan->attr.read_timer_interval;
411 luc->attr.output = (enum lttng_ust_output) chan->attr.output;
412 luc->monitor_timer_interval = ((struct lttng_channel_extended *)
413 chan->attr.extended.ptr)->monitor_timer_interval;
414 luc->attr.u.s.blocking_timeout = ((struct lttng_channel_extended *)
415 chan->attr.extended.ptr)->blocking_timeout;
416
417 /* Translate to UST output enum */
418 switch (luc->attr.output) {
419 default:
420 luc->attr.output = LTTNG_UST_MMAP;
421 break;
422 }
423
424 /*
425 * If we receive an empty string for channel name, it means the
426 * default channel name is requested.
427 */
428 if (chan->name[0] == '\0') {
429 strncpy(luc->name, DEFAULT_CHANNEL_NAME, sizeof(luc->name));
430 } else {
431 /* Copy channel name */
432 strncpy(luc->name, chan->name, sizeof(luc->name));
433 }
434 luc->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
435
436 /* Init node */
437 lttng_ht_node_init_str(&luc->node, luc->name);
438 CDS_INIT_LIST_HEAD(&luc->ctx_list);
439
440 /* Alloc hash tables */
441 luc->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
442 luc->ctx = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
443
444 /* On-disk circular buffer parameters */
445 luc->tracefile_size = chan->attr.tracefile_size;
446 luc->tracefile_count = chan->attr.tracefile_count;
447
448 DBG2("Trace UST channel %s created", luc->name);
449
450 error:
451 return luc;
452 }
453
454 /*
455 * Allocate and initialize a ust map data structure.
456 *
457 * Return pointer to structure or NULL.
458 */
459 struct ltt_ust_map *trace_ust_create_map(const struct lttng_map *map)
460 {
461 struct ltt_ust_map *umap = NULL;
462 enum lttng_map_status map_status;
463 const char *map_name = NULL;
464 unsigned int dimension_count;
465 uint64_t dimension_len;
466
467 umap = zmalloc(sizeof(*umap));
468 if (!umap) {
469 PERROR("ltt_ust_map zmalloc");
470 goto end;
471 }
472
473 map_status = lttng_map_get_name(map, &map_name);
474 if (map_status != LTTNG_MAP_STATUS_OK) {
475 ERR("Can't get map name");
476 umap = NULL;
477 goto end;
478 }
479
480 dimension_count = lttng_map_get_dimension_count(map);
481 assert(dimension_count == 1);
482
483 map_status = lttng_map_get_dimension_length(map, 0, &dimension_len);
484 if (map_status != LTTNG_MAP_STATUS_OK) {
485 ERR("Can't get map first dimension length");
486 umap = NULL;
487 goto end;
488 }
489 assert(dimension_len > 0);
490
491 strncpy(umap->name, map_name, sizeof(umap->name));
492
493 umap->enabled = 1;
494 umap->bucket_count = dimension_len;
495 umap->coalesce_hits = lttng_map_get_coalesce_hits(map);
496 umap->bitness = lttng_map_get_bitness(map);
497 umap->nr_cpu = ustctl_get_nr_cpu_per_counter();
498
499 umap->dead_app_kv_values.dead_app_kv_values_32bits = lttng_ht_new(0,
500 LTTNG_HT_TYPE_STRING);
501 umap->dead_app_kv_values.dead_app_kv_values_64bits = lttng_ht_new(0,
502 LTTNG_HT_TYPE_STRING);
503 pthread_mutex_init(&umap->dead_app_kv_values.lock, NULL);
504
505 umap->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
506
507 /* Init node */
508 lttng_ht_node_init_str(&umap->node, umap->name);
509
510 DBG2("Trace UST map %s created", umap->name);
511 end:
512 return umap;
513 }
514
515 /*
516 * Validates an exclusion list.
517 *
518 * Returns 0 if valid, negative value if invalid.
519 */
520 static int validate_exclusion(struct lttng_event_exclusion *exclusion)
521 {
522 size_t i;
523 int ret = 0;
524
525 assert(exclusion);
526
527 for (i = 0; i < exclusion->count; ++i) {
528 size_t j;
529 const char *name_a =
530 LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion, i);
531
532 for (j = 0; j < i; ++j) {
533 const char *name_b =
534 LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion, j);
535
536 if (!strncmp(name_a, name_b, LTTNG_SYMBOL_NAME_LEN)) {
537 /* Match! */
538 ret = -1;
539 goto end;
540 }
541 }
542 }
543
544 end:
545 return ret;
546 }
547
548 /*
549 * Allocate and initialize a ust event. Set name and event type.
550 * We own filter_expression, filter, and exclusion.
551 *
552 * Return an lttng_error_code
553 */
554 enum lttng_error_code trace_ust_create_event(uint64_t tracer_token,
555 const char *ev_name,
556 struct lttng_map_key *key,
557 enum lttng_event_type ev_type,
558 enum lttng_loglevel_type ev_loglevel_type,
559 enum lttng_loglevel ev_loglevel,
560 char *filter_expression,
561 struct lttng_bytecode *filter,
562 struct lttng_event_exclusion *exclusion,
563 bool internal_event,
564 struct ltt_ust_event **ust_event)
565 {
566 struct ltt_ust_event *local_ust_event;
567 enum lttng_error_code ret = LTTNG_OK;
568
569 if (exclusion && validate_exclusion(exclusion)) {
570 ret = LTTNG_ERR_INVALID;
571 goto error;
572 }
573
574 local_ust_event = zmalloc(sizeof(struct ltt_ust_event));
575 if (local_ust_event == NULL) {
576 PERROR("ust event zmalloc");
577 ret = LTTNG_ERR_NOMEM;
578 goto error;
579 }
580
581 local_ust_event->internal = internal_event;
582 local_ust_event->attr.token = tracer_token;
583
584 switch (ev_type) {
585 case LTTNG_EVENT_PROBE:
586 local_ust_event->attr.instrumentation = LTTNG_UST_PROBE;
587 break;
588 case LTTNG_EVENT_FUNCTION:
589 local_ust_event->attr.instrumentation = LTTNG_UST_FUNCTION;
590 break;
591 case LTTNG_EVENT_FUNCTION_ENTRY:
592 local_ust_event->attr.instrumentation = LTTNG_UST_FUNCTION;
593 break;
594 case LTTNG_EVENT_TRACEPOINT:
595 local_ust_event->attr.instrumentation = LTTNG_UST_TRACEPOINT;
596 break;
597 default:
598 ERR("Unknown ust instrumentation type (%d)", ev_type);
599 ret = LTTNG_ERR_INVALID;
600 goto error_free_event;
601 }
602
603 /* Copy event name */
604 strncpy(local_ust_event->attr.name, ev_name, LTTNG_UST_SYM_NAME_LEN);
605 local_ust_event->attr.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
606
607 switch (ev_loglevel_type) {
608 case LTTNG_EVENT_LOGLEVEL_ALL:
609 local_ust_event->attr.loglevel_type = LTTNG_UST_LOGLEVEL_ALL;
610 local_ust_event->attr.loglevel = -1; /* Force to -1 */
611 break;
612 case LTTNG_EVENT_LOGLEVEL_RANGE:
613 local_ust_event->attr.loglevel_type = LTTNG_UST_LOGLEVEL_RANGE;
614 local_ust_event->attr.loglevel = ev_loglevel;
615 break;
616 case LTTNG_EVENT_LOGLEVEL_SINGLE:
617 local_ust_event->attr.loglevel_type = LTTNG_UST_LOGLEVEL_SINGLE;
618 local_ust_event->attr.loglevel = ev_loglevel;
619 break;
620 default:
621 ERR("Unknown ust loglevel type (%d)", ev_loglevel_type);
622 ret = LTTNG_ERR_INVALID;
623 goto error_free_event;
624 }
625
626 /* Same layout. */
627 local_ust_event->key = key;
628 local_ust_event->filter_expression = filter_expression;
629 local_ust_event->filter = filter;
630 local_ust_event->exclusion = exclusion;
631
632 /* Take a reference on the lttng_map_key to bounds its lifetime to the
633 * ust_event.
634 */
635 if (key) {
636 lttng_map_key_get(key);
637 }
638
639 /* Init node */
640 lttng_ht_node_init_str(&local_ust_event->node, local_ust_event->attr.name);
641
642 DBG2("Trace UST event %s, tracer token %"PRIu64", loglevel (%d,%d) created",
643 local_ust_event->attr.name, local_ust_event->attr.token,
644 local_ust_event->attr.loglevel_type,
645 local_ust_event->attr.loglevel);
646
647 *ust_event = local_ust_event;
648
649 return ret;
650
651 error_free_event:
652 free(local_ust_event);
653 error:
654 free(filter_expression);
655 free(filter);
656 free(exclusion);
657 return ret;
658 }
659
660 static
661 int trace_ust_context_type_event_to_ust(
662 enum lttng_event_context_type type)
663 {
664 int utype;
665
666 switch (type) {
667 case LTTNG_EVENT_CONTEXT_VTID:
668 utype = LTTNG_UST_CONTEXT_VTID;
669 break;
670 case LTTNG_EVENT_CONTEXT_VPID:
671 utype = LTTNG_UST_CONTEXT_VPID;
672 break;
673 case LTTNG_EVENT_CONTEXT_PTHREAD_ID:
674 utype = LTTNG_UST_CONTEXT_PTHREAD_ID;
675 break;
676 case LTTNG_EVENT_CONTEXT_PROCNAME:
677 utype = LTTNG_UST_CONTEXT_PROCNAME;
678 break;
679 case LTTNG_EVENT_CONTEXT_IP:
680 utype = LTTNG_UST_CONTEXT_IP;
681 break;
682 case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
683 if (!ustctl_has_perf_counters()) {
684 utype = -1;
685 WARN("Perf counters not implemented in UST");
686 } else {
687 utype = LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER;
688 }
689 break;
690 case LTTNG_EVENT_CONTEXT_APP_CONTEXT:
691 utype = LTTNG_UST_CONTEXT_APP_CONTEXT;
692 break;
693 case LTTNG_EVENT_CONTEXT_CGROUP_NS:
694 utype = LTTNG_UST_CONTEXT_CGROUP_NS;
695 break;
696 case LTTNG_EVENT_CONTEXT_IPC_NS:
697 utype = LTTNG_UST_CONTEXT_IPC_NS;
698 break;
699 case LTTNG_EVENT_CONTEXT_MNT_NS:
700 utype = LTTNG_UST_CONTEXT_MNT_NS;
701 break;
702 case LTTNG_EVENT_CONTEXT_NET_NS:
703 utype = LTTNG_UST_CONTEXT_NET_NS;
704 break;
705 case LTTNG_EVENT_CONTEXT_PID_NS:
706 utype = LTTNG_UST_CONTEXT_PID_NS;
707 break;
708 case LTTNG_EVENT_CONTEXT_TIME_NS:
709 utype = LTTNG_UST_CONTEXT_TIME_NS;
710 break;
711 case LTTNG_EVENT_CONTEXT_USER_NS:
712 utype = LTTNG_UST_CONTEXT_USER_NS;
713 break;
714 case LTTNG_EVENT_CONTEXT_UTS_NS:
715 utype = LTTNG_UST_CONTEXT_UTS_NS;
716 break;
717 case LTTNG_EVENT_CONTEXT_VUID:
718 utype = LTTNG_UST_CONTEXT_VUID;
719 break;
720 case LTTNG_EVENT_CONTEXT_VEUID:
721 utype = LTTNG_UST_CONTEXT_VEUID;
722 break;
723 case LTTNG_EVENT_CONTEXT_VSUID:
724 utype = LTTNG_UST_CONTEXT_VSUID;
725 break;
726 case LTTNG_EVENT_CONTEXT_VGID:
727 utype = LTTNG_UST_CONTEXT_VGID;
728 break;
729 case LTTNG_EVENT_CONTEXT_VEGID:
730 utype = LTTNG_UST_CONTEXT_VEGID;
731 break;
732 case LTTNG_EVENT_CONTEXT_VSGID:
733 utype = LTTNG_UST_CONTEXT_VSGID;
734 break;
735 default:
736 utype = -1;
737 break;
738 }
739 return utype;
740 }
741
742 /*
743 * Return 1 if contexts match, 0 otherwise.
744 */
745 int trace_ust_match_context(const struct ltt_ust_context *uctx,
746 const struct lttng_event_context *ctx)
747 {
748 int utype;
749
750 utype = trace_ust_context_type_event_to_ust(ctx->ctx);
751 if (utype < 0) {
752 return 0;
753 }
754 if (uctx->ctx.ctx != utype) {
755 return 0;
756 }
757 switch (utype) {
758 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
759 if (uctx->ctx.u.perf_counter.type
760 != ctx->u.perf_counter.type) {
761 return 0;
762 }
763 if (uctx->ctx.u.perf_counter.config
764 != ctx->u.perf_counter.config) {
765 return 0;
766 }
767 if (strncmp(uctx->ctx.u.perf_counter.name,
768 ctx->u.perf_counter.name,
769 LTTNG_UST_SYM_NAME_LEN)) {
770 return 0;
771 }
772 break;
773 case LTTNG_UST_CONTEXT_APP_CONTEXT:
774 assert(uctx->ctx.u.app_ctx.provider_name);
775 assert(uctx->ctx.u.app_ctx.ctx_name);
776 if (strcmp(uctx->ctx.u.app_ctx.provider_name,
777 ctx->u.app_ctx.provider_name) ||
778 strcmp(uctx->ctx.u.app_ctx.ctx_name,
779 ctx->u.app_ctx.ctx_name)) {
780 return 0;
781 }
782 default:
783 break;
784
785 }
786 return 1;
787 }
788
789 /*
790 * Allocate and initialize an UST context.
791 *
792 * Return pointer to structure or NULL.
793 */
794 struct ltt_ust_context *trace_ust_create_context(
795 const struct lttng_event_context *ctx)
796 {
797 struct ltt_ust_context *uctx = NULL;
798 int utype;
799
800 assert(ctx);
801
802 utype = trace_ust_context_type_event_to_ust(ctx->ctx);
803 if (utype < 0) {
804 ERR("Invalid UST context");
805 goto end;
806 }
807
808 uctx = zmalloc(sizeof(struct ltt_ust_context));
809 if (!uctx) {
810 PERROR("zmalloc ltt_ust_context");
811 goto end;
812 }
813
814 uctx->ctx.ctx = (enum lttng_ust_context_type) utype;
815 switch (utype) {
816 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
817 uctx->ctx.u.perf_counter.type = ctx->u.perf_counter.type;
818 uctx->ctx.u.perf_counter.config = ctx->u.perf_counter.config;
819 strncpy(uctx->ctx.u.perf_counter.name, ctx->u.perf_counter.name,
820 LTTNG_UST_SYM_NAME_LEN);
821 uctx->ctx.u.perf_counter.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
822 break;
823 case LTTNG_UST_CONTEXT_APP_CONTEXT:
824 {
825 char *provider_name = NULL, *ctx_name = NULL;
826
827 provider_name = strdup(ctx->u.app_ctx.provider_name);
828 if (!provider_name) {
829 goto error;
830 }
831 uctx->ctx.u.app_ctx.provider_name = provider_name;
832
833 ctx_name = strdup(ctx->u.app_ctx.ctx_name);
834 if (!ctx_name) {
835 goto error;
836 }
837 uctx->ctx.u.app_ctx.ctx_name = ctx_name;
838 break;
839 }
840 default:
841 break;
842 }
843 lttng_ht_node_init_ulong(&uctx->node, (unsigned long) uctx->ctx.ctx);
844 end:
845 return uctx;
846 error:
847 trace_ust_destroy_context(uctx);
848 return NULL;
849 }
850
851 static void destroy_id_tracker_node_rcu(struct rcu_head *head)
852 {
853 struct ust_id_tracker_node *tracker_node = caa_container_of(
854 head, struct ust_id_tracker_node, node.head);
855 free(tracker_node);
856 }
857
858 static void destroy_id_tracker_node(struct ust_id_tracker_node *tracker_node)
859 {
860 call_rcu(&tracker_node->node.head, destroy_id_tracker_node_rcu);
861 }
862
863 static int init_id_tracker(struct ust_id_tracker *id_tracker)
864 {
865 int ret = LTTNG_OK;
866
867 id_tracker->ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
868 if (!id_tracker->ht) {
869 ret = LTTNG_ERR_NOMEM;
870 goto end;
871 }
872
873 end:
874 return ret;
875 }
876
877 /*
878 * Teardown id tracker content, but don't free id_tracker object.
879 */
880 static void fini_id_tracker(struct ust_id_tracker *id_tracker)
881 {
882 struct ust_id_tracker_node *tracker_node;
883 struct lttng_ht_iter iter;
884
885 if (!id_tracker->ht) {
886 return;
887 }
888 rcu_read_lock();
889 cds_lfht_for_each_entry (id_tracker->ht->ht, &iter.iter, tracker_node,
890 node.node) {
891 int ret = lttng_ht_del(id_tracker->ht, &iter);
892
893 assert(!ret);
894 destroy_id_tracker_node(tracker_node);
895 }
896 rcu_read_unlock();
897 ht_cleanup_push(id_tracker->ht);
898 id_tracker->ht = NULL;
899 }
900
901 static struct ust_id_tracker_node *id_tracker_lookup(
902 struct ust_id_tracker *id_tracker,
903 int id,
904 struct lttng_ht_iter *iter)
905 {
906 unsigned long _id = (unsigned long) id;
907 struct lttng_ht_node_ulong *node;
908
909 lttng_ht_lookup(id_tracker->ht, (void *) _id, iter);
910 node = lttng_ht_iter_get_node_ulong(iter);
911 if (node) {
912 return caa_container_of(node, struct ust_id_tracker_node, node);
913 } else {
914 return NULL;
915 }
916 }
917
918 static int id_tracker_add_id(struct ust_id_tracker *id_tracker, int id)
919 {
920 int retval = LTTNG_OK;
921 struct ust_id_tracker_node *tracker_node;
922 struct lttng_ht_iter iter;
923
924 if (id < 0) {
925 retval = LTTNG_ERR_INVALID;
926 goto end;
927 }
928 tracker_node = id_tracker_lookup(id_tracker, id, &iter);
929 if (tracker_node) {
930 /* Already exists. */
931 retval = LTTNG_ERR_PROCESS_ATTR_EXISTS;
932 goto end;
933 }
934 tracker_node = zmalloc(sizeof(*tracker_node));
935 if (!tracker_node) {
936 retval = LTTNG_ERR_NOMEM;
937 goto end;
938 }
939 lttng_ht_node_init_ulong(&tracker_node->node, (unsigned long) id);
940 lttng_ht_add_unique_ulong(id_tracker->ht, &tracker_node->node);
941 end:
942 return retval;
943 }
944
945 static int id_tracker_del_id(struct ust_id_tracker *id_tracker, int id)
946 {
947 int retval = LTTNG_OK, ret;
948 struct ust_id_tracker_node *tracker_node;
949 struct lttng_ht_iter iter;
950
951 if (id < 0) {
952 retval = LTTNG_ERR_INVALID;
953 goto end;
954 }
955 tracker_node = id_tracker_lookup(id_tracker, id, &iter);
956 if (!tracker_node) {
957 /* Not found */
958 retval = LTTNG_ERR_PROCESS_ATTR_MISSING;
959 goto end;
960 }
961 ret = lttng_ht_del(id_tracker->ht, &iter);
962 assert(!ret);
963
964 destroy_id_tracker_node(tracker_node);
965 end:
966 return retval;
967 }
968
969 static struct ust_id_tracker *get_id_tracker(struct ltt_ust_session *session,
970 enum lttng_process_attr process_attr)
971 {
972 switch (process_attr) {
973 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
974 return &session->vpid_tracker;
975 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
976 return &session->vuid_tracker;
977 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
978 return &session->vgid_tracker;
979 default:
980 return NULL;
981 }
982 }
983
984 static struct process_attr_tracker *_trace_ust_get_process_attr_tracker(
985 struct ltt_ust_session *session,
986 enum lttng_process_attr process_attr)
987 {
988 switch (process_attr) {
989 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
990 return session->tracker_vpid;
991 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
992 return session->tracker_vuid;
993 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
994 return session->tracker_vgid;
995 default:
996 return NULL;
997 }
998 }
999
1000 const struct process_attr_tracker *trace_ust_get_process_attr_tracker(
1001 struct ltt_ust_session *session,
1002 enum lttng_process_attr process_attr)
1003 {
1004 return (const struct process_attr_tracker *)
1005 _trace_ust_get_process_attr_tracker(
1006 session, process_attr);
1007 }
1008
1009 /*
1010 * The session lock is held when calling this function.
1011 */
1012 int trace_ust_id_tracker_lookup(enum lttng_process_attr process_attr,
1013 struct ltt_ust_session *session,
1014 int id)
1015 {
1016 struct lttng_ht_iter iter;
1017 struct ust_id_tracker *id_tracker;
1018
1019 id_tracker = get_id_tracker(session, process_attr);
1020 if (!id_tracker) {
1021 abort();
1022 }
1023 if (!id_tracker->ht) {
1024 return 1;
1025 }
1026 if (id_tracker_lookup(id_tracker, id, &iter)) {
1027 return 1;
1028 }
1029 return 0;
1030 }
1031
1032 /*
1033 * Called with the session lock held.
1034 */
1035 enum lttng_error_code trace_ust_process_attr_tracker_set_tracking_policy(
1036 struct ltt_ust_session *session,
1037 enum lttng_process_attr process_attr,
1038 enum lttng_tracking_policy policy)
1039 {
1040 int ret;
1041 enum lttng_error_code ret_code = LTTNG_OK;
1042 struct ust_id_tracker *id_tracker =
1043 get_id_tracker(session, process_attr);
1044 struct process_attr_tracker *tracker =
1045 _trace_ust_get_process_attr_tracker(
1046 session, process_attr);
1047 bool should_update_apps = false;
1048 enum lttng_tracking_policy previous_policy;
1049
1050 if (!tracker) {
1051 ret_code = LTTNG_ERR_INVALID;
1052 goto end;
1053 }
1054
1055 previous_policy = process_attr_tracker_get_tracking_policy(tracker);
1056 ret = process_attr_tracker_set_tracking_policy(tracker, policy);
1057 if (ret) {
1058 ret_code = LTTNG_ERR_UNK;
1059 goto end;
1060 }
1061
1062 if (previous_policy == policy) {
1063 goto end;
1064 }
1065
1066 switch (policy) {
1067 case LTTNG_TRACKING_POLICY_INCLUDE_ALL:
1068 /* Track all values: destroy tracker if exists. */
1069 if (id_tracker->ht) {
1070 fini_id_tracker(id_tracker);
1071 /* Ensure all apps have session. */
1072 should_update_apps = true;
1073 }
1074 break;
1075 case LTTNG_TRACKING_POLICY_EXCLUDE_ALL:
1076 case LTTNG_TRACKING_POLICY_INCLUDE_SET:
1077 /* fall-through. */
1078 fini_id_tracker(id_tracker);
1079 ret_code = init_id_tracker(id_tracker);
1080 if (ret_code != LTTNG_OK) {
1081 ERR("Error initializing ID tracker");
1082 goto end;
1083 }
1084 /* Remove all apps from session. */
1085 should_update_apps = true;
1086 break;
1087 default:
1088 abort();
1089 }
1090 if (should_update_apps && session->active) {
1091 ust_app_global_update_all(session);
1092 }
1093 end:
1094 return ret_code;
1095 }
1096
1097 /* Called with the session lock held. */
1098 enum lttng_error_code trace_ust_process_attr_tracker_inclusion_set_add_value(
1099 struct ltt_ust_session *session,
1100 enum lttng_process_attr process_attr,
1101 const struct process_attr_value *value)
1102 {
1103 enum lttng_error_code ret_code = LTTNG_OK;
1104 bool should_update_apps = false;
1105 struct ust_id_tracker *id_tracker =
1106 get_id_tracker(session, process_attr);
1107 struct process_attr_tracker *tracker;
1108 int integral_value;
1109 enum process_attr_tracker_status status;
1110 struct ust_app *app;
1111
1112 /*
1113 * Convert process attribute tracker value to the integral
1114 * representation required by the kern-ctl API.
1115 */
1116 switch (process_attr) {
1117 case LTTNG_PROCESS_ATTR_PROCESS_ID:
1118 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
1119 integral_value = (int) value->value.pid;
1120 break;
1121 case LTTNG_PROCESS_ATTR_USER_ID:
1122 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
1123 if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME) {
1124 uid_t uid;
1125
1126 ret_code = utils_user_id_from_name(
1127 value->value.user_name, &uid);
1128 if (ret_code != LTTNG_OK) {
1129 goto end;
1130 }
1131 integral_value = (int) uid;
1132 } else {
1133 integral_value = (int) value->value.uid;
1134 }
1135 break;
1136 case LTTNG_PROCESS_ATTR_GROUP_ID:
1137 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
1138 if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME) {
1139 gid_t gid;
1140
1141 ret_code = utils_group_id_from_name(
1142 value->value.group_name, &gid);
1143 if (ret_code != LTTNG_OK) {
1144 goto end;
1145 }
1146 integral_value = (int) gid;
1147 } else {
1148 integral_value = (int) value->value.gid;
1149 }
1150 break;
1151 default:
1152 ret_code = LTTNG_ERR_INVALID;
1153 goto end;
1154 }
1155
1156 tracker = _trace_ust_get_process_attr_tracker(session, process_attr);
1157 if (!tracker) {
1158 ret_code = LTTNG_ERR_INVALID;
1159 goto end;
1160 }
1161
1162 status = process_attr_tracker_inclusion_set_add_value(tracker, value);
1163 if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
1164 switch (status) {
1165 case PROCESS_ATTR_TRACKER_STATUS_EXISTS:
1166 ret_code = LTTNG_ERR_PROCESS_ATTR_EXISTS;
1167 break;
1168 case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY:
1169 ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY;
1170 break;
1171 case PROCESS_ATTR_TRACKER_STATUS_ERROR:
1172 default:
1173 ret_code = LTTNG_ERR_UNK;
1174 break;
1175 }
1176 goto end;
1177 }
1178
1179 DBG("User space track %s %d for session id %" PRIu64,
1180 lttng_process_attr_to_string(process_attr),
1181 integral_value, session->id);
1182
1183 ret_code = id_tracker_add_id(id_tracker, integral_value);
1184 if (ret_code != LTTNG_OK) {
1185 goto end;
1186 }
1187 /* Add session to application */
1188 switch (process_attr) {
1189 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
1190 app = ust_app_find_by_pid(integral_value);
1191 if (app) {
1192 should_update_apps = true;
1193 }
1194 break;
1195 default:
1196 should_update_apps = true;
1197 break;
1198 }
1199 if (should_update_apps && session->active) {
1200 ust_app_global_update_all(session);
1201 }
1202 end:
1203 return ret_code;
1204 }
1205
1206 /* Called with the session lock held. */
1207 enum lttng_error_code trace_ust_process_attr_tracker_inclusion_set_remove_value(
1208 struct ltt_ust_session *session,
1209 enum lttng_process_attr process_attr,
1210 const struct process_attr_value *value)
1211 {
1212 enum lttng_error_code ret_code = LTTNG_OK;
1213 bool should_update_apps = false;
1214 struct ust_id_tracker *id_tracker =
1215 get_id_tracker(session, process_attr);
1216 struct process_attr_tracker *tracker;
1217 int integral_value;
1218 enum process_attr_tracker_status status;
1219 struct ust_app *app;
1220
1221 /*
1222 * Convert process attribute tracker value to the integral
1223 * representation required by the kern-ctl API.
1224 */
1225 switch (process_attr) {
1226 case LTTNG_PROCESS_ATTR_PROCESS_ID:
1227 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
1228 integral_value = (int) value->value.pid;
1229 break;
1230 case LTTNG_PROCESS_ATTR_USER_ID:
1231 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
1232 if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME) {
1233 uid_t uid;
1234
1235 ret_code = utils_user_id_from_name(
1236 value->value.user_name, &uid);
1237 if (ret_code != LTTNG_OK) {
1238 goto end;
1239 }
1240 integral_value = (int) uid;
1241 } else {
1242 integral_value = (int) value->value.uid;
1243 }
1244 break;
1245 case LTTNG_PROCESS_ATTR_GROUP_ID:
1246 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
1247 if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME) {
1248 gid_t gid;
1249
1250 ret_code = utils_group_id_from_name(
1251 value->value.group_name, &gid);
1252 if (ret_code != LTTNG_OK) {
1253 goto end;
1254 }
1255 integral_value = (int) gid;
1256 } else {
1257 integral_value = (int) value->value.gid;
1258 }
1259 break;
1260 default:
1261 ret_code = LTTNG_ERR_INVALID;
1262 goto end;
1263 }
1264
1265 tracker = _trace_ust_get_process_attr_tracker(session, process_attr);
1266 if (!tracker) {
1267 ret_code = LTTNG_ERR_INVALID;
1268 goto end;
1269 }
1270
1271 status = process_attr_tracker_inclusion_set_remove_value(
1272 tracker, value);
1273 if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
1274 switch (status) {
1275 case PROCESS_ATTR_TRACKER_STATUS_MISSING:
1276 ret_code = LTTNG_ERR_PROCESS_ATTR_MISSING;
1277 break;
1278 case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY:
1279 ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY;
1280 break;
1281 case PROCESS_ATTR_TRACKER_STATUS_ERROR:
1282 default:
1283 ret_code = LTTNG_ERR_UNK;
1284 break;
1285 }
1286 goto end;
1287 }
1288
1289 DBG("User space untrack %s %d for session id %" PRIu64,
1290 lttng_process_attr_to_string(process_attr),
1291 integral_value, session->id);
1292
1293 ret_code = id_tracker_del_id(id_tracker, integral_value);
1294 if (ret_code != LTTNG_OK) {
1295 goto end;
1296 }
1297 /* Add session to application */
1298 switch (process_attr) {
1299 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
1300 app = ust_app_find_by_pid(integral_value);
1301 if (app) {
1302 should_update_apps = true;
1303 }
1304 break;
1305 default:
1306 should_update_apps = true;
1307 break;
1308 }
1309 if (should_update_apps && session->active) {
1310 ust_app_global_update_all(session);
1311 }
1312 end:
1313 return ret_code;
1314 }
1315
1316 /*
1317 * RCU safe free context structure.
1318 */
1319 static void destroy_context_rcu(struct rcu_head *head)
1320 {
1321 struct lttng_ht_node_ulong *node =
1322 caa_container_of(head, struct lttng_ht_node_ulong, head);
1323 struct ltt_ust_context *ctx =
1324 caa_container_of(node, struct ltt_ust_context, node);
1325
1326 trace_ust_destroy_context(ctx);
1327 }
1328
1329 /*
1330 * Cleanup UST context hash table.
1331 */
1332 static void destroy_contexts(struct lttng_ht *ht)
1333 {
1334 int ret;
1335 struct lttng_ht_node_ulong *node;
1336 struct lttng_ht_iter iter;
1337 struct ltt_ust_context *ctx;
1338
1339 assert(ht);
1340
1341 rcu_read_lock();
1342 cds_lfht_for_each_entry(ht->ht, &iter.iter, node, node) {
1343 /* Remove from ordered list. */
1344 ctx = caa_container_of(node, struct ltt_ust_context, node);
1345 cds_list_del(&ctx->list);
1346 /* Remove from channel's hash table. */
1347 ret = lttng_ht_del(ht, &iter);
1348 if (!ret) {
1349 call_rcu(&node->head, destroy_context_rcu);
1350 }
1351 }
1352 rcu_read_unlock();
1353
1354 ht_cleanup_push(ht);
1355 }
1356
1357 /*
1358 * Cleanup ust event structure.
1359 */
1360 void trace_ust_destroy_event(struct ltt_ust_event *event)
1361 {
1362 assert(event);
1363
1364 DBG2("Trace destroy UST event %s", event->attr.name);
1365 lttng_map_key_put(event->key);
1366 free(event->filter_expression);
1367 free(event->filter);
1368 free(event->exclusion);
1369 free(event);
1370 }
1371
1372 /*
1373 * Cleanup ust context structure.
1374 */
1375 void trace_ust_destroy_context(struct ltt_ust_context *ctx)
1376 {
1377 assert(ctx);
1378
1379 if (ctx->ctx.ctx == LTTNG_UST_CONTEXT_APP_CONTEXT) {
1380 free(ctx->ctx.u.app_ctx.provider_name);
1381 free(ctx->ctx.u.app_ctx.ctx_name);
1382 }
1383 free(ctx);
1384 }
1385
1386 /*
1387 * URCU intermediate call to complete destroy event.
1388 */
1389 static void destroy_event_rcu(struct rcu_head *head)
1390 {
1391 struct lttng_ht_node_str *node =
1392 caa_container_of(head, struct lttng_ht_node_str, head);
1393 struct ltt_ust_event *event =
1394 caa_container_of(node, struct ltt_ust_event, node);
1395
1396 trace_ust_destroy_event(event);
1397 }
1398
1399 /*
1400 * Cleanup UST events hashtable.
1401 */
1402 static void destroy_events(struct lttng_ht *events)
1403 {
1404 int ret;
1405 struct lttng_ht_node_str *node;
1406 struct lttng_ht_iter iter;
1407
1408 assert(events);
1409
1410 rcu_read_lock();
1411 cds_lfht_for_each_entry(events->ht, &iter.iter, node, node) {
1412 ret = lttng_ht_del(events, &iter);
1413 assert(!ret);
1414 call_rcu(&node->head, destroy_event_rcu);
1415 }
1416 rcu_read_unlock();
1417
1418 ht_cleanup_push(events);
1419 }
1420
1421 /*
1422 * Cleanup ust channel structure.
1423 *
1424 * Should _NOT_ be called with RCU read lock held.
1425 */
1426 static void _trace_ust_destroy_channel(struct ltt_ust_channel *channel)
1427 {
1428 assert(channel);
1429
1430 DBG2("Trace destroy UST channel %s", channel->name);
1431
1432 free(channel);
1433 }
1434
1435 /*
1436 * Cleanup ust map structure.
1437 *
1438 * Should _NOT_ be called with RCU read lock held.
1439 */
1440 static void _trace_ust_destroy_map(struct ltt_ust_map *map)
1441 {
1442 struct map_kv_ht_entry *kv_entry;
1443 struct lttng_ht_iter ht_iter;
1444 struct lttng_ht *dead_app_kv_ht;
1445
1446 assert(map);
1447
1448 DBG2("Trace destroy UST map %s", map->name);
1449
1450 /*
1451 * Remove all the keys before destroying the hashtables.
1452 */
1453 dead_app_kv_ht = map->dead_app_kv_values.dead_app_kv_values_32bits;
1454 cds_lfht_for_each_entry(dead_app_kv_ht->ht, &ht_iter.iter, kv_entry, node.node) {
1455 struct lttng_ht_iter entry_iter;
1456
1457 entry_iter.iter.node = &kv_entry->node.node;
1458 lttng_ht_del(dead_app_kv_ht, &entry_iter);
1459
1460 free(kv_entry->key);
1461 free(kv_entry);
1462 }
1463 lttng_ht_destroy(map->dead_app_kv_values.dead_app_kv_values_32bits);
1464
1465 dead_app_kv_ht = map->dead_app_kv_values.dead_app_kv_values_64bits;
1466 cds_lfht_for_each_entry(dead_app_kv_ht->ht, &ht_iter.iter, kv_entry, node.node) {
1467 struct lttng_ht_iter entry_iter;
1468
1469 entry_iter.iter.node = &kv_entry->node.node;
1470 lttng_ht_del(dead_app_kv_ht, &entry_iter);
1471
1472 free(kv_entry->key);
1473 free(kv_entry);
1474 }
1475
1476 lttng_ht_destroy(map->dead_app_kv_values.dead_app_kv_values_64bits);
1477
1478 lttng_map_put(map->map);
1479 free(map);
1480 }
1481
1482 /*
1483 * URCU intermediate call to complete destroy channel.
1484 */
1485 static void destroy_channel_rcu(struct rcu_head *head)
1486 {
1487 struct lttng_ht_node_str *node =
1488 caa_container_of(head, struct lttng_ht_node_str, head);
1489 struct ltt_ust_channel *channel =
1490 caa_container_of(node, struct ltt_ust_channel, node);
1491
1492 _trace_ust_destroy_channel(channel);
1493 }
1494
1495 /*
1496 * URCU intermediate call to complete destroy map.
1497 */
1498 static void destroy_map_rcu(struct rcu_head *head)
1499 {
1500 struct lttng_ht_node_str *node =
1501 caa_container_of(head, struct lttng_ht_node_str, head);
1502 struct ltt_ust_map *map =
1503 caa_container_of(node, struct ltt_ust_map, node);
1504
1505 _trace_ust_destroy_map(map);
1506 }
1507
1508 void trace_ust_destroy_channel(struct ltt_ust_channel *channel)
1509 {
1510 /* Destroying all events of the channel */
1511 destroy_events(channel->events);
1512 /* Destroying all context of the channel */
1513 destroy_contexts(channel->ctx);
1514
1515 call_rcu(&channel->node.head, destroy_channel_rcu);
1516 }
1517
1518 void trace_ust_destroy_map(struct ltt_ust_map *map)
1519 {
1520 /* Destroying all events of the map */
1521 destroy_events(map->events);
1522
1523 call_rcu(&map->node.head, destroy_map_rcu);
1524 }
1525
1526 /*
1527 * Remove an UST channel from a channel HT.
1528 */
1529 void trace_ust_delete_channel(struct lttng_ht *ht,
1530 struct ltt_ust_channel *channel)
1531 {
1532 int ret;
1533 struct lttng_ht_iter iter;
1534
1535 assert(ht);
1536 assert(channel);
1537
1538 iter.iter.node = &channel->node.node;
1539 ret = lttng_ht_del(ht, &iter);
1540 assert(!ret);
1541 }
1542
1543 /*
1544 * Remove an UST map from a map HT.
1545 */
1546 void trace_ust_delete_map(struct lttng_ht *ht,
1547 struct ltt_ust_map *map)
1548 {
1549 int ret;
1550 struct lttng_ht_iter iter;
1551
1552 assert(ht);
1553 assert(map);
1554
1555 iter.iter.node = &map->node.node;
1556 ret = lttng_ht_del(ht, &iter);
1557 assert(!ret);
1558 }
1559
1560 /*
1561 * Iterate over a hash table containing channels and cleanup safely.
1562 */
1563 static void destroy_channels(struct lttng_ht *channels)
1564 {
1565 struct lttng_ht_node_str *node;
1566 struct lttng_ht_iter iter;
1567
1568 assert(channels);
1569
1570 rcu_read_lock();
1571 cds_lfht_for_each_entry(channels->ht, &iter.iter, node, node) {
1572 struct ltt_ust_channel *chan =
1573 caa_container_of(node, struct ltt_ust_channel, node);
1574
1575 trace_ust_delete_channel(channels, chan);
1576 trace_ust_destroy_channel(chan);
1577 }
1578 rcu_read_unlock();
1579
1580 ht_cleanup_push(channels);
1581 }
1582
1583 /*
1584 * Iterate over a hash table containing maps and cleanup safely.
1585 */
1586 static void destroy_maps(struct lttng_ht *maps)
1587 {
1588 struct lttng_ht_node_str *node;
1589 struct lttng_ht_iter iter;
1590
1591 assert(maps);
1592
1593 rcu_read_lock();
1594 cds_lfht_for_each_entry(maps->ht, &iter.iter, node, node) {
1595 struct ltt_ust_map *map =
1596 caa_container_of(node, struct ltt_ust_map, node);
1597
1598 trace_ust_delete_map(maps, map);
1599 trace_ust_destroy_map(map);
1600 }
1601 rcu_read_unlock();
1602
1603 ht_cleanup_push(maps);
1604 }
1605 /*
1606 * Cleanup UST global domain.
1607 */
1608 static void destroy_domain_global(struct ltt_ust_domain_global *dom)
1609 {
1610 assert(dom);
1611
1612 destroy_channels(dom->channels);
1613 destroy_maps(dom->maps);
1614 }
1615
1616 /*
1617 * Cleanup ust session structure, keeping data required by
1618 * destroy notifier.
1619 *
1620 * Should *NOT* be called with RCU read-side lock held.
1621 */
1622 void trace_ust_destroy_session(struct ltt_ust_session *session)
1623 {
1624 struct agent *agt;
1625 struct buffer_reg_uid *reg, *sreg;
1626 struct lttng_ht_iter iter;
1627
1628 assert(session);
1629
1630 DBG2("Trace UST destroy session %" PRIu64, session->id);
1631
1632 /* Cleaning up UST domain */
1633 destroy_domain_global(&session->domain_global);
1634
1635 rcu_read_lock();
1636 cds_lfht_for_each_entry(session->agents->ht, &iter.iter, agt, node.node) {
1637 int ret = lttng_ht_del(session->agents, &iter);
1638
1639 assert(!ret);
1640 agent_destroy(agt);
1641 }
1642 rcu_read_unlock();
1643
1644 ht_cleanup_push(session->agents);
1645
1646 /* Cleanup UID buffer registry object(s). */
1647 cds_list_for_each_entry_safe(reg, sreg, &session->buffer_reg_uid_list,
1648 lnode) {
1649 cds_list_del(&reg->lnode);
1650 buffer_reg_uid_remove(reg);
1651 buffer_reg_uid_destroy(reg, session->consumer);
1652 }
1653
1654 process_attr_tracker_destroy(session->tracker_vpid);
1655 process_attr_tracker_destroy(session->tracker_vuid);
1656 process_attr_tracker_destroy(session->tracker_vgid);
1657
1658 fini_id_tracker(&session->vpid_tracker);
1659 fini_id_tracker(&session->vuid_tracker);
1660 fini_id_tracker(&session->vgid_tracker);
1661 lttng_trace_chunk_put(session->current_trace_chunk);
1662 }
1663
1664 /* Free elements needed by destroy notifiers. */
1665 void trace_ust_free_session(struct ltt_ust_session *session)
1666 {
1667 consumer_output_put(session->consumer);
1668 free(session);
1669 }
This page took 0.090718 seconds and 5 git commands to generate.