#include <inttypes.h>
#include <common/common.h>
+#include <common/trace-chunk.h>
#include <common/kernel-ctl/kernel-ctl.h>
#include <common/kernel-ctl/kernel-ioctl.h>
#include <common/sessiond-comm/sessiond-comm.h>
*/
void kernel_destroy_session(struct ltt_kernel_session *ksess)
{
+ struct lttng_trace_chunk *trace_chunk;
+
if (ksess == NULL) {
DBG3("No kernel session when tearing down session");
return;
}
DBG("Tearing down kernel session");
+ trace_chunk = ksess->current_trace_chunk;
/*
* Destroy channels on the consumer if at least one FD has been sent and we
consumer_output_send_destroy_relayd(ksess->consumer);
trace_kernel_destroy_session(ksess);
+ lttng_trace_chunk_put(trace_chunk);
}
/*
/*
* Take a snapshot for a given kernel session.
*
- * Return 0 on success or else return a LTTNG_ERR code.
+ * Return LTTNG_OK on success or else return a LTTNG_ERR code.
*/
-int kernel_snapshot_record(struct ltt_kernel_session *ksess,
- struct snapshot_output *output, int wait,
+enum lttng_error_code kernel_snapshot_record(
+ struct ltt_kernel_session *ksess,
+ const struct consumer_output *output, int wait,
uint64_t nb_packets_per_stream)
{
int err, ret, saved_metadata_fd;
+ enum lttng_error_code status = LTTNG_OK;
struct consumer_socket *socket;
struct lttng_ht_iter iter;
struct ltt_kernel_metadata *saved_metadata;
- struct ltt_session *session;
- uint64_t trace_archive_id;
assert(ksess);
assert(ksess->consumer);
DBG("Kernel snapshot record started");
- session = session_find_by_id(ksess->id);
- assert(session);
- assert(pthread_mutex_trylock(&session->lock));
- assert(session_trylock_list());
- trace_archive_id = session->current_archive_id;
-
/* Save current metadata since the following calls will change it. */
saved_metadata = ksess->metadata;
saved_metadata_fd = ksess->metadata_stream_fd;
ret = kernel_open_metadata(ksess);
if (ret < 0) {
- ret = LTTNG_ERR_KERN_META_FAIL;
+ status = LTTNG_ERR_KERN_META_FAIL;
goto error;
}
ret = kernel_open_metadata_stream(ksess);
if (ret < 0) {
- ret = LTTNG_ERR_KERN_META_FAIL;
+ status = LTTNG_ERR_KERN_META_FAIL;
goto error_open_stream;
}
/* Send metadata to consumer and snapshot everything. */
- cds_lfht_for_each_entry(ksess->consumer->socks->ht, &iter.iter,
+ cds_lfht_for_each_entry(output->socks->ht, &iter.iter,
socket, node.node) {
- struct consumer_output *saved_output;
struct ltt_kernel_channel *chan;
- /*
- * Temporarly switch consumer output for our snapshot output. As long
- * as the session lock is taken, this is safe.
- */
- saved_output = ksess->consumer;
- ksess->consumer = output->consumer;
-
pthread_mutex_lock(socket->lock);
/* This stream must not be monitored by the consumer. */
ret = kernel_consumer_add_metadata(socket, ksess, 0);
pthread_mutex_unlock(socket->lock);
- /* Put back the saved consumer output into the session. */
- ksess->consumer = saved_output;
if (ret < 0) {
- ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+ status = LTTNG_ERR_KERN_META_FAIL;
goto error_consumer;
}
/* For each channel, ask the consumer to snapshot it. */
cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
- ret = consumer_snapshot_channel(socket, chan->key, output, 0,
+ status = consumer_snapshot_channel(socket, chan->key, output, 0,
ksess->uid, ksess->gid,
DEFAULT_KERNEL_TRACE_DIR, wait,
- nb_packets_per_stream,
- trace_archive_id);
- if (ret < 0) {
- ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+ nb_packets_per_stream);
+ if (status != LTTNG_OK) {
(void) kernel_consumer_destroy_metadata(socket,
ksess->metadata);
goto error_consumer;
}
/* Snapshot metadata, */
- ret = consumer_snapshot_channel(socket, ksess->metadata->key, output,
+ status = consumer_snapshot_channel(socket, ksess->metadata->key, output,
1, ksess->uid, ksess->gid,
- DEFAULT_KERNEL_TRACE_DIR, wait, 0,
- trace_archive_id);
- if (ret < 0) {
- ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+ DEFAULT_KERNEL_TRACE_DIR, wait, 0);
+ if (status != LTTNG_OK) {
goto error_consumer;
}
(void) kernel_consumer_destroy_metadata(socket, ksess->metadata);
}
- ret = LTTNG_OK;
-
error_consumer:
/* Close newly opened metadata stream. It's now on the consumer side. */
err = close(ksess->metadata_stream_fd);
/* Restore metadata state.*/
ksess->metadata = saved_metadata;
ksess->metadata_stream_fd = saved_metadata_fd;
-
rcu_read_unlock();
- return ret;
+ return status;
}
/*
/*
* Rotate a kernel session.
*
- * Return 0 on success or else return a LTTNG_ERR code.
+ * Return LTTNG_OK on success or else an LTTng error code.
*/
-int kernel_rotate_session(struct ltt_session *session)
+enum lttng_error_code kernel_rotate_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;
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. */
+ /* 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);
+ DBG("Rotate kernel 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);
+ /* is_metadata_channel */ false);
if (ret < 0) {
- ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+ status = LTTNG_ERR_KERN_CONSUMER_FAIL;
goto error;
}
}
*/
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);
+ /* is_metadata_channel */ true);
if (ret < 0) {
- ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
+ status = LTTNG_ERR_KERN_CONSUMER_FAIL;
goto error;
}
}
- ret = LTTNG_OK;
+error:
+ rcu_read_unlock();
+ return status;
+}
+
+enum lttng_error_code kernel_create_channel_subdirectories(
+ const struct ltt_kernel_session *ksess)
+{
+ enum lttng_error_code ret = LTTNG_OK;
+ enum lttng_trace_chunk_status chunk_status;
+
+ rcu_read_lock();
+ assert(ksess->current_trace_chunk);
+ /*
+ * Create the index subdirectory which will take care
+ * of implicitly creating the channel's path.
+ */
+ chunk_status = lttng_trace_chunk_create_subdirectory(
+ ksess->current_trace_chunk,
+ DEFAULT_KERNEL_TRACE_DIR "/" DEFAULT_INDEX_DIR);
+ if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+ ret = LTTNG_ERR_CREATE_DIR_FAIL;
+ goto error;
+ }
error:
rcu_read_unlock();
return ret;