Tests: Add test to check shared-memory FD leaks after relayd dies
[lttng-tools.git] / src / bin / lttng-sessiond / trace-ust.cpp
CommitLineData
97ee3a89 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
ab5be9fa 3 * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
97ee3a89 4 *
ab5be9fa 5 * SPDX-License-Identifier: GPL-2.0-only
97ee3a89 6 *
97ee3a89
DG
7 */
8
6c1c0768 9#define _LGPL_SOURCE
28ab034a
JG
10#include "agent.hpp"
11#include "buffer-registry.hpp"
12#include "trace-ust.hpp"
13#include "ust-app.hpp"
14#include "utils.hpp"
97ee3a89 15
c9e313bc
SM
16#include <common/common.hpp>
17#include <common/defaults.hpp>
18#include <common/trace-chunk.hpp>
56047f5a 19#include <common/urcu.hpp>
c9e313bc 20#include <common/utils.hpp>
97ee3a89 21
28ab034a
JG
22#include <inttypes.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
97ee3a89 27
b0f2e8db
JG
28namespace lsu = lttng::sessiond::ust;
29
025faf73
DG
30/*
31 * Match function for the events hash table lookup.
32 *
33 * Matches by name only. Used by the disable command.
34 */
28ab034a 35int trace_ust_ht_match_event_by_name(struct cds_lfht_node *node, const void *_key)
18eace3b
DG
36{
37 struct ltt_ust_event *event;
38 const char *name;
39
a0377dfe
FD
40 LTTNG_ASSERT(node);
41 LTTNG_ASSERT(_key);
18eace3b
DG
42
43 event = caa_container_of(node, struct ltt_ust_event, node.node);
7966af57 44 name = (const char *) _key;
18eace3b
DG
45
46 /* Event name */
47 if (strncmp(event->attr.name, name, sizeof(event->attr.name)) != 0) {
48 goto no_match;
49 }
50
025faf73 51 /* Match */
18eace3b
DG
52 return 1;
53
54no_match:
55 return 0;
56}
57
025faf73
DG
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 */
18eace3b
DG
64int 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;
2106efa0 68 int ev_loglevel_value;
19a97244 69 int ll_match;
18eace3b 70
a0377dfe
FD
71 LTTNG_ASSERT(node);
72 LTTNG_ASSERT(_key);
18eace3b
DG
73
74 event = caa_container_of(node, struct ltt_ust_event, node.node);
7966af57 75 key = (ltt_ust_ht_key *) _key;
2106efa0 76 ev_loglevel_value = event->attr.loglevel;
18eace3b 77
f19e9f8b 78 /* Match the 4 elements of the key: name, filter, loglevel, exclusions. */
18eace3b
DG
79
80 /* Event name */
81 if (strncmp(event->attr.name, key->name, sizeof(event->attr.name)) != 0) {
18eace3b
DG
82 goto no_match;
83 }
84
b953b8cd 85 /* Event loglevel value and type. */
19a97244 86 ll_match = loglevels_match(event->attr.loglevel_type,
28ab034a
JG
87 ev_loglevel_value,
88 key->loglevel_type,
89 key->loglevel_value,
90 LTTNG_UST_ABI_LOGLEVEL_ALL);
19a97244
PP
91
92 if (!ll_match) {
b953b8cd 93 goto no_match;
18eace3b
DG
94 }
95
96 /* Only one of the filters is NULL, fail. */
97 if ((key->filter && !event->filter) || (!key->filter && event->filter)) {
18eace3b
DG
98 goto no_match;
99 }
100
025faf73
DG
101 if (key->filter && event->filter) {
102 /* Both filters exists, check length followed by the bytecode. */
103 if (event->filter->len != key->filter->len ||
28ab034a 104 memcmp(event->filter->data, key->filter->data, event->filter->len) != 0) {
025faf73
DG
105 goto no_match;
106 }
18eace3b
DG
107 }
108
f19e9f8b
JI
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) {
a5b7e00c
PP
115 size_t i;
116
117 /* Check exclusion counts first. */
118 if (event->exclusion->count != key->exclusion->count) {
f19e9f8b
JI
119 goto no_match;
120 }
a5b7e00c
PP
121
122 /* Compare names individually. */
123 for (i = 0; i < event->exclusion->count; ++i) {
124 size_t j;
28ab034a
JG
125 bool found = false;
126 const char *name_ev = LTTNG_EVENT_EXCLUSION_NAME_AT(event->exclusion, i);
a5b7e00c
PP
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 =
28ab034a 134 LTTNG_EVENT_EXCLUSION_NAME_AT(key->exclusion, j);
a5b7e00c 135
28ab034a 136 if (!strncmp(name_ev, name_key, LTTNG_SYMBOL_NAME_LEN)) {
a5b7e00c
PP
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 }
f19e9f8b 151 }
025faf73
DG
152 /* Match. */
153 return 1;
18eace3b
DG
154
155no_match:
156 return 0;
18eace3b
DG
157}
158
0177d773 159/*
2223c96f
DG
160 * Find the channel in the hashtable and return channel pointer. RCU read side
161 * lock MUST be acquired before calling this.
0177d773 162 */
28ab034a 163struct ltt_ust_channel *trace_ust_find_channel_by_name(struct lttng_ht *ht, const char *name)
0177d773 164{
bec39940
DG
165 struct lttng_ht_node_str *node;
166 struct lttng_ht_iter iter;
0177d773 167
48b7cdc2 168 ASSERT_RCU_READ_LOCKED();
85076754
MD
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
28ab034a 176 lttng_ht_lookup(ht, (void *) name, &iter);
bec39940 177 node = lttng_ht_iter_get_node_str(&iter);
cd9adb8b 178 if (node == nullptr) {
44d3bd01
DG
179 goto error;
180 }
181
f6a9efaa 182 DBG2("Trace UST channel %s found by name", name);
0177d773 183
0114db0e 184 return lttng::utils::container_of(node, &ltt_ust_channel::node);
97ee3a89
DG
185
186error:
f6a9efaa 187 DBG2("Trace UST channel %s not found by name", name);
cd9adb8b 188 return nullptr;
97ee3a89
DG
189}
190
191/*
2223c96f
DG
192 * Find the event in the hashtable and return event pointer. RCU read side lock
193 * MUST be acquired before calling this.
97ee3a89 194 */
18eace3b 195struct ltt_ust_event *trace_ust_find_event(struct lttng_ht *ht,
28ab034a
JG
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)
97ee3a89 201{
bec39940
DG
202 struct lttng_ht_node_str *node;
203 struct lttng_ht_iter iter;
18eace3b 204 struct ltt_ust_ht_key key;
97ee3a89 205
a0377dfe
FD
206 LTTNG_ASSERT(name);
207 LTTNG_ASSERT(ht);
48b7cdc2 208 ASSERT_RCU_READ_LOCKED();
18eace3b
DG
209
210 key.name = name;
211 key.filter = filter;
b953b8cd
PP
212 key.loglevel_type = loglevel_type;
213 key.loglevel_value = loglevel_value;
10646003 214 key.exclusion = exclusion;
18eace3b 215
28ab034a
JG
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);
bec39940 221 node = lttng_ht_iter_get_node_str(&iter);
cd9adb8b 222 if (node == nullptr) {
97ee3a89
DG
223 goto error;
224 }
225
18eace3b 226 DBG2("Trace UST event %s found", key.name);
f6a9efaa 227
0114db0e 228 return lttng::utils::container_of(node, &ltt_ust_event::node);
97ee3a89
DG
229
230error:
18eace3b 231 DBG2("Trace UST event %s NOT found", key.name);
cd9adb8b 232 return nullptr;
97ee3a89
DG
233}
234
fefd409b
DG
235/*
236 * Lookup an agent in the session agents hash table by domain type and return
237 * the object if found else NULL.
4da703ad
JG
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.
fefd409b
DG
241 */
242struct agent *trace_ust_find_agent(struct ltt_ust_session *session,
28ab034a 243 enum lttng_domain_type domain_type)
fefd409b 244{
cd9adb8b 245 struct agent *agt = nullptr;
fefd409b
DG
246 struct lttng_ht_node_u64 *node;
247 struct lttng_ht_iter iter;
248 uint64_t key;
249
a0377dfe 250 LTTNG_ASSERT(session);
fefd409b
DG
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 }
0114db0e 261 agt = lttng::utils::container_of(node, &agent::node);
fefd409b
DG
262
263end:
264 return agt;
265}
266
97ee3a89
DG
267/*
268 * Allocate and initialize a ust session data structure.
269 *
270 * Return pointer to structure or NULL.
271 */
d9bf3ca4 272struct ltt_ust_session *trace_ust_create_session(uint64_t session_id)
97ee3a89
DG
273{
274 struct ltt_ust_session *lus;
275
276 /* Allocate a new ltt ust session */
64803277 277 lus = zmalloc<ltt_ust_session>();
cd9adb8b 278 if (lus == nullptr) {
ba7f0ae5 279 PERROR("create ust session zmalloc");
55c9e7ca 280 goto error_alloc;
97ee3a89
DG
281 }
282
283 /* Init data structure */
a991f516 284 lus->id = session_id;
14fb1ebe 285 lus->active = 0;
97ee3a89 286
84ad93e8
DG
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;
fc4b93fa 293 lus->metadata_attr.output = LTTNG_UST_ABI_MMAP;
84ad93e8 294
7972aab2
DG
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 */
8692d4e5 301 lus->buffer_type = LTTNG_BUFFER_PER_UID;
7972aab2
DG
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);
f6a9efaa
DG
306
307 /* Alloc UST global domain channels' HT */
bec39940 308 lus->domain_global.channels = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
fefd409b
DG
309 /* Alloc agent hash table. */
310 lus->agents = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
44d3bd01 311
159b042f
JG
312 lus->tracker_vpid = process_attr_tracker_create();
313 if (!lus->tracker_vpid) {
55c9e7ca
JR
314 goto error;
315 }
159b042f
JG
316 lus->tracker_vuid = process_attr_tracker_create();
317 if (!lus->tracker_vuid) {
55c9e7ca
JR
318 goto error;
319 }
159b042f
JG
320 lus->tracker_vgid = process_attr_tracker_create();
321 if (!lus->tracker_vgid) {
55c9e7ca
JR
322 goto error;
323 }
00e2e675 324 lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
cd9adb8b 325 if (lus->consumer == nullptr) {
55c9e7ca 326 goto error;
00e2e675
DG
327 }
328
44d3bd01
DG
329 DBG2("UST trace session create successful");
330
97ee3a89
DG
331 return lus;
332
55c9e7ca 333error:
159b042f
JG
334 process_attr_tracker_destroy(lus->tracker_vpid);
335 process_attr_tracker_destroy(lus->tracker_vuid);
336 process_attr_tracker_destroy(lus->tracker_vgid);
3c339053
FD
337 lttng_ht_destroy(lus->domain_global.channels);
338 lttng_ht_destroy(lus->agents);
44844c29 339 free(lus);
55c9e7ca 340error_alloc:
cd9adb8b 341 return nullptr;
97ee3a89
DG
342}
343
344/*
345 * Allocate and initialize a ust channel data structure.
346 *
347 * Return pointer to structure or NULL.
348 */
51755dc8 349struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan,
28ab034a 350 enum lttng_domain_type domain)
97ee3a89 351{
97ee3a89
DG
352 struct ltt_ust_channel *luc;
353
a0377dfe 354 LTTNG_ASSERT(chan);
0525e9ae 355
64803277 356 luc = zmalloc<ltt_ust_channel>();
cd9adb8b 357 if (luc == nullptr) {
df0f840b 358 PERROR("ltt_ust_channel zmalloc");
97ee3a89
DG
359 goto error;
360 }
361
51755dc8
JG
362 luc->domain = domain;
363
44d3bd01 364 /* Copy UST channel attributes */
48842b30
DG
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;
fc4b93fa 370 luc->attr.output = (enum lttng_ust_abi_output) chan->attr.output;
28ab034a
JG
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;
44d3bd01
DG
375
376 /* Translate to UST output enum */
377 switch (luc->attr.output) {
378 default:
fc4b93fa 379 luc->attr.output = LTTNG_UST_ABI_MMAP;
44d3bd01 380 break;
97ee3a89 381 }
97ee3a89 382
85076754
MD
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 }
fc4b93fa 393 luc->name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
97ee3a89 394
f6a9efaa 395 /* Init node */
bec39940 396 lttng_ht_node_init_str(&luc->node, luc->name);
31746f93
DG
397 CDS_INIT_LIST_HEAD(&luc->ctx_list);
398
f6a9efaa 399 /* Alloc hash tables */
bec39940
DG
400 luc->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
401 luc->ctx = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
f6a9efaa 402
1624d5b7
JD
403 /* On-disk circular buffer parameters */
404 luc->tracefile_size = chan->attr.tracefile_size;
405 luc->tracefile_count = chan->attr.tracefile_count;
406
f6a9efaa
DG
407 DBG2("Trace UST channel %s created", luc->name);
408
97ee3a89 409error:
7972aab2 410 return luc;
97ee3a89
DG
411}
412
ad11a1d3
PP
413/*
414 * Validates an exclusion list.
415 *
416 * Returns 0 if valid, negative value if invalid.
417 */
418static int validate_exclusion(struct lttng_event_exclusion *exclusion)
419{
420 size_t i;
421 int ret = 0;
422
a0377dfe 423 LTTNG_ASSERT(exclusion);
ad11a1d3
PP
424
425 for (i = 0; i < exclusion->count; ++i) {
426 size_t j;
28ab034a 427 const char *name_a = LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion, i);
ad11a1d3
PP
428
429 for (j = 0; j < i; ++j) {
28ab034a 430 const char *name_b = LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion, j);
ad11a1d3
PP
431
432 if (!strncmp(name_a, name_b, LTTNG_SYMBOL_NAME_LEN)) {
433 /* Match! */
434 ret = -1;
435 goto end;
436 }
437 }
438 }
439
440end:
441 return ret;
442}
443
97ee3a89
DG
444/*
445 * Allocate and initialize a ust event. Set name and event type.
49d21f93 446 * We own filter_expression, filter, and exclusion.
97ee3a89 447 *
39687410 448 * Return an lttng_error_code
97ee3a89 449 */
39687410 450enum lttng_error_code trace_ust_create_event(struct lttng_event *ev,
28ab034a
JG
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)
97ee3a89 456{
39687410
FD
457 struct ltt_ust_event *local_ust_event;
458 enum lttng_error_code ret = LTTNG_OK;
97ee3a89 459
a0377dfe 460 LTTNG_ASSERT(ev);
0525e9ae 461
ad11a1d3 462 if (exclusion && validate_exclusion(exclusion)) {
39687410 463 ret = LTTNG_ERR_INVALID;
ad11a1d3
PP
464 goto error;
465 }
466
64803277 467 local_ust_event = zmalloc<ltt_ust_event>();
cd9adb8b 468 if (local_ust_event == nullptr) {
ba7f0ae5 469 PERROR("ust event zmalloc");
39687410 470 ret = LTTNG_ERR_NOMEM;
97ee3a89
DG
471 goto error;
472 }
473
39687410 474 local_ust_event->internal = internal_event;
88f06f15 475
97ee3a89
DG
476 switch (ev->type) {
477 case LTTNG_EVENT_PROBE:
fc4b93fa 478 local_ust_event->attr.instrumentation = LTTNG_UST_ABI_PROBE;
97ee3a89
DG
479 break;
480 case LTTNG_EVENT_FUNCTION:
fc4b93fa 481 local_ust_event->attr.instrumentation = LTTNG_UST_ABI_FUNCTION;
97ee3a89
DG
482 break;
483 case LTTNG_EVENT_FUNCTION_ENTRY:
fc4b93fa 484 local_ust_event->attr.instrumentation = LTTNG_UST_ABI_FUNCTION;
97ee3a89
DG
485 break;
486 case LTTNG_EVENT_TRACEPOINT:
fc4b93fa 487 local_ust_event->attr.instrumentation = LTTNG_UST_ABI_TRACEPOINT;
97ee3a89
DG
488 break;
489 default:
490 ERR("Unknown ust instrumentation type (%d)", ev->type);
39687410 491 ret = LTTNG_ERR_INVALID;
44844c29 492 goto error_free_event;
97ee3a89
DG
493 }
494
495 /* Copy event name */
fc4b93fa
MD
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';
97ee3a89 498
0cda4f28 499 switch (ev->loglevel_type) {
8005f29a 500 case LTTNG_EVENT_LOGLEVEL_ALL:
fc4b93fa 501 local_ust_event->attr.loglevel_type = LTTNG_UST_ABI_LOGLEVEL_ALL;
28ab034a 502 local_ust_event->attr.loglevel = -1; /* Force to -1 */
0cda4f28 503 break;
8005f29a 504 case LTTNG_EVENT_LOGLEVEL_RANGE:
fc4b93fa 505 local_ust_event->attr.loglevel_type = LTTNG_UST_ABI_LOGLEVEL_RANGE;
39687410 506 local_ust_event->attr.loglevel = ev->loglevel;
8005f29a
MD
507 break;
508 case LTTNG_EVENT_LOGLEVEL_SINGLE:
fc4b93fa 509 local_ust_event->attr.loglevel_type = LTTNG_UST_ABI_LOGLEVEL_SINGLE;
39687410 510 local_ust_event->attr.loglevel = ev->loglevel;
0cda4f28
MD
511 break;
512 default:
4431494b 513 ERR("Unknown ust loglevel type (%d)", ev->loglevel_type);
39687410 514 ret = LTTNG_ERR_INVALID;
0cda4f28
MD
515 goto error_free_event;
516 }
517
025faf73 518 /* Same layout. */
39687410
FD
519 local_ust_event->filter_expression = filter_expression;
520 local_ust_event->filter = filter;
521 local_ust_event->exclusion = exclusion;
0cda4f28 522
f6a9efaa 523 /* Init node */
39687410 524 lttng_ht_node_init_str(&local_ust_event->node, local_ust_event->attr.name);
97ee3a89 525
300b8fd5 526 DBG2("Trace UST event %s, loglevel (%d,%d) created",
28ab034a
JG
527 local_ust_event->attr.name,
528 local_ust_event->attr.loglevel_type,
529 local_ust_event->attr.loglevel);
39687410
FD
530
531 *ust_event = local_ust_event;
284d8f55 532
39687410 533 return ret;
97ee3a89 534
44844c29 535error_free_event:
39687410 536 free(local_ust_event);
97ee3a89 537error:
49d21f93
MD
538 free(filter_expression);
539 free(filter);
540 free(exclusion);
39687410 541 return ret;
97ee3a89
DG
542}
543
28ab034a 544static int trace_ust_context_type_event_to_ust(enum lttng_event_context_type type)
55cc08a6 545{
aa3514e9 546 int utype;
0525e9ae 547
aa3514e9 548 switch (type) {
9197c5c4 549 case LTTNG_EVENT_CONTEXT_VTID:
fc4b93fa 550 utype = LTTNG_UST_ABI_CONTEXT_VTID;
9197c5c4
MD
551 break;
552 case LTTNG_EVENT_CONTEXT_VPID:
fc4b93fa 553 utype = LTTNG_UST_ABI_CONTEXT_VPID;
9197c5c4
MD
554 break;
555 case LTTNG_EVENT_CONTEXT_PTHREAD_ID:
fc4b93fa 556 utype = LTTNG_UST_ABI_CONTEXT_PTHREAD_ID;
9197c5c4
MD
557 break;
558 case LTTNG_EVENT_CONTEXT_PROCNAME:
fc4b93fa 559 utype = LTTNG_UST_ABI_CONTEXT_PROCNAME;
9197c5c4 560 break;
7c612c2e 561 case LTTNG_EVENT_CONTEXT_IP:
fc4b93fa 562 utype = LTTNG_UST_ABI_CONTEXT_IP;
7c612c2e 563 break;
aa3514e9 564 case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
b623cb6a 565 if (!lttng_ust_ctl_has_perf_counters()) {
354e561b
MD
566 utype = -1;
567 WARN("Perf counters not implemented in UST");
568 } else {
fc4b93fa 569 utype = LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER;
354e561b 570 }
aa3514e9 571 break;
bdf64013 572 case LTTNG_EVENT_CONTEXT_APP_CONTEXT:
fc4b93fa 573 utype = LTTNG_UST_ABI_CONTEXT_APP_CONTEXT;
bdf64013 574 break;
f17b8732 575 case LTTNG_EVENT_CONTEXT_CGROUP_NS:
fc4b93fa 576 utype = LTTNG_UST_ABI_CONTEXT_CGROUP_NS;
f17b8732
MJ
577 break;
578 case LTTNG_EVENT_CONTEXT_IPC_NS:
fc4b93fa 579 utype = LTTNG_UST_ABI_CONTEXT_IPC_NS;
f17b8732
MJ
580 break;
581 case LTTNG_EVENT_CONTEXT_MNT_NS:
fc4b93fa 582 utype = LTTNG_UST_ABI_CONTEXT_MNT_NS;
f17b8732
MJ
583 break;
584 case LTTNG_EVENT_CONTEXT_NET_NS:
fc4b93fa 585 utype = LTTNG_UST_ABI_CONTEXT_NET_NS;
f17b8732
MJ
586 break;
587 case LTTNG_EVENT_CONTEXT_PID_NS:
fc4b93fa 588 utype = LTTNG_UST_ABI_CONTEXT_PID_NS;
f17b8732 589 break;
d37ac3cd 590 case LTTNG_EVENT_CONTEXT_TIME_NS:
fc4b93fa 591 utype = LTTNG_UST_ABI_CONTEXT_TIME_NS;
d37ac3cd 592 break;
f17b8732 593 case LTTNG_EVENT_CONTEXT_USER_NS:
fc4b93fa 594 utype = LTTNG_UST_ABI_CONTEXT_USER_NS;
f17b8732
MJ
595 break;
596 case LTTNG_EVENT_CONTEXT_UTS_NS:
fc4b93fa 597 utype = LTTNG_UST_ABI_CONTEXT_UTS_NS;
f17b8732 598 break;
4fc59cb8 599 case LTTNG_EVENT_CONTEXT_VUID:
fc4b93fa 600 utype = LTTNG_UST_ABI_CONTEXT_VUID;
4fc59cb8
MJ
601 break;
602 case LTTNG_EVENT_CONTEXT_VEUID:
fc4b93fa 603 utype = LTTNG_UST_ABI_CONTEXT_VEUID;
4fc59cb8
MJ
604 break;
605 case LTTNG_EVENT_CONTEXT_VSUID:
fc4b93fa 606 utype = LTTNG_UST_ABI_CONTEXT_VSUID;
4fc59cb8
MJ
607 break;
608 case LTTNG_EVENT_CONTEXT_VGID:
fc4b93fa 609 utype = LTTNG_UST_ABI_CONTEXT_VGID;
4fc59cb8
MJ
610 break;
611 case LTTNG_EVENT_CONTEXT_VEGID:
fc4b93fa 612 utype = LTTNG_UST_ABI_CONTEXT_VEGID;
4fc59cb8
MJ
613 break;
614 case LTTNG_EVENT_CONTEXT_VSGID:
fc4b93fa 615 utype = LTTNG_UST_ABI_CONTEXT_VSGID;
4fc59cb8 616 break;
9197c5c4 617 default:
aa3514e9
MD
618 utype = -1;
619 break;
620 }
621 return utype;
622}
623
624/*
625 * Return 1 if contexts match, 0 otherwise.
626 */
df4f5a87 627int trace_ust_match_context(const struct ltt_ust_context *uctx,
28ab034a 628 const struct lttng_event_context *ctx)
aa3514e9
MD
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) {
fc4b93fa 640 case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER:
28ab034a 641 if (uctx->ctx.u.perf_counter.type != ctx->u.perf_counter.type) {
aa3514e9
MD
642 return 0;
643 }
28ab034a 644 if (uctx->ctx.u.perf_counter.config != ctx->u.perf_counter.config) {
aa3514e9
MD
645 return 0;
646 }
647 if (strncmp(uctx->ctx.u.perf_counter.name,
28ab034a 648 ctx->u.perf_counter.name,
5c7248cd 649 LTTNG_UST_ABI_SYM_NAME_LEN) != 0) {
aa3514e9
MD
650 return 0;
651 }
652 break;
fc4b93fa 653 case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT:
a0377dfe
FD
654 LTTNG_ASSERT(uctx->ctx.u.app_ctx.provider_name);
655 LTTNG_ASSERT(uctx->ctx.u.app_ctx.ctx_name);
5c7248cd
JG
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) {
54fb33cf
JG
658 return 0;
659 }
aa3514e9
MD
660 default:
661 break;
aa3514e9
MD
662 }
663 return 1;
664}
665
666/*
667 * Allocate and initialize an UST context.
668 *
669 * Return pointer to structure or NULL.
670 */
28ab034a 671struct ltt_ust_context *trace_ust_create_context(const struct lttng_event_context *ctx)
aa3514e9 672{
cd9adb8b 673 struct ltt_ust_context *uctx = nullptr;
aa3514e9
MD
674 int utype;
675
a0377dfe 676 LTTNG_ASSERT(ctx);
aa3514e9
MD
677
678 utype = trace_ust_context_type_event_to_ust(ctx->ctx);
679 if (utype < 0) {
1cf992b8 680 ERR("Invalid UST context");
bdf64013 681 goto end;
9197c5c4 682 }
55cc08a6 683
64803277 684 uctx = zmalloc<ltt_ust_context>();
bdf64013 685 if (!uctx) {
55cc08a6 686 PERROR("zmalloc ltt_ust_context");
bdf64013 687 goto end;
55cc08a6
DG
688 }
689
fc4b93fa 690 uctx->ctx.ctx = (enum lttng_ust_abi_context_type) utype;
aa3514e9 691 switch (utype) {
fc4b93fa 692 case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER:
aa3514e9
MD
693 uctx->ctx.u.perf_counter.type = ctx->u.perf_counter.type;
694 uctx->ctx.u.perf_counter.config = ctx->u.perf_counter.config;
28ab034a
JG
695 strncpy(uctx->ctx.u.perf_counter.name,
696 ctx->u.perf_counter.name,
697 LTTNG_UST_ABI_SYM_NAME_LEN);
fc4b93fa 698 uctx->ctx.u.perf_counter.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
aa3514e9 699 break;
fc4b93fa 700 case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT:
bdf64013 701 {
cd9adb8b 702 char *provider_name = nullptr, *ctx_name = nullptr;
bdf64013
JG
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 }
aa3514e9
MD
717 default:
718 break;
719 }
bec39940 720 lttng_ht_node_init_ulong(&uctx->node, (unsigned long) uctx->ctx.ctx);
bdf64013 721end:
55cc08a6 722 return uctx;
55cc08a6 723error:
bdf64013 724 trace_ust_destroy_context(uctx);
cd9adb8b 725 return nullptr;
55cc08a6
DG
726}
727
55c9e7ca 728static void destroy_id_tracker_node_rcu(struct rcu_head *head)
a9ad0c8f 729{
28ab034a
JG
730 struct ust_id_tracker_node *tracker_node =
731 caa_container_of(head, struct ust_id_tracker_node, node.head);
a9ad0c8f
MD
732 free(tracker_node);
733}
734
55c9e7ca 735static void destroy_id_tracker_node(struct ust_id_tracker_node *tracker_node)
a9ad0c8f 736{
55c9e7ca 737 call_rcu(&tracker_node->node.head, destroy_id_tracker_node_rcu);
a9ad0c8f
MD
738}
739
55c9e7ca 740static int init_id_tracker(struct ust_id_tracker *id_tracker)
a9ad0c8f 741{
55c9e7ca 742 int ret = LTTNG_OK;
a9ad0c8f 743
55c9e7ca
JR
744 id_tracker->ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
745 if (!id_tracker->ht) {
746 ret = LTTNG_ERR_NOMEM;
a9ad0c8f
MD
747 goto end;
748 }
749
750end:
751 return ret;
752}
753
754/*
55c9e7ca 755 * Teardown id tracker content, but don't free id_tracker object.
a9ad0c8f 756 */
55c9e7ca 757static void fini_id_tracker(struct ust_id_tracker *id_tracker)
a9ad0c8f 758{
55c9e7ca 759 struct ust_id_tracker_node *tracker_node;
a9ad0c8f
MD
760 struct lttng_ht_iter iter;
761
55c9e7ca 762 if (!id_tracker->ht) {
a9ad0c8f
MD
763 return;
764 }
a9ad0c8f 765
56047f5a
JG
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 }
a9ad0c8f 775 }
56047f5a 776
3c339053 777 lttng_ht_destroy(id_tracker->ht);
cd9adb8b 778 id_tracker->ht = nullptr;
a9ad0c8f
MD
779}
780
28ab034a
JG
781static struct ust_id_tracker_node *
782id_tracker_lookup(struct ust_id_tracker *id_tracker, int id, struct lttng_ht_iter *iter)
a9ad0c8f 783{
55c9e7ca 784 unsigned long _id = (unsigned long) id;
a9ad0c8f
MD
785 struct lttng_ht_node_ulong *node;
786
55c9e7ca 787 lttng_ht_lookup(id_tracker->ht, (void *) _id, iter);
a9ad0c8f
MD
788 node = lttng_ht_iter_get_node_ulong(iter);
789 if (node) {
0114db0e 790 return lttng::utils::container_of(node, &ust_id_tracker_node::node);
a9ad0c8f 791 } else {
cd9adb8b 792 return nullptr;
a9ad0c8f
MD
793 }
794}
795
55c9e7ca 796static int id_tracker_add_id(struct ust_id_tracker *id_tracker, int id)
a9ad0c8f
MD
797{
798 int retval = LTTNG_OK;
55c9e7ca 799 struct ust_id_tracker_node *tracker_node;
a9ad0c8f
MD
800 struct lttng_ht_iter iter;
801
55c9e7ca 802 if (id < 0) {
a9ad0c8f
MD
803 retval = LTTNG_ERR_INVALID;
804 goto end;
805 }
55c9e7ca 806 tracker_node = id_tracker_lookup(id_tracker, id, &iter);
a9ad0c8f
MD
807 if (tracker_node) {
808 /* Already exists. */
159b042f 809 retval = LTTNG_ERR_PROCESS_ATTR_EXISTS;
a9ad0c8f
MD
810 goto end;
811 }
64803277 812 tracker_node = zmalloc<ust_id_tracker_node>();
a9ad0c8f
MD
813 if (!tracker_node) {
814 retval = LTTNG_ERR_NOMEM;
815 goto end;
816 }
55c9e7ca
JR
817 lttng_ht_node_init_ulong(&tracker_node->node, (unsigned long) id);
818 lttng_ht_add_unique_ulong(id_tracker->ht, &tracker_node->node);
a9ad0c8f
MD
819end:
820 return retval;
821}
822
55c9e7ca 823static int id_tracker_del_id(struct ust_id_tracker *id_tracker, int id)
a9ad0c8f
MD
824{
825 int retval = LTTNG_OK, ret;
55c9e7ca 826 struct ust_id_tracker_node *tracker_node;
a9ad0c8f
MD
827 struct lttng_ht_iter iter;
828
55c9e7ca 829 if (id < 0) {
a9ad0c8f
MD
830 retval = LTTNG_ERR_INVALID;
831 goto end;
832 }
55c9e7ca 833 tracker_node = id_tracker_lookup(id_tracker, id, &iter);
a9ad0c8f
MD
834 if (!tracker_node) {
835 /* Not found */
159b042f 836 retval = LTTNG_ERR_PROCESS_ATTR_MISSING;
a9ad0c8f
MD
837 goto end;
838 }
55c9e7ca 839 ret = lttng_ht_del(id_tracker->ht, &iter);
a0377dfe 840 LTTNG_ASSERT(!ret);
a9ad0c8f 841
55c9e7ca 842 destroy_id_tracker_node(tracker_node);
a9ad0c8f
MD
843end:
844 return retval;
845}
846
55c9e7ca 847static struct ust_id_tracker *get_id_tracker(struct ltt_ust_session *session,
28ab034a 848 enum lttng_process_attr process_attr)
55c9e7ca 849{
159b042f
JG
850 switch (process_attr) {
851 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
55c9e7ca 852 return &session->vpid_tracker;
159b042f 853 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
55c9e7ca 854 return &session->vuid_tracker;
159b042f 855 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
55c9e7ca
JR
856 return &session->vgid_tracker;
857 default:
cd9adb8b 858 return nullptr;
55c9e7ca
JR
859 }
860}
861
28ab034a
JG
862static struct process_attr_tracker *
863_trace_ust_get_process_attr_tracker(struct ltt_ust_session *session,
864 enum lttng_process_attr process_attr)
55c9e7ca 865{
159b042f
JG
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;
55c9e7ca 873 default:
cd9adb8b 874 return nullptr;
55c9e7ca
JR
875 }
876}
877
28ab034a
JG
878const struct process_attr_tracker *
879trace_ust_get_process_attr_tracker(struct ltt_ust_session *session,
880 enum lttng_process_attr process_attr)
159b042f 881{
28ab034a
JG
882 return (const struct process_attr_tracker *) _trace_ust_get_process_attr_tracker(
883 session, process_attr);
159b042f
JG
884}
885
a9ad0c8f
MD
886/*
887 * The session lock is held when calling this function.
888 */
159b042f 889int trace_ust_id_tracker_lookup(enum lttng_process_attr process_attr,
28ab034a
JG
890 struct ltt_ust_session *session,
891 int id)
a9ad0c8f
MD
892{
893 struct lttng_ht_iter iter;
55c9e7ca 894 struct ust_id_tracker *id_tracker;
a9ad0c8f 895
159b042f 896 id_tracker = get_id_tracker(session, process_attr);
55c9e7ca
JR
897 if (!id_tracker) {
898 abort();
899 }
900 if (!id_tracker->ht) {
a9ad0c8f
MD
901 return 1;
902 }
55c9e7ca 903 if (id_tracker_lookup(id_tracker, id, &iter)) {
a9ad0c8f
MD
904 return 1;
905 }
906 return 0;
907}
908
909/*
910 * Called with the session lock held.
911 */
28ab034a
JG
912enum lttng_error_code
913trace_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)
a9ad0c8f 916{
159b042f
JG
917 int ret;
918 enum lttng_error_code ret_code = LTTNG_OK;
28ab034a 919 struct ust_id_tracker *id_tracker = get_id_tracker(session, process_attr);
159b042f 920 struct process_attr_tracker *tracker =
28ab034a 921 _trace_ust_get_process_attr_tracker(session, process_attr);
88e3c2f5 922 bool should_update_apps = false;
159b042f 923 enum lttng_tracking_policy previous_policy;
55c9e7ca 924
159b042f
JG
925 if (!tracker) {
926 ret_code = LTTNG_ERR_INVALID;
927 goto end;
55c9e7ca 928 }
a9ad0c8f 929
159b042f
JG
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;
55c9e7ca
JR
934 goto end;
935 }
936
159b042f
JG
937 if (previous_policy == policy) {
938 goto end;
55c9e7ca 939 }
159b042f
JG
940
941 switch (policy) {
942 case LTTNG_TRACKING_POLICY_INCLUDE_ALL:
943 /* Track all values: destroy tracker if exists. */
55c9e7ca
JR
944 if (id_tracker->ht) {
945 fini_id_tracker(id_tracker);
a9ad0c8f 946 /* Ensure all apps have session. */
88e3c2f5 947 should_update_apps = true;
a9ad0c8f 948 }
159b042f
JG
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);
7966af57 954 ret_code = (lttng_error_code) init_id_tracker(id_tracker);
159b042f
JG
955 if (ret_code != LTTNG_OK) {
956 ERR("Error initializing ID tracker");
957 goto end;
a9ad0c8f 958 }
159b042f
JG
959 /* Remove all apps from session. */
960 should_update_apps = true;
961 break;
962 default:
963 abort();
a9ad0c8f 964 }
88e3c2f5
JG
965 if (should_update_apps && session->active) {
966 ust_app_global_update_all(session);
967 }
a9ad0c8f 968end:
159b042f 969 return ret_code;
a9ad0c8f
MD
970}
971
159b042f 972/* Called with the session lock held. */
28ab034a
JG
973enum lttng_error_code
974trace_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)
a9ad0c8f 977{
159b042f 978 enum lttng_error_code ret_code = LTTNG_OK;
a5a30920 979 bool should_update_apps = false;
28ab034a 980 struct ust_id_tracker *id_tracker = get_id_tracker(session, process_attr);
159b042f
JG
981 struct process_attr_tracker *tracker;
982 int integral_value;
983 enum process_attr_tracker_status status;
984 struct ust_app *app;
55c9e7ca 985
159b042f
JG
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
28ab034a 1000 ret_code = utils_user_id_from_name(value->value.user_name, &uid);
159b042f
JG
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
28ab034a 1014 ret_code = utils_group_id_from_name(value->value.group_name, &gid);
159b042f
JG
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;
55c9e7ca
JR
1025 goto end;
1026 }
a9ad0c8f 1027
159b042f
JG
1028 tracker = _trace_ust_get_process_attr_tracker(session, process_attr);
1029 if (!tracker) {
1030 ret_code = LTTNG_ERR_INVALID;
74675e31 1031 goto end;
55c9e7ca
JR
1032 }
1033
159b042f
JG
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;
a9ad0c8f 1047 }
159b042f
JG
1048 goto end;
1049 }
a9ad0c8f 1050
159b042f 1051 DBG("User space track %s %d for session id %" PRIu64,
28ab034a
JG
1052 lttng_process_attr_to_string(process_attr),
1053 integral_value,
1054 session->id);
a9ad0c8f 1055
7966af57 1056 ret_code = (lttng_error_code) id_tracker_add_id(id_tracker, integral_value);
159b042f
JG
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) {
a5a30920 1065 should_update_apps = true;
a9ad0c8f 1066 }
159b042f
JG
1067 break;
1068 default:
1069 should_update_apps = true;
1070 break;
a9ad0c8f 1071 }
a5a30920
JR
1072 if (should_update_apps && session->active) {
1073 ust_app_global_update_all(session);
1074 }
a9ad0c8f 1075end:
159b042f 1076 return ret_code;
a9ad0c8f
MD
1077}
1078
159b042f 1079/* Called with the session lock held. */
28ab034a
JG
1080enum lttng_error_code
1081trace_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)
a5dfbb9d 1084{
159b042f
JG
1085 enum lttng_error_code ret_code = LTTNG_OK;
1086 bool should_update_apps = false;
28ab034a 1087 struct ust_id_tracker *id_tracker = get_id_tracker(session, process_attr);
159b042f
JG
1088 struct process_attr_tracker *tracker;
1089 int integral_value;
1090 enum process_attr_tracker_status status;
1091 struct ust_app *app;
a5dfbb9d 1092
159b042f
JG
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
28ab034a 1107 ret_code = utils_user_id_from_name(value->value.user_name, &uid);
159b042f
JG
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
28ab034a 1121 ret_code = utils_group_id_from_name(value->value.group_name, &gid);
159b042f
JG
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;
a5dfbb9d
MD
1133 }
1134
159b042f
JG
1135 tracker = _trace_ust_get_process_attr_tracker(session, process_attr);
1136 if (!tracker) {
1137 ret_code = LTTNG_ERR_INVALID;
74675e31 1138 goto end;
159b042f
JG
1139 }
1140
28ab034a 1141 status = process_attr_tracker_inclusion_set_remove_value(tracker, value);
159b042f
JG
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 }
a7a533cd 1155 goto end;
a5dfbb9d 1156 }
a7a533cd 1157
159b042f 1158 DBG("User space untrack %s %d for session id %" PRIu64,
28ab034a
JG
1159 lttng_process_attr_to_string(process_attr),
1160 integral_value,
1161 session->id);
159b042f 1162
7966af57 1163 ret_code = (lttng_error_code) id_tracker_del_id(id_tracker, integral_value);
159b042f 1164 if (ret_code != LTTNG_OK) {
a7a533cd
JR
1165 goto end;
1166 }
159b042f
JG
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 }
a7a533cd 1182end:
159b042f 1183 return ret_code;
a5dfbb9d
MD
1184}
1185
f6a9efaa
DG
1186/*
1187 * RCU safe free context structure.
1188 */
1189static void destroy_context_rcu(struct rcu_head *head)
1190{
bec39940 1191 struct lttng_ht_node_ulong *node =
0114db0e 1192 lttng::utils::container_of(head, &lttng_ht_node_ulong::head);
28ab034a 1193 struct ltt_ust_context *ctx = lttng::utils::container_of(node, &ltt_ust_context::node);
f6a9efaa 1194
bdf64013 1195 trace_ust_destroy_context(ctx);
f6a9efaa
DG
1196}
1197
1198/*
1199 * Cleanup UST context hash table.
1200 */
7bd39047 1201static void destroy_contexts(struct lttng_ht *ht)
f6a9efaa
DG
1202{
1203 int ret;
bec39940
DG
1204 struct lttng_ht_node_ulong *node;
1205 struct lttng_ht_iter iter;
31746f93 1206 struct ltt_ust_context *ctx;
f6a9efaa 1207
a0377dfe 1208 LTTNG_ASSERT(ht);
0525e9ae 1209
56047f5a
JG
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 }
f6a9efaa 1222 }
f6a9efaa 1223 }
ed52805d 1224
3c339053 1225 lttng_ht_destroy(ht);
f6a9efaa
DG
1226}
1227
97ee3a89
DG
1228/*
1229 * Cleanup ust event structure.
1230 */
1231void trace_ust_destroy_event(struct ltt_ust_event *event)
1232{
a0377dfe 1233 LTTNG_ASSERT(event);
0525e9ae 1234
f6a9efaa 1235 DBG2("Trace destroy UST event %s", event->attr.name);
6b453b5e 1236 free(event->filter_expression);
53a80697 1237 free(event->filter);
40024f8a 1238 free(event->exclusion);
97ee3a89
DG
1239 free(event);
1240}
1241
bdf64013
JG
1242/*
1243 * Cleanup ust context structure.
1244 */
1245void trace_ust_destroy_context(struct ltt_ust_context *ctx)
1246{
a0377dfe 1247 LTTNG_ASSERT(ctx);
bdf64013 1248
fc4b93fa 1249 if (ctx->ctx.ctx == LTTNG_UST_ABI_CONTEXT_APP_CONTEXT) {
bdf64013
JG
1250 free(ctx->ctx.u.app_ctx.provider_name);
1251 free(ctx->ctx.u.app_ctx.ctx_name);
1252 }
1253 free(ctx);
1254}
1255
f6a9efaa
DG
1256/*
1257 * URCU intermediate call to complete destroy event.
1258 */
1259static void destroy_event_rcu(struct rcu_head *head)
1260{
28ab034a
JG
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);
f6a9efaa
DG
1263
1264 trace_ust_destroy_event(event);
1265}
1266
284d8f55
DG
1267/*
1268 * Cleanup UST events hashtable.
1269 */
7bd39047 1270static void destroy_events(struct lttng_ht *events)
ed52805d
DG
1271{
1272 int ret;
bec39940
DG
1273 struct lttng_ht_node_str *node;
1274 struct lttng_ht_iter iter;
ed52805d 1275
a0377dfe 1276 LTTNG_ASSERT(events);
0525e9ae 1277
56047f5a
JG
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 }
ed52805d
DG
1286 }
1287
3c339053 1288 lttng_ht_destroy(events);
ed52805d
DG
1289}
1290
97ee3a89
DG
1291/*
1292 * Cleanup ust channel structure.
36b588ed
MD
1293 *
1294 * Should _NOT_ be called with RCU read lock held.
97ee3a89 1295 */
36b588ed 1296static void _trace_ust_destroy_channel(struct ltt_ust_channel *channel)
97ee3a89 1297{
a0377dfe 1298 LTTNG_ASSERT(channel);
0525e9ae 1299
f6a9efaa 1300 DBG2("Trace destroy UST channel %s", channel->name);
97ee3a89 1301
97ee3a89 1302 free(channel);
f6a9efaa
DG
1303}
1304
1305/*
1306 * URCU intermediate call to complete destroy channel.
1307 */
1308static void destroy_channel_rcu(struct rcu_head *head)
1309{
28ab034a
JG
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);
f6a9efaa 1312
36b588ed
MD
1313 _trace_ust_destroy_channel(channel);
1314}
1315
1316void trace_ust_destroy_channel(struct ltt_ust_channel *channel)
1317{
627cbbe7
MD
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
36b588ed 1323 call_rcu(&channel->node.head, destroy_channel_rcu);
97ee3a89
DG
1324}
1325
d5979e4a
DG
1326/*
1327 * Remove an UST channel from a channel HT.
1328 */
28ab034a 1329void trace_ust_delete_channel(struct lttng_ht *ht, struct ltt_ust_channel *channel)
d5979e4a
DG
1330{
1331 int ret;
1332 struct lttng_ht_iter iter;
1333
a0377dfe
FD
1334 LTTNG_ASSERT(ht);
1335 LTTNG_ASSERT(channel);
d5979e4a
DG
1336
1337 iter.iter.node = &channel->node.node;
1338 ret = lttng_ht_del(ht, &iter);
a0377dfe 1339 LTTNG_ASSERT(!ret);
d5979e4a
DG
1340}
1341
d7bfb9b0
JG
1342int trace_ust_regenerate_metadata(struct ltt_ust_session *usess)
1343{
1344 int ret = 0;
cd9adb8b
JG
1345 struct buffer_reg_uid *uid_reg = nullptr;
1346 struct buffer_reg_session *session_reg = nullptr;
d7bfb9b0 1347
56047f5a 1348 lttng::urcu::read_lock_guard read_lock;
28ab034a 1349 cds_list_for_each_entry (uid_reg, &usess->buffer_reg_uid_list, lnode) {
b0f2e8db 1350 lsu::registry_session *registry;
d7bfb9b0
JG
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
1364end:
d7bfb9b0
JG
1365 return ret;
1366}
1367
97ee3a89 1368/*
f6a9efaa 1369 * Iterate over a hash table containing channels and cleanup safely.
97ee3a89 1370 */
bec39940 1371static void destroy_channels(struct lttng_ht *channels)
f6a9efaa 1372{
bec39940
DG
1373 struct lttng_ht_node_str *node;
1374 struct lttng_ht_iter iter;
f6a9efaa 1375
a0377dfe 1376 LTTNG_ASSERT(channels);
0525e9ae 1377
56047f5a
JG
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);
627cbbe7 1384
56047f5a
JG
1385 trace_ust_delete_channel(channels, chan);
1386 trace_ust_destroy_channel(chan);
1387 }
f6a9efaa 1388 }
ed52805d 1389
3c339053 1390 lttng_ht_destroy(channels);
f6a9efaa
DG
1391}
1392
f6a9efaa
DG
1393/*
1394 * Cleanup UST global domain.
1395 */
1396static void destroy_domain_global(struct ltt_ust_domain_global *dom)
1397{
a0377dfe 1398 LTTNG_ASSERT(dom);
0525e9ae 1399
f6a9efaa
DG
1400 destroy_channels(dom->channels);
1401}
97ee3a89 1402
f6a9efaa 1403/*
d070c424
MD
1404 * Cleanup ust session structure, keeping data required by
1405 * destroy notifier.
f6a9efaa
DG
1406 */
1407void trace_ust_destroy_session(struct ltt_ust_session *session)
1408{
fefd409b 1409 struct agent *agt;
7972aab2 1410 struct buffer_reg_uid *reg, *sreg;
fefd409b 1411 struct lttng_ht_iter iter;
7972aab2 1412
a0377dfe 1413 LTTNG_ASSERT(session);
97ee3a89 1414
d9bf3ca4 1415 DBG2("Trace UST destroy session %" PRIu64, session->id);
f6a9efaa 1416
f6a9efaa
DG
1417 /* Cleaning up UST domain */
1418 destroy_domain_global(&session->domain_global);
fefd409b 1419
56047f5a
JG
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);
d0edf546 1425
56047f5a
JG
1426 LTTNG_ASSERT(!ret);
1427 agent_destroy(agt);
1428 }
fefd409b 1429 }
7972aab2 1430
3c339053 1431 lttng_ht_destroy(session->agents);
8ada2175 1432
7972aab2 1433 /* Cleanup UID buffer registry object(s). */
28ab034a 1434 cds_list_for_each_entry_safe (reg, sreg, &session->buffer_reg_uid_list, lnode) {
7972aab2
DG
1435 cds_list_del(&reg->lnode);
1436 buffer_reg_uid_remove(reg);
1437 buffer_reg_uid_destroy(reg, session->consumer);
1438 }
44d3bd01 1439
159b042f
JG
1440 process_attr_tracker_destroy(session->tracker_vpid);
1441 process_attr_tracker_destroy(session->tracker_vuid);
1442 process_attr_tracker_destroy(session->tracker_vgid);
55c9e7ca
JR
1443
1444 fini_id_tracker(&session->vpid_tracker);
1445 fini_id_tracker(&session->vuid_tracker);
1446 fini_id_tracker(&session->vgid_tracker);
82b69413 1447 lttng_trace_chunk_put(session->current_trace_chunk);
d070c424
MD
1448}
1449
1450/* Free elements needed by destroy notifiers. */
1451void trace_ust_free_session(struct ltt_ust_session *session)
1452{
1453 consumer_output_put(session->consumer);
97ee3a89
DG
1454 free(session);
1455}
This page took 0.175617 seconds and 4 git commands to generate.