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