#include "kern-modules.h"
#include "utils.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)
end:
cds_list_add_tail(&ctx->list, &chan->ctx_list);
+ ctx->in_list = true;
+ ctx = NULL;
error:
+ if (ctx) {
+ trace_kernel_destroy_context(ctx);
+ }
return ret;
}
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;
}
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;
}
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;
}
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) {
/* 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,
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,
}
/* 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;
error:
return ret;
}
+
+/*
+ * Clear a kernel session.
+ *
+ * Return LTTNG_OK on success or else an LTTng error code.
+ */
+enum lttng_error_code kernel_clear_session(struct ltt_session *session)
+{
+ int ret;
+ enum lttng_error_code status = LTTNG_OK;
+ struct consumer_socket *socket;
+ struct lttng_ht_iter iter;
+ struct ltt_kernel_session *ksess = session->kernel_session;
+
+ assert(ksess);
+ assert(ksess->consumer);
+
+ DBG("Clear kernel session %s (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;
+
+ /* For each channel, ask the consumer to clear it. */
+ cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
+ DBG("Clear kernel channel %" PRIu64 ", session %s",
+ chan->key, session->name);
+ ret = consumer_clear_channel(socket, chan->key,
+ ksess->consumer);
+ if (ret < 0) {
+ goto error;
+ }
+ }
+
+ if (!ksess->metadata) {
+ /*
+ * Nothing to do for the metadata.
+ * This is a snpashot session.
+ * The metadata is genererated on the fly.
+ */
+ continue;
+ }
+
+ /*
+ * Clear the metadata channel.
+ * Metadata channel is not cleared per se but we still need to
+ * perform rotation operation on it behind the scene.
+ */
+ ret = consumer_clear_channel(socket, ksess->metadata->key,
+ ksess->consumer);
+ if (ret < 0) {
+ goto error;
+ }
+ }
+
+ goto end;
+error:
+ switch (-ret) {
+ case LTTCOMM_CONSUMERD_RELAYD_DISALLOW_CLEAR:
+ status = LTTNG_ERR_CLEAR_RELAY_DISALLOW;
+ break;
+ default:
+ status = LTTNG_ERR_CLEAR_FAIL_CONSUMER;
+ break;
+ }
+end:
+ rcu_read_unlock();
+ return status;
+}