re-dump metadata cache at the right place
[lttng-tools.git] / src / bin / lttng-sessiond / kernel.c
index ae8349c897ded12d90bfc2d018ba1994e1822f63..ef5733c66eb2b652e66cb6c508b52183fee37429 100644 (file)
 #include "kernel-consumer.h"
 #include "kern-modules.h"
 #include "utils.h"
+#include "rotation-thread.h"
 
 /*
  * Add context on a kernel channel.
+ *
+ * Assumes the ownership of ctx.
  */
 int kernel_add_channel_context(struct ltt_kernel_channel *chan,
                struct ltt_kernel_context *ctx)
@@ -63,12 +66,16 @@ int kernel_add_channel_context(struct ltt_kernel_channel *chan,
                        goto error;
                }
        }
+       ret = 0;
 
 end:
        cds_list_add_tail(&ctx->list, &chan->ctx_list);
-       return 0;
-
+       ctx->in_list = true;
+       ctx = NULL;
 error:
+       if (ctx) {
+               trace_kernel_destroy_context(ctx);
+       }
        return ret;
 }
 
@@ -576,25 +583,6 @@ void kernel_wait_quiescent(int fd)
        }
 }
 
-/*
- * Kernel calibrate
- */
-int kernel_calibrate(int fd, struct lttng_kernel_calibrate *calibrate)
-{
-       int ret;
-
-       assert(calibrate);
-
-       ret = kernctl_calibrate(fd, calibrate);
-       if (ret < 0) {
-               PERROR("calibrate ioctl");
-               return -1;
-       }
-
-       return 0;
-}
-
-
 /*
  *  Force flush buffer of metadata.
  */
@@ -663,17 +651,22 @@ error:
  * Open stream of channel, register it to the kernel tracer and add it
  * to the stream list of the channel.
  *
+ * Note: given that the streams may appear in random order wrt CPU
+ * number (e.g. cpu hotplug), the index value of the stream number in
+ * the stream name is not necessarily linked to the CPU number.
+ *
  * Return the number of created stream. Else, a negative value.
  */
 int kernel_open_channel_stream(struct ltt_kernel_channel *channel)
 {
-       int ret, count = 0;
+       int ret;
        struct ltt_kernel_stream *lks;
 
        assert(channel);
 
        while ((ret = kernctl_create_stream(channel->fd)) >= 0) {
-               lks = trace_kernel_create_stream(channel->channel->name, count);
+               lks = trace_kernel_create_stream(channel->channel->name,
+                               channel->stream_count);
                if (lks == NULL) {
                        ret = close(ret);
                        if (ret) {
@@ -692,13 +685,10 @@ int kernel_open_channel_stream(struct ltt_kernel_channel *channel)
                lks->tracefile_size = channel->channel->attr.tracefile_size;
                lks->tracefile_count = channel->channel->attr.tracefile_count;
 
-               /* Add stream to channe stream list */
+               /* Add stream to channel stream list */
                cds_list_add(&lks->list, &channel->stream_list.head);
                channel->stream_count++;
 
-               /* Increment counter which represent CPU number. */
-               count++;
-
                DBG("Kernel stream %s created (fd: %d, state: %d)", lks->name, lks->fd,
                                lks->state);
        }
@@ -1105,3 +1095,117 @@ int kernel_syscall_mask(int chan_fd, char **syscall_mask, uint32_t *nr_bits)
 
        return kernctl_syscall_mask(chan_fd, syscall_mask, nr_bits);
 }
+
+/*
+ * Check for the support of the RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS via abi
+ * version number.
+ *
+ * Return 1 on success, 0 when feature is not supported, negative value in case
+ * of errors.
+ */
+int kernel_supports_ring_buffer_snapshot_sample_positions(int tracer_fd)
+{
+       int ret = 0; // Not supported by default
+       struct lttng_kernel_tracer_abi_version abi;
+
+       ret = kernctl_tracer_abi_version(tracer_fd, &abi);
+       if (ret < 0) {
+               ERR("Failed to retrieve lttng-modules ABI version");
+               goto error;
+       }
+
+       /*
+        * RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS was introduced in 2.3
+        */
+       if (abi.major >= 2 && abi.minor >= 3) {
+               /* Supported */
+               ret = 1;
+       } else {
+               /* Not supported */
+               ret = 0;
+       }
+error:
+       return ret;
+}
+
+/*
+ * Rotate a kernel session.
+ *
+ * Return 0 on success or else return a LTTNG_ERR code.
+ */
+int kernel_rotate_session(struct ltt_session *session)
+{
+       int ret;
+       struct consumer_socket *socket;
+       struct lttng_ht_iter iter;
+       struct ltt_kernel_session *ksess = session->kernel_session;
+
+       assert(ksess);
+       assert(ksess->consumer);
+
+       DBG("Rotate kernel session started");
+
+       rcu_read_lock();
+
+       cds_lfht_for_each_entry(ksess->consumer->socks->ht, &iter.iter,
+                       socket, node.node) {
+               struct ltt_kernel_channel *chan;
+
+               /*
+                * Account the metadata channel first to make sure the
+                * number of channels waiting for a rotation cannot
+                * reach 0 before we complete the iteration over all
+                * the channels.
+                */
+               ret = rotate_add_channel_pending(ksess->metadata->fd,
+                               LTTNG_DOMAIN_KERNEL, session);
+               if (ret < 0) {
+                       ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+                       pthread_mutex_unlock(socket->lock);
+                       goto error;
+               }
+
+               /* For each channel, ask the consumer to rotate it. */
+               cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
+                       /* FIXME: is that lock necessary, we don't do it in UST ? */
+                       pthread_mutex_lock(socket->lock);
+                       ret = rotate_add_channel_pending(chan->fd,
+                                       LTTNG_DOMAIN_KERNEL, session);
+                       if (ret < 0) {
+                               ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+                               pthread_mutex_unlock(socket->lock);
+                               goto error;
+                       }
+
+                       ret = consumer_rotate_channel(socket, chan->fd,
+                                       ksess->uid, ksess->gid, ksess->consumer,
+                                       "", 0);
+                       if (ret < 0) {
+                               ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+                               pthread_mutex_unlock(socket->lock);
+                               goto error;
+                       }
+
+                       pthread_mutex_unlock(socket->lock);
+               }
+
+               /*
+                * Rotate the metadata channel.
+                */
+               pthread_mutex_lock(socket->lock);
+               ret = consumer_rotate_channel(socket, ksess->metadata->fd,
+                               ksess->uid, ksess->gid, ksess->consumer, "", 1);
+               if (ret < 0) {
+                       ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+                       pthread_mutex_unlock(socket->lock);
+                       goto error;
+               }
+               pthread_mutex_unlock(socket->lock);
+       }
+
+       ret = LTTNG_OK;
+
+error:
+       rcu_read_unlock();
+       return ret;
+}
This page took 0.028479 seconds and 5 git commands to generate.