2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2 only,
7 * as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <common/common.h>
27 #include <common/defaults.h>
29 #include "buffer-registry.h"
30 #include "trace-ust.h"
36 * Match function for the events hash table lookup.
38 * Matches by name only. Used by the disable command.
40 int trace_ust_ht_match_event_by_name(struct cds_lfht_node
*node
,
43 struct ltt_ust_event
*event
;
49 event
= caa_container_of(node
, struct ltt_ust_event
, node
.node
);
53 if (strncmp(event
->attr
.name
, name
, sizeof(event
->attr
.name
)) != 0) {
65 * Match function for the hash table lookup.
67 * It matches an ust event based on three attributes which are the event name,
68 * the filter bytecode and the loglevel.
70 int trace_ust_ht_match_event(struct cds_lfht_node
*node
, const void *_key
)
72 struct ltt_ust_event
*event
;
73 const struct ltt_ust_ht_key
*key
;
74 int ev_loglevel_value
;
80 event
= caa_container_of(node
, struct ltt_ust_event
, node
.node
);
82 ev_loglevel_value
= event
->attr
.loglevel
;
84 /* Match the 4 elements of the key: name, filter, loglevel, exclusions. */
87 if (strncmp(event
->attr
.name
, key
->name
, sizeof(event
->attr
.name
)) != 0) {
91 /* Event loglevel value and type. */
92 ll_match
= loglevels_match(event
->attr
.loglevel_type
,
93 ev_loglevel_value
, key
->loglevel_type
,
94 key
->loglevel_value
, LTTNG_UST_LOGLEVEL_ALL
);
100 /* Only one of the filters is NULL, fail. */
101 if ((key
->filter
&& !event
->filter
) || (!key
->filter
&& event
->filter
)) {
105 if (key
->filter
&& event
->filter
) {
106 /* Both filters exists, check length followed by the bytecode. */
107 if (event
->filter
->len
!= key
->filter
->len
||
108 memcmp(event
->filter
->data
, key
->filter
->data
,
109 event
->filter
->len
) != 0) {
114 /* If only one of the exclusions is NULL, fail. */
115 if ((key
->exclusion
&& !event
->exclusion
) || (!key
->exclusion
&& event
->exclusion
)) {
119 if (key
->exclusion
&& event
->exclusion
) {
122 /* Check exclusion counts first. */
123 if (event
->exclusion
->count
!= key
->exclusion
->count
) {
127 /* Compare names individually. */
128 for (i
= 0; i
< event
->exclusion
->count
; ++i
) {
131 const char *name_ev
=
132 LTTNG_EVENT_EXCLUSION_NAME_AT(
133 event
->exclusion
, i
);
136 * Compare this exclusion name to all the key's
139 for (j
= 0; j
< key
->exclusion
->count
; ++j
) {
140 const char *name_key
=
141 LTTNG_EVENT_EXCLUSION_NAME_AT(
144 if (!strncmp(name_ev
, name_key
,
145 LTTNG_SYMBOL_NAME_LEN
)) {
153 * If the current exclusion name was not found amongst
154 * the key's exclusion names, then there's no match.
169 * Find the channel in the hashtable and return channel pointer. RCU read side
170 * lock MUST be acquired before calling this.
172 struct ltt_ust_channel
*trace_ust_find_channel_by_name(struct lttng_ht
*ht
,
175 struct lttng_ht_node_str
*node
;
176 struct lttng_ht_iter iter
;
179 * If we receive an empty string for channel name, it means the
180 * default channel name is requested.
183 name
= DEFAULT_CHANNEL_NAME
;
185 lttng_ht_lookup(ht
, (void *)name
, &iter
);
186 node
= lttng_ht_iter_get_node_str(&iter
);
191 DBG2("Trace UST channel %s found by name", name
);
193 return caa_container_of(node
, struct ltt_ust_channel
, node
);
196 DBG2("Trace UST channel %s not found by name", name
);
201 * Find the event in the hashtable and return event pointer. RCU read side lock
202 * MUST be acquired before calling this.
204 struct ltt_ust_event
*trace_ust_find_event(struct lttng_ht
*ht
,
205 char *name
, struct lttng_filter_bytecode
*filter
,
206 enum lttng_ust_loglevel_type loglevel_type
, int loglevel_value
,
207 struct lttng_event_exclusion
*exclusion
)
209 struct lttng_ht_node_str
*node
;
210 struct lttng_ht_iter iter
;
211 struct ltt_ust_ht_key key
;
218 key
.loglevel_type
= loglevel_type
;
219 key
.loglevel_value
= loglevel_value
;
220 key
.exclusion
= exclusion
;
222 cds_lfht_lookup(ht
->ht
, ht
->hash_fct((void *) name
, lttng_ht_seed
),
223 trace_ust_ht_match_event
, &key
, &iter
.iter
);
224 node
= lttng_ht_iter_get_node_str(&iter
);
229 DBG2("Trace UST event %s found", key
.name
);
231 return caa_container_of(node
, struct ltt_ust_event
, node
);
234 DBG2("Trace UST event %s NOT found", key
.name
);
239 * Lookup an agent in the session agents hash table by domain type and return
240 * the object if found else NULL.
242 * RCU read side lock must be acquired before calling and only released
243 * once the agent is no longer in scope or being used.
245 struct agent
*trace_ust_find_agent(struct ltt_ust_session
*session
,
246 enum lttng_domain_type domain_type
)
248 struct agent
*agt
= NULL
;
249 struct lttng_ht_node_u64
*node
;
250 struct lttng_ht_iter iter
;
255 DBG3("Trace ust agent lookup for domain %d", domain_type
);
259 lttng_ht_lookup(session
->agents
, &key
, &iter
);
260 node
= lttng_ht_iter_get_node_u64(&iter
);
264 agt
= caa_container_of(node
, struct agent
, node
);
271 * Allocate and initialize a ust session data structure.
273 * Return pointer to structure or NULL.
275 struct ltt_ust_session
*trace_ust_create_session(uint64_t session_id
)
277 struct ltt_ust_session
*lus
;
279 /* Allocate a new ltt ust session */
280 lus
= zmalloc(sizeof(struct ltt_ust_session
));
282 PERROR("create ust session zmalloc");
286 /* Init data structure */
287 lus
->id
= session_id
;
290 /* Set default metadata channel attribute. */
291 lus
->metadata_attr
.overwrite
= DEFAULT_CHANNEL_OVERWRITE
;
292 lus
->metadata_attr
.subbuf_size
= default_get_metadata_subbuf_size();
293 lus
->metadata_attr
.num_subbuf
= DEFAULT_METADATA_SUBBUF_NUM
;
294 lus
->metadata_attr
.switch_timer_interval
= DEFAULT_METADATA_SWITCH_TIMER
;
295 lus
->metadata_attr
.read_timer_interval
= DEFAULT_METADATA_READ_TIMER
;
296 lus
->metadata_attr
.output
= LTTNG_UST_MMAP
;
299 * Default buffer type. This can be changed through an enable channel
300 * requesting a different type. Note that this can only be changed once
301 * during the session lifetime which is at the first enable channel and
302 * only before start. The flag buffer_type_changed indicates the status.
304 lus
->buffer_type
= LTTNG_BUFFER_PER_UID
;
305 /* Once set to 1, the buffer_type is immutable for the session. */
306 lus
->buffer_type_changed
= 0;
307 /* Init it in case it get used after allocation. */
308 CDS_INIT_LIST_HEAD(&lus
->buffer_reg_uid_list
);
310 /* Alloc UST global domain channels' HT */
311 lus
->domain_global
.channels
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
312 /* Alloc agent hash table. */
313 lus
->agents
= lttng_ht_new(0, LTTNG_HT_TYPE_U64
);
315 lus
->tracker_list_vpid
= lttng_tracker_list_create();
316 if (!lus
->tracker_list_vpid
) {
319 lus
->tracker_list_vuid
= lttng_tracker_list_create();
320 if (!lus
->tracker_list_vuid
) {
323 lus
->tracker_list_vgid
= lttng_tracker_list_create();
324 if (!lus
->tracker_list_vgid
) {
327 lus
->consumer
= consumer_create_output(CONSUMER_DST_LOCAL
);
328 if (lus
->consumer
== NULL
) {
332 DBG2("UST trace session create successful");
337 lttng_tracker_list_destroy(lus
->tracker_list_vpid
);
338 lttng_tracker_list_destroy(lus
->tracker_list_vuid
);
339 lttng_tracker_list_destroy(lus
->tracker_list_vgid
);
340 ht_cleanup_push(lus
->domain_global
.channels
);
341 ht_cleanup_push(lus
->agents
);
348 * Allocate and initialize a ust channel data structure.
350 * Return pointer to structure or NULL.
352 struct ltt_ust_channel
*trace_ust_create_channel(struct lttng_channel
*chan
,
353 enum lttng_domain_type domain
)
355 struct ltt_ust_channel
*luc
;
359 luc
= zmalloc(sizeof(struct ltt_ust_channel
));
361 PERROR("ltt_ust_channel zmalloc");
365 luc
->domain
= domain
;
367 /* Copy UST channel attributes */
368 luc
->attr
.overwrite
= chan
->attr
.overwrite
;
369 luc
->attr
.subbuf_size
= chan
->attr
.subbuf_size
;
370 luc
->attr
.num_subbuf
= chan
->attr
.num_subbuf
;
371 luc
->attr
.switch_timer_interval
= chan
->attr
.switch_timer_interval
;
372 luc
->attr
.read_timer_interval
= chan
->attr
.read_timer_interval
;
373 luc
->attr
.output
= (enum lttng_ust_output
) chan
->attr
.output
;
374 luc
->monitor_timer_interval
= ((struct lttng_channel_extended
*)
375 chan
->attr
.extended
.ptr
)->monitor_timer_interval
;
376 luc
->attr
.u
.s
.blocking_timeout
= ((struct lttng_channel_extended
*)
377 chan
->attr
.extended
.ptr
)->blocking_timeout
;
379 /* Translate to UST output enum */
380 switch (luc
->attr
.output
) {
382 luc
->attr
.output
= LTTNG_UST_MMAP
;
387 * If we receive an empty string for channel name, it means the
388 * default channel name is requested.
390 if (chan
->name
[0] == '\0') {
391 strncpy(luc
->name
, DEFAULT_CHANNEL_NAME
, sizeof(luc
->name
));
393 /* Copy channel name */
394 strncpy(luc
->name
, chan
->name
, sizeof(luc
->name
));
396 luc
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
399 lttng_ht_node_init_str(&luc
->node
, luc
->name
);
400 CDS_INIT_LIST_HEAD(&luc
->ctx_list
);
402 /* Alloc hash tables */
403 luc
->events
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
404 luc
->ctx
= lttng_ht_new(0, LTTNG_HT_TYPE_ULONG
);
406 /* On-disk circular buffer parameters */
407 luc
->tracefile_size
= chan
->attr
.tracefile_size
;
408 luc
->tracefile_count
= chan
->attr
.tracefile_count
;
410 DBG2("Trace UST channel %s created", luc
->name
);
417 * Validates an exclusion list.
419 * Returns 0 if valid, negative value if invalid.
421 static int validate_exclusion(struct lttng_event_exclusion
*exclusion
)
428 for (i
= 0; i
< exclusion
->count
; ++i
) {
431 LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion
, i
);
433 for (j
= 0; j
< i
; ++j
) {
435 LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion
, j
);
437 if (!strncmp(name_a
, name_b
, LTTNG_SYMBOL_NAME_LEN
)) {
450 * Allocate and initialize a ust event. Set name and event type.
451 * We own filter_expression, filter, and exclusion.
453 * Return pointer to structure or NULL.
455 struct ltt_ust_event
*trace_ust_create_event(struct lttng_event
*ev
,
456 char *filter_expression
,
457 struct lttng_filter_bytecode
*filter
,
458 struct lttng_event_exclusion
*exclusion
,
461 struct ltt_ust_event
*lue
;
465 if (exclusion
&& validate_exclusion(exclusion
)) {
469 lue
= zmalloc(sizeof(struct ltt_ust_event
));
471 PERROR("ust event zmalloc");
475 lue
->internal
= internal_event
;
478 case LTTNG_EVENT_PROBE
:
479 lue
->attr
.instrumentation
= LTTNG_UST_PROBE
;
481 case LTTNG_EVENT_FUNCTION
:
482 lue
->attr
.instrumentation
= LTTNG_UST_FUNCTION
;
484 case LTTNG_EVENT_FUNCTION_ENTRY
:
485 lue
->attr
.instrumentation
= LTTNG_UST_FUNCTION
;
487 case LTTNG_EVENT_TRACEPOINT
:
488 lue
->attr
.instrumentation
= LTTNG_UST_TRACEPOINT
;
491 ERR("Unknown ust instrumentation type (%d)", ev
->type
);
492 goto error_free_event
;
495 /* Copy event name */
496 strncpy(lue
->attr
.name
, ev
->name
, LTTNG_UST_SYM_NAME_LEN
);
497 lue
->attr
.name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
499 switch (ev
->loglevel_type
) {
500 case LTTNG_EVENT_LOGLEVEL_ALL
:
501 lue
->attr
.loglevel_type
= LTTNG_UST_LOGLEVEL_ALL
;
502 lue
->attr
.loglevel
= -1; /* Force to -1 */
504 case LTTNG_EVENT_LOGLEVEL_RANGE
:
505 lue
->attr
.loglevel_type
= LTTNG_UST_LOGLEVEL_RANGE
;
506 lue
->attr
.loglevel
= ev
->loglevel
;
508 case LTTNG_EVENT_LOGLEVEL_SINGLE
:
509 lue
->attr
.loglevel_type
= LTTNG_UST_LOGLEVEL_SINGLE
;
510 lue
->attr
.loglevel
= ev
->loglevel
;
513 ERR("Unknown ust loglevel type (%d)", ev
->loglevel_type
);
514 goto error_free_event
;
518 lue
->filter_expression
= filter_expression
;
519 lue
->filter
= filter
;
520 lue
->exclusion
= exclusion
;
523 lttng_ht_node_init_str(&lue
->node
, lue
->attr
.name
);
525 DBG2("Trace UST event %s, loglevel (%d,%d) created",
526 lue
->attr
.name
, lue
->attr
.loglevel_type
,
534 free(filter_expression
);
541 int trace_ust_context_type_event_to_ust(
542 enum lttng_event_context_type type
)
547 case LTTNG_EVENT_CONTEXT_VTID
:
548 utype
= LTTNG_UST_CONTEXT_VTID
;
550 case LTTNG_EVENT_CONTEXT_VPID
:
551 utype
= LTTNG_UST_CONTEXT_VPID
;
553 case LTTNG_EVENT_CONTEXT_PTHREAD_ID
:
554 utype
= LTTNG_UST_CONTEXT_PTHREAD_ID
;
556 case LTTNG_EVENT_CONTEXT_PROCNAME
:
557 utype
= LTTNG_UST_CONTEXT_PROCNAME
;
559 case LTTNG_EVENT_CONTEXT_IP
:
560 utype
= LTTNG_UST_CONTEXT_IP
;
562 case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER
:
563 if (!ustctl_has_perf_counters()) {
565 WARN("Perf counters not implemented in UST");
567 utype
= LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER
;
570 case LTTNG_EVENT_CONTEXT_APP_CONTEXT
:
571 utype
= LTTNG_UST_CONTEXT_APP_CONTEXT
;
581 * Return 1 if contexts match, 0 otherwise.
583 int trace_ust_match_context(struct ltt_ust_context
*uctx
,
584 struct lttng_event_context
*ctx
)
588 utype
= trace_ust_context_type_event_to_ust(ctx
->ctx
);
592 if (uctx
->ctx
.ctx
!= utype
) {
596 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER
:
597 if (uctx
->ctx
.u
.perf_counter
.type
598 != ctx
->u
.perf_counter
.type
) {
601 if (uctx
->ctx
.u
.perf_counter
.config
602 != ctx
->u
.perf_counter
.config
) {
605 if (strncmp(uctx
->ctx
.u
.perf_counter
.name
,
606 ctx
->u
.perf_counter
.name
,
607 LTTNG_UST_SYM_NAME_LEN
)) {
611 case LTTNG_UST_CONTEXT_APP_CONTEXT
:
612 assert(uctx
->ctx
.u
.app_ctx
.provider_name
);
613 assert(uctx
->ctx
.u
.app_ctx
.ctx_name
);
614 if (strcmp(uctx
->ctx
.u
.app_ctx
.provider_name
,
615 ctx
->u
.app_ctx
.provider_name
) ||
616 strcmp(uctx
->ctx
.u
.app_ctx
.ctx_name
,
617 ctx
->u
.app_ctx
.ctx_name
)) {
628 * Allocate and initialize an UST context.
630 * Return pointer to structure or NULL.
632 struct ltt_ust_context
*trace_ust_create_context(
633 struct lttng_event_context
*ctx
)
635 struct ltt_ust_context
*uctx
= NULL
;
640 utype
= trace_ust_context_type_event_to_ust(ctx
->ctx
);
642 ERR("Invalid UST context");
646 uctx
= zmalloc(sizeof(struct ltt_ust_context
));
648 PERROR("zmalloc ltt_ust_context");
652 uctx
->ctx
.ctx
= (enum lttng_ust_context_type
) utype
;
654 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER
:
655 uctx
->ctx
.u
.perf_counter
.type
= ctx
->u
.perf_counter
.type
;
656 uctx
->ctx
.u
.perf_counter
.config
= ctx
->u
.perf_counter
.config
;
657 strncpy(uctx
->ctx
.u
.perf_counter
.name
, ctx
->u
.perf_counter
.name
,
658 LTTNG_UST_SYM_NAME_LEN
);
659 uctx
->ctx
.u
.perf_counter
.name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
661 case LTTNG_UST_CONTEXT_APP_CONTEXT
:
663 char *provider_name
= NULL
, *ctx_name
= NULL
;
665 provider_name
= strdup(ctx
->u
.app_ctx
.provider_name
);
666 if (!provider_name
) {
669 uctx
->ctx
.u
.app_ctx
.provider_name
= provider_name
;
671 ctx_name
= strdup(ctx
->u
.app_ctx
.ctx_name
);
675 uctx
->ctx
.u
.app_ctx
.ctx_name
= ctx_name
;
681 lttng_ht_node_init_ulong(&uctx
->node
, (unsigned long) uctx
->ctx
.ctx
);
685 trace_ust_destroy_context(uctx
);
690 void destroy_id_tracker_node_rcu(struct rcu_head
*head
)
692 struct ust_id_tracker_node
*tracker_node
=
693 caa_container_of(head
, struct ust_id_tracker_node
, node
.head
);
698 void destroy_id_tracker_node(struct ust_id_tracker_node
*tracker_node
)
701 call_rcu(&tracker_node
->node
.head
, destroy_id_tracker_node_rcu
);
705 int init_id_tracker(struct ust_id_tracker
*id_tracker
)
709 id_tracker
->ht
= lttng_ht_new(0, LTTNG_HT_TYPE_ULONG
);
710 if (!id_tracker
->ht
) {
711 ret
= LTTNG_ERR_NOMEM
;
720 * Teardown id tracker content, but don't free id_tracker object.
723 void fini_id_tracker(struct ust_id_tracker
*id_tracker
)
725 struct ust_id_tracker_node
*tracker_node
;
726 struct lttng_ht_iter iter
;
728 if (!id_tracker
->ht
) {
732 cds_lfht_for_each_entry(id_tracker
->ht
->ht
,
733 &iter
.iter
, tracker_node
, node
.node
) {
734 int ret
= lttng_ht_del(id_tracker
->ht
, &iter
);
737 destroy_id_tracker_node(tracker_node
);
740 ht_cleanup_push(id_tracker
->ht
);
741 id_tracker
->ht
= NULL
;
745 struct ust_id_tracker_node
*id_tracker_lookup(
746 struct ust_id_tracker
*id_tracker
, int id
,
747 struct lttng_ht_iter
*iter
)
749 unsigned long _id
= (unsigned long) id
;
750 struct lttng_ht_node_ulong
*node
;
752 lttng_ht_lookup(id_tracker
->ht
, (void *) _id
, iter
);
753 node
= lttng_ht_iter_get_node_ulong(iter
);
755 return caa_container_of(node
, struct ust_id_tracker_node
,
763 int id_tracker_add_id(struct ust_id_tracker
*id_tracker
, int id
)
765 int retval
= LTTNG_OK
;
766 struct ust_id_tracker_node
*tracker_node
;
767 struct lttng_ht_iter iter
;
770 retval
= LTTNG_ERR_INVALID
;
773 tracker_node
= id_tracker_lookup(id_tracker
, id
, &iter
);
775 /* Already exists. */
776 retval
= LTTNG_ERR_ID_TRACKED
;
779 tracker_node
= zmalloc(sizeof(*tracker_node
));
781 retval
= LTTNG_ERR_NOMEM
;
784 lttng_ht_node_init_ulong(&tracker_node
->node
, (unsigned long) id
);
785 lttng_ht_add_unique_ulong(id_tracker
->ht
, &tracker_node
->node
);
791 int id_tracker_del_id(struct ust_id_tracker
*id_tracker
, int id
)
793 int retval
= LTTNG_OK
, ret
;
794 struct ust_id_tracker_node
*tracker_node
;
795 struct lttng_ht_iter iter
;
798 retval
= LTTNG_ERR_INVALID
;
801 tracker_node
= id_tracker_lookup(id_tracker
, id
, &iter
);
804 retval
= LTTNG_ERR_ID_NOT_TRACKED
;
807 ret
= lttng_ht_del(id_tracker
->ht
, &iter
);
810 destroy_id_tracker_node(tracker_node
);
816 struct ust_id_tracker
*get_id_tracker(struct ltt_ust_session
*session
,
817 enum lttng_tracker_type tracker_type
)
819 switch (tracker_type
) {
820 case LTTNG_TRACKER_VPID
:
821 return &session
->vpid_tracker
;
822 case LTTNG_TRACKER_VUID
:
823 return &session
->vuid_tracker
;
824 case LTTNG_TRACKER_VGID
:
825 return &session
->vgid_tracker
;
832 struct lttng_tracker_list
*get_id_tracker_list(struct ltt_ust_session
*session
,
833 enum lttng_tracker_type tracker_type
)
835 switch (tracker_type
) {
836 case LTTNG_TRACKER_VPID
:
837 return session
->tracker_list_vpid
;
838 case LTTNG_TRACKER_VUID
:
839 return session
->tracker_list_vuid
;
840 case LTTNG_TRACKER_VGID
:
841 return session
->tracker_list_vgid
;
848 * The session lock is held when calling this function.
850 int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type
,
851 struct ltt_ust_session
*session
, int id
)
853 struct lttng_ht_iter iter
;
854 struct ust_id_tracker
*id_tracker
;
856 id_tracker
= get_id_tracker(session
, tracker_type
);
860 if (!id_tracker
->ht
) {
863 if (id_tracker_lookup(id_tracker
, id
, &iter
)) {
870 * Called with the session lock held.
872 int trace_ust_track_id(enum lttng_tracker_type tracker_type
,
873 struct ltt_ust_session
*session
,
874 struct lttng_tracker_id
*id
)
876 int retval
= LTTNG_OK
;
877 struct ust_id_tracker
*id_tracker
;
878 struct lttng_tracker_list
*tracker_list
;
880 struct lttng_tracker_id
*saved_ids
;
881 ssize_t saved_ids_count
, i
;
883 if (tracker_type
== LTTNG_TRACKER_PID
) {
884 DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
885 tracker_type
= LTTNG_TRACKER_VPID
;
888 retval
= lttng_tracker_id_lookup_string(tracker_type
,
890 if (retval
!= LTTNG_OK
) {
893 tracker_list
= get_id_tracker_list(session
, tracker_type
);
895 return LTTNG_ERR_INVALID
;
897 /* Save list for restore on error. */
898 saved_ids_count
= lttng_tracker_id_get_list(tracker_list
, &saved_ids
);
899 if (saved_ids_count
< 0) {
900 return LTTNG_ERR_INVALID
;
903 retval
= lttng_tracker_list_add(tracker_list
, id
);
904 if (retval
!= LTTNG_OK
) {
908 id_tracker
= get_id_tracker(session
, tracker_type
);
913 /* Track all ids: destroy tracker if exists. */
914 if (id_tracker
->ht
) {
915 fini_id_tracker(id_tracker
);
916 /* Ensure all apps have session. */
917 ust_app_global_update_all(session
);
920 if (!id_tracker
->ht
) {
921 /* Create tracker. */
922 retval
= init_id_tracker(id_tracker
);
923 if (retval
!= LTTNG_OK
) {
924 ERR("Error initializing ID tracker");
927 retval
= id_tracker_add_id(id_tracker
, value
);
928 if (retval
!= LTTNG_OK
) {
929 fini_id_tracker(id_tracker
);
932 /* Keep only apps matching ID. */
933 ust_app_global_update_all(session
);
937 retval
= id_tracker_add_id(id_tracker
, value
);
938 if (retval
!= LTTNG_OK
) {
941 /* Add session to application */
942 switch (tracker_type
) {
943 case LTTNG_TRACKER_VPID
:
944 app
= ust_app_find_by_pid(value
);
946 ust_app_global_update(session
, app
);
950 /* Keep only apps matching ID. */
951 ust_app_global_update_all(session
);
958 if (lttng_tracker_id_set_list(tracker_list
, saved_ids
, saved_ids_count
) != LTTNG_OK
) {
959 ERR("Error on tracker add error handling.\n");
962 for (i
= 0; i
< saved_ids_count
; i
++) {
963 free(saved_ids
[i
].string
);
970 * Called with the session lock held.
972 int trace_ust_untrack_id(enum lttng_tracker_type tracker_type
,
973 struct ltt_ust_session
*session
, struct lttng_tracker_id
*id
)
975 int retval
= LTTNG_OK
;
976 struct ust_id_tracker
*id_tracker
;
977 struct lttng_tracker_list
*tracker_list
;
979 struct lttng_tracker_id
*saved_ids
;
980 ssize_t saved_ids_count
, i
;
982 if (tracker_type
== LTTNG_TRACKER_PID
) {
983 DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
984 tracker_type
= LTTNG_TRACKER_VPID
;
987 retval
= lttng_tracker_id_lookup_string(tracker_type
,
989 if (retval
!= LTTNG_OK
) {
993 tracker_list
= get_id_tracker_list(session
, tracker_type
);
995 return LTTNG_ERR_INVALID
;
997 /* Save list for restore on error. */
998 saved_ids_count
= lttng_tracker_id_get_list(tracker_list
, &saved_ids
);
999 if (saved_ids_count
< 0) {
1000 return LTTNG_ERR_INVALID
;
1002 /* Remove from list. */
1003 retval
= lttng_tracker_list_remove(tracker_list
, id
);
1004 if (retval
!= LTTNG_OK
) {
1008 id_tracker
= get_id_tracker(session
, tracker_type
);
1014 /* Create empty tracker, replace old tracker. */
1015 struct ust_id_tracker tmp_tracker
;
1017 tmp_tracker
= *id_tracker
;
1018 retval
= init_id_tracker(id_tracker
);
1019 if (retval
!= LTTNG_OK
) {
1020 ERR("Error initializing ID tracker");
1021 /* Rollback operation. */
1022 *id_tracker
= tmp_tracker
;
1025 fini_id_tracker(&tmp_tracker
);
1027 /* Keep only apps matching ID. */
1028 ust_app_global_update_all(session
);
1030 struct ust_app
*app
;
1032 if (!id_tracker
->ht
) {
1033 /* No ID being tracked. */
1034 retval
= LTTNG_ERR_ID_NOT_TRACKED
;
1037 /* Remove ID from tracker */
1038 retval
= id_tracker_del_id(id_tracker
, value
);
1039 if (retval
!= LTTNG_OK
) {
1042 switch (tracker_type
) {
1043 case LTTNG_TRACKER_VPID
:
1044 /* Remove session from application. */
1045 app
= ust_app_find_by_pid(value
);
1047 ust_app_global_update(session
, app
);
1051 /* Keep only apps matching ID. */
1052 ust_app_global_update_all(session
);
1058 if (lttng_tracker_id_set_list(tracker_list
, saved_ids
, saved_ids_count
) != LTTNG_OK
) {
1059 ERR("Error on tracker remove error handling.\n");
1062 for (i
= 0; i
< saved_ids_count
; i
++) {
1063 free(saved_ids
[i
].string
);
1070 * Called with session lock held.
1072 ssize_t
trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type
,
1073 struct ltt_ust_session
*session
,
1074 struct lttng_tracker_id
**_ids
)
1076 struct lttng_tracker_list
*tracker_list
;
1078 if (tracker_type
== LTTNG_TRACKER_PID
) {
1079 DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
1080 tracker_type
= LTTNG_TRACKER_VPID
;
1083 tracker_list
= get_id_tracker_list(session
, tracker_type
);
1084 if (!tracker_list
) {
1085 return -LTTNG_ERR_INVALID
;
1087 return lttng_tracker_id_get_list(tracker_list
, _ids
);
1091 * RCU safe free context structure.
1093 static void destroy_context_rcu(struct rcu_head
*head
)
1095 struct lttng_ht_node_ulong
*node
=
1096 caa_container_of(head
, struct lttng_ht_node_ulong
, head
);
1097 struct ltt_ust_context
*ctx
=
1098 caa_container_of(node
, struct ltt_ust_context
, node
);
1100 trace_ust_destroy_context(ctx
);
1104 * Cleanup UST context hash table.
1106 static void destroy_contexts(struct lttng_ht
*ht
)
1109 struct lttng_ht_node_ulong
*node
;
1110 struct lttng_ht_iter iter
;
1111 struct ltt_ust_context
*ctx
;
1116 cds_lfht_for_each_entry(ht
->ht
, &iter
.iter
, node
, node
) {
1117 /* Remove from ordered list. */
1118 ctx
= caa_container_of(node
, struct ltt_ust_context
, node
);
1119 cds_list_del(&ctx
->list
);
1120 /* Remove from channel's hash table. */
1121 ret
= lttng_ht_del(ht
, &iter
);
1123 call_rcu(&node
->head
, destroy_context_rcu
);
1128 ht_cleanup_push(ht
);
1132 * Cleanup ust event structure.
1134 void trace_ust_destroy_event(struct ltt_ust_event
*event
)
1138 DBG2("Trace destroy UST event %s", event
->attr
.name
);
1139 free(event
->filter_expression
);
1140 free(event
->filter
);
1141 free(event
->exclusion
);
1146 * Cleanup ust context structure.
1148 void trace_ust_destroy_context(struct ltt_ust_context
*ctx
)
1152 if (ctx
->ctx
.ctx
== LTTNG_UST_CONTEXT_APP_CONTEXT
) {
1153 free(ctx
->ctx
.u
.app_ctx
.provider_name
);
1154 free(ctx
->ctx
.u
.app_ctx
.ctx_name
);
1160 * URCU intermediate call to complete destroy event.
1162 static void destroy_event_rcu(struct rcu_head
*head
)
1164 struct lttng_ht_node_str
*node
=
1165 caa_container_of(head
, struct lttng_ht_node_str
, head
);
1166 struct ltt_ust_event
*event
=
1167 caa_container_of(node
, struct ltt_ust_event
, node
);
1169 trace_ust_destroy_event(event
);
1173 * Cleanup UST events hashtable.
1175 static void destroy_events(struct lttng_ht
*events
)
1178 struct lttng_ht_node_str
*node
;
1179 struct lttng_ht_iter iter
;
1184 cds_lfht_for_each_entry(events
->ht
, &iter
.iter
, node
, node
) {
1185 ret
= lttng_ht_del(events
, &iter
);
1187 call_rcu(&node
->head
, destroy_event_rcu
);
1191 ht_cleanup_push(events
);
1195 * Cleanup ust channel structure.
1197 * Should _NOT_ be called with RCU read lock held.
1199 static void _trace_ust_destroy_channel(struct ltt_ust_channel
*channel
)
1203 DBG2("Trace destroy UST channel %s", channel
->name
);
1209 * URCU intermediate call to complete destroy channel.
1211 static void destroy_channel_rcu(struct rcu_head
*head
)
1213 struct lttng_ht_node_str
*node
=
1214 caa_container_of(head
, struct lttng_ht_node_str
, head
);
1215 struct ltt_ust_channel
*channel
=
1216 caa_container_of(node
, struct ltt_ust_channel
, node
);
1218 _trace_ust_destroy_channel(channel
);
1221 void trace_ust_destroy_channel(struct ltt_ust_channel
*channel
)
1223 /* Destroying all events of the channel */
1224 destroy_events(channel
->events
);
1225 /* Destroying all context of the channel */
1226 destroy_contexts(channel
->ctx
);
1228 call_rcu(&channel
->node
.head
, destroy_channel_rcu
);
1232 * Remove an UST channel from a channel HT.
1234 void trace_ust_delete_channel(struct lttng_ht
*ht
,
1235 struct ltt_ust_channel
*channel
)
1238 struct lttng_ht_iter iter
;
1243 iter
.iter
.node
= &channel
->node
.node
;
1244 ret
= lttng_ht_del(ht
, &iter
);
1249 * Iterate over a hash table containing channels and cleanup safely.
1251 static void destroy_channels(struct lttng_ht
*channels
)
1253 struct lttng_ht_node_str
*node
;
1254 struct lttng_ht_iter iter
;
1259 cds_lfht_for_each_entry(channels
->ht
, &iter
.iter
, node
, node
) {
1260 struct ltt_ust_channel
*chan
=
1261 caa_container_of(node
, struct ltt_ust_channel
, node
);
1263 trace_ust_delete_channel(channels
, chan
);
1264 trace_ust_destroy_channel(chan
);
1268 ht_cleanup_push(channels
);
1272 * Cleanup UST global domain.
1274 static void destroy_domain_global(struct ltt_ust_domain_global
*dom
)
1278 destroy_channels(dom
->channels
);
1282 * Cleanup ust session structure
1284 * Should *NOT* be called with RCU read-side lock held.
1286 void trace_ust_destroy_session(struct ltt_ust_session
*session
)
1289 struct buffer_reg_uid
*reg
, *sreg
;
1290 struct lttng_ht_iter iter
;
1294 DBG2("Trace UST destroy session %" PRIu64
, session
->id
);
1296 /* Cleaning up UST domain */
1297 destroy_domain_global(&session
->domain_global
);
1300 cds_lfht_for_each_entry(session
->agents
->ht
, &iter
.iter
, agt
, node
.node
) {
1301 int ret
= lttng_ht_del(session
->agents
, &iter
);
1308 ht_cleanup_push(session
->agents
);
1310 /* Cleanup UID buffer registry object(s). */
1311 cds_list_for_each_entry_safe(reg
, sreg
, &session
->buffer_reg_uid_list
,
1313 cds_list_del(®
->lnode
);
1314 buffer_reg_uid_remove(reg
);
1315 buffer_reg_uid_destroy(reg
, session
->consumer
);
1318 consumer_output_put(session
->consumer
);
1320 lttng_tracker_list_destroy(session
->tracker_list_vpid
);
1321 lttng_tracker_list_destroy(session
->tracker_list_vuid
);
1322 lttng_tracker_list_destroy(session
->tracker_list_vgid
);
1324 fini_id_tracker(&session
->vpid_tracker
);
1325 fini_id_tracker(&session
->vuid_tracker
);
1326 fini_id_tracker(&session
->vgid_tracker
);