- /* Setup key for the match function. */
- strncpy(key.name, name, sizeof(key.name));
- key.name[sizeof(key.name) - 1] = '\0';
- key.signature = sig;
-
- cds_lfht_lookup(chan->ht->ht, chan->ht->hash_fct(&key, lttng_ht_seed),
- chan->ht->match_fct, &key, &iter.iter);
- node = lttng_ht_iter_get_node_u64(&iter);
- if (!node) {
- goto end;
- }
- event = caa_container_of(node, struct ust_registry_event, node);
-
-end:
- return event;
-}
-
-/*
- * Create a ust_registry_event from the given parameters and add it to the
- * registry hash table. If event_id is valid, it is set with the newly created
- * event id.
- *
- * On success, return 0 else a negative value. The created event MUST be unique
- * so on duplicate entry -EINVAL is returned. On error, event_id is untouched.
- *
- * Should be called with session registry mutex held.
- */
-int ust_registry_create_event(struct ust_registry_session *session,
- uint64_t chan_key, int session_objd, int channel_objd, char *name,
- char *sig, size_t nr_fields, struct lttng_ust_ctl_field *fields,
- int loglevel_value, char *model_emf_uri, int buffer_type,
- uint32_t *event_id_p, struct ust_app *app)
-{
- int ret;
- uint32_t event_id;
- struct cds_lfht_node *nptr;
- struct ust_registry_event *event = NULL;
- struct ust_registry_channel *chan;
-
- LTTNG_ASSERT(session);
- LTTNG_ASSERT(name);
- LTTNG_ASSERT(sig);
- LTTNG_ASSERT(event_id_p);
-
- 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 || channel_objd < 0) {
- ret = -EINVAL;
- goto error_free;
- }
-
- chan = ust_registry_channel_find(session, chan_key);
- if (!chan) {
- ret = -EINVAL;
- goto error_free;
- }
-
- /* Check if we've reached the maximum possible id. */
- if (ust_registry_is_max_id(chan->used_event_id)) {
- ret = -ENOENT;
- goto error_free;
- }
-
- event = alloc_event(session_objd, channel_objd, name, sig, nr_fields,
- fields, loglevel_value, model_emf_uri, app);
- if (!event) {
- ret = -ENOMEM;
- goto error_free;
- }
-
- DBG3("UST registry creating event with event: %s, sig: %s, id: %u, "
- "chan_objd: %u, sess_objd: %u, chan_id: %u", event->name,
- event->signature, event->id, event->channel_objd,
- event->session_objd, chan->chan_id);
-
- /*
- * This is an add unique with a custom match function for event. The node
- * are matched using the event name and signature.
- */
- nptr = cds_lfht_add_unique(chan->ht->ht, chan->ht->hash_fct(event,
- lttng_ht_seed), chan->ht->match_fct, event, &event->node.node);
- if (nptr != &event->node.node) {
- if (buffer_type == LTTNG_BUFFER_PER_UID) {
- /*
- * This is normal, we just have to send the event id of the
- * returned node and make sure we destroy the previously allocated
- * event object.
- */
- destroy_event(event);
- event = caa_container_of(nptr, struct ust_registry_event,
- node.node);
- LTTNG_ASSERT(event);
- event_id = event->id;
- } else {
- ERR("UST registry create event add unique failed for event: %s, "
- "sig: %s, id: %u, chan_objd: %u, sess_objd: %u",
- event->name, event->signature, event->id,
- event->channel_objd, event->session_objd);
- ret = -EINVAL;
- goto error_unlock;
- }
- } else {
- /* Request next event id if the node was successfully added. */
- event_id = event->id = ust_registry_get_next_event_id(chan);
- }
-
- *event_id_p = event_id;
-
- if (!event->metadata_dumped) {
- /* Append to metadata */
- ret = ust_metadata_event_statedump(session, chan, event);
- if (ret) {
- ERR("Error appending event metadata (errno = %d)", ret);
- rcu_read_unlock();
- return ret;
- }
- }
-
- rcu_read_unlock();
- return 0;
-
-error_free:
- free(sig);
- free(fields);
- free(model_emf_uri);
-error_unlock:
- rcu_read_unlock();
- destroy_event(event);
- return ret;