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