+
+/*
+ * kernel_create_channel_stream
+ *
+ * Create a stream for a channel, register it to the kernel tracer and add it
+ * to the stream list of the channel.
+ *
+ * Return the number of created stream. Else, a negative value.
+ */
+int kernel_create_channel_stream(struct ltt_kernel_channel *channel)
+{
+ int ret;
+ struct ltt_kernel_stream *lks;
+
+ while ((ret = kernctl_create_stream(channel->fd)) > 0) {
+ lks = trace_create_kernel_stream();
+ if (lks == NULL) {
+ close(ret);
+ goto error;
+ }
+
+ lks->fd = ret;
+ ret = asprintf(&lks->pathname, "%s/trace_%d",
+ channel->pathname, channel->stream_count);
+ if (ret < 0) {
+ perror("asprintf kernel create stream");
+ goto error;
+ }
+
+ /* Add stream to channe stream list */
+ cds_list_add(&lks->list, &channel->stream_list.head);
+ channel->stream_count++;
+
+ DBG("Kernel stream %d created (fd: %d, state: %d, path: %s)",
+ channel->stream_count, lks->fd, lks->state, lks->pathname);
+ }
+
+ return channel->stream_count;
+
+error:
+ return -1;
+}
+
+/*
+ * kernel_create_metadata_stream
+ *
+ * Create the metadata stream and set it to the kernel session.
+ */
+int kernel_create_metadata_stream(struct ltt_kernel_session *session)
+{
+ int ret;
+
+ ret = kernctl_create_stream(session->metadata->fd);
+ if (ret < 0) {
+ perror("kernel create metadata stream");
+ goto error;
+ }
+
+ DBG("Kernel metadata stream created (fd: %d)", ret);
+ session->metadata_stream_fd = ret;
+
+ return 0;
+
+error:
+ return -1;
+}
+
+/*
+ * kernel_list_events
+ *
+ * Get the event list from the kernel tracer and return that list in the CTF
+ * format.
+ */
+ssize_t kernel_list_events(int tracer_fd, char **list)
+{
+ int fd;
+ char *buf, *line = NULL;
+ size_t nb, nbmem, total = 0;
+ ssize_t size;
+ FILE *fp;
+
+ fd = kernctl_tracepoint_list(tracer_fd);
+ if (fd < 0) {
+ perror("kernel tracepoint list");
+ goto error;
+ }
+
+ fp = fdopen(fd, "r");
+ if (fp == NULL) {
+ perror("kernel tracepoint list fdopen");
+ goto error;
+ }
+
+ /*
+ * Init memory size counter
+ * See kernel-ctl.h for explanation of this value
+ */
+ nbmem = KERNEL_EVENT_LIST_SIZE;
+ buf = malloc(nbmem);
+
+ while ((size = getline(&line, &nb, fp)) != -1) {
+ if (total + size > nbmem) {
+ DBG("Reallocating event list from %ld to %ld bytes", nbmem,
+ total + size + KERNEL_EVENT_LIST_SIZE);
+ /* Adding the default size again */
+ nbmem = total + size + KERNEL_EVENT_LIST_SIZE;
+ buf = realloc(buf, nbmem);
+ if (buf == NULL) {
+ perror("realloc list events");
+ goto error;
+ }
+ }
+ memcpy(buf + total, line, size);
+ total += size;
+ }
+
+ *list = buf;
+
+ DBG("Kernel list events done");
+
+ return total;
+
+error:
+ return -1;
+}
+