Cleanup: ust_session_id unused by buffer_reg_uid_consumer_channel_key
[lttng-tools.git] / src / bin / lttng-sessiond / kernel.c
index b32193451f2060c401ac9d7503f2e48574be3fe4..19a325da1f1421b27c73bfb7866ae5204b87ca7b 100644 (file)
 #include "kernel-consumer.h"
 #include "kern-modules.h"
 #include "utils.h"
+#include "rotate.h"
+
+/*
+ * Key used to reference a channel between the sessiond and the consumer. This
+ * is only read and updated with the session_list lock held.
+ */
+static uint64_t next_kernel_channel_key;
 
 /*
  * 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 +72,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;
 }
 
@@ -163,8 +176,10 @@ int kernel_create_channel(struct ltt_kernel_session *session,
        cds_list_add(&lkc->list, &session->channel_list.head);
        session->channel_count++;
        lkc->session = session;
+       lkc->key = ++next_kernel_channel_key;
 
-       DBG("Kernel channel %s created (fd: %d)", lkc->channel->name, lkc->fd);
+       DBG("Kernel channel %s created (fd: %d, key: %" PRIu64 ")",
+                       lkc->channel->name, lkc->fd, lkc->key);
 
        return 0;
 
@@ -285,7 +300,8 @@ int kernel_disable_channel(struct ltt_kernel_channel *chan)
        }
 
        chan->enabled = 0;
-       DBG("Kernel channel %s disabled (fd: %d)", chan->channel->name, chan->fd);
+       DBG("Kernel channel %s disabled (fd: %d, key: %" PRIu64 ")",
+                       chan->channel->name, chan->fd, chan->key);
 
        return 0;
 
@@ -309,7 +325,8 @@ int kernel_enable_channel(struct ltt_kernel_channel *chan)
        }
 
        chan->enabled = 1;
-       DBG("Kernel channel %s enabled (fd: %d)", chan->channel->name, chan->fd);
+       DBG("Kernel channel %s enabled (fd: %d, key: %" PRIu64 ")",
+                       chan->channel->name, chan->fd, chan->key);
 
        return 0;
 
@@ -519,6 +536,7 @@ int kernel_open_metadata(struct ltt_kernel_session *session)
        }
 
        lkm->fd = ret;
+       lkm->key = ++next_kernel_channel_key;
        /* Prevent fd duplication after execlp() */
        ret = fcntl(lkm->fd, F_SETFD, FD_CLOEXEC);
        if (ret < 0) {
@@ -808,38 +826,38 @@ error:
 /*
  * Get kernel version and validate it.
  */
-int kernel_validate_version(int tracer_fd)
+int kernel_validate_version(int tracer_fd,
+               struct lttng_kernel_tracer_version *version,
+               struct lttng_kernel_tracer_abi_version *abi_version)
 {
        int ret;
-       struct lttng_kernel_tracer_version version;
-       struct lttng_kernel_tracer_abi_version abi_version;
 
-       ret = kernctl_tracer_version(tracer_fd, &version);
+       ret = kernctl_tracer_version(tracer_fd, version);
        if (ret < 0) {
                ERR("Failed to retrieve the lttng-modules version");
                goto error;
        }
 
        /* Validate version */
-       if (version.major != VERSION_MAJOR) {
+       if (version->major != VERSION_MAJOR) {
                ERR("Kernel tracer major version (%d) is not compatible with lttng-tools major version (%d)",
-                       version.major, VERSION_MAJOR);
+                       version->major, VERSION_MAJOR);
                goto error_version;
        }
-       ret = kernctl_tracer_abi_version(tracer_fd, &abi_version);
+       ret = kernctl_tracer_abi_version(tracer_fd, abi_version);
        if (ret < 0) {
                ERR("Failed to retrieve lttng-modules ABI version");
                goto error;
        }
-       if (abi_version.major != LTTNG_MODULES_ABI_MAJOR_VERSION) {
+       if (abi_version->major != LTTNG_MODULES_ABI_MAJOR_VERSION) {
                ERR("Kernel tracer ABI version (%d.%d) does not match the expected ABI major version (%d.*)",
-                       abi_version.major, abi_version.minor,
+                       abi_version->major, abi_version->minor,
                        LTTNG_MODULES_ABI_MAJOR_VERSION);
                goto error;
        }
        DBG2("Kernel tracer version validated (%d.%d, ABI %d.%d)",
-                       version.major, version.minor,
-                       abi_version.major, abi_version.minor);
+                       version->major, version->minor,
+                       abi_version->major, abi_version->minor);
        return 0;
 
 error_version:
@@ -1023,12 +1041,10 @@ int kernel_snapshot_record(struct ltt_kernel_session *ksess,
 
                /* For each channel, ask the consumer to snapshot it. */
                cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
-                       pthread_mutex_lock(socket->lock);
-                       ret = consumer_snapshot_channel(socket, chan->fd, output, 0,
+                       ret = consumer_snapshot_channel(socket, chan->key, output, 0,
                                        ksess->uid, ksess->gid,
                                        DEFAULT_KERNEL_TRACE_DIR, wait,
                                        nb_packets_per_stream);
-                       pthread_mutex_unlock(socket->lock);
                        if (ret < 0) {
                                ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
                                (void) kernel_consumer_destroy_metadata(socket,
@@ -1038,11 +1054,9 @@ int kernel_snapshot_record(struct ltt_kernel_session *ksess,
                }
 
                /* Snapshot metadata, */
-               pthread_mutex_lock(socket->lock);
-               ret = consumer_snapshot_channel(socket, ksess->metadata->fd, output,
+               ret = consumer_snapshot_channel(socket, ksess->metadata->key, output,
                                1, ksess->uid, ksess->gid,
                                DEFAULT_KERNEL_TRACE_DIR, wait, 0);
-               pthread_mutex_unlock(socket->lock);
                if (ret < 0) {
                        ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
                        goto error_consumer;
@@ -1120,3 +1134,88 @@ int kernel_supports_ring_buffer_snapshot_sample_positions(int tracer_fd)
 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 %s started (session %" PRIu64 ")",
+                       session->name, session->id);
+
+       rcu_read_lock();
+
+       /*
+        * Note that this loop will end after one iteration given that there is
+        * only one kernel consumer.
+        */
+       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->key,
+                               LTTNG_DOMAIN_KERNEL, session);
+               if (ret < 0) {
+                       ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+                       goto error;
+               }
+
+               /* For each channel, ask the consumer to rotate it. */
+               cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
+                       ret = rotate_add_channel_pending(chan->key,
+                                       LTTNG_DOMAIN_KERNEL, session);
+                       if (ret < 0) {
+                               ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+                               goto error;
+                       }
+
+                       DBG("Rotate channel %" PRIu64 ", session %s", chan->key, session->name);
+                       ret = consumer_rotate_channel(socket, chan->key,
+                                       ksess->uid, ksess->gid, ksess->consumer,
+                                       ksess->consumer->subdir,
+                                       /* is_metadata_channel */ false,
+                                       session->current_archive_id,
+                                       &session->rotate_pending_relay);
+                       if (ret < 0) {
+                               ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+                               goto error;
+                       }
+               }
+
+               /*
+                * Rotate the metadata channel.
+                */
+               ret = consumer_rotate_channel(socket, ksess->metadata->key,
+                               ksess->uid, ksess->gid, ksess->consumer,
+                               ksess->consumer->subdir,
+                               /* is_metadata_channel */ true,
+                               session->current_archive_id,
+                               &session->rotate_pending_relay);
+               if (ret < 0) {
+                       ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+                       goto error;
+               }
+       }
+
+       ret = LTTNG_OK;
+
+error:
+       rcu_read_unlock();
+       return ret;
+}
This page took 0.026548 seconds and 4 git commands to generate.