2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <common/common.h>
23 #include <common/hashtable/utils.h>
24 #include <lttng/lttng.h>
26 #include "ust-registry.h"
31 * Hash table match function for event in the registry.
33 static int ht_match_event(struct cds_lfht_node
*node
, const void *_key
)
35 struct ust_registry_event
*event
;
36 const struct ust_registry_event
*key
;
41 event
= caa_container_of(node
, struct ust_registry_event
, node
.node
);
45 /* It has to be a perfect match. */
46 if (strncmp(event
->name
, key
->name
, sizeof(event
->name
))) {
50 /* It has to be a perfect match. */
51 if (strncmp(event
->signature
, key
->signature
,
52 strlen(event
->signature
))) {
63 static unsigned long ht_hash_event(void *_key
, unsigned long seed
)
66 struct ust_registry_event
*key
= _key
;
70 xored_key
= (uint64_t) (hash_key_str(key
->name
, seed
) ^
71 hash_key_str(key
->signature
, seed
));
73 return hash_key_u64(&xored_key
, seed
);
76 static int compare_enums(const struct ust_registry_enum
*reg_enum_a
,
77 const struct ust_registry_enum
*reg_enum_b
)
82 assert(strcmp(reg_enum_a
->name
, reg_enum_b
->name
) == 0);
83 if (reg_enum_a
->nr_entries
!= reg_enum_b
->nr_entries
) {
87 for (i
= 0; i
< reg_enum_a
->nr_entries
; i
++) {
88 const struct ustctl_enum_entry
*entries_a
, *entries_b
;
90 entries_a
= ®_enum_a
->entries
[i
];
91 entries_b
= ®_enum_b
->entries
[i
];
92 if (entries_a
->start
!= entries_b
->start
) {
96 if (entries_a
->end
!= entries_b
->end
) {
100 if (strcmp(entries_a
->string
, entries_b
->string
)) {
110 * Hash table match function for enumerations in the session. Match is
111 * performed on enumeration name, and confirmed by comparing the enum
114 static int ht_match_enum(struct cds_lfht_node
*node
, const void *_key
)
116 struct ust_registry_enum
*_enum
;
117 const struct ust_registry_enum
*key
;
122 _enum
= caa_container_of(node
, struct ust_registry_enum
,
127 if (strncmp(_enum
->name
, key
->name
, LTTNG_UST_SYM_NAME_LEN
)) {
130 if (compare_enums(_enum
, key
)) {
142 * Hash table match function for enumerations in the session. Match is
143 * performed by enumeration ID.
145 static int ht_match_enum_id(struct cds_lfht_node
*node
, const void *_key
)
147 struct ust_registry_enum
*_enum
;
148 const struct ust_registry_enum
*key
= _key
;
153 _enum
= caa_container_of(node
, struct ust_registry_enum
, node
.node
);
156 if (_enum
->id
!= key
->id
) {
168 * Hash table hash function for enumerations in the session. The
169 * enumeration name is used for hashing.
171 static unsigned long ht_hash_enum(void *_key
, unsigned long seed
)
173 struct ust_registry_enum
*key
= _key
;
176 return hash_key_str(key
->name
, seed
);
180 * Return negative value on error, 0 if OK.
182 * TODO: we could add stricter verification of more types to catch
183 * errors in liblttng-ust implementation earlier than consumption by the
187 int validate_event_field(struct ustctl_field
*field
,
188 const char *event_name
,
191 switch(field
->type
.atype
) {
192 case ustctl_atype_integer
:
193 case ustctl_atype_enum
:
194 case ustctl_atype_array
:
195 case ustctl_atype_sequence
:
196 case ustctl_atype_string
:
199 case ustctl_atype_float
:
200 switch (field
->type
.u
.basic
._float
.mant_dig
) {
202 WARN("UST application '%s' (pid: %d) has unknown float mantissa '%u' "
203 "in field '%s', rejecting event '%s'",
205 field
->type
.u
.basic
._float
.mant_dig
,
221 int validate_event_fields(size_t nr_fields
, struct ustctl_field
*fields
,
222 const char *event_name
, struct ust_app
*app
)
226 for (i
= 0; i
< nr_fields
; i
++) {
227 if (validate_event_field(&fields
[i
], event_name
, app
) < 0)
234 * Allocate event and initialize it. This does NOT set a valid event id from a
237 static struct ust_registry_event
*alloc_event(int session_objd
,
238 int channel_objd
, char *name
, char *sig
, size_t nr_fields
,
239 struct ustctl_field
*fields
, int loglevel_value
,
240 char *model_emf_uri
, struct ust_app
*app
)
242 struct ust_registry_event
*event
= NULL
;
245 * Ensure that the field content is valid.
247 if (validate_event_fields(nr_fields
, fields
, name
, app
) < 0) {
251 event
= zmalloc(sizeof(*event
));
253 PERROR("zmalloc ust registry event");
257 event
->session_objd
= session_objd
;
258 event
->channel_objd
= channel_objd
;
259 /* Allocated by ustctl. */
260 event
->signature
= sig
;
261 event
->nr_fields
= nr_fields
;
262 event
->fields
= fields
;
263 event
->loglevel_value
= loglevel_value
;
264 event
->model_emf_uri
= model_emf_uri
;
266 /* Copy event name and force NULL byte. */
267 strncpy(event
->name
, name
, sizeof(event
->name
));
268 event
->name
[sizeof(event
->name
) - 1] = '\0';
270 cds_lfht_node_init(&event
->node
.node
);
277 * Free event data structure. This does NOT delete it from any hash table. It's
278 * safe to pass a NULL pointer. This shoudl be called inside a call RCU if the
279 * event is previously deleted from a rcu hash table.
281 static void destroy_event(struct ust_registry_event
*event
)
288 free(event
->model_emf_uri
);
289 free(event
->signature
);
294 * Destroy event function call of the call RCU.
296 static void destroy_event_rcu(struct rcu_head
*head
)
298 struct lttng_ht_node_u64
*node
=
299 caa_container_of(head
, struct lttng_ht_node_u64
, head
);
300 struct ust_registry_event
*event
=
301 caa_container_of(node
, struct ust_registry_event
, node
);
303 destroy_event(event
);
307 * Find an event using the name and signature in the given registry. RCU read
308 * side lock MUST be acquired before calling this function and as long as the
309 * event reference is kept by the caller.
311 * On success, the event pointer is returned else NULL.
313 struct ust_registry_event
*ust_registry_find_event(
314 struct ust_registry_channel
*chan
, char *name
, char *sig
)
316 struct lttng_ht_node_u64
*node
;
317 struct lttng_ht_iter iter
;
318 struct ust_registry_event
*event
= NULL
;
319 struct ust_registry_event key
;
325 /* Setup key for the match function. */
326 strncpy(key
.name
, name
, sizeof(key
.name
));
327 key
.name
[sizeof(key
.name
) - 1] = '\0';
330 cds_lfht_lookup(chan
->ht
->ht
, chan
->ht
->hash_fct(&key
, lttng_ht_seed
),
331 chan
->ht
->match_fct
, &key
, &iter
.iter
);
332 node
= lttng_ht_iter_get_node_u64(&iter
);
336 event
= caa_container_of(node
, struct ust_registry_event
, node
);
343 * Create a ust_registry_event from the given parameters and add it to the
344 * registry hash table. If event_id is valid, it is set with the newly created
347 * On success, return 0 else a negative value. The created event MUST be unique
348 * so on duplicate entry -EINVAL is returned. On error, event_id is untouched.
350 * Should be called with session registry mutex held.
352 int ust_registry_create_event(struct ust_registry_session
*session
,
353 uint64_t chan_key
, int session_objd
, int channel_objd
, char *name
,
354 char *sig
, size_t nr_fields
, struct ustctl_field
*fields
,
355 int loglevel_value
, char *model_emf_uri
, int buffer_type
,
356 uint32_t *event_id_p
, struct ust_app
*app
)
360 struct cds_lfht_node
*nptr
;
361 struct ust_registry_event
*event
= NULL
;
362 struct ust_registry_channel
*chan
;
372 * This should not happen but since it comes from the UST tracer, an
373 * external party, don't assert and simply validate values.
375 if (session_objd
< 0 || channel_objd
< 0) {
380 chan
= ust_registry_channel_find(session
, chan_key
);
386 /* Check if we've reached the maximum possible id. */
387 if (ust_registry_is_max_id(chan
->used_event_id
)) {
392 event
= alloc_event(session_objd
, channel_objd
, name
, sig
, nr_fields
,
393 fields
, loglevel_value
, model_emf_uri
, app
);
399 DBG3("UST registry creating event with event: %s, sig: %s, id: %u, "
400 "chan_objd: %u, sess_objd: %u, chan_id: %u", event
->name
,
401 event
->signature
, event
->id
, event
->channel_objd
,
402 event
->session_objd
, chan
->chan_id
);
405 * This is an add unique with a custom match function for event. The node
406 * are matched using the event name and signature.
408 nptr
= cds_lfht_add_unique(chan
->ht
->ht
, chan
->ht
->hash_fct(event
,
409 lttng_ht_seed
), chan
->ht
->match_fct
, event
, &event
->node
.node
);
410 if (nptr
!= &event
->node
.node
) {
411 if (buffer_type
== LTTNG_BUFFER_PER_UID
) {
413 * This is normal, we just have to send the event id of the
414 * returned node and make sure we destroy the previously allocated
417 destroy_event(event
);
418 event
= caa_container_of(nptr
, struct ust_registry_event
,
421 event_id
= event
->id
;
423 ERR("UST registry create event add unique failed for event: %s, "
424 "sig: %s, id: %u, chan_objd: %u, sess_objd: %u",
425 event
->name
, event
->signature
, event
->id
,
426 event
->channel_objd
, event
->session_objd
);
431 /* Request next event id if the node was successfully added. */
432 event_id
= event
->id
= ust_registry_get_next_event_id(chan
);
435 *event_id_p
= event_id
;
437 if (!event
->metadata_dumped
) {
438 /* Append to metadata */
439 ret
= ust_metadata_event_statedump(session
, chan
, event
);
441 ERR("Error appending event metadata (errno = %d)", ret
);
456 destroy_event(event
);
461 * For a given event in a registry, delete the entry and destroy the event.
462 * This MUST be called within a RCU read side lock section.
464 void ust_registry_destroy_event(struct ust_registry_channel
*chan
,
465 struct ust_registry_event
*event
)
468 struct lttng_ht_iter iter
;
473 /* Delete the node first. */
474 iter
.iter
.node
= &event
->node
.node
;
475 ret
= lttng_ht_del(chan
->ht
, &iter
);
478 call_rcu(&event
->node
.head
, destroy_event_rcu
);
483 static void destroy_enum(struct ust_registry_enum
*reg_enum
)
488 free(reg_enum
->entries
);
492 static void destroy_enum_rcu(struct rcu_head
*head
)
494 struct ust_registry_enum
*reg_enum
=
495 caa_container_of(head
, struct ust_registry_enum
, rcu_head
);
497 destroy_enum(reg_enum
);
501 * Lookup enumeration by name and comparing enumeration entries.
502 * Needs to be called from RCU read-side critical section.
504 struct ust_registry_enum
*
505 ust_registry_lookup_enum(struct ust_registry_session
*session
,
506 const struct ust_registry_enum
*reg_enum_lookup
)
508 struct ust_registry_enum
*reg_enum
= NULL
;
509 struct lttng_ht_node_str
*node
;
510 struct lttng_ht_iter iter
;
512 cds_lfht_lookup(session
->enums
->ht
,
513 ht_hash_enum((void *) ®_enum_lookup
, lttng_ht_seed
),
514 ht_match_enum
, ®_enum_lookup
, &iter
.iter
);
515 node
= lttng_ht_iter_get_node_str(&iter
);
519 reg_enum
= caa_container_of(node
, struct ust_registry_enum
, node
);
525 * Lookup enumeration by enum ID.
526 * Needs to be called from RCU read-side critical section.
528 struct ust_registry_enum
*
529 ust_registry_lookup_enum_by_id(struct ust_registry_session
*session
,
530 const char *enum_name
, uint64_t enum_id
)
532 struct ust_registry_enum
*reg_enum
= NULL
;
533 struct lttng_ht_node_str
*node
;
534 struct lttng_ht_iter iter
;
535 struct ust_registry_enum reg_enum_lookup
;
537 memset(®_enum_lookup
, 0, sizeof(reg_enum_lookup
));
538 strncpy(reg_enum_lookup
.name
, enum_name
, LTTNG_UST_SYM_NAME_LEN
);
539 reg_enum_lookup
.name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
540 reg_enum_lookup
.id
= enum_id
;
541 cds_lfht_lookup(session
->enums
->ht
,
542 ht_hash_enum((void *) ®_enum_lookup
, lttng_ht_seed
),
543 ht_match_enum_id
, ®_enum_lookup
, &iter
.iter
);
544 node
= lttng_ht_iter_get_node_str(&iter
);
548 reg_enum
= caa_container_of(node
, struct ust_registry_enum
, node
);
554 * Create a ust_registry_enum from the given parameters and add it to the
555 * registry hash table, or find it if already there.
557 * On success, return 0 else a negative value.
559 * Should be called with session registry mutex held.
561 * We receive ownership of entries.
563 int ust_registry_create_or_find_enum(struct ust_registry_session
*session
,
564 int session_objd
, char *enum_name
,
565 struct ustctl_enum_entry
*entries
, size_t nr_entries
,
569 struct cds_lfht_node
*nodep
;
570 struct ust_registry_enum
*reg_enum
= NULL
, *old_reg_enum
;
578 * This should not happen but since it comes from the UST tracer, an
579 * external party, don't assert and simply validate values.
581 if (session_objd
< 0) {
586 /* Check if the enumeration was already dumped */
587 reg_enum
= zmalloc(sizeof(*reg_enum
));
589 PERROR("zmalloc ust registry enumeration");
593 strncpy(reg_enum
->name
, enum_name
, LTTNG_UST_SYM_NAME_LEN
);
594 reg_enum
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
595 /* entries will be owned by reg_enum. */
596 reg_enum
->entries
= entries
;
597 reg_enum
->nr_entries
= nr_entries
;
600 old_reg_enum
= ust_registry_lookup_enum(session
, reg_enum
);
602 DBG("enum %s already in sess_objd: %u", enum_name
, session_objd
);
603 /* Fall through. Use prior enum. */
604 destroy_enum(reg_enum
);
605 reg_enum
= old_reg_enum
;
607 DBG("UST registry creating enum: %s, sess_objd: %u",
608 enum_name
, session_objd
);
609 if (session
->next_enum_id
== -1ULL) {
611 destroy_enum(reg_enum
);
614 reg_enum
->id
= session
->next_enum_id
++;
615 cds_lfht_node_init(®_enum
->node
.node
);
616 nodep
= cds_lfht_add_unique(session
->enums
->ht
,
617 ht_hash_enum(reg_enum
, lttng_ht_seed
),
618 ht_match_enum_id
, reg_enum
,
619 ®_enum
->node
.node
);
620 assert(nodep
== ®_enum
->node
.node
);
622 DBG("UST registry reply with enum %s with id %" PRIu64
" in sess_objd: %u",
623 enum_name
, reg_enum
->id
, session_objd
);
624 *enum_id
= reg_enum
->id
;
632 * For a given enumeration in a registry, delete the entry and destroy
634 * This MUST be called within a RCU read side lock section.
636 void ust_registry_destroy_enum(struct ust_registry_session
*reg_session
,
637 struct ust_registry_enum
*reg_enum
)
640 struct lttng_ht_iter iter
;
645 /* Delete the node first. */
646 iter
.iter
.node
= ®_enum
->node
.node
;
647 ret
= lttng_ht_del(reg_session
->enums
, &iter
);
649 call_rcu(®_enum
->rcu_head
, destroy_enum_rcu
);
653 * We need to execute ht_destroy outside of RCU read-side critical
654 * section and outside of call_rcu thread, so we postpone its execution
655 * using ht_cleanup_push. It is simpler than to change the semantic of
656 * the many callers of delete_ust_app_session().
659 void destroy_channel_rcu(struct rcu_head
*head
)
661 struct ust_registry_channel
*chan
=
662 caa_container_of(head
, struct ust_registry_channel
, rcu_head
);
665 ht_cleanup_push(chan
->ht
);
667 free(chan
->ctx_fields
);
672 * Destroy every element of the registry and free the memory. This does NOT
673 * free the registry pointer since it might not have been allocated before so
674 * it's the caller responsability.
676 static void destroy_channel(struct ust_registry_channel
*chan
)
678 struct lttng_ht_iter iter
;
679 struct ust_registry_event
*event
;
684 /* Destroy all event associated with this registry. */
685 cds_lfht_for_each_entry(chan
->ht
->ht
, &iter
.iter
, event
, node
.node
) {
686 /* Delete the node from the ht and free it. */
687 ust_registry_destroy_event(chan
, event
);
690 call_rcu(&chan
->rcu_head
, destroy_channel_rcu
);
694 * Initialize registry with default values.
696 int ust_registry_channel_add(struct ust_registry_session
*session
,
700 struct ust_registry_channel
*chan
;
704 chan
= zmalloc(sizeof(*chan
));
706 PERROR("zmalloc ust registry channel");
711 chan
->ht
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
717 /* Set custom match function. */
718 chan
->ht
->match_fct
= ht_match_event
;
719 chan
->ht
->hash_fct
= ht_hash_event
;
722 * Assign a channel ID right now since the event notification comes
723 * *before* the channel notify so the ID needs to be set at this point so
724 * the metadata can be dumped for that event.
726 if (ust_registry_is_max_id(session
->used_channel_id
)) {
730 chan
->chan_id
= ust_registry_get_next_chan_id(session
);
733 lttng_ht_node_init_u64(&chan
->node
, key
);
734 lttng_ht_add_unique_u64(session
->channels
, &chan
->node
);
740 destroy_channel(chan
);
746 * Find a channel in the given registry. RCU read side lock MUST be acquired
747 * before calling this function and as long as the event reference is kept by
750 * On success, the pointer is returned else NULL.
752 struct ust_registry_channel
*ust_registry_channel_find(
753 struct ust_registry_session
*session
, uint64_t key
)
755 struct lttng_ht_node_u64
*node
;
756 struct lttng_ht_iter iter
;
757 struct ust_registry_channel
*chan
= NULL
;
760 assert(session
->channels
);
762 DBG3("UST registry channel finding key %" PRIu64
, key
);
764 lttng_ht_lookup(session
->channels
, &key
, &iter
);
765 node
= lttng_ht_iter_get_node_u64(&iter
);
769 chan
= caa_container_of(node
, struct ust_registry_channel
, node
);
776 * Remove channel using key from registry and free memory.
778 void ust_registry_channel_del_free(struct ust_registry_session
*session
,
781 struct lttng_ht_iter iter
;
782 struct ust_registry_channel
*chan
;
788 chan
= ust_registry_channel_find(session
, key
);
794 iter
.iter
.node
= &chan
->node
.node
;
795 ret
= lttng_ht_del(session
->channels
, &iter
);
798 destroy_channel(chan
);
805 * Initialize registry with default values and set the newly allocated session
806 * pointer to sessionp.
808 * Return 0 on success and sessionp is set or else return -1 and sessionp is
811 int ust_registry_session_init(struct ust_registry_session
**sessionp
,
813 uint32_t bits_per_long
,
814 uint32_t uint8_t_alignment
,
815 uint32_t uint16_t_alignment
,
816 uint32_t uint32_t_alignment
,
817 uint32_t uint64_t_alignment
,
818 uint32_t long_alignment
,
822 const char *root_shm_path
,
823 const char *shm_path
,
828 struct ust_registry_session
*session
;
832 session
= zmalloc(sizeof(*session
));
834 PERROR("zmalloc ust registry session");
838 pthread_mutex_init(&session
->lock
, NULL
);
839 session
->bits_per_long
= bits_per_long
;
840 session
->uint8_t_alignment
= uint8_t_alignment
;
841 session
->uint16_t_alignment
= uint16_t_alignment
;
842 session
->uint32_t_alignment
= uint32_t_alignment
;
843 session
->uint64_t_alignment
= uint64_t_alignment
;
844 session
->long_alignment
= long_alignment
;
845 session
->byte_order
= byte_order
;
846 session
->metadata_fd
= -1;
849 session
->next_enum_id
= 0;
850 strncpy(session
->root_shm_path
, root_shm_path
,
851 sizeof(session
->root_shm_path
));
852 session
->root_shm_path
[sizeof(session
->root_shm_path
) - 1] = '\0';
854 strncpy(session
->shm_path
, shm_path
,
855 sizeof(session
->shm_path
));
856 session
->shm_path
[sizeof(session
->shm_path
) - 1] = '\0';
857 strncpy(session
->metadata_path
, shm_path
,
858 sizeof(session
->metadata_path
));
859 session
->metadata_path
[sizeof(session
->metadata_path
) - 1] = '\0';
860 strncat(session
->metadata_path
, "/metadata",
861 sizeof(session
->metadata_path
)
862 - strlen(session
->metadata_path
) - 1);
864 if (session
->shm_path
[0]) {
865 ret
= run_as_mkdir_recursive(session
->shm_path
,
869 PERROR("run_as_mkdir_recursive");
873 if (session
->metadata_path
[0]) {
874 /* Create metadata file */
875 ret
= run_as_open(session
->metadata_path
,
876 O_WRONLY
| O_CREAT
| O_EXCL
,
877 S_IRUSR
| S_IWUSR
, euid
, egid
);
879 PERROR("Opening metadata file");
882 session
->metadata_fd
= ret
;
885 session
->enums
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
886 if (!session
->enums
) {
890 /* hash/match functions are specified at call site. */
891 session
->enums
->match_fct
= NULL
;
892 session
->enums
->hash_fct
= NULL
;
894 session
->channels
= lttng_ht_new(0, LTTNG_HT_TYPE_U64
);
895 if (!session
->channels
) {
899 ret
= lttng_uuid_generate(session
->uuid
);
901 ERR("Failed to generate UST uuid (errno = %d)", ret
);
905 pthread_mutex_lock(&session
->lock
);
906 ret
= ust_metadata_session_statedump(session
, app
, major
, minor
);
907 pthread_mutex_unlock(&session
->lock
);
909 ERR("Failed to generate session metadata (errno = %d)", ret
);
918 ust_registry_session_destroy(session
);
925 * Destroy session registry. This does NOT free the given pointer since it
926 * might get passed as a reference. The registry lock should NOT be acquired.
928 void ust_registry_session_destroy(struct ust_registry_session
*reg
)
931 struct lttng_ht_iter iter
;
932 struct ust_registry_channel
*chan
;
933 struct ust_registry_enum
*reg_enum
;
939 /* On error, EBUSY can be returned if lock. Code flow error. */
940 ret
= pthread_mutex_destroy(®
->lock
);
945 /* Destroy all event associated with this registry. */
946 cds_lfht_for_each_entry(reg
->channels
->ht
, &iter
.iter
, chan
,
948 /* Delete the node from the ht and free it. */
949 ret
= lttng_ht_del(reg
->channels
, &iter
);
951 destroy_channel(chan
);
954 ht_cleanup_push(reg
->channels
);
958 if (reg
->metadata_fd
>= 0) {
959 ret
= close(reg
->metadata_fd
);
963 ret
= run_as_unlink(reg
->metadata_path
,
969 if (reg
->root_shm_path
[0]) {
971 * Try deleting the directory hierarchy.
973 (void) run_as_recursive_rmdir(reg
->root_shm_path
,
976 /* Destroy the enum hash table */
979 /* Destroy all enum entries associated with this registry. */
980 cds_lfht_for_each_entry(reg
->enums
->ht
, &iter
.iter
, reg_enum
,
982 ust_registry_destroy_enum(reg
, reg_enum
);
985 ht_cleanup_push(reg
->enums
);