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