Initial work for kernel tracing support
[lttng-tools.git] / ltt-sessiond / kernel-ctl.c
index 969acfbf437deb51de608fcba7d991e9ba8353b6..d00f7e5bc4e48266a736959d7351cd086164735a 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
+#define _GNU_SOURCE
 #include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
+#include "lttngerr.h"
 #include "ltt-sessiond.h"
 #include "libkernelctl.h"
 #include "kernel-ctl.h"
@@ -31,7 +34,7 @@
  *
  *  Create a new kernel session using the command context session.
  */
-int kernel_create_session(struct command_ctx *cmd_ctx, int tracer_fd)
+int kernel_create_session(struct ltt_session *session, int tracer_fd)
 {
        int ret;
        struct ltt_kernel_session *lks;
@@ -51,8 +54,13 @@ int kernel_create_session(struct command_ctx *cmd_ctx, int tracer_fd)
 
        /* Assigning session fd and to the command context */
        lks->fd = ret;
-       cmd_ctx->session->kernel_session = lks;
-       cmd_ctx->session->kern_session_count++;
+       lks->channel_count = 0;
+       lks->stream_count_global = 0;
+       session->kernel_session = lks;
+       session->kern_session_count++;
+       CDS_INIT_LIST_HEAD(&lks->channel_list.head);
+
+       DBG("Kernel session created (fd: %d)", lks->fd);
 
        return 0;
 
@@ -65,7 +73,7 @@ error:
  *
  *  Create a kernel channel within the kernel session.
  */
-int kernel_create_channel(struct command_ctx *cmd_ctx)
+int kernel_create_channel(struct ltt_kernel_session *session)
 {
        int ret;
        struct ltt_kernel_channel *lkc;
@@ -86,17 +94,30 @@ int kernel_create_channel(struct command_ctx *cmd_ctx)
        chan->switch_timer_interval = DEFAULT_KERNEL_SWITCH_TIMER;
        chan->read_timer_interval = DEFAULT_KERNEL_READ_TIMER;
 
-       ret = kernctl_create_channel(cmd_ctx->session->kernel_session->fd, chan);
+       ret = kernctl_create_channel(session->fd, chan);
        if (ret < 0) {
                perror("ioctl create channel");
                goto error;
        }
 
+       /* Setup the channel */
        lkc->fd = ret;
        lkc->channel = chan;
+       lkc->stream_count = 0;
+       ret = asprintf(&lkc->pathname, "%s", DEFAULT_TRACE_OUTPUT);
+       if (ret < 0) {
+               perror("asprintf kernel create channel");
+               goto error;
+       }
+
+       DBG("Channel path set to %s", lkc->pathname);
+
        CDS_INIT_LIST_HEAD(&lkc->events_list.head);
+       CDS_INIT_LIST_HEAD(&lkc->stream_list.head);
+       cds_list_add(&lkc->list, &session->channel_list.head);
+       session->channel_count++;
 
-       cmd_ctx->session->kernel_session->channel = lkc;
+       DBG("Kernel channel created (fd: %d)", lkc->fd);
 
        return 0;
 
@@ -109,9 +130,10 @@ error:
  *
  *  Enable kernel event.
  */
-int kernel_enable_event(struct ltt_kernel_channel *channel, char *name)
+int kernel_enable_event(struct ltt_kernel_session *session, char *name)
 {
        int ret;
+       struct ltt_kernel_channel *chan;
        struct ltt_kernel_event *event;
        struct lttng_kernel_event *lke;
 
@@ -129,13 +151,17 @@ int kernel_enable_event(struct ltt_kernel_channel *channel, char *name)
        lke->instrumentation = LTTNG_KERNEL_TRACEPOINTS;
        event->event = lke;
 
-       ret = kernctl_create_event(channel->fd, lke);
-       if (ret < 0) {
-               goto error;
-       }
+       cds_list_for_each_entry(chan, &session->channel_list.head, list) {
+               ret = kernctl_create_event(chan->fd, lke);
+               if (ret < 0) {
+                       goto error;
+               }
 
-       /* Add event to event list */
-       cds_list_add(&event->list, &channel->events_list.head);
+               event->fd = ret;
+               /* Add event to event list */
+               cds_list_add(&event->list, &chan->events_list.head);
+               DBG("Event %s enabled (fd: %d)", name, event->fd);
+       }
 
        return 0;
 
@@ -174,9 +200,126 @@ int kernel_open_metadata(struct ltt_kernel_session *session)
                goto error;
        }
 
+       lkm->fd = ret;
+       lkm->conf = conf;
+       ret = asprintf(&lkm->pathname, "%s/metadata", DEFAULT_TRACE_OUTPUT);
+       if (ret < 0) {
+               perror("asprintf kernel metadata");
+               goto error;
+       }
        session->metadata = lkm;
-       session->metadata->fd = ret;
-       session->metadata->conf = conf;
+
+       DBG("Kernel metadata opened (fd: %d)", lkm->fd);
+
+       return 0;
+
+error:
+       return ret;
+}
+
+/*
+ *  kernel_start_session
+ *
+ *  Start tracing session.
+ */
+int kernel_start_session(struct ltt_kernel_session *session)
+{
+       int ret;
+
+       ret = kernctl_start_session(session->fd);
+       if (ret < 0) {
+               goto error;
+       }
+
+       DBG("Kernel session started");
+
+       return 0;
+
+error:
+       return ret;
+}
+
+/*
+ *  kernel_stop_session
+ *
+ *  Stop tracing session.
+ */
+int kernel_stop_session(struct ltt_kernel_session *session)
+{
+       int ret;
+
+       ret = kernctl_stop_session(session->fd);
+       if (ret < 0) {
+               goto error;
+       }
+
+       DBG("Kernel session stopped");
+
+       return 0;
+
+error:
+       return ret;
+}
+
+/*
+ *  kernel_create_channel_stream
+ *
+ *  Create a stream for a 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 = malloc(sizeof(struct ltt_kernel_stream));
+               if (lks == NULL) {
+                       perror("kernel create stream malloc");
+                       ret = -errno;
+                       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;
+               }
+               lks->state = 0;
+
+               cds_list_add(&lks->list, &channel->stream_list.head);
+               channel->stream_count++;
+       }
+
+       DBG("Kernel channel stream created (num: %d)", channel->stream_count);
+
+       return channel->stream_count;
+
+error:
+       return ret;
+}
+
+/*
+ *  kernel_create_metadata_stream
+ *
+ *  Create the metadata stream.
+ */
+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");
+               ret = -errno;
+               goto error;
+       }
+
+       DBG("Kernel metadata stream created (fd: %d)", ret);
+       session->metadata_stream_fd = ret;
 
        return 0;
 
This page took 0.025264 seconds and 4 git commands to generate.