2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
8 #include "bin/lttng-sessiond/event-notifier-error-accounting.h"
13 #include <common/common.h>
14 #include <common/hashtable/utils.h>
15 #include <lttng/lttng.h>
16 #include <lttng/map-key.h>
17 #include <lttng/map-key-internal.h>
19 #include "ust-registry.h"
21 #include "ust-field-utils.h"
23 #include "lttng-sessiond.h"
24 #include "notification-thread-commands.h"
28 * Hash table match function for event in the registry.
30 static int ht_match_event(struct cds_lfht_node
*node
, const void *_key
)
32 const struct ust_registry_event
*key
;
33 struct ust_registry_event
*event
;
39 event
= caa_container_of(node
, struct ust_registry_event
, node
.node
);
43 /* It has to be a perfect match. First, compare the event names. */
44 if (strncmp(event
->name
, key
->name
, sizeof(event
->name
))) {
48 /* Compare log levels. */
49 if (event
->loglevel_value
!= key
->loglevel_value
) {
53 /* Compare the number of fields. */
54 if (event
->nr_fields
!= key
->nr_fields
) {
58 /* Compare each field individually. */
59 for (i
= 0; i
< event
->nr_fields
; i
++) {
60 if (!match_ustctl_field(&event
->fields
[i
], &key
->fields
[i
])) {
65 /* Compare model URI. */
66 if (event
->model_emf_uri
!= NULL
&& key
->model_emf_uri
== NULL
) {
68 } else if(event
->model_emf_uri
== NULL
&& key
->model_emf_uri
!= NULL
) {
70 } else if (event
->model_emf_uri
!= NULL
&& key
->model_emf_uri
!= NULL
) {
71 if (strcmp(event
->model_emf_uri
, key
->model_emf_uri
)) {
83 static unsigned long ht_hash_event(const void *_key
, unsigned long seed
)
86 const struct ust_registry_event
*key
= _key
;
90 hashed_key
= (uint64_t) hash_key_str(key
->name
, seed
);
92 return hash_key_u64(&hashed_key
, seed
);
95 static int compare_enums(const struct ust_registry_enum
*reg_enum_a
,
96 const struct ust_registry_enum
*reg_enum_b
)
101 assert(strcmp(reg_enum_a
->name
, reg_enum_b
->name
) == 0);
102 if (reg_enum_a
->nr_entries
!= reg_enum_b
->nr_entries
) {
106 for (i
= 0; i
< reg_enum_a
->nr_entries
; i
++) {
107 const struct ustctl_enum_entry
*entries_a
, *entries_b
;
109 entries_a
= ®_enum_a
->entries
[i
];
110 entries_b
= ®_enum_b
->entries
[i
];
111 if (entries_a
->start
.value
!= entries_b
->start
.value
) {
115 if (entries_a
->end
.value
!= entries_b
->end
.value
) {
119 if (entries_a
->start
.signedness
!= entries_b
->start
.signedness
) {
123 if (entries_a
->end
.signedness
!= entries_b
->end
.signedness
) {
128 if (strcmp(entries_a
->string
, entries_b
->string
)) {
138 * Hash table match function for enumerations in the session. Match is
139 * performed on enumeration name, and confirmed by comparing the enum
142 static int ht_match_enum(struct cds_lfht_node
*node
, const void *_key
)
144 struct ust_registry_enum
*_enum
;
145 const struct ust_registry_enum
*key
;
150 _enum
= caa_container_of(node
, struct ust_registry_enum
,
155 if (strncmp(_enum
->name
, key
->name
, LTTNG_UST_SYM_NAME_LEN
)) {
158 if (compare_enums(_enum
, key
)) {
170 * Hash table match function for enumerations in the session. Match is
171 * performed by enumeration ID.
173 static int ht_match_enum_id(struct cds_lfht_node
*node
, const void *_key
)
175 struct ust_registry_enum
*_enum
;
176 const struct ust_registry_enum
*key
= _key
;
181 _enum
= caa_container_of(node
, struct ust_registry_enum
, node
.node
);
184 if (_enum
->id
!= key
->id
) {
196 * Hash table hash function for enumerations in the session. The
197 * enumeration name is used for hashing.
199 static unsigned long ht_hash_enum(void *_key
, unsigned long seed
)
201 struct ust_registry_enum
*key
= _key
;
204 return hash_key_str(key
->name
, seed
);
208 * Return negative value on error, 0 if OK.
210 * TODO: we could add stricter verification of more types to catch
211 * errors in liblttng-ust implementation earlier than consumption by the
215 int validate_event_field(struct ustctl_field
*field
,
216 const char *event_name
,
221 switch(field
->type
.atype
) {
222 case ustctl_atype_integer
:
223 case ustctl_atype_enum
:
224 case ustctl_atype_array
:
225 case ustctl_atype_sequence
:
226 case ustctl_atype_string
:
227 case ustctl_atype_variant
:
228 case ustctl_atype_array_nestable
:
229 case ustctl_atype_sequence_nestable
:
230 case ustctl_atype_enum_nestable
:
231 case ustctl_atype_variant_nestable
:
233 case ustctl_atype_struct
:
234 if (field
->type
.u
.legacy
._struct
.nr_fields
!= 0) {
235 WARN("Unsupported non-empty struct field.");
240 case ustctl_atype_struct_nestable
:
241 if (field
->type
.u
.struct_nestable
.nr_fields
!= 0) {
242 WARN("Unsupported non-empty struct field.");
248 case ustctl_atype_float
:
249 switch (field
->type
.u
._float
.mant_dig
) {
251 WARN("UST application '%s' (pid: %d) has unknown float mantissa '%u' "
252 "in field '%s', rejecting event '%s'",
254 field
->type
.u
._float
.mant_dig
,
273 int validate_event_fields(size_t nr_fields
, struct ustctl_field
*fields
,
274 const char *event_name
, struct ust_app
*app
)
278 for (i
= 0; i
< nr_fields
; i
++) {
279 if (validate_event_field(&fields
[i
], event_name
, app
) < 0)
286 * Allocate event and initialize it. This does NOT set a valid event id from a
289 static struct ust_registry_event
*alloc_event(int session_objd
,
290 int container_objd
, char *name
, char *sig
, size_t nr_fields
,
291 struct ustctl_field
*fields
, int loglevel_value
,
292 char *model_emf_uri
, struct ust_app
*app
)
294 struct ust_registry_event
*event
= NULL
;
297 * Ensure that the field content is valid.
299 if (validate_event_fields(nr_fields
, fields
, name
, app
) < 0) {
303 event
= zmalloc(sizeof(*event
));
305 PERROR("zmalloc ust registry event");
309 event
->session_objd
= session_objd
;
310 event
->container_objd
= container_objd
;
311 /* Allocated by ustctl. */
312 event
->signature
= sig
;
313 event
->nr_fields
= nr_fields
;
314 event
->fields
= fields
;
315 event
->loglevel_value
= loglevel_value
;
316 event
->model_emf_uri
= model_emf_uri
;
318 /* Copy event name and force NULL byte. */
319 strncpy(event
->name
, name
, sizeof(event
->name
));
320 event
->name
[sizeof(event
->name
) - 1] = '\0';
322 cds_lfht_node_init(&event
->node
.node
);
329 * Free event data structure. This does NOT delete it from any hash table. It's
330 * safe to pass a NULL pointer. This shoudl be called inside a call RCU if the
331 * event is previously deleted from a rcu hash table.
333 static void destroy_event(struct ust_registry_event
*event
)
340 free(event
->model_emf_uri
);
341 free(event
->signature
);
346 * Destroy event function call of the call RCU.
348 static void destroy_event_rcu(struct rcu_head
*head
)
350 struct lttng_ht_node_u64
*node
=
351 caa_container_of(head
, struct lttng_ht_node_u64
, head
);
352 struct ust_registry_event
*event
=
353 caa_container_of(node
, struct ust_registry_event
, node
);
355 destroy_event(event
);
359 * Destroy ust_registry_map_key_ht_entry function call of the call RCU.
361 static void destroy_ust_registry_map_key_ht_entry(struct rcu_head
*head
)
363 struct lttng_ht_node_u64
*node
=
364 caa_container_of(head
, struct lttng_ht_node_u64
, head
);
365 struct ust_registry_map_key_ht_entry
*entry
=
366 caa_container_of(node
, struct ust_registry_map_key_ht_entry
, node
);
368 lttng_map_key_put(entry
->key
);
373 * Destroy ust_registry_map_index_ht_entry function call of the call RCU.
375 static void destroy_ust_registry_map_index_ht_entry(struct rcu_head
*head
)
377 struct lttng_ht_node_str
*node
=
378 caa_container_of(head
, struct lttng_ht_node_str
, head
);
379 struct ust_registry_map_index_ht_entry
*entry
=
380 caa_container_of(node
, struct ust_registry_map_index_ht_entry
, node
);
386 * Find an event using the name and signature in the given registry. RCU read
387 * side lock MUST be acquired before calling this function and as long as the
388 * event reference is kept by the caller.
390 * On success, the event pointer is returned else NULL.
392 struct ust_registry_event
*ust_registry_chan_find_event(
393 struct ust_registry_channel
*chan
, char *name
, char *sig
)
395 struct lttng_ht_node_u64
*node
;
396 struct lttng_ht_iter iter
;
397 struct ust_registry_event
*event
= NULL
;
398 struct ust_registry_event key
;
404 /* Setup key for the match function. */
405 strncpy(key
.name
, name
, sizeof(key
.name
));
406 key
.name
[sizeof(key
.name
) - 1] = '\0';
409 cds_lfht_lookup(chan
->ht
->ht
, chan
->ht
->hash_fct(&key
, lttng_ht_seed
),
410 chan
->ht
->match_fct
, &key
, &iter
.iter
);
411 node
= lttng_ht_iter_get_node_u64(&iter
);
415 event
= caa_container_of(node
, struct ust_registry_event
, node
);
422 * Create a ust_registry_event from the given parameters and add it to the
423 * registry hash table. If event_id is valid, it is set with the newly created
426 * On success, return 0 else a negative value. The created event MUST be unique
427 * so on duplicate entry -EINVAL is returned. On error, event_id is untouched.
429 * Should be called with session registry mutex held.
431 int ust_registry_chan_create_event(struct ust_registry_session
*session
,
432 uint64_t chan_key
, int session_objd
, int channel_objd
, char *name
,
433 char *sig
, size_t nr_fields
, struct ustctl_field
*fields
,
434 int loglevel_value
, char *model_emf_uri
, int buffer_type
,
435 uint32_t *event_id_p
, struct ust_app
*app
)
439 struct cds_lfht_node
*nptr
;
440 struct ust_registry_event
*event
= NULL
;
441 struct ust_registry_channel
*chan
;
451 * This should not happen but since it comes from the UST tracer, an
452 * external party, don't assert and simply validate values.
454 if (session_objd
< 0 || channel_objd
< 0) {
459 chan
= ust_registry_channel_find(session
, chan_key
);
465 /* Check if we've reached the maximum possible id. */
466 if (ust_registry_is_max_id(chan
->used_event_id
)) {
471 event
= alloc_event(session_objd
, channel_objd
, name
, sig
, nr_fields
,
472 fields
, loglevel_value
, model_emf_uri
, app
);
478 DBG3("UST registry creating event with event: %s, sig: %s, id: %u, "
479 "chan_objd: %u, sess_objd: %u, chan_id: %u", event
->name
,
480 event
->signature
, event
->id
, event
->container_objd
,
481 event
->session_objd
, chan
->chan_id
);
484 * This is an add unique with a custom match function for event. The node
485 * are matched using the event name and signature.
487 nptr
= cds_lfht_add_unique(chan
->ht
->ht
, chan
->ht
->hash_fct(event
,
488 lttng_ht_seed
), chan
->ht
->match_fct
, event
, &event
->node
.node
);
489 if (nptr
!= &event
->node
.node
) {
490 if (buffer_type
== LTTNG_BUFFER_PER_UID
) {
492 * This is normal, we just have to send the event id of the
493 * returned node and make sure we destroy the previously allocated
496 destroy_event(event
);
497 event
= caa_container_of(nptr
, struct ust_registry_event
,
500 event_id
= event
->id
;
502 ERR("UST registry create event add unique failed for event: %s, "
503 "sig: %s, id: %u, chan_objd: %u, sess_objd: %u",
504 event
->name
, event
->signature
, event
->id
,
505 event
->container_objd
, event
->session_objd
);
510 /* Request next event id if the node was successfully added. */
511 event_id
= event
->id
= ust_registry_channel_get_next_event_id(chan
);
514 *event_id_p
= event_id
;
516 if (!event
->metadata_dumped
) {
517 /* Append to metadata */
518 ret
= ust_metadata_event_statedump(session
, chan
, event
);
520 ERR("Error appending event metadata (errno = %d)", ret
);
535 destroy_event(event
);
540 int format_event_key(const struct lttng_map_key
*key
,
541 const char *full_event_name
, char **formated_key
)
544 char _key
[LTTNG_UST_KEY_TOKEN_STRING_LEN_MAX
] = {0};
545 enum lttng_map_key_status key_status
;
546 unsigned int i
, token_count
;
547 char *cloned_full_event_name
;
548 const char *provider_name
, *event_name
;
551 assert(full_event_name
);
553 cloned_full_event_name
= strdup(full_event_name
);
555 provider_name
= strtok(cloned_full_event_name
, ":");
556 event_name
= strtok(NULL
, ":");
558 key_status
= lttng_map_key_get_token_count(key
, &token_count
);
559 if (key_status
!= LTTNG_MAP_KEY_STATUS_OK
) {
560 ERR("Error getting map key token count");
565 if (token_count
== 0) {
566 ERR("Map key token number is zero");
571 for (i
= 0; i
< token_count
; i
++) {
572 const struct lttng_map_key_token
*token
=
573 lttng_map_key_get_token_at_index(key
, i
);
574 switch (token
->type
) {
575 case LTTNG_MAP_KEY_TOKEN_TYPE_STRING
:
577 struct lttng_map_key_token_string
*str_token
=
578 (struct lttng_map_key_token_string
*) token
;
579 DBG("Appending a string type key token: str = '%s'", str_token
->string
);
581 strcat(_key
, lttng_map_key_token_string_get_string(str_token
));
585 case LTTNG_MAP_KEY_TOKEN_TYPE_VARIABLE
:
587 struct lttng_map_key_token_variable
*var_token
=
588 (struct lttng_map_key_token_variable
*) token
;
590 switch (var_token
->type
) {
591 case LTTNG_MAP_KEY_TOKEN_VARIABLE_TYPE_EVENT_NAME
:
592 DBG("Serializing a event name variable type key token: event_name = '%s'",
594 strcat(_key
, event_name
);
596 case LTTNG_MAP_KEY_TOKEN_VARIABLE_TYPE_PROVIDER_NAME
:
597 DBG("Serializing a provider name variable type key token: provider_name = '%s'",
599 strcat(_key
, provider_name
);
611 *formated_key
= strdup(_key
);
615 free(cloned_full_event_name
);
620 const struct lttng_map_key
*ust_registry_map_find_key_for_token(
621 struct ust_registry_map
*map
,
622 uint64_t tracer_token
)
624 struct lttng_ht_iter iter
;
625 struct lttng_ht_node_u64
*key_node
;
626 struct ust_registry_map_key_ht_entry
*key_entry
;
627 const struct lttng_map_key
*key
= NULL
;;
630 lttng_ht_lookup(map
->tracer_token_to_map_key_ht
,
631 (void *) &tracer_token
, &iter
);
633 key_node
= lttng_ht_iter_get_node_u64(&iter
);
639 * It's already mapped. Return the key we allocated already.
641 key_entry
= caa_container_of(key_node
,
642 struct ust_registry_map_key_ht_entry
, node
);
645 key
= key_entry
->key
;
647 DBG("Returning map key object associated to the tracer token: key = %p, tracer_token = %"PRIu64
,
648 key_entry
->key
, tracer_token
);
654 int ust_registry_map_add_token_key_mapping(struct ust_registry_session
*session
,
655 uint64_t map_key
, uint64_t tracer_token
,
656 struct lttng_map_key
*key
)
659 struct ust_registry_map_key_ht_entry
*key_entry
;
660 struct ust_registry_map
*map
;
661 const struct lttng_map_key
*existing_mapping
= NULL
;
664 map
= ust_registry_map_find(session
, map_key
);
671 /* JORAJ check if the mapping already exist, we might want to *move this
672 * to the caller or at least provide more check if for some scenario
673 * (PID) this should never happen
675 existing_mapping
= ust_registry_map_find_key_for_token(map
, tracer_token
);
676 if (existing_mapping
!= NULL
) {
677 assert(existing_mapping
== key
);
682 key_entry
= zmalloc(sizeof(struct ust_registry_map_key_ht_entry
));
687 key_entry
->key
= key
;
689 /* Ensure the lifetime of the lttng_map_key object. */
690 lttng_map_key_get(key
);
694 lttng_ht_node_init_u64(&key_entry
->node
, tracer_token
);
695 lttng_ht_add_unique_u64(map
->tracer_token_to_map_key_ht
,
708 int ust_registry_map_find_or_create_index_for_key(struct ust_registry_map
*map
,
709 const char *formated_key
, uint64_t *index
)
712 struct lttng_ht_iter iter
;
713 struct lttng_ht_node_str
*index_node
;
714 struct ust_registry_map_index_ht_entry
*index_entry
;
717 assert(formated_key
);
720 * First try to check if we already mapped this formated key to an
723 lttng_ht_lookup(map
->key_string_to_bucket_index_ht
,
724 (void *) formated_key
, &iter
);
726 index_node
= lttng_ht_iter_get_node_str(&iter
);
729 * It's already mapped. Return the index we allocated already.
731 index_entry
= caa_container_of(index_node
,
732 struct ust_registry_map_index_ht_entry
, node
);
735 *index
= index_entry
->index
;
737 DBG("Returning an already allocated index for formated key: key = '%s', index = %"PRIu64
,
738 formated_key
, *index
);
741 * It's not mapped. Create a new mapping, add it to the
742 * hashtable and return it.
744 index_entry
= zmalloc(sizeof(struct ust_registry_map_index_ht_entry
));
750 index_entry
->index
= ust_registry_map_get_next_event_id(map
);
751 index_entry
->formated_key
= strdup(formated_key
);
752 lttng_ht_node_init_str(&index_entry
->node
, index_entry
->formated_key
);
754 lttng_ht_add_unique_str(map
->key_string_to_bucket_index_ht
,
757 *index
= index_entry
->index
;
758 DBG("Allocated counter index for new formated_key: key = '%s', index = %"PRIu64
,
759 formated_key
, *index
);
768 * Create a ust_registry_event from the given parameters and add it to the
769 * registry hash table. If event_id is valid, it is set with the newly created
772 * On success, return 0 else a negative value. The created event MUST be unique
773 * so on duplicate entry -EINVAL is returned. On error, event_id is untouched.
775 * Should be called with session registry mutex held.
777 int ust_registry_map_create_event(struct ust_registry_session
*session
,
778 uint64_t map_key
, int session_objd
, int map_objd
, char *name
,
779 char *sig
, size_t nr_fields
, struct ustctl_field
*fields
,
780 int loglevel_value
, char *model_emf_uri
, int buffer_type
,
781 uint64_t tracer_token
, uint64_t *counter_index_p
,
785 uint64_t counter_index
;
786 struct ust_registry_map
*map
;
788 const struct lttng_map_key
*key
;
793 assert(counter_index_p
);
798 * This should not happen but since it comes from the UST tracer, an
799 * external party, don't assert and simply validate values.
801 if (session_objd
< 0 || map_objd
< 0) {
806 map
= ust_registry_map_find(session
, map_key
);
812 /* Check if we've reached the maximum possible id. */
813 if (ust_registry_is_max_id(map
->used_event_id
)) {
818 key
= ust_registry_map_find_key_for_token(map
, tracer_token
);
820 ERR("Tracer token %"PRIu64
" not found for map id = %"PRIu32
,
821 tracer_token
, map
->map_id
);
826 ret
= format_event_key(key
, name
, &formated_key
);
828 ERR("Error formating key");
833 ret
= ust_registry_map_find_or_create_index_for_key(map
, formated_key
,
836 ERR("Error finding or creating index for formated_key = '%s'",
843 DBG3("UST registry allocating counter index %"PRIu64
" to event: %s, "
844 "signature: %s, sess_objd: %u, map_objd: %u, map_id: %u",
845 counter_index
, name
, sig
, session_objd
, map_objd
, map
->map_id
);
847 *counter_index_p
= counter_index
;
863 * For a given event in a registry, delete the entry and destroy the event.
864 * This MUST be called within a RCU read side lock section.
866 void ust_registry_chan_destroy_event(struct ust_registry_channel
*chan
,
867 struct ust_registry_event
*event
)
870 struct lttng_ht_iter iter
;
875 /* Delete the node first. */
876 iter
.iter
.node
= &event
->node
.node
;
877 ret
= lttng_ht_del(chan
->ht
, &iter
);
880 call_rcu(&event
->node
.head
, destroy_event_rcu
);
886 * This MUST be called within a RCU read side lock section.
888 static void ust_registry_map_key_entry_destroy(struct lttng_ht
*ht
,
889 struct ust_registry_map_key_ht_entry
*entry
)
892 struct lttng_ht_iter iter
;
897 /* Delete the node first. */
898 iter
.iter
.node
= &entry
->node
.node
;
899 ret
= lttng_ht_del(ht
, &iter
);
902 call_rcu(&entry
->node
.head
, destroy_ust_registry_map_key_ht_entry
);
908 * This MUST be called within a RCU read side lock section.
910 static void ust_registry_map_index_ht_entry_destroy(struct lttng_ht
*ht
,
911 struct ust_registry_map_index_ht_entry
*entry
)
914 struct lttng_ht_iter iter
;
919 /* Delete the node first. */
920 iter
.iter
.node
= &entry
->node
.node
;
921 ret
= lttng_ht_del(ht
, &iter
);
924 call_rcu(&entry
->node
.head
, destroy_ust_registry_map_index_ht_entry
);
930 * For a given event in a registry, delete the entry and destroy the event.
931 * This MUST be called within a RCU read side lock section.
933 void ust_registry_map_destroy_event(struct ust_registry_map
*map
,
934 struct ust_registry_event
*event
)
937 struct lttng_ht_iter iter
;
942 /* Delete the node first. */
943 iter
.iter
.node
= &event
->node
.node
;
944 ret
= lttng_ht_del(map
->events_ht
, &iter
);
947 call_rcu(&event
->node
.head
, destroy_event_rcu
);
952 static void destroy_enum(struct ust_registry_enum
*reg_enum
)
957 free(reg_enum
->entries
);
961 static void destroy_enum_rcu(struct rcu_head
*head
)
963 struct ust_registry_enum
*reg_enum
=
964 caa_container_of(head
, struct ust_registry_enum
, rcu_head
);
966 destroy_enum(reg_enum
);
970 * Lookup enumeration by name and comparing enumeration entries.
971 * Needs to be called from RCU read-side critical section.
973 static struct ust_registry_enum
*ust_registry_lookup_enum(
974 struct ust_registry_session
*session
,
975 const struct ust_registry_enum
*reg_enum_lookup
)
977 struct ust_registry_enum
*reg_enum
= NULL
;
978 struct lttng_ht_node_str
*node
;
979 struct lttng_ht_iter iter
;
981 cds_lfht_lookup(session
->enums
->ht
,
982 ht_hash_enum((void *) reg_enum_lookup
, lttng_ht_seed
),
983 ht_match_enum
, reg_enum_lookup
, &iter
.iter
);
984 node
= lttng_ht_iter_get_node_str(&iter
);
988 reg_enum
= caa_container_of(node
, struct ust_registry_enum
, node
);
994 * Lookup enumeration by enum ID.
995 * Needs to be called from RCU read-side critical section.
997 struct ust_registry_enum
*
998 ust_registry_lookup_enum_by_id(struct ust_registry_session
*session
,
999 const char *enum_name
, uint64_t enum_id
)
1001 struct ust_registry_enum
*reg_enum
= NULL
;
1002 struct lttng_ht_node_str
*node
;
1003 struct lttng_ht_iter iter
;
1004 struct ust_registry_enum reg_enum_lookup
;
1006 memset(®_enum_lookup
, 0, sizeof(reg_enum_lookup
));
1007 strncpy(reg_enum_lookup
.name
, enum_name
, LTTNG_UST_SYM_NAME_LEN
);
1008 reg_enum_lookup
.name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1009 reg_enum_lookup
.id
= enum_id
;
1010 cds_lfht_lookup(session
->enums
->ht
,
1011 ht_hash_enum((void *) ®_enum_lookup
, lttng_ht_seed
),
1012 ht_match_enum_id
, ®_enum_lookup
, &iter
.iter
);
1013 node
= lttng_ht_iter_get_node_str(&iter
);
1017 reg_enum
= caa_container_of(node
, struct ust_registry_enum
, node
);
1023 * Create a ust_registry_enum from the given parameters and add it to the
1024 * registry hash table, or find it if already there.
1026 * On success, return 0 else a negative value.
1028 * Should be called with session registry mutex held.
1030 * We receive ownership of entries.
1032 int ust_registry_create_or_find_enum(struct ust_registry_session
*session
,
1033 int session_objd
, char *enum_name
,
1034 struct ustctl_enum_entry
*entries
, size_t nr_entries
,
1038 struct cds_lfht_node
*nodep
;
1039 struct ust_registry_enum
*reg_enum
= NULL
, *old_reg_enum
;
1047 * This should not happen but since it comes from the UST tracer, an
1048 * external party, don't assert and simply validate values.
1050 if (session_objd
< 0) {
1055 /* Check if the enumeration was already dumped */
1056 reg_enum
= zmalloc(sizeof(*reg_enum
));
1058 PERROR("zmalloc ust registry enumeration");
1062 strncpy(reg_enum
->name
, enum_name
, LTTNG_UST_SYM_NAME_LEN
);
1063 reg_enum
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1064 /* entries will be owned by reg_enum. */
1065 reg_enum
->entries
= entries
;
1066 reg_enum
->nr_entries
= nr_entries
;
1069 old_reg_enum
= ust_registry_lookup_enum(session
, reg_enum
);
1071 DBG("enum %s already in sess_objd: %u", enum_name
, session_objd
);
1072 /* Fall through. Use prior enum. */
1073 destroy_enum(reg_enum
);
1074 reg_enum
= old_reg_enum
;
1076 DBG("UST registry creating enum: %s, sess_objd: %u",
1077 enum_name
, session_objd
);
1078 if (session
->next_enum_id
== -1ULL) {
1080 destroy_enum(reg_enum
);
1083 reg_enum
->id
= session
->next_enum_id
++;
1084 cds_lfht_node_init(®_enum
->node
.node
);
1085 nodep
= cds_lfht_add_unique(session
->enums
->ht
,
1086 ht_hash_enum(reg_enum
, lttng_ht_seed
),
1087 ht_match_enum_id
, reg_enum
,
1088 ®_enum
->node
.node
);
1089 assert(nodep
== ®_enum
->node
.node
);
1091 DBG("UST registry reply with enum %s with id %" PRIu64
" in sess_objd: %u",
1092 enum_name
, reg_enum
->id
, session_objd
);
1093 *enum_id
= reg_enum
->id
;
1101 * For a given enumeration in a registry, delete the entry and destroy
1103 * This MUST be called within a RCU read side lock section.
1105 static void ust_registry_destroy_enum(struct ust_registry_session
*reg_session
,
1106 struct ust_registry_enum
*reg_enum
)
1109 struct lttng_ht_iter iter
;
1111 assert(reg_session
);
1114 /* Delete the node first. */
1115 iter
.iter
.node
= ®_enum
->node
.node
;
1116 ret
= lttng_ht_del(reg_session
->enums
, &iter
);
1118 call_rcu(®_enum
->rcu_head
, destroy_enum_rcu
);
1122 * We need to execute ht_destroy outside of RCU read-side critical
1123 * section and outside of call_rcu thread, so we postpone its execution
1124 * using ht_cleanup_push. It is simpler than to change the semantic of
1125 * the many callers of delete_ust_app_session().
1128 void destroy_channel_rcu(struct rcu_head
*head
)
1130 struct ust_registry_channel
*chan
=
1131 caa_container_of(head
, struct ust_registry_channel
, rcu_head
);
1134 ht_cleanup_push(chan
->ht
);
1136 free(chan
->ctx_fields
);
1141 * We need to execute ht_destroy outside of RCU read-side critical
1142 * section and outside of call_rcu thread, so we postpone its execution
1143 * using ht_cleanup_push. It is simpler than to mapge the semantic of
1144 * the many callers of delete_ust_app_session().
1147 void destroy_map_rcu(struct rcu_head
*head
)
1149 struct ust_registry_map
*map
=
1150 caa_container_of(head
, struct ust_registry_map
, rcu_head
);
1152 if (map
->events_ht
) {
1153 ht_cleanup_push(map
->events_ht
);
1156 if (map
->tracer_token_to_map_key_ht
) {
1157 ht_cleanup_push(map
->tracer_token_to_map_key_ht
);
1160 if (map
->key_string_to_bucket_index_ht
) {
1161 ht_cleanup_push(map
->key_string_to_bucket_index_ht
);
1168 * Destroy every element of the registry and free the memory. This does NOT
1169 * free the registry pointer since it might not have been allocated before so
1170 * it's the caller responsability.
1172 static void destroy_channel(struct ust_registry_channel
*chan
, bool notif
)
1174 struct lttng_ht_iter iter
;
1175 struct ust_registry_event
*event
;
1176 enum lttng_error_code cmd_ret
;
1181 cmd_ret
= notification_thread_command_remove_channel(
1182 notification_thread_handle
, chan
->consumer_key
,
1184 if (cmd_ret
!= LTTNG_OK
) {
1185 ERR("Failed to remove channel from notification thread");
1191 /* Destroy all event associated with this registry. */
1192 cds_lfht_for_each_entry(
1193 chan
->ht
->ht
, &iter
.iter
, event
, node
.node
) {
1194 /* Delete the node from the ht and free it. */
1195 ust_registry_chan_destroy_event(chan
, event
);
1199 call_rcu(&chan
->rcu_head
, destroy_channel_rcu
);
1203 * Destroy every element of the registry and free the memory. This does NOT
1204 * free the registry pointer since it might not have been allocated before so
1205 * it's the caller responsability.
1207 static void destroy_map(struct ust_registry_map
*map
)
1209 struct lttng_ht_iter iter
;
1210 struct ust_registry_event
*event
;
1211 struct ust_registry_map_key_ht_entry
*key_entry
;
1212 struct ust_registry_map_index_ht_entry
*index_entry
;
1217 if (map
->events_ht
) {
1218 /* Destroy all event associated with this registry. */
1219 cds_lfht_for_each_entry(map
->events_ht
->ht
, &iter
.iter
, event
, node
.node
) {
1220 /* Delete the node from the ht and free it. */
1221 ust_registry_map_destroy_event(map
, event
);
1225 /* Destroy all map_key entries associated with this registry. */
1226 cds_lfht_for_each_entry (map
->tracer_token_to_map_key_ht
->ht
,
1227 &iter
.iter
, key_entry
, node
.node
) {
1228 ust_registry_map_key_entry_destroy(
1229 map
->tracer_token_to_map_key_ht
,
1233 /* Destroy all index entry associated with this registry. */
1234 cds_lfht_for_each_entry(map
->key_string_to_bucket_index_ht
->ht
,
1235 &iter
.iter
, index_entry
, node
.node
) {
1236 ust_registry_map_index_ht_entry_destroy(
1237 map
->key_string_to_bucket_index_ht
,
1241 call_rcu(&map
->rcu_head
, destroy_map_rcu
);
1245 * Initialize registry with default values.
1247 int ust_registry_channel_add(struct ust_registry_session
*session
,
1251 struct ust_registry_channel
*chan
;
1255 chan
= zmalloc(sizeof(*chan
));
1257 PERROR("zmalloc ust registry channel");
1262 chan
->ht
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
1268 /* Set custom match function. */
1269 chan
->ht
->match_fct
= ht_match_event
;
1270 chan
->ht
->hash_fct
= ht_hash_event
;
1273 * Assign a channel ID right now since the event notification comes
1274 * *before* the channel notify so the ID needs to be set at this point so
1275 * the metadata can be dumped for that event.
1277 if (ust_registry_is_max_id(session
->used_channel_id
)) {
1281 chan
->chan_id
= ust_registry_get_next_chan_id(session
);
1284 lttng_ht_node_init_u64(&chan
->node
, key
);
1285 lttng_ht_add_unique_u64(session
->channels
, &chan
->node
);
1291 destroy_channel(chan
, false);
1297 * Initialize registry map entry with default values.
1299 int ust_registry_map_add(struct ust_registry_session
*session
,
1303 struct ust_registry_map
*map
;
1307 map
= zmalloc(sizeof(*map
));
1309 PERROR("zmalloc ust registry map");
1314 map
->events_ht
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
1315 if (!map
->events_ht
) {
1320 /* Set custom match function. */
1321 map
->events_ht
->match_fct
= ht_match_event
;
1322 map
->events_ht
->hash_fct
= ht_hash_event
;
1324 map
->tracer_token_to_map_key_ht
= lttng_ht_new(0, LTTNG_HT_TYPE_U64
);
1325 if (!map
->tracer_token_to_map_key_ht
) {
1330 map
->key_string_to_bucket_index_ht
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
1331 if (!map
->key_string_to_bucket_index_ht
) {
1337 * FIXME frdeso: fix this comment
1338 * Assign a map ID right now since the event notification comes
1339 * *before* the map notify so the ID needs to be set at this point so
1340 * the metadata can be dumped for that event.
1342 if (ust_registry_is_max_id(session
->used_map_id
)) {
1346 map
->map_id
= ust_registry_get_next_map_id(session
);
1349 lttng_ht_node_init_u64(&map
->node
, key
);
1350 lttng_ht_add_unique_u64(session
->maps
, &map
->node
);
1362 * Find a channel in the given registry. RCU read side lock MUST be acquired
1363 * before calling this function and as long as the event reference is kept by
1366 * On success, the pointer is returned else NULL.
1368 struct ust_registry_channel
*ust_registry_channel_find(
1369 struct ust_registry_session
*session
, uint64_t key
)
1371 struct lttng_ht_node_u64
*node
;
1372 struct lttng_ht_iter iter
;
1373 struct ust_registry_channel
*chan
= NULL
;
1376 assert(session
->channels
);
1378 DBG3("UST registry channel finding key %" PRIu64
, key
);
1380 lttng_ht_lookup(session
->channels
, &key
, &iter
);
1381 node
= lttng_ht_iter_get_node_u64(&iter
);
1385 chan
= caa_container_of(node
, struct ust_registry_channel
, node
);
1392 * Find a map in the given registry. RCU read side lock MUST be acquired
1393 * before calling this function and as long as the event reference is kept by
1396 * On success, the pointer is returned else NULL.
1398 struct ust_registry_map
*ust_registry_map_find(
1399 struct ust_registry_session
*session
, uint64_t key
)
1401 struct lttng_ht_node_u64
*node
;
1402 struct lttng_ht_iter iter
;
1403 struct ust_registry_map
*map
= NULL
;
1406 assert(session
->maps
);
1408 DBG3("UST registry map finding key %" PRIu64
, key
);
1410 lttng_ht_lookup(session
->maps
, &key
, &iter
);
1411 node
= lttng_ht_iter_get_node_u64(&iter
);
1415 map
= caa_container_of(node
, struct ust_registry_map
, node
);
1422 * Remove channel using key from registry and free memory.
1424 void ust_registry_channel_del_free(struct ust_registry_session
*session
,
1425 uint64_t key
, bool notif
)
1427 struct lttng_ht_iter iter
;
1428 struct ust_registry_channel
*chan
;
1434 chan
= ust_registry_channel_find(session
, key
);
1440 iter
.iter
.node
= &chan
->node
.node
;
1441 ret
= lttng_ht_del(session
->channels
, &iter
);
1444 destroy_channel(chan
, notif
);
1451 * Remove map using key from registry and free memory.
1453 void ust_registry_map_del_free(struct ust_registry_session
*session
,
1456 struct lttng_ht_iter iter
;
1457 struct ust_registry_map
*map
;
1463 map
= ust_registry_map_find(session
, key
);
1469 iter
.iter
.node
= &map
->node
.node
;
1470 ret
= lttng_ht_del(session
->maps
, &iter
);
1480 * Initialize registry with default values and set the newly allocated session
1481 * pointer to sessionp.
1483 * Return 0 on success and sessionp is set or else return -1 and sessionp is
1486 int ust_registry_session_init(struct ust_registry_session
**sessionp
,
1487 struct ust_app
*app
,
1488 uint32_t bits_per_long
,
1489 uint32_t uint8_t_alignment
,
1490 uint32_t uint16_t_alignment
,
1491 uint32_t uint32_t_alignment
,
1492 uint32_t uint64_t_alignment
,
1493 uint32_t long_alignment
,
1497 const char *root_shm_path
,
1498 const char *shm_path
,
1501 uint64_t tracing_id
,
1505 struct ust_registry_session
*session
;
1509 session
= zmalloc(sizeof(*session
));
1511 PERROR("zmalloc ust registry session");
1515 pthread_mutex_init(&session
->lock
, NULL
);
1516 session
->bits_per_long
= bits_per_long
;
1517 session
->uint8_t_alignment
= uint8_t_alignment
;
1518 session
->uint16_t_alignment
= uint16_t_alignment
;
1519 session
->uint32_t_alignment
= uint32_t_alignment
;
1520 session
->uint64_t_alignment
= uint64_t_alignment
;
1521 session
->long_alignment
= long_alignment
;
1522 session
->byte_order
= byte_order
;
1523 session
->metadata_fd
= -1;
1524 session
->uid
= euid
;
1525 session
->gid
= egid
;
1526 session
->next_enum_id
= 0;
1527 session
->major
= major
;
1528 session
->minor
= minor
;
1529 strncpy(session
->root_shm_path
, root_shm_path
,
1530 sizeof(session
->root_shm_path
));
1531 session
->root_shm_path
[sizeof(session
->root_shm_path
) - 1] = '\0';
1533 strncpy(session
->shm_path
, shm_path
,
1534 sizeof(session
->shm_path
));
1535 session
->shm_path
[sizeof(session
->shm_path
) - 1] = '\0';
1536 strncpy(session
->metadata_path
, shm_path
,
1537 sizeof(session
->metadata_path
));
1538 session
->metadata_path
[sizeof(session
->metadata_path
) - 1] = '\0';
1539 strncat(session
->metadata_path
, "/metadata",
1540 sizeof(session
->metadata_path
)
1541 - strlen(session
->metadata_path
) - 1);
1543 if (session
->shm_path
[0]) {
1544 ret
= run_as_mkdir_recursive(session
->shm_path
,
1548 PERROR("run_as_mkdir_recursive");
1552 if (session
->metadata_path
[0]) {
1553 /* Create metadata file */
1554 ret
= run_as_open(session
->metadata_path
,
1555 O_WRONLY
| O_CREAT
| O_EXCL
,
1556 S_IRUSR
| S_IWUSR
, euid
, egid
);
1558 PERROR("Opening metadata file");
1561 session
->metadata_fd
= ret
;
1564 session
->enums
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
1565 if (!session
->enums
) {
1566 ERR("Failed to create enums hash table");
1569 /* hash/match functions are specified at call site. */
1570 session
->enums
->match_fct
= NULL
;
1571 session
->enums
->hash_fct
= NULL
;
1573 session
->channels
= lttng_ht_new(0, LTTNG_HT_TYPE_U64
);
1574 if (!session
->channels
) {
1578 session
->maps
= lttng_ht_new(0, LTTNG_HT_TYPE_U64
);
1579 if (!session
->maps
) {
1580 lttng_ht_destroy(session
->channels
);
1584 ret
= lttng_uuid_generate(session
->uuid
);
1586 ERR("Failed to generate UST uuid (errno = %d)", ret
);
1590 session
->tracing_id
= tracing_id
;
1591 session
->tracing_uid
= tracing_uid
;
1593 pthread_mutex_lock(&session
->lock
);
1594 ret
= ust_metadata_session_statedump(session
, app
, major
, minor
);
1595 pthread_mutex_unlock(&session
->lock
);
1597 ERR("Failed to generate session metadata (errno = %d)", ret
);
1601 *sessionp
= session
;
1606 ust_registry_session_destroy(session
);
1613 * Destroy session registry. This does NOT free the given pointer since it
1614 * might get passed as a reference. The registry lock should NOT be acquired.
1616 void ust_registry_session_destroy(struct ust_registry_session
*reg
)
1619 struct lttng_ht_iter iter
;
1620 struct ust_registry_channel
*chan
;
1621 struct ust_registry_enum
*reg_enum
;
1627 /* On error, EBUSY can be returned if lock. Code flow error. */
1628 ret
= pthread_mutex_destroy(®
->lock
);
1631 if (reg
->channels
) {
1633 /* Destroy all event associated with this registry. */
1634 cds_lfht_for_each_entry(reg
->channels
->ht
, &iter
.iter
, chan
,
1636 /* Delete the node from the ht and free it. */
1637 ret
= lttng_ht_del(reg
->channels
, &iter
);
1639 destroy_channel(chan
, true);
1642 ht_cleanup_push(reg
->channels
);
1645 free(reg
->metadata
);
1646 if (reg
->metadata_fd
>= 0) {
1647 ret
= close(reg
->metadata_fd
);
1651 ret
= run_as_unlink(reg
->metadata_path
,
1652 reg
->uid
, reg
->gid
);
1657 if (reg
->root_shm_path
[0]) {
1659 * Try deleting the directory hierarchy.
1661 (void) run_as_rmdir_recursive(reg
->root_shm_path
,
1663 LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG
);
1665 /* Destroy the enum hash table */
1668 /* Destroy all enum entries associated with this registry. */
1669 cds_lfht_for_each_entry(reg
->enums
->ht
, &iter
.iter
, reg_enum
,
1671 ust_registry_destroy_enum(reg
, reg_enum
);
1674 ht_cleanup_push(reg
->enums
);