+ assert(reg_chan);
+
+ /*
+ * Create the buffers on the consumer side. This call populates the
+ * ust app channel object with all streams and data object.
+ */
+ ret = do_consumer_create_channel(usess, ua_sess, ua_chan,
+ app->bits_per_long, reg_uid->registry->reg.ust);
+ if (ret < 0) {
+ /*
+ * Let's remove the previously created buffer registry channel so
+ * it's not visible anymore in the session registry.
+ */
+ ust_registry_channel_del_free(reg_uid->registry->reg.ust,
+ ua_chan->tracing_channel_id);
+ buffer_reg_channel_remove(reg_uid->registry, reg_chan);
+ buffer_reg_channel_destroy(reg_chan, LTTNG_DOMAIN_UST);
+ goto error;
+ }
+
+ /*
+ * Setup the streams and add it to the session registry.
+ */
+ ret = setup_buffer_reg_channel(reg_uid->registry, ua_chan, reg_chan);
+ if (ret < 0) {
+ goto error;
+ }
+
+ }
+
+ /* Send buffers to the application. */
+ ret = send_channel_uid_to_ust(reg_chan, app, ua_sess, ua_chan);
+ if (ret < 0) {
+ goto error;
+ }
+
+error:
+ return ret;
+}
+
+/*
+ * Create and send to the application the created buffers with per PID buffers.
+ *
+ * Return 0 on success else a negative value.
+ */
+static int create_channel_per_pid(struct ust_app *app,
+ struct ltt_ust_session *usess, struct ust_app_session *ua_sess,
+ struct ust_app_channel *ua_chan)
+{
+ int ret;
+ struct ust_registry_session *registry;
+
+ assert(app);
+ assert(usess);
+ assert(ua_sess);
+ assert(ua_chan);
+
+ DBG("UST app creating channel %s with per PID buffers", ua_chan->name);
+
+ rcu_read_lock();
+
+ registry = get_session_registry(ua_sess);
+ assert(registry);
+
+ /* Create and add a new channel registry to session. */
+ ret = ust_registry_channel_add(registry, ua_chan->key);
+ if (ret < 0) {
+ goto error;
+ }
+
+ /* Create and get channel on the consumer side. */
+ ret = do_consumer_create_channel(usess, ua_sess, ua_chan,
+ app->bits_per_long, registry);
+ if (ret < 0) {
+ goto error;
+ }
+
+ ret = send_channel_pid_to_ust(app, ua_sess, ua_chan);
+ if (ret < 0) {
+ goto error;
+ }
+
+error:
+ rcu_read_unlock();
+ return ret;
+}
+
+/*
+ * From an already allocated ust app channel, create the channel buffers if
+ * need and send it to the application. This MUST be called with a RCU read
+ * side lock acquired.
+ *
+ * Return 0 on success or else a negative value.
+ */
+static int do_create_channel(struct ust_app *app,
+ struct ltt_ust_session *usess, struct ust_app_session *ua_sess,
+ struct ust_app_channel *ua_chan)
+{
+ int ret;
+
+ assert(app);
+ assert(usess);
+ assert(ua_sess);
+ assert(ua_chan);
+
+ /* Handle buffer type before sending the channel to the application. */
+ switch (usess->buffer_type) {
+ case LTTNG_BUFFER_PER_UID:
+ {
+ ret = create_channel_per_uid(app, usess, ua_sess, ua_chan);
+ if (ret < 0) {
+ goto error;
+ }
+ break;
+ }
+ case LTTNG_BUFFER_PER_PID:
+ {
+ ret = create_channel_per_pid(app, usess, ua_sess, ua_chan);
+ if (ret < 0) {
+ goto error;
+ }
+ break;
+ }
+ default:
+ assert(0);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ /* Initialize ust objd object using the received handle and add it. */
+ lttng_ht_node_init_ulong(&ua_chan->ust_objd_node, ua_chan->handle);
+ lttng_ht_add_unique_ulong(app->ust_objd, &ua_chan->ust_objd_node);
+
+ /* If channel is not enabled, disable it on the tracer */
+ if (!ua_chan->enabled) {
+ ret = disable_ust_channel(app, ua_sess, ua_chan);
+ if (ret < 0) {
+ goto error;
+ }
+ }
+
+error:
+ return ret;
+}
+
+/*
+ * Create UST app channel and create it on the tracer. Set ua_chanp of the
+ * newly created channel if not NULL.
+ *
+ * Called with UST app session lock and RCU read-side lock held.
+ *
+ * Return 0 on success or else a negative value.
+ */
+static int create_ust_app_channel(struct ust_app_session *ua_sess,
+ struct ltt_ust_channel *uchan, struct ust_app *app,
+ enum lttng_ust_chan_type type, struct ltt_ust_session *usess,
+ struct ust_app_channel **ua_chanp)
+{
+ int ret = 0;
+ struct lttng_ht_iter iter;
+ struct lttng_ht_node_str *ua_chan_node;
+ struct ust_app_channel *ua_chan;
+
+ /* Lookup channel in the ust app session */
+ lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &iter);
+ ua_chan_node = lttng_ht_iter_get_node_str(&iter);
+ if (ua_chan_node != NULL) {
+ ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+ goto end;
+ }
+
+ ua_chan = alloc_ust_app_channel(uchan->name, ua_sess, &uchan->attr);
+ if (ua_chan == NULL) {
+ /* Only malloc can fail here */
+ ret = -ENOMEM;
+ goto error_alloc;
+ }
+ shadow_copy_channel(ua_chan, uchan);
+
+ /* Set channel type. */
+ ua_chan->attr.type = type;
+
+ ret = do_create_channel(app, usess, ua_sess, ua_chan);
+ if (ret < 0) {
+ goto error;
+ }
+
+ DBG2("UST app create channel %s for PID %d completed", ua_chan->name,
+ app->pid);
+
+ /* Only add the channel if successful on the tracer side. */
+ lttng_ht_add_unique_str(ua_sess->channels, &ua_chan->node);
+
+end:
+ if (ua_chanp) {
+ *ua_chanp = ua_chan;
+ }
+
+ /* Everything went well. */
+ return 0;
+
+error:
+ delete_ust_app_channel(ua_chan->is_sent ? app->sock : -1, ua_chan, app);
+error_alloc:
+ return ret;
+}
+
+/*
+ * Create UST app event and create it on the tracer side.
+ *
+ * Called with ust app session mutex held.
+ */
+static
+int create_ust_app_event(struct ust_app_session *ua_sess,
+ struct ust_app_channel *ua_chan, struct ltt_ust_event *uevent,
+ struct ust_app *app)
+{
+ int ret = 0;
+ struct ust_app_event *ua_event;
+
+ /* Get event node */
+ ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name,
+ uevent->filter, uevent->attr.loglevel);
+ if (ua_event != NULL) {
+ ret = -EEXIST;
+ goto end;
+ }
+
+ /* Does not exist so create one */
+ ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr);
+ if (ua_event == NULL) {
+ /* Only malloc can failed so something is really wrong */
+ ret = -ENOMEM;
+ goto end;
+ }
+ shadow_copy_event(ua_event, uevent);
+
+ /* Create it on the tracer side */
+ ret = create_ust_event(app, ua_sess, ua_chan, ua_event);
+ if (ret < 0) {
+ /* Not found previously means that it does not exist on the tracer */
+ assert(ret != -LTTNG_UST_ERR_EXIST);
+ goto error;
+ }
+
+ add_unique_ust_app_event(ua_chan, ua_event);
+
+ DBG2("UST app create event %s for PID %d completed", ua_event->name,
+ app->pid);
+
+end:
+ return ret;
+
+error:
+ /* Valid. Calling here is already in a read side lock */
+ delete_ust_app_event(-1, ua_event);
+ return ret;
+}
+
+/*
+ * Create UST metadata and open it on the tracer side.
+ *
+ * Called with UST app session lock held and RCU read side lock.
+ */
+static int create_ust_app_metadata(struct ust_app_session *ua_sess,
+ struct ust_app *app, struct consumer_output *consumer,
+ struct ustctl_consumer_channel_attr *attr)
+{
+ int ret = 0;
+ struct ust_app_channel *metadata;
+ struct consumer_socket *socket;
+ struct ust_registry_session *registry;
+
+ assert(ua_sess);
+ assert(app);
+ assert(consumer);
+
+ registry = get_session_registry(ua_sess);
+ assert(registry);
+
+ /* Metadata already exists for this registry or it was closed previously */
+ if (registry->metadata_key || registry->metadata_closed) {
+ ret = 0;
+ goto error;
+ }
+
+ /* Allocate UST metadata */
+ metadata = alloc_ust_app_channel(DEFAULT_METADATA_NAME, ua_sess, NULL);
+ if (!metadata) {
+ /* malloc() failed */
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ if (!attr) {
+ /* Set default attributes for metadata. */
+ metadata->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE;
+ metadata->attr.subbuf_size = default_get_metadata_subbuf_size();
+ metadata->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM;
+ metadata->attr.switch_timer_interval = DEFAULT_METADATA_SWITCH_TIMER;
+ metadata->attr.read_timer_interval = DEFAULT_METADATA_READ_TIMER;
+ metadata->attr.output = LTTNG_UST_MMAP;
+ metadata->attr.type = LTTNG_UST_CHAN_METADATA;
+ } else {
+ memcpy(&metadata->attr, attr, sizeof(metadata->attr));
+ metadata->attr.output = LTTNG_UST_MMAP;
+ metadata->attr.type = LTTNG_UST_CHAN_METADATA;
+ }
+
+ /* Need one fd for the channel. */
+ ret = lttng_fd_get(LTTNG_FD_APPS, 1);
+ if (ret < 0) {
+ ERR("Exhausted number of available FD upon create metadata");
+ goto error;
+ }
+
+ /* Get the right consumer socket for the application. */
+ socket = consumer_find_socket_by_bitness(app->bits_per_long, consumer);
+ if (!socket) {
+ ret = -EINVAL;
+ goto error_consumer;
+ }
+
+ /*
+ * Keep metadata key so we can identify it on the consumer side. Assign it
+ * to the registry *before* we ask the consumer so we avoid the race of the
+ * consumer requesting the metadata and the ask_channel call on our side
+ * did not returned yet.
+ */
+ registry->metadata_key = metadata->key;
+
+ /*
+ * Ask the metadata channel creation to the consumer. The metadata object
+ * will be created by the consumer and kept their. However, the stream is
+ * never added or monitored until we do a first push metadata to the
+ * consumer.
+ */
+ ret = ust_consumer_ask_channel(ua_sess, metadata, consumer, socket,
+ registry);
+ if (ret < 0) {
+ /* Nullify the metadata key so we don't try to close it later on. */
+ registry->metadata_key = 0;
+ goto error_consumer;
+ }
+
+ /*
+ * The setup command will make the metadata stream be sent to the relayd,
+ * if applicable, and the thread managing the metadatas. This is important
+ * because after this point, if an error occurs, the only way the stream
+ * can be deleted is to be monitored in the consumer.
+ */
+ ret = consumer_setup_metadata(socket, metadata->key);
+ if (ret < 0) {
+ /* Nullify the metadata key so we don't try to close it later on. */
+ registry->metadata_key = 0;
+ goto error_consumer;
+ }
+
+ DBG2("UST metadata with key %" PRIu64 " created for app pid %d",
+ metadata->key, app->pid);
+
+error_consumer:
+ lttng_fd_put(LTTNG_FD_APPS, 1);
+ delete_ust_app_channel(-1, metadata, app);
+error:
+ return ret;
+}
+
+/*
+ * Return pointer to traceable apps list.
+ */
+struct lttng_ht *ust_app_get_ht(void)
+{
+ return ust_app_ht;
+}
+
+/*
+ * Return ust app pointer or NULL if not found. RCU read side lock MUST be
+ * acquired before calling this function.
+ */
+struct ust_app *ust_app_find_by_pid(pid_t pid)
+{
+ struct ust_app *app = NULL;
+ struct lttng_ht_node_ulong *node;
+ struct lttng_ht_iter iter;
+
+ lttng_ht_lookup(ust_app_ht, (void *)((unsigned long) pid), &iter);
+ node = lttng_ht_iter_get_node_ulong(&iter);
+ if (node == NULL) {
+ DBG2("UST app no found with pid %d", pid);
+ goto error;