X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-registry.cpp;h=323fdd6a757b82a0a6938adec9bb41cb1d520e25;hb=97f630d42cd12a475293af66e75a71ab7b490633;hp=ce76e403f3bb361882be569c7a60619f56ebbd4b;hpb=b0f2e8db59fcadc8f4b06a94175792be3c431004;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-registry.cpp b/src/bin/lttng-sessiond/ust-registry.cpp index ce76e403f..323fdd6a7 100644 --- a/src/bin/lttng-sessiond/ust-registry.cpp +++ b/src/bin/lttng-sessiond/ust-registry.cpp @@ -28,73 +28,6 @@ namespace ls = lttng::sessiond; namespace lst = lttng::sessiond::trace; namespace lsu = lttng::sessiond::ust; -/* - * Hash table match function for enumerations in the session. Match is - * performed on enumeration name, and confirmed by comparing the enum - * entries. - */ -static int ht_match_enum(struct cds_lfht_node *node, const void *_key) -{ - lsu::registry_enum *_enum; - const lsu::registry_enum *key; - - LTTNG_ASSERT(node); - LTTNG_ASSERT(_key); - - DIAGNOSTIC_PUSH - DIAGNOSTIC_IGNORE_INVALID_OFFSETOF - _enum = caa_container_of(node, lsu::registry_enum, - node.node); - DIAGNOSTIC_POP - - LTTNG_ASSERT(_enum); - key = (lsu::registry_enum *) _key; - - return *_enum == *key; -} - -/* - * Hash table match function for enumerations in the session. Match is - * performed by enumeration ID. - */ -static int ht_match_enum_id(struct cds_lfht_node *node, const void *_key) -{ - lsu::registry_enum *_enum; - const lsu::registry_enum *key = (lsu::registry_enum *) _key; - - LTTNG_ASSERT(node); - LTTNG_ASSERT(_key); - - DIAGNOSTIC_PUSH - DIAGNOSTIC_IGNORE_INVALID_OFFSETOF - _enum = caa_container_of(node, lsu::registry_enum, node.node); - DIAGNOSTIC_POP - - LTTNG_ASSERT(_enum); - - if (_enum->id != key->id) { - goto no_match; - } - - /* Match. */ - return 1; - -no_match: - return 0; -} - -/* - * Hash table hash function for enumerations in the session. The - * enumeration name is used for hashing. - */ -static unsigned long ht_hash_enum(void *_key, unsigned long seed) -{ - lsu::registry_enum *key = (lsu::registry_enum *) _key; - - LTTNG_ASSERT(key); - return hash_key_str(key->name.c_str(), seed); -} - /* * Destroy event function call of the call RCU. */ @@ -134,196 +67,6 @@ void ust_registry_channel_destroy_event(lsu::registry_channel *chan, return; } -static void destroy_enum(lsu::registry_enum *reg_enum) -{ - if (!reg_enum) { - return; - } - - delete reg_enum; -} - -static void destroy_enum_rcu(struct rcu_head *head) -{ - DIAGNOSTIC_PUSH - DIAGNOSTIC_IGNORE_INVALID_OFFSETOF - lsu::registry_enum *reg_enum = - caa_container_of(head, lsu::registry_enum, rcu_head); - DIAGNOSTIC_POP - - destroy_enum(reg_enum); -} - -/* - * Lookup enumeration by name and comparing enumeration entries. - * Needs to be called from RCU read-side critical section. - */ -static lsu::registry_enum *ust_registry_lookup_enum( - lsu::registry_session *session, - const lsu::registry_enum *reg_enum_lookup) -{ - lsu::registry_enum *reg_enum = NULL; - struct lttng_ht_node_str *node; - struct lttng_ht_iter iter; - - ASSERT_RCU_READ_LOCKED(); - - cds_lfht_lookup(session->_enums->ht, - ht_hash_enum((void *) reg_enum_lookup, lttng_ht_seed), - ht_match_enum, reg_enum_lookup, &iter.iter); - node = lttng_ht_iter_get_node_str(&iter); - if (!node) { - goto end; - } - - DIAGNOSTIC_PUSH - DIAGNOSTIC_IGNORE_INVALID_OFFSETOF - reg_enum = caa_container_of(node, lsu::registry_enum, node); - DIAGNOSTIC_POP - -end: - return reg_enum; -} - -/* - * Lookup enumeration by enum ID. - */ -lsu::registry_enum::const_rcu_protected_reference -ust_registry_lookup_enum_by_id(const lsu::registry_session *session, - const char *enum_name, uint64_t enum_id) -{ - lsu::registry_enum *reg_enum = NULL; - struct lttng_ht_node_str *node; - struct lttng_ht_iter iter; - lttng::urcu::unique_read_lock rcu_lock; - /* - * Hack: only the name is used for hashing; the rest of the attributes - * can be fudged. - */ - lsu::registry_signed_enum reg_enum_lookup(enum_name, nullptr, 0); - - ASSERT_RCU_READ_LOCKED(); - - reg_enum_lookup.id = enum_id; - cds_lfht_lookup(session->_enums->ht, - ht_hash_enum((void *) ®_enum_lookup, lttng_ht_seed), - ht_match_enum_id, ®_enum_lookup, &iter.iter); - node = lttng_ht_iter_get_node_str(&iter); - if (!node) { - LTTNG_THROW_PROTOCOL_ERROR(fmt::format( - "Unknown enumeration referenced by application event field: enum name = `{}`, enum id = {}", - enum_name, enum_id)); - } - - DIAGNOSTIC_PUSH - DIAGNOSTIC_IGNORE_INVALID_OFFSETOF - reg_enum = caa_container_of(node, lsu::registry_enum, node); - DIAGNOSTIC_POP - - return lsu::registry_enum::const_rcu_protected_reference{*reg_enum, std::move(rcu_lock)}; -} - -/* - * Create a lsu::registry_enum from the given parameters and add it to the - * registry hash table, or find it if already there. - * - * On success, return 0 else a negative value. - * - * Should be called with session registry mutex held. - * - * We receive ownership of entries. - */ -int ust_registry_create_or_find_enum(lsu::registry_session *session, - int session_objd, char *enum_name, - struct lttng_ust_ctl_enum_entry *raw_entries, size_t nr_entries, - uint64_t *enum_id) -{ - int ret = 0; - struct cds_lfht_node *nodep; - lsu::registry_enum *reg_enum = NULL, *old_reg_enum; - auto entries = lttng::make_unique_wrapper(raw_entries); - - LTTNG_ASSERT(session); - LTTNG_ASSERT(enum_name); - - rcu_read_lock(); - - /* - * This should not happen but since it comes from the UST tracer, an - * external party, don't assert and simply validate values. - */ - if (session_objd < 0 || nr_entries == 0 || - lttng_strnlen(enum_name, LTTNG_UST_ABI_SYM_NAME_LEN) == - LTTNG_UST_ABI_SYM_NAME_LEN) { - ret = -EINVAL; - goto end; - } - - try { - if (entries->start.signedness) { - reg_enum = new lsu::registry_signed_enum( - enum_name, entries.get(), nr_entries); - } else { - reg_enum = new lsu::registry_unsigned_enum( - enum_name, entries.get(), nr_entries); - } - } catch (const std::exception& ex) { - ERR("Failed to create ust registry enumeration: %s", ex.what()); - ret = -ENOMEM; - goto end; - } - - old_reg_enum = ust_registry_lookup_enum(session, reg_enum); - if (old_reg_enum) { - DBG("enum %s already in sess_objd: %u", enum_name, session_objd); - /* Fall through. Use prior enum. */ - destroy_enum(reg_enum); - reg_enum = old_reg_enum; - } else { - DBG("UST registry creating enum: %s, sess_objd: %u", - enum_name, session_objd); - if (session->_next_enum_id == -1ULL) { - ret = -EOVERFLOW; - destroy_enum(reg_enum); - goto end; - } - reg_enum->id = session->_next_enum_id++; - nodep = cds_lfht_add_unique(session->_enums->ht, - ht_hash_enum(reg_enum, lttng_ht_seed), - ht_match_enum_id, reg_enum, - ®_enum->node.node); - LTTNG_ASSERT(nodep == ®_enum->node.node); - } - DBG("UST registry reply with enum %s with id %" PRIu64 " in sess_objd: %u", - enum_name, reg_enum->id, session_objd); - *enum_id = reg_enum->id; -end: - rcu_read_unlock(); - return ret; -} - -/* - * For a given enumeration in a registry, delete the entry and destroy - * the enumeration. - * This MUST be called within a RCU read side lock section. - */ -void ust_registry_destroy_enum(lsu::registry_session *reg_session, - lsu::registry_enum *reg_enum) -{ - int ret; - struct lttng_ht_iter iter; - - LTTNG_ASSERT(reg_session); - LTTNG_ASSERT(reg_enum); - ASSERT_RCU_READ_LOCKED(); - - /* Delete the node first. */ - iter.iter.node = ®_enum->node.node; - ret = lttng_ht_del(reg_session->_enums.get(), &iter); - LTTNG_ASSERT(!ret); - call_rcu(®_enum->rcu_head, destroy_enum_rcu); -} - lsu::registry_session *ust_registry_session_per_uid_create(const lttng::sessiond::trace::abi& abi, uint32_t major, uint32_t minor,