-/*
- * Return wildcard for a given event name if the event name match the
- * one of the wildcards.
- * Must be called with ust lock held.
- * Returns NULL if not present.
- */
-static
-struct wildcard_entry *match_wildcard(const struct lttng_event_desc *desc)
-{
- struct wildcard_entry *e;
-
- cds_list_for_each_entry(e, &wildcard_list, list) {
- /* If only contain '*' */
- if (strlen(e->name) == 1)
- goto possible_match;
- /* Compare excluding final '*' */
- if (!strncmp(desc->name, e->name, strlen(e->name) - 1))
- goto possible_match;
- continue; /* goto next, no match */
- possible_match:
- if (lttng_loglevel_match(desc,
- e->loglevel_type,
- e->loglevel)) {
- return e;
- }
- /* no match, loop to next */
- }
- return NULL;
-}
-
-/*
- * called at event creation if probe is missing.
- * called with session mutex held.
- */
-static
-int add_pending_probe(struct lttng_event *event, const char *name,
- enum lttng_ust_loglevel_type loglevel_type,
- int loglevel)
-{
- struct cds_hlist_head *head;
- struct ust_pending_probe *e;
- size_t name_len = strlen(name) + 1;
- uint32_t hash;
-
- if (name_len > LTTNG_UST_SYM_NAME_LEN) {
- WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN);
- name_len = LTTNG_UST_SYM_NAME_LEN;
- }
- hash = jhash(name, name_len - 1, 0);
- head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)];
- e = zmalloc(sizeof(struct ust_pending_probe) + name_len);
- if (!e)
- return -ENOMEM;
- memcpy(&e->name[0], name, name_len);
- e->name[name_len - 1] = '\0';
- e->loglevel_type = loglevel_type;
- e->loglevel = loglevel;
- cds_hlist_add_head(&e->node, head);
- e->event = event;
- event->pending_probe = e;
- return 0;
-}
-
-/*
- * remove a pending probe. called when at event teardown and when an
- * event is fixed (probe is loaded).
- * called with session mutex held.
- */
-static
-void remove_pending_probe(struct ust_pending_probe *e)
-{
- if (!e)
- return;
- cds_hlist_del(&e->node);
- free(e);
-}
-
-/*
- * Called at library load: connect the probe on the events pending on
- * probe load.
- * called with session mutex held.
- */
-int pending_probe_fix_events(const struct lttng_event_desc *desc)
-{
- struct cds_hlist_head *head;
- struct cds_hlist_node *node, *p;
- struct ust_pending_probe *e;
- const char *name = desc->name;
- int ret = 0;
- struct lttng_ust_event event_param;
- size_t name_len = strlen(name) + 1;
- uint32_t hash;
-
- /* Wildcard */
- {
- struct wildcard_entry *wildcard;
-
- //FIXME: should iterate on all match for filter.
- //FIXME: should re-use pending event if present rather
- //than create duplicate.
- wildcard = match_wildcard(desc);
- if (strcmp(desc->name, "lttng_ust:metadata") && wildcard) {
- struct session_wildcard *sw;
-
- cds_list_for_each_entry(sw, &wildcard->session_list,
- session_list) {
- struct lttng_event *ev;
- int ret;
-
- memcpy(&event_param, &sw->event_param,
- sizeof(event_param));
- strncpy(event_param.name,
- desc->name,
- sizeof(event_param.name));
- event_param.name[sizeof(event_param.name) - 1] = '\0';
- /* create event */
- ret = lttng_event_create(sw->chan,
- &event_param, &ev);
- if (ret) {
- DBG("Error creating event");
- continue;
- }
- cds_list_add(&ev->wildcard_list,
- &sw->events);
- lttng_filter_event_link_wildcard_bytecode(ev,
- sw);
- }
- }
- }
-
- if (name_len > LTTNG_UST_SYM_NAME_LEN) {
- WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN);
- name_len = LTTNG_UST_SYM_NAME_LEN;
- }
- hash = jhash(name, name_len - 1, 0);
- head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)];
- cds_hlist_for_each_entry_safe(e, node, p, head, node) {
- struct lttng_event *event;
- struct lttng_channel *chan;
-
- if (!lttng_loglevel_match(desc,
- e->loglevel_type,
- e->loglevel)) {
- continue;
- }
- if (strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) {
- continue;
- }
- /* TODO: wildcard same as pending event: duplicate */
- /* TODO: Should apply filter though */
- event = e->event;
- chan = event->chan;
- assert(!event->desc);
- event->desc = desc;
- event->pending_probe = NULL;
- remove_pending_probe(e);
- ret |= __tracepoint_probe_register(name,
- event->desc->probe_callback,
- event, event->desc->signature);
- if (ret)
- continue;
- event->id = chan->free_event_id++;
- ret |= _lttng_event_metadata_statedump(chan->session, chan,
- event);
- lttng_filter_event_link_bytecode(event);
- }
- return ret;
-}
-