+error:
+ free(pathname);
+ return ret;
+}
+
+/*
+ * Sending metadata to the consumer with command ADD_CHANNEL and ADD_STREAM.
+ *
+ * The consumer socket lock must be held by the caller.
+ */
+int kernel_consumer_add_metadata(struct consumer_socket *sock,
+ struct ltt_kernel_session *ksession, unsigned int monitor)
+{
+ int ret;
+ char *pathname;
+ struct lttcomm_consumer_msg lkm;
+ struct consumer_output *consumer;
+ struct ltt_session *session;
+
+ rcu_read_lock();
+
+ /* Safety net */
+ assert(ksession);
+ assert(ksession->consumer);
+ assert(sock);
+
+ DBG("Sending metadata %d to kernel consumer",
+ ksession->metadata_stream_fd);
+
+ /* Get consumer output pointer */
+ consumer = ksession->consumer;
+
+ if (monitor) {
+ pathname = create_channel_path(consumer,
+ ksession->uid, ksession->gid);
+ } else {
+ /* Empty path. */
+ pathname = strdup("");
+ }
+ if (!pathname) {
+ ret = -1;
+ goto error;
+ }
+
+ session = session_find_by_id(ksession->id);
+ assert(session);
+ assert(pthread_mutex_trylock(&session->lock));
+ assert(session_trylock_list());
+
+ /* Prep channel message structure */
+ consumer_init_add_channel_comm_msg(&lkm,
+ ksession->metadata->key,
+ ksession->id,
+ pathname,
+ ksession->uid,
+ ksession->gid,
+ consumer->net_seq_index,
+ DEFAULT_METADATA_NAME,
+ 1,
+ DEFAULT_KERNEL_CHANNEL_OUTPUT,
+ CONSUMER_CHANNEL_TYPE_METADATA,
+ 0, 0,
+ monitor, 0, 0);
+
+ health_code_update();
+
+ ret = consumer_send_channel(sock, &lkm);
+ if (ret < 0) {
+ goto error;
+ }
+
+ health_code_update();
+
+ /* Prep stream message structure */
+ consumer_init_add_stream_comm_msg(&lkm,
+ ksession->metadata->key,
+ ksession->metadata_stream_fd,
+ 0 /* CPU: 0 for metadata. */,
+ session->current_archive_id);
+
+ health_code_update();
+
+ /* Send stream and file descriptor */
+ ret = consumer_send_stream(sock, consumer, &lkm,
+ &ksession->metadata_stream_fd, 1);
+ if (ret < 0) {
+ goto error;
+ }
+
+ health_code_update();