Fix: use metadata key instead of fd for consumer rotation command
[lttng-tools.git] / src / bin / lttng-sessiond / kernel.c
index 158a12a3633fa54100c81d0f5179b6c2c9d9c68e..2b59fe09d3b19924993b08849b5360d5d8eeac9e 100644 (file)
@@ -33,6 +33,7 @@
 #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
@@ -535,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) {
@@ -1052,7 +1054,7 @@ int kernel_snapshot_record(struct ltt_kernel_session *ksess,
                }
 
                /* Snapshot metadata, */
-               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);
                if (ret < 0) {
@@ -1132,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->rotate_count,
+                                       &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->rotate_count,
+                               &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.026732 seconds and 5 git commands to generate.