2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
11 #include <common/common.h>
12 #include <common/hashtable/utils.h>
13 #include <lttng/lttng.h>
15 #include "ust-registry.h"
17 #include "ust-field-utils.h"
19 #include "lttng-sessiond.h"
20 #include "notification-thread-commands.h"
23 * Hash table match function for event in the registry.
25 static int ht_match_event(struct cds_lfht_node
*node
, const void *_key
)
27 const struct ust_registry_event
*key
;
28 struct ust_registry_event
*event
;
33 event
= caa_container_of(node
, struct ust_registry_event
, node
.node
);
35 key
= (ust_registry_event
*) _key
;
37 /* It has to be a perfect match. First, compare the event names. */
38 if (strncmp(event
->name
, key
->name
, sizeof(event
->name
))) {
42 /* Compare log levels. */
43 if (event
->loglevel_value
!= key
->loglevel_value
) {
47 /* Compare the arrays of fields. */
48 if (!match_lttng_ust_ctl_field_array(event
->fields
, event
->nr_fields
,
49 key
->fields
, key
->nr_fields
)) {
53 /* Compare model URI. */
54 if (event
->model_emf_uri
!= NULL
&& key
->model_emf_uri
== NULL
) {
56 } else if(event
->model_emf_uri
== NULL
&& key
->model_emf_uri
!= NULL
) {
58 } else if (event
->model_emf_uri
!= NULL
&& key
->model_emf_uri
!= NULL
) {
59 if (strcmp(event
->model_emf_uri
, key
->model_emf_uri
)) {
71 static unsigned long ht_hash_event(const void *_key
, unsigned long seed
)
74 const struct ust_registry_event
*key
= (ust_registry_event
*) _key
;
78 hashed_key
= (uint64_t) hash_key_str(key
->name
, seed
);
80 return hash_key_u64(&hashed_key
, seed
);
83 static int compare_enums(const struct ust_registry_enum
*reg_enum_a
,
84 const struct ust_registry_enum
*reg_enum_b
)
89 LTTNG_ASSERT(strcmp(reg_enum_a
->name
, reg_enum_b
->name
) == 0);
90 if (reg_enum_a
->nr_entries
!= reg_enum_b
->nr_entries
) {
94 for (i
= 0; i
< reg_enum_a
->nr_entries
; i
++) {
95 const struct lttng_ust_ctl_enum_entry
*entries_a
, *entries_b
;
97 entries_a
= ®_enum_a
->entries
[i
];
98 entries_b
= ®_enum_b
->entries
[i
];
99 if (entries_a
->start
.value
!= entries_b
->start
.value
) {
103 if (entries_a
->end
.value
!= entries_b
->end
.value
) {
107 if (entries_a
->start
.signedness
!= entries_b
->start
.signedness
) {
111 if (entries_a
->end
.signedness
!= entries_b
->end
.signedness
) {
116 if (strcmp(entries_a
->string
, entries_b
->string
)) {
126 * Hash table match function for enumerations in the session. Match is
127 * performed on enumeration name, and confirmed by comparing the enum
130 static int ht_match_enum(struct cds_lfht_node
*node
, const void *_key
)
132 struct ust_registry_enum
*_enum
;
133 const struct ust_registry_enum
*key
;
138 _enum
= caa_container_of(node
, struct ust_registry_enum
,
141 key
= (ust_registry_enum
*) _key
;
143 if (strncmp(_enum
->name
, key
->name
, LTTNG_UST_ABI_SYM_NAME_LEN
)) {
146 if (compare_enums(_enum
, key
)) {
158 * Hash table match function for enumerations in the session. Match is
159 * performed by enumeration ID.
161 static int ht_match_enum_id(struct cds_lfht_node
*node
, const void *_key
)
163 struct ust_registry_enum
*_enum
;
164 const struct ust_registry_enum
*key
= (ust_registry_enum
*) _key
;
169 _enum
= caa_container_of(node
, struct ust_registry_enum
, node
.node
);
172 if (_enum
->id
!= key
->id
) {
184 * Hash table hash function for enumerations in the session. The
185 * enumeration name is used for hashing.
187 static unsigned long ht_hash_enum(void *_key
, unsigned long seed
)
189 struct ust_registry_enum
*key
= (ust_registry_enum
*) _key
;
192 return hash_key_str(key
->name
, seed
);
196 * Return negative value on error, 0 if OK.
198 * TODO: we could add stricter verification of more types to catch
199 * errors in liblttng-ust implementation earlier than consumption by the
203 int validate_event_field(struct lttng_ust_ctl_field
*field
,
204 const char *event_name
,
209 switch(field
->type
.atype
) {
210 case lttng_ust_ctl_atype_integer
:
211 case lttng_ust_ctl_atype_enum
:
212 case lttng_ust_ctl_atype_array
:
213 case lttng_ust_ctl_atype_sequence
:
214 case lttng_ust_ctl_atype_string
:
215 case lttng_ust_ctl_atype_variant
:
216 case lttng_ust_ctl_atype_array_nestable
:
217 case lttng_ust_ctl_atype_sequence_nestable
:
218 case lttng_ust_ctl_atype_enum_nestable
:
219 case lttng_ust_ctl_atype_variant_nestable
:
221 case lttng_ust_ctl_atype_struct
:
222 if (field
->type
.u
.legacy
._struct
.nr_fields
!= 0) {
223 WARN("Unsupported non-empty struct field.");
228 case lttng_ust_ctl_atype_struct_nestable
:
229 if (field
->type
.u
.struct_nestable
.nr_fields
!= 0) {
230 WARN("Unsupported non-empty struct field.");
236 case lttng_ust_ctl_atype_float
:
237 switch (field
->type
.u
._float
.mant_dig
) {
239 WARN("UST application '%s' (pid: %d) has unknown float mantissa '%u' "
240 "in field '%s', rejecting event '%s'",
242 field
->type
.u
._float
.mant_dig
,
261 int validate_event_fields(size_t nr_fields
, struct lttng_ust_ctl_field
*fields
,
262 const char *event_name
, struct ust_app
*app
)
266 for (i
= 0; i
< nr_fields
; i
++) {
267 if (validate_event_field(&fields
[i
], event_name
, app
) < 0)
274 * Allocate event and initialize it. This does NOT set a valid event id from a
277 static struct ust_registry_event
*alloc_event(int session_objd
,
278 int channel_objd
, char *name
, char *sig
, size_t nr_fields
,
279 struct lttng_ust_ctl_field
*fields
, int loglevel_value
,
280 char *model_emf_uri
, struct ust_app
*app
)
282 struct ust_registry_event
*event
= NULL
;
285 * Ensure that the field content is valid.
287 if (validate_event_fields(nr_fields
, fields
, name
, app
) < 0) {
291 event
= (ust_registry_event
*) zmalloc(sizeof(*event
));
293 PERROR("zmalloc ust registry event");
297 event
->session_objd
= session_objd
;
298 event
->channel_objd
= channel_objd
;
299 /* Allocated by ustctl. */
300 event
->signature
= sig
;
301 event
->nr_fields
= nr_fields
;
302 event
->fields
= fields
;
303 event
->loglevel_value
= loglevel_value
;
304 event
->model_emf_uri
= model_emf_uri
;
306 /* Copy event name and force NULL byte. */
307 strncpy(event
->name
, name
, sizeof(event
->name
));
308 event
->name
[sizeof(event
->name
) - 1] = '\0';
310 cds_lfht_node_init(&event
->node
.node
);
317 * Free event data structure. This does NOT delete it from any hash table. It's
318 * safe to pass a NULL pointer. This should be called inside a call RCU if the
319 * event is previously deleted from a rcu hash table.
321 static void destroy_event(struct ust_registry_event
*event
)
328 free(event
->model_emf_uri
);
329 free(event
->signature
);
334 * Destroy event function call of the call RCU.
336 static void destroy_event_rcu(struct rcu_head
*head
)
338 struct lttng_ht_node_u64
*node
=
339 caa_container_of(head
, struct lttng_ht_node_u64
, head
);
340 struct ust_registry_event
*event
=
341 caa_container_of(node
, struct ust_registry_event
, node
);
343 destroy_event(event
);
347 * Find an event using the name and signature in the given registry. RCU read
348 * side lock MUST be acquired before calling this function and as long as the
349 * event reference is kept by the caller.
351 * On success, the event pointer is returned else NULL.
353 struct ust_registry_event
*ust_registry_find_event(
354 struct ust_registry_channel
*chan
, char *name
, char *sig
)
356 struct lttng_ht_node_u64
*node
;
357 struct lttng_ht_iter iter
;
358 struct ust_registry_event
*event
= NULL
;
359 struct ust_registry_event key
;
364 ASSERT_RCU_READ_LOCKED();
366 /* Setup key for the match function. */
367 strncpy(key
.name
, name
, sizeof(key
.name
));
368 key
.name
[sizeof(key
.name
) - 1] = '\0';
371 cds_lfht_lookup(chan
->ht
->ht
, chan
->ht
->hash_fct(&key
, lttng_ht_seed
),
372 chan
->ht
->match_fct
, &key
, &iter
.iter
);
373 node
= lttng_ht_iter_get_node_u64(&iter
);
377 event
= caa_container_of(node
, struct ust_registry_event
, node
);
384 * Create a ust_registry_event from the given parameters and add it to the
385 * registry hash table. If event_id is valid, it is set with the newly created
388 * On success, return 0 else a negative value. The created event MUST be unique
389 * so on duplicate entry -EINVAL is returned. On error, event_id is untouched.
391 * Should be called with session registry mutex held.
393 int ust_registry_create_event(struct ust_registry_session
*session
,
394 uint64_t chan_key
, int session_objd
, int channel_objd
, char *name
,
395 char *sig
, size_t nr_fields
, struct lttng_ust_ctl_field
*fields
,
396 int loglevel_value
, char *model_emf_uri
, int buffer_type
,
397 uint32_t *event_id_p
, struct ust_app
*app
)
401 struct cds_lfht_node
*nptr
;
402 struct ust_registry_event
*event
= NULL
;
403 struct ust_registry_channel
*chan
;
405 LTTNG_ASSERT(session
);
408 LTTNG_ASSERT(event_id_p
);
413 * This should not happen but since it comes from the UST tracer, an
414 * external party, don't assert and simply validate values.
416 if (session_objd
< 0 || channel_objd
< 0) {
421 chan
= ust_registry_channel_find(session
, chan_key
);
427 /* Check if we've reached the maximum possible id. */
428 if (ust_registry_is_max_id(chan
->used_event_id
)) {
433 event
= alloc_event(session_objd
, channel_objd
, name
, sig
, nr_fields
,
434 fields
, loglevel_value
, model_emf_uri
, app
);
440 DBG3("UST registry creating event with event: %s, sig: %s, id: %u, "
441 "chan_objd: %u, sess_objd: %u, chan_id: %u", event
->name
,
442 event
->signature
, event
->id
, event
->channel_objd
,
443 event
->session_objd
, chan
->chan_id
);
446 * This is an add unique with a custom match function for event. The node
447 * are matched using the event name and signature.
449 nptr
= cds_lfht_add_unique(chan
->ht
->ht
, chan
->ht
->hash_fct(event
,
450 lttng_ht_seed
), chan
->ht
->match_fct
, event
, &event
->node
.node
);
451 if (nptr
!= &event
->node
.node
) {
452 if (buffer_type
== LTTNG_BUFFER_PER_UID
) {
454 * This is normal, we just have to send the event id of the
455 * returned node and make sure we destroy the previously allocated
458 destroy_event(event
);
459 event
= caa_container_of(nptr
, struct ust_registry_event
,
462 event_id
= event
->id
;
464 ERR("UST registry create event add unique failed for event: %s, "
465 "sig: %s, id: %u, chan_objd: %u, sess_objd: %u",
466 event
->name
, event
->signature
, event
->id
,
467 event
->channel_objd
, event
->session_objd
);
472 /* Request next event id if the node was successfully added. */
473 event_id
= event
->id
= ust_registry_get_next_event_id(chan
);
476 *event_id_p
= event_id
;
478 if (!event
->metadata_dumped
) {
479 /* Append to metadata */
480 ret
= ust_metadata_event_statedump(session
, chan
, event
);
482 ERR("Error appending event metadata (errno = %d)", ret
);
497 destroy_event(event
);
502 * For a given event in a registry, delete the entry and destroy the event.
503 * This MUST be called within a RCU read side lock section.
505 void ust_registry_destroy_event(struct ust_registry_channel
*chan
,
506 struct ust_registry_event
*event
)
509 struct lttng_ht_iter iter
;
513 ASSERT_RCU_READ_LOCKED();
515 /* Delete the node first. */
516 iter
.iter
.node
= &event
->node
.node
;
517 ret
= lttng_ht_del(chan
->ht
, &iter
);
520 call_rcu(&event
->node
.head
, destroy_event_rcu
);
525 static void destroy_enum(struct ust_registry_enum
*reg_enum
)
530 free(reg_enum
->entries
);
534 static void destroy_enum_rcu(struct rcu_head
*head
)
536 struct ust_registry_enum
*reg_enum
=
537 caa_container_of(head
, struct ust_registry_enum
, rcu_head
);
539 destroy_enum(reg_enum
);
543 * Lookup enumeration by name and comparing enumeration entries.
544 * Needs to be called from RCU read-side critical section.
546 static struct ust_registry_enum
*ust_registry_lookup_enum(
547 struct ust_registry_session
*session
,
548 const struct ust_registry_enum
*reg_enum_lookup
)
550 struct ust_registry_enum
*reg_enum
= NULL
;
551 struct lttng_ht_node_str
*node
;
552 struct lttng_ht_iter iter
;
554 ASSERT_RCU_READ_LOCKED();
556 cds_lfht_lookup(session
->enums
->ht
,
557 ht_hash_enum((void *) reg_enum_lookup
, lttng_ht_seed
),
558 ht_match_enum
, reg_enum_lookup
, &iter
.iter
);
559 node
= lttng_ht_iter_get_node_str(&iter
);
563 reg_enum
= caa_container_of(node
, struct ust_registry_enum
, node
);
569 * Lookup enumeration by enum ID.
570 * Needs to be called from RCU read-side critical section.
572 struct ust_registry_enum
*
573 ust_registry_lookup_enum_by_id(struct ust_registry_session
*session
,
574 const char *enum_name
, uint64_t enum_id
)
576 struct ust_registry_enum
*reg_enum
= NULL
;
577 struct lttng_ht_node_str
*node
;
578 struct lttng_ht_iter iter
;
579 struct ust_registry_enum reg_enum_lookup
;
581 ASSERT_RCU_READ_LOCKED();
583 memset(®_enum_lookup
, 0, sizeof(reg_enum_lookup
));
584 strncpy(reg_enum_lookup
.name
, enum_name
, LTTNG_UST_ABI_SYM_NAME_LEN
);
585 reg_enum_lookup
.name
[LTTNG_UST_ABI_SYM_NAME_LEN
- 1] = '\0';
586 reg_enum_lookup
.id
= enum_id
;
587 cds_lfht_lookup(session
->enums
->ht
,
588 ht_hash_enum((void *) ®_enum_lookup
, lttng_ht_seed
),
589 ht_match_enum_id
, ®_enum_lookup
, &iter
.iter
);
590 node
= lttng_ht_iter_get_node_str(&iter
);
594 reg_enum
= caa_container_of(node
, struct ust_registry_enum
, node
);
600 * Create a ust_registry_enum from the given parameters and add it to the
601 * registry hash table, or find it if already there.
603 * On success, return 0 else a negative value.
605 * Should be called with session registry mutex held.
607 * We receive ownership of entries.
609 int ust_registry_create_or_find_enum(struct ust_registry_session
*session
,
610 int session_objd
, char *enum_name
,
611 struct lttng_ust_ctl_enum_entry
*entries
, size_t nr_entries
,
615 struct cds_lfht_node
*nodep
;
616 struct ust_registry_enum
*reg_enum
= NULL
, *old_reg_enum
;
618 LTTNG_ASSERT(session
);
619 LTTNG_ASSERT(enum_name
);
624 * This should not happen but since it comes from the UST tracer, an
625 * external party, don't assert and simply validate values.
627 if (session_objd
< 0) {
632 /* Check if the enumeration was already dumped */
633 reg_enum
= (ust_registry_enum
*) zmalloc(sizeof(*reg_enum
));
635 PERROR("zmalloc ust registry enumeration");
639 strncpy(reg_enum
->name
, enum_name
, LTTNG_UST_ABI_SYM_NAME_LEN
);
640 reg_enum
->name
[LTTNG_UST_ABI_SYM_NAME_LEN
- 1] = '\0';
641 /* entries will be owned by reg_enum. */
642 reg_enum
->entries
= entries
;
643 reg_enum
->nr_entries
= nr_entries
;
646 old_reg_enum
= ust_registry_lookup_enum(session
, reg_enum
);
648 DBG("enum %s already in sess_objd: %u", enum_name
, session_objd
);
649 /* Fall through. Use prior enum. */
650 destroy_enum(reg_enum
);
651 reg_enum
= old_reg_enum
;
653 DBG("UST registry creating enum: %s, sess_objd: %u",
654 enum_name
, session_objd
);
655 if (session
->next_enum_id
== -1ULL) {
657 destroy_enum(reg_enum
);
660 reg_enum
->id
= session
->next_enum_id
++;
661 cds_lfht_node_init(®_enum
->node
.node
);
662 nodep
= cds_lfht_add_unique(session
->enums
->ht
,
663 ht_hash_enum(reg_enum
, lttng_ht_seed
),
664 ht_match_enum_id
, reg_enum
,
665 ®_enum
->node
.node
);
666 LTTNG_ASSERT(nodep
== ®_enum
->node
.node
);
668 DBG("UST registry reply with enum %s with id %" PRIu64
" in sess_objd: %u",
669 enum_name
, reg_enum
->id
, session_objd
);
670 *enum_id
= reg_enum
->id
;
678 * For a given enumeration in a registry, delete the entry and destroy
680 * This MUST be called within a RCU read side lock section.
682 static void ust_registry_destroy_enum(struct ust_registry_session
*reg_session
,
683 struct ust_registry_enum
*reg_enum
)
686 struct lttng_ht_iter iter
;
688 LTTNG_ASSERT(reg_session
);
689 LTTNG_ASSERT(reg_enum
);
690 ASSERT_RCU_READ_LOCKED();
692 /* Delete the node first. */
693 iter
.iter
.node
= ®_enum
->node
.node
;
694 ret
= lttng_ht_del(reg_session
->enums
, &iter
);
696 call_rcu(®_enum
->rcu_head
, destroy_enum_rcu
);
700 void destroy_channel_rcu(struct rcu_head
*head
)
702 struct ust_registry_channel
*chan
=
703 caa_container_of(head
, struct ust_registry_channel
, rcu_head
);
706 lttng_ht_destroy(chan
->ht
);
708 free(chan
->ctx_fields
);
713 * Destroy every element of the registry and free the memory. This does NOT
714 * free the registry pointer since it might not have been allocated before so
715 * it's the caller responsability.
717 static void destroy_channel(struct ust_registry_channel
*chan
, bool notif
)
719 struct lttng_ht_iter iter
;
720 struct ust_registry_event
*event
;
721 enum lttng_error_code cmd_ret
;
726 cmd_ret
= notification_thread_command_remove_channel(
727 the_notification_thread_handle
,
728 chan
->consumer_key
, LTTNG_DOMAIN_UST
);
729 if (cmd_ret
!= LTTNG_OK
) {
730 ERR("Failed to remove channel from notification thread");
736 /* Destroy all event associated with this registry. */
737 cds_lfht_for_each_entry(
738 chan
->ht
->ht
, &iter
.iter
, event
, node
.node
) {
739 /* Delete the node from the ht and free it. */
740 ust_registry_destroy_event(chan
, event
);
744 call_rcu(&chan
->rcu_head
, destroy_channel_rcu
);
748 * Initialize registry with default values.
750 int ust_registry_channel_add(struct ust_registry_session
*session
,
754 struct ust_registry_channel
*chan
;
756 LTTNG_ASSERT(session
);
758 chan
= (ust_registry_channel
*) zmalloc(sizeof(*chan
));
760 PERROR("zmalloc ust registry channel");
765 chan
->ht
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
771 /* Set custom match function. */
772 chan
->ht
->match_fct
= ht_match_event
;
773 chan
->ht
->hash_fct
= ht_hash_event
;
776 * Assign a channel ID right now since the event notification comes
777 * *before* the channel notify so the ID needs to be set at this point so
778 * the metadata can be dumped for that event.
780 if (ust_registry_is_max_id(session
->used_channel_id
)) {
784 chan
->chan_id
= ust_registry_get_next_chan_id(session
);
787 lttng_ht_node_init_u64(&chan
->node
, key
);
788 lttng_ht_add_unique_u64(session
->channels
, &chan
->node
);
794 destroy_channel(chan
, false);
800 * Find a channel in the given registry. RCU read side lock MUST be acquired
801 * before calling this function and as long as the event reference is kept by
804 * On success, the pointer is returned else NULL.
806 struct ust_registry_channel
*ust_registry_channel_find(
807 struct ust_registry_session
*session
, uint64_t key
)
809 struct lttng_ht_node_u64
*node
;
810 struct lttng_ht_iter iter
;
811 struct ust_registry_channel
*chan
= NULL
;
813 LTTNG_ASSERT(session
);
814 LTTNG_ASSERT(session
->channels
);
815 ASSERT_RCU_READ_LOCKED();
817 DBG3("UST registry channel finding key %" PRIu64
, key
);
819 lttng_ht_lookup(session
->channels
, &key
, &iter
);
820 node
= lttng_ht_iter_get_node_u64(&iter
);
824 chan
= caa_container_of(node
, struct ust_registry_channel
, node
);
831 * Remove channel using key from registry and free memory.
833 void ust_registry_channel_del_free(struct ust_registry_session
*session
,
834 uint64_t key
, bool notif
)
836 struct lttng_ht_iter iter
;
837 struct ust_registry_channel
*chan
;
840 LTTNG_ASSERT(session
);
843 chan
= ust_registry_channel_find(session
, key
);
849 iter
.iter
.node
= &chan
->node
.node
;
850 ret
= lttng_ht_del(session
->channels
, &iter
);
853 destroy_channel(chan
, notif
);
860 * Initialize registry with default values and set the newly allocated session
861 * pointer to sessionp.
863 * Return 0 on success and sessionp is set or else return -1 and sessionp is
866 int ust_registry_session_init(struct ust_registry_session
**sessionp
,
868 uint32_t bits_per_long
,
869 uint32_t uint8_t_alignment
,
870 uint32_t uint16_t_alignment
,
871 uint32_t uint32_t_alignment
,
872 uint32_t uint64_t_alignment
,
873 uint32_t long_alignment
,
877 const char *root_shm_path
,
878 const char *shm_path
,
885 struct ust_registry_session
*session
;
887 LTTNG_ASSERT(sessionp
);
889 session
= (ust_registry_session
*) zmalloc(sizeof(*session
));
891 PERROR("zmalloc ust registry session");
895 pthread_mutex_init(&session
->lock
, NULL
);
896 session
->bits_per_long
= bits_per_long
;
897 session
->uint8_t_alignment
= uint8_t_alignment
;
898 session
->uint16_t_alignment
= uint16_t_alignment
;
899 session
->uint32_t_alignment
= uint32_t_alignment
;
900 session
->uint64_t_alignment
= uint64_t_alignment
;
901 session
->long_alignment
= long_alignment
;
902 session
->byte_order
= byte_order
;
903 session
->metadata_fd
= -1;
906 session
->next_enum_id
= 0;
907 session
->major
= major
;
908 session
->minor
= minor
;
909 strncpy(session
->root_shm_path
, root_shm_path
,
910 sizeof(session
->root_shm_path
));
911 session
->root_shm_path
[sizeof(session
->root_shm_path
) - 1] = '\0';
913 strncpy(session
->shm_path
, shm_path
,
914 sizeof(session
->shm_path
));
915 session
->shm_path
[sizeof(session
->shm_path
) - 1] = '\0';
916 strncpy(session
->metadata_path
, shm_path
,
917 sizeof(session
->metadata_path
));
918 session
->metadata_path
[sizeof(session
->metadata_path
) - 1] = '\0';
919 strncat(session
->metadata_path
, "/metadata",
920 sizeof(session
->metadata_path
)
921 - strlen(session
->metadata_path
) - 1);
923 if (session
->shm_path
[0]) {
924 ret
= run_as_mkdir_recursive(session
->shm_path
,
928 PERROR("run_as_mkdir_recursive");
932 if (session
->metadata_path
[0]) {
933 /* Create metadata file */
934 ret
= run_as_open(session
->metadata_path
,
935 O_WRONLY
| O_CREAT
| O_EXCL
,
936 S_IRUSR
| S_IWUSR
, euid
, egid
);
938 PERROR("Opening metadata file");
941 session
->metadata_fd
= ret
;
944 session
->enums
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
945 if (!session
->enums
) {
946 ERR("Failed to create enums hash table");
949 /* hash/match functions are specified at call site. */
950 session
->enums
->match_fct
= NULL
;
951 session
->enums
->hash_fct
= NULL
;
953 session
->channels
= lttng_ht_new(0, LTTNG_HT_TYPE_U64
);
954 if (!session
->channels
) {
958 ret
= lttng_uuid_generate(session
->uuid
);
960 ERR("Failed to generate UST uuid (errno = %d)", ret
);
964 session
->tracing_id
= tracing_id
;
965 session
->tracing_uid
= tracing_uid
;
967 pthread_mutex_lock(&session
->lock
);
968 ret
= ust_metadata_session_statedump(session
, app
, major
, minor
);
969 pthread_mutex_unlock(&session
->lock
);
971 ERR("Failed to generate session metadata (errno = %d)", ret
);
980 ust_registry_session_destroy(session
);
987 * Destroy session registry. This does NOT free the given pointer since it
988 * might get passed as a reference. The registry lock should NOT be acquired.
990 void ust_registry_session_destroy(struct ust_registry_session
*reg
)
993 struct lttng_ht_iter iter
;
994 struct ust_registry_channel
*chan
;
995 struct ust_registry_enum
*reg_enum
;
1001 /* On error, EBUSY can be returned if lock. Code flow error. */
1002 ret
= pthread_mutex_destroy(®
->lock
);
1005 if (reg
->channels
) {
1007 /* Destroy all event associated with this registry. */
1008 cds_lfht_for_each_entry(reg
->channels
->ht
, &iter
.iter
, chan
,
1010 /* Delete the node from the ht and free it. */
1011 ret
= lttng_ht_del(reg
->channels
, &iter
);
1013 destroy_channel(chan
, true);
1016 lttng_ht_destroy(reg
->channels
);
1019 free(reg
->metadata
);
1020 if (reg
->metadata_fd
>= 0) {
1021 ret
= close(reg
->metadata_fd
);
1025 ret
= run_as_unlink(reg
->metadata_path
,
1026 reg
->uid
, reg
->gid
);
1031 if (reg
->root_shm_path
[0]) {
1033 * Try deleting the directory hierarchy.
1035 (void) run_as_rmdir_recursive(reg
->root_shm_path
,
1037 LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG
);
1039 /* Destroy the enum hash table */
1042 /* Destroy all enum entries associated with this registry. */
1043 cds_lfht_for_each_entry(reg
->enums
->ht
, &iter
.iter
, reg_enum
,
1045 ust_registry_destroy_enum(reg
, reg_enum
);
1048 lttng_ht_destroy(reg
->enums
);