2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
11 #include <common/common.hpp>
12 #include <common/hashtable/utils.hpp>
13 #include <common/exception.hpp>
14 #include <lttng/lttng.h>
16 #include "ust-registry.hpp"
17 #include "ust-app.hpp"
18 #include "ust-field-utils.hpp"
20 #include "lttng-sessiond.hpp"
21 #include "notification-thread-commands.hpp"
24 * Hash table match function for event in the registry.
26 static int ht_match_event(struct cds_lfht_node
*node
, const void *_key
)
28 const struct ust_registry_event
*key
;
29 struct ust_registry_event
*event
;
34 event
= caa_container_of(node
, struct ust_registry_event
, node
.node
);
36 key
= (ust_registry_event
*) _key
;
38 /* It has to be a perfect match. First, compare the event names. */
39 if (strncmp(event
->name
, key
->name
, sizeof(event
->name
))) {
43 /* Compare log levels. */
44 if (event
->loglevel_value
!= key
->loglevel_value
) {
48 /* Compare the arrays of fields. */
49 if (!match_lttng_ust_ctl_field_array(event
->fields
, event
->nr_fields
,
50 key
->fields
, key
->nr_fields
)) {
54 /* Compare model URI. */
55 if (event
->model_emf_uri
!= NULL
&& key
->model_emf_uri
== NULL
) {
57 } else if(event
->model_emf_uri
== NULL
&& key
->model_emf_uri
!= NULL
) {
59 } else if (event
->model_emf_uri
!= NULL
&& key
->model_emf_uri
!= NULL
) {
60 if (strcmp(event
->model_emf_uri
, key
->model_emf_uri
)) {
72 static unsigned long ht_hash_event(const void *_key
, unsigned long seed
)
75 const struct ust_registry_event
*key
= (ust_registry_event
*) _key
;
79 hashed_key
= (uint64_t) hash_key_str(key
->name
, seed
);
81 return hash_key_u64(&hashed_key
, seed
);
84 static int compare_enums(const struct ust_registry_enum
*reg_enum_a
,
85 const struct ust_registry_enum
*reg_enum_b
)
90 LTTNG_ASSERT(strcmp(reg_enum_a
->name
, reg_enum_b
->name
) == 0);
91 if (reg_enum_a
->nr_entries
!= reg_enum_b
->nr_entries
) {
95 for (i
= 0; i
< reg_enum_a
->nr_entries
; i
++) {
96 const struct lttng_ust_ctl_enum_entry
*entries_a
, *entries_b
;
98 entries_a
= ®_enum_a
->entries
[i
];
99 entries_b
= ®_enum_b
->entries
[i
];
100 if (entries_a
->start
.value
!= entries_b
->start
.value
) {
104 if (entries_a
->end
.value
!= entries_b
->end
.value
) {
108 if (entries_a
->start
.signedness
!= entries_b
->start
.signedness
) {
112 if (entries_a
->end
.signedness
!= entries_b
->end
.signedness
) {
117 if (strcmp(entries_a
->string
, entries_b
->string
)) {
127 * Hash table match function for enumerations in the session. Match is
128 * performed on enumeration name, and confirmed by comparing the enum
131 static int ht_match_enum(struct cds_lfht_node
*node
, const void *_key
)
133 struct ust_registry_enum
*_enum
;
134 const struct ust_registry_enum
*key
;
139 _enum
= caa_container_of(node
, struct ust_registry_enum
,
142 key
= (ust_registry_enum
*) _key
;
144 if (strncmp(_enum
->name
, key
->name
, LTTNG_UST_ABI_SYM_NAME_LEN
)) {
147 if (compare_enums(_enum
, key
)) {
159 * Hash table match function for enumerations in the session. Match is
160 * performed by enumeration ID.
162 static int ht_match_enum_id(struct cds_lfht_node
*node
, const void *_key
)
164 struct ust_registry_enum
*_enum
;
165 const struct ust_registry_enum
*key
= (ust_registry_enum
*) _key
;
170 _enum
= caa_container_of(node
, struct ust_registry_enum
, node
.node
);
173 if (_enum
->id
!= key
->id
) {
185 * Hash table hash function for enumerations in the session. The
186 * enumeration name is used for hashing.
188 static unsigned long ht_hash_enum(void *_key
, unsigned long seed
)
190 struct ust_registry_enum
*key
= (ust_registry_enum
*) _key
;
193 return hash_key_str(key
->name
, seed
);
197 * Return negative value on error, 0 if OK.
199 * TODO: we could add stricter verification of more types to catch
200 * errors in liblttng-ust implementation earlier than consumption by the
204 int validate_event_field(struct lttng_ust_ctl_field
*field
,
205 const char *event_name
,
210 switch(field
->type
.atype
) {
211 case lttng_ust_ctl_atype_integer
:
212 case lttng_ust_ctl_atype_enum
:
213 case lttng_ust_ctl_atype_array
:
214 case lttng_ust_ctl_atype_sequence
:
215 case lttng_ust_ctl_atype_string
:
216 case lttng_ust_ctl_atype_variant
:
217 case lttng_ust_ctl_atype_array_nestable
:
218 case lttng_ust_ctl_atype_sequence_nestable
:
219 case lttng_ust_ctl_atype_enum_nestable
:
220 case lttng_ust_ctl_atype_variant_nestable
:
222 case lttng_ust_ctl_atype_struct
:
223 if (field
->type
.u
.legacy
._struct
.nr_fields
!= 0) {
224 WARN("Unsupported non-empty struct field.");
229 case lttng_ust_ctl_atype_struct_nestable
:
230 if (field
->type
.u
.struct_nestable
.nr_fields
!= 0) {
231 WARN("Unsupported non-empty struct field.");
237 case lttng_ust_ctl_atype_float
:
238 switch (field
->type
.u
._float
.mant_dig
) {
240 WARN("UST application '%s' (pid: %d) has unknown float mantissa '%u' "
241 "in field '%s', rejecting event '%s'",
243 field
->type
.u
._float
.mant_dig
,
262 int validate_event_fields(size_t nr_fields
, struct lttng_ust_ctl_field
*fields
,
263 const char *event_name
, struct ust_app
*app
)
267 for (i
= 0; i
< nr_fields
; i
++) {
268 if (validate_event_field(&fields
[i
], event_name
, app
) < 0)
275 * Allocate event and initialize it. This does NOT set a valid event id from a
278 static struct ust_registry_event
*alloc_event(int session_objd
,
279 int channel_objd
, char *name
, char *sig
, size_t nr_fields
,
280 struct lttng_ust_ctl_field
*fields
, int loglevel_value
,
281 char *model_emf_uri
, struct ust_app
*app
)
283 struct ust_registry_event
*event
= NULL
;
286 * Ensure that the field content is valid.
288 if (validate_event_fields(nr_fields
, fields
, name
, app
) < 0) {
292 event
= zmalloc
<ust_registry_event
>();
294 PERROR("zmalloc ust registry event");
298 event
->session_objd
= session_objd
;
299 event
->channel_objd
= channel_objd
;
300 /* Allocated by ustctl. */
301 event
->signature
= sig
;
302 event
->nr_fields
= nr_fields
;
303 event
->fields
= fields
;
304 event
->loglevel_value
= loglevel_value
;
305 event
->model_emf_uri
= model_emf_uri
;
307 /* Copy event name and force NULL byte. */
308 strncpy(event
->name
, name
, sizeof(event
->name
));
309 event
->name
[sizeof(event
->name
) - 1] = '\0';
311 cds_lfht_node_init(&event
->node
.node
);
318 * Free event data structure. This does NOT delete it from any hash table. It's
319 * safe to pass a NULL pointer. This should be called inside a call RCU if the
320 * event is previously deleted from a rcu hash table.
322 static void destroy_event(struct ust_registry_event
*event
)
329 free(event
->model_emf_uri
);
330 free(event
->signature
);
335 * Destroy event function call of the call RCU.
337 static void destroy_event_rcu(struct rcu_head
*head
)
339 struct lttng_ht_node_u64
*node
=
340 caa_container_of(head
, struct lttng_ht_node_u64
, head
);
341 struct ust_registry_event
*event
=
342 caa_container_of(node
, struct ust_registry_event
, node
);
344 destroy_event(event
);
348 * Find an event using the name and signature in the given registry. RCU read
349 * side lock MUST be acquired before calling this function and as long as the
350 * event reference is kept by the caller.
352 * On success, the event pointer is returned else NULL.
354 struct ust_registry_event
*ust_registry_find_event(
355 struct ust_registry_channel
*chan
, char *name
, char *sig
)
357 struct lttng_ht_node_u64
*node
;
358 struct lttng_ht_iter iter
;
359 struct ust_registry_event
*event
= NULL
;
360 struct ust_registry_event key
;
365 ASSERT_RCU_READ_LOCKED();
367 /* Setup key for the match function. */
368 strncpy(key
.name
, name
, sizeof(key
.name
));
369 key
.name
[sizeof(key
.name
) - 1] = '\0';
372 cds_lfht_lookup(chan
->events
->ht
, chan
->events
->hash_fct(&key
, lttng_ht_seed
),
373 chan
->events
->match_fct
, &key
, &iter
.iter
);
374 node
= lttng_ht_iter_get_node_u64(&iter
);
378 event
= caa_container_of(node
, struct ust_registry_event
, node
);
385 * Create a ust_registry_event from the given parameters and add it to the
386 * registry hash table. If event_id is valid, it is set with the newly created
389 * On success, return 0 else a negative value. The created event MUST be unique
390 * so on duplicate entry -EINVAL is returned. On error, event_id is untouched.
392 * Should be called with session registry mutex held.
394 int ust_registry_create_event(ust_registry_session
*session
,
395 uint64_t chan_key
, int session_objd
, int channel_objd
, char *name
,
396 char *sig
, size_t nr_fields
, struct lttng_ust_ctl_field
*fields
,
397 int loglevel_value
, char *model_emf_uri
, int buffer_type
,
398 uint32_t *event_id_p
, struct ust_app
*app
)
402 struct cds_lfht_node
*nptr
;
403 struct ust_registry_event
*event
= NULL
;
404 struct ust_registry_channel
*chan
;
406 LTTNG_ASSERT(session
);
409 LTTNG_ASSERT(event_id_p
);
414 * This should not happen but since it comes from the UST tracer, an
415 * external party, don't assert and simply validate values.
417 if (session_objd
< 0 || channel_objd
< 0) {
422 chan
= ust_registry_channel_find(session
, chan_key
);
428 /* Check if we've reached the maximum possible id. */
429 if (ust_registry_is_max_id(chan
->used_event_id
)) {
434 event
= alloc_event(session_objd
, channel_objd
, name
, sig
, nr_fields
,
435 fields
, loglevel_value
, model_emf_uri
, app
);
441 DBG3("UST registry creating event with event: %s, sig: %s, id: %u, "
442 "chan_objd: %u, sess_objd: %u, chan_id: %u", event
->name
,
443 event
->signature
, event
->id
, event
->channel_objd
,
444 event
->session_objd
, chan
->chan_id
);
447 * This is an add unique with a custom match function for event. The node
448 * are matched using the event name and signature.
450 nptr
= cds_lfht_add_unique(chan
->events
->ht
, chan
->events
->hash_fct(event
,
451 lttng_ht_seed
), chan
->events
->match_fct
, event
, &event
->node
.node
);
452 if (nptr
!= &event
->node
.node
) {
453 if (buffer_type
== LTTNG_BUFFER_PER_UID
) {
455 * This is normal, we just have to send the event id of the
456 * returned node and make sure we destroy the previously allocated
459 destroy_event(event
);
460 event
= caa_container_of(nptr
, struct ust_registry_event
,
463 event_id
= event
->id
;
465 ERR("UST registry create event add unique failed for event: %s, "
466 "sig: %s, id: %u, chan_objd: %u, sess_objd: %u",
467 event
->name
, event
->signature
, event
->id
,
468 event
->channel_objd
, event
->session_objd
);
473 /* Request next event id if the node was successfully added. */
474 event_id
= event
->id
= ust_registry_get_next_event_id(chan
);
477 *event_id_p
= event_id
;
479 if (!event
->metadata_dumped
) {
480 /* Append to metadata */
481 ret
= ust_metadata_event_statedump(session
, chan
, event
);
483 ERR("Error appending event metadata (errno = %d)", ret
);
498 destroy_event(event
);
503 * For a given event in a registry, delete the entry and destroy the event.
504 * This MUST be called within a RCU read side lock section.
506 void ust_registry_destroy_event(struct ust_registry_channel
*chan
,
507 struct ust_registry_event
*event
)
510 struct lttng_ht_iter iter
;
514 ASSERT_RCU_READ_LOCKED();
516 /* Delete the node first. */
517 iter
.iter
.node
= &event
->node
.node
;
518 ret
= lttng_ht_del(chan
->events
, &iter
);
521 call_rcu(&event
->node
.head
, destroy_event_rcu
);
526 static void destroy_enum(struct ust_registry_enum
*reg_enum
)
531 free(reg_enum
->entries
);
535 static void destroy_enum_rcu(struct rcu_head
*head
)
537 struct ust_registry_enum
*reg_enum
=
538 caa_container_of(head
, struct ust_registry_enum
, rcu_head
);
540 destroy_enum(reg_enum
);
544 * Lookup enumeration by name and comparing enumeration entries.
545 * Needs to be called from RCU read-side critical section.
547 static struct ust_registry_enum
*ust_registry_lookup_enum(
548 ust_registry_session
*session
,
549 const struct ust_registry_enum
*reg_enum_lookup
)
551 struct ust_registry_enum
*reg_enum
= NULL
;
552 struct lttng_ht_node_str
*node
;
553 struct lttng_ht_iter iter
;
555 ASSERT_RCU_READ_LOCKED();
557 cds_lfht_lookup(session
->_enums
->ht
,
558 ht_hash_enum((void *) reg_enum_lookup
, lttng_ht_seed
),
559 ht_match_enum
, reg_enum_lookup
, &iter
.iter
);
560 node
= lttng_ht_iter_get_node_str(&iter
);
564 reg_enum
= caa_container_of(node
, struct ust_registry_enum
, node
);
570 * Lookup enumeration by enum ID.
571 * Needs to be called from RCU read-side critical section.
573 struct ust_registry_enum
*
574 ust_registry_lookup_enum_by_id(ust_registry_session
*session
,
575 const char *enum_name
, uint64_t enum_id
)
577 struct ust_registry_enum
*reg_enum
= NULL
;
578 struct lttng_ht_node_str
*node
;
579 struct lttng_ht_iter iter
;
580 struct ust_registry_enum reg_enum_lookup
;
582 ASSERT_RCU_READ_LOCKED();
584 memset(®_enum_lookup
, 0, sizeof(reg_enum_lookup
));
585 strncpy(reg_enum_lookup
.name
, enum_name
, LTTNG_UST_ABI_SYM_NAME_LEN
);
586 reg_enum_lookup
.name
[LTTNG_UST_ABI_SYM_NAME_LEN
- 1] = '\0';
587 reg_enum_lookup
.id
= enum_id
;
588 cds_lfht_lookup(session
->_enums
->ht
,
589 ht_hash_enum((void *) ®_enum_lookup
, lttng_ht_seed
),
590 ht_match_enum_id
, ®_enum_lookup
, &iter
.iter
);
591 node
= lttng_ht_iter_get_node_str(&iter
);
595 reg_enum
= caa_container_of(node
, struct ust_registry_enum
, node
);
601 * Create a ust_registry_enum from the given parameters and add it to the
602 * registry hash table, or find it if already there.
604 * On success, return 0 else a negative value.
606 * Should be called with session registry mutex held.
608 * We receive ownership of entries.
610 int ust_registry_create_or_find_enum(ust_registry_session
*session
,
611 int session_objd
, char *enum_name
,
612 struct lttng_ust_ctl_enum_entry
*entries
, size_t nr_entries
,
616 struct cds_lfht_node
*nodep
;
617 struct ust_registry_enum
*reg_enum
= NULL
, *old_reg_enum
;
619 LTTNG_ASSERT(session
);
620 LTTNG_ASSERT(enum_name
);
625 * This should not happen but since it comes from the UST tracer, an
626 * external party, don't assert and simply validate values.
628 if (session_objd
< 0) {
633 /* Check if the enumeration was already dumped */
634 reg_enum
= zmalloc
<ust_registry_enum
>();
636 PERROR("zmalloc ust registry enumeration");
640 strncpy(reg_enum
->name
, enum_name
, LTTNG_UST_ABI_SYM_NAME_LEN
);
641 reg_enum
->name
[LTTNG_UST_ABI_SYM_NAME_LEN
- 1] = '\0';
642 /* entries will be owned by reg_enum. */
643 reg_enum
->entries
= entries
;
644 reg_enum
->nr_entries
= nr_entries
;
647 old_reg_enum
= ust_registry_lookup_enum(session
, reg_enum
);
649 DBG("enum %s already in sess_objd: %u", enum_name
, session_objd
);
650 /* Fall through. Use prior enum. */
651 destroy_enum(reg_enum
);
652 reg_enum
= old_reg_enum
;
654 DBG("UST registry creating enum: %s, sess_objd: %u",
655 enum_name
, session_objd
);
656 if (session
->_next_enum_id
== -1ULL) {
658 destroy_enum(reg_enum
);
661 reg_enum
->id
= session
->_next_enum_id
++;
662 cds_lfht_node_init(®_enum
->node
.node
);
663 nodep
= cds_lfht_add_unique(session
->_enums
->ht
,
664 ht_hash_enum(reg_enum
, lttng_ht_seed
),
665 ht_match_enum_id
, reg_enum
,
666 ®_enum
->node
.node
);
667 LTTNG_ASSERT(nodep
== ®_enum
->node
.node
);
669 DBG("UST registry reply with enum %s with id %" PRIu64
" in sess_objd: %u",
670 enum_name
, reg_enum
->id
, session_objd
);
671 *enum_id
= reg_enum
->id
;
679 * For a given enumeration in a registry, delete the entry and destroy
681 * This MUST be called within a RCU read side lock section.
683 void ust_registry_destroy_enum(ust_registry_session
*reg_session
,
684 struct ust_registry_enum
*reg_enum
)
687 struct lttng_ht_iter iter
;
689 LTTNG_ASSERT(reg_session
);
690 LTTNG_ASSERT(reg_enum
);
691 ASSERT_RCU_READ_LOCKED();
693 /* Delete the node first. */
694 iter
.iter
.node
= ®_enum
->node
.node
;
695 ret
= lttng_ht_del(reg_session
->_enums
.get(), &iter
);
697 call_rcu(®_enum
->rcu_head
, destroy_enum_rcu
);
701 void destroy_channel_rcu(struct rcu_head
*head
)
703 struct ust_registry_channel
*chan
=
704 caa_container_of(head
, struct ust_registry_channel
, rcu_head
);
707 lttng_ht_destroy(chan
->events
);
710 free(chan
->ctx_fields
);
715 * Destroy every element of the registry and free the memory. This does NOT
716 * free the registry pointer since it might not have been allocated before so
717 * it's the caller responsability.
719 void ust_registry_channel_destroy(struct ust_registry_channel
*chan
, bool notify
)
721 struct lttng_ht_iter iter
;
722 struct ust_registry_event
*event
;
723 enum lttng_error_code cmd_ret
;
728 cmd_ret
= notification_thread_command_remove_channel(
729 the_notification_thread_handle
,
730 chan
->consumer_key
, LTTNG_DOMAIN_UST
);
731 if (cmd_ret
!= LTTNG_OK
) {
732 ERR("Failed to remove channel from notification thread");
738 /* Destroy all event associated with this registry. */
739 cds_lfht_for_each_entry(
740 chan
->events
->ht
, &iter
.iter
, event
, node
.node
) {
741 /* Delete the node from the ht and free it. */
742 ust_registry_destroy_event(chan
, event
);
746 call_rcu(&chan
->rcu_head
, destroy_channel_rcu
);
750 * Initialize registry with default values.
752 int ust_registry_channel_add(ust_registry_session
*session
,
756 struct ust_registry_channel
*chan
;
758 LTTNG_ASSERT(session
);
760 chan
= zmalloc
<ust_registry_channel
>();
762 PERROR("zmalloc ust registry channel");
767 chan
->events
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
773 /* Set custom match function. */
774 chan
->events
->match_fct
= ht_match_event
;
775 chan
->events
->hash_fct
= ht_hash_event
;
778 * Assign a channel ID right now since the event notification comes
779 * *before* the channel notify so the ID needs to be set at this point so
780 * the metadata can be dumped for that event.
782 if (ust_registry_is_max_id(session
->_used_channel_id
)) {
786 chan
->chan_id
= ust_registry_get_next_chan_id(session
);
789 lttng_ht_node_init_u64(&chan
->node
, key
);
790 lttng_ht_add_unique_u64(session
->_channels
.get(), &chan
->node
);
796 ust_registry_channel_destroy(chan
, false);
802 * Find a channel in the given registry. RCU read side lock MUST be acquired
803 * before calling this function and as long as the event reference is kept by
806 * On success, the pointer is returned else NULL.
808 struct ust_registry_channel
*ust_registry_channel_find(
809 ust_registry_session
*session
, uint64_t key
)
811 struct lttng_ht_node_u64
*node
;
812 struct lttng_ht_iter iter
;
813 struct ust_registry_channel
*chan
= NULL
;
815 LTTNG_ASSERT(session
);
816 LTTNG_ASSERT(session
->_channels
);
817 ASSERT_RCU_READ_LOCKED();
819 DBG3("UST registry channel finding key %" PRIu64
, key
);
821 lttng_ht_lookup(session
->_channels
.get(), &key
, &iter
);
822 node
= lttng_ht_iter_get_node_u64(&iter
);
826 chan
= caa_container_of(node
, struct ust_registry_channel
, node
);
833 * Remove channel using key from registry and free memory.
835 void ust_registry_channel_del_free(ust_registry_session
*session
,
836 uint64_t key
, bool notif
)
838 struct lttng_ht_iter iter
;
839 struct ust_registry_channel
*chan
;
842 LTTNG_ASSERT(session
);
845 chan
= ust_registry_channel_find(session
, key
);
851 iter
.iter
.node
= &chan
->node
.node
;
852 ret
= lttng_ht_del(session
->_channels
.get(), &iter
);
855 ust_registry_channel_destroy(chan
, notif
);
861 ust_registry_session
*ust_registry_session_per_uid_create(uint32_t bits_per_long
,
862 uint32_t uint8_t_alignment
,
863 uint32_t uint16_t_alignment
,
864 uint32_t uint32_t_alignment
,
865 uint32_t uint64_t_alignment
,
866 uint32_t long_alignment
,
870 const char *root_shm_path
,
871 const char *shm_path
,
878 return new ust_registry_session_per_uid(bits_per_long
, uint8_t_alignment
,
879 uint16_t_alignment
, uint32_t_alignment
, uint64_t_alignment
,
880 long_alignment
, byte_order
, major
, minor
, root_shm_path
, shm_path
,
881 euid
, egid
, tracing_id
, tracing_uid
);
882 } catch (const std::exception
&ex
) {
883 ERR("Failed to create per-uid registry session: %s", ex
.what());
888 ust_registry_session
*ust_registry_session_per_pid_create(struct ust_app
*app
,
889 uint32_t bits_per_long
,
890 uint32_t uint8_t_alignment
,
891 uint32_t uint16_t_alignment
,
892 uint32_t uint32_t_alignment
,
893 uint32_t uint64_t_alignment
,
894 uint32_t long_alignment
,
898 const char *root_shm_path
,
899 const char *shm_path
,
905 return new ust_registry_session_per_pid(*app
, bits_per_long
, uint8_t_alignment
,
906 uint16_t_alignment
, uint32_t_alignment
, uint64_t_alignment
,
907 long_alignment
, byte_order
, major
, minor
, root_shm_path
, shm_path
,
908 euid
, egid
, tracing_id
);
909 } catch (const std::exception
&ex
) {
910 ERR("Failed to create per-pid registry session: %s", ex
.what());
916 * Destroy session registry. This does NOT free the given pointer since it
917 * might get passed as a reference. The registry lock should NOT be acquired.
919 void ust_registry_session_destroy(ust_registry_session
*reg
)