+
+void ltt_probes_prune_event_list(struct lttng_ust_tracepoint_list *list)
+{
+ struct tp_list_entry *list_entry, *tmp;
+
+ cds_list_for_each_entry_safe(list_entry, tmp, &list->head, head) {
+ cds_list_del(&list_entry->head);
+ free(list_entry);
+ }
+}
+
+/*
+ * called with UST lock held.
+ */
+int ltt_probes_get_event_list(struct lttng_ust_tracepoint_list *list)
+{
+ struct lttng_probe_desc *probe_desc;
+ int i;
+
+ CDS_INIT_LIST_HEAD(&list->head);
+ cds_list_for_each_entry(probe_desc, &probe_list, head) {
+ for (i = 0; i < probe_desc->nr_events; i++) {
+ struct tp_list_entry *list_entry;
+
+ list_entry = zmalloc(sizeof(*list_entry));
+ if (!list_entry)
+ goto err_nomem;
+ cds_list_add(&list_entry->head, &list->head);
+ strncpy(list_entry->tp.name,
+ probe_desc->event_desc[i]->name,
+ LTTNG_UST_SYM_NAME_LEN);
+ list_entry->tp.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ if (!probe_desc->event_desc[i]->loglevel) {
+ list_entry->tp.loglevel = TRACE_DEFAULT;
+ } else {
+ list_entry->tp.loglevel = *(*probe_desc->event_desc[i]->loglevel);
+ }
+ }
+ }
+ if (cds_list_empty(&list->head))
+ list->iter = NULL;
+ else
+ list->iter =
+ cds_list_first_entry(&list->head, struct tp_list_entry, head);
+ return 0;
+
+err_nomem:
+ ltt_probes_prune_event_list(list);
+ return -ENOMEM;
+}
+
+/*
+ * Return current iteration position, advance internal iterator to next.
+ * Return NULL if end of list.
+ */
+struct lttng_ust_tracepoint_iter *
+ lttng_ust_tracepoint_list_get_iter_next(struct lttng_ust_tracepoint_list *list)
+{
+ struct tp_list_entry *entry;
+
+ if (!list->iter)
+ return NULL;
+ entry = list->iter;
+ if (entry->head.next == &list->head)
+ list->iter = NULL;
+ else
+ list->iter = cds_list_entry(entry->head.next,
+ struct tp_list_entry, head);
+ return &entry->tp;
+}
+
+/*
+ * marshall all probes/all events and create those that fit the
+ * wildcard. Add them to the events list as created.
+ */
+void ltt_probes_create_wildcard_events(struct wildcard_entry *entry,
+ struct session_wildcard *wildcard)
+{
+ struct lttng_probe_desc *probe_desc;
+ struct lttng_ust_event event_param;
+ int i;
+
+ cds_list_for_each_entry(probe_desc, &probe_list, head) {
+ for (i = 0; i < probe_desc->nr_events; i++) {
+ const struct lttng_event_desc *event_desc;
+ int match = 0;
+
+ event_desc = probe_desc->event_desc[i];
+ /* compare excluding final '*' */
+ assert(strlen(entry->name) > 0);
+ if (strcmp(event_desc->name, "lttng_ust:metadata")
+ && (strlen(entry->name) == 1
+ || !strncmp(event_desc->name, entry->name,
+ strlen(entry->name) - 1))) {
+ if (ltt_loglevel_match(event_desc,
+ entry->loglevel_type,
+ entry->loglevel)) {
+ match = 1;
+ }
+ }
+ if (match) {
+ struct ltt_event *ev;
+ int ret;
+
+ memcpy(&event_param, &wildcard->event_param,
+ sizeof(event_param));
+ memcpy(event_param.name,
+ event_desc->name,
+ sizeof(event_param.name));
+ /* create event */
+ ret = ltt_event_create(wildcard->chan,
+ &event_param, NULL,
+ &ev);
+ if (ret) {
+ DBG("Error creating event");
+ continue;
+ }
+ cds_list_add(&ev->wildcard_list,
+ &wildcard->events);
+ }
+ }
+ }
+}
+