#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)
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;
}
* 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) {
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);
}
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;
+}