relayd: create stream files relative to a session's trace chunk
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 25 Jul 2019 19:30:54 +0000 (15:30 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 9 Aug 2019 15:28:43 +0000 (11:28 -0400)
Like to the consumer daemon, the relay daemon now creates its
stream files through the lttng_trace_chunk interface. This
requires changes across the session daemon and relay daemon.

The changes to the relay daemon mainly target the file creation.
In the session daemon, the snapshot command has been heavily
modified to fully initialize the ltt_session's ust and kernel
consumer_outputs _before_ the snapshot trace chunk is created.

This way, the session is setup in the same way a regular network
streaming session would be, a temporary trace chunk is created to
contain the snapshot's content, the actual snapshot is taken, and
the session's original consumer_outputs are restored.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
25 files changed:
src/bin/lttng-relayd/cmd-2-1.c
src/bin/lttng-relayd/cmd-2-11.c
src/bin/lttng-relayd/cmd-2-2.c
src/bin/lttng-relayd/ctf-trace.c
src/bin/lttng-relayd/ctf-trace.h
src/bin/lttng-relayd/main.c
src/bin/lttng-relayd/stream.c
src/bin/lttng-relayd/stream.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/consumer.c
src/bin/lttng-sessiond/consumer.h
src/bin/lttng-sessiond/kernel.c
src/bin/lttng-sessiond/kernel.h
src/bin/lttng-sessiond/session.c
src/bin/lttng-sessiond/session.h
src/bin/lttng-sessiond/ust-app.c
src/bin/lttng-sessiond/ust-app.h
src/bin/lttng-sessiond/ust-consumer.c
src/bin/lttng-sessiond/utils.c
src/bin/lttng-sessiond/utils.h
src/common/consumer/consumer.h
src/common/index/index.c
src/common/index/index.h
src/common/relayd/relayd.c
src/common/sessiond-comm/relayd.h

index 99aa86668048e719daa4100a09ff425de806dd3a..38381f894daad1662e10fad02550d9b5366ff623 100644 (file)
@@ -55,7 +55,7 @@ int cmd_recv_stream_2_1(const struct lttng_buffer_view *payload,
                ERR("Path name too long");
                goto error;
        }
-       path_name = create_output_path(stream_info.pathname);
+       path_name = strdup(stream_info.pathname);
        if (!path_name) {
                PERROR("Path name allocation");
                ret = -ENOMEM;
index 7d90be9f9f014d1f87cd0b05aba7f74591b1b3f9..79f439c4652ead386f140bc00a1287e668159927 100644 (file)
@@ -148,7 +148,7 @@ int cmd_recv_stream_2_11(const struct lttng_buffer_view *payload,
        header.pathname_len = be32toh(header.pathname_len);
        header.tracefile_size = be64toh(header.tracefile_size);
        header.tracefile_count = be64toh(header.tracefile_count);
-       header.trace_archive_id = be64toh(header.trace_archive_id);
+       header.trace_chunk_id = be64toh(header.trace_chunk_id);
 
        received_names_size = header.channel_name_len + header.pathname_len;
        if (payload->size < header_len + received_names_size) {
@@ -195,7 +195,7 @@ int cmd_recv_stream_2_11(const struct lttng_buffer_view *payload,
                goto error;
        }
 
-       path_name = create_output_path(pathname_view.data);
+       path_name = strdup(pathname_view.data);
        if (!path_name) {
                PERROR("Path name allocation");
                ret = -ENOMEM;
@@ -204,7 +204,7 @@ int cmd_recv_stream_2_11(const struct lttng_buffer_view *payload,
 
        *tracefile_size = header.tracefile_size;
        *tracefile_count = header.tracefile_count;
-       *trace_archive_id = header.trace_archive_id;
+       *trace_archive_id = header.trace_chunk_id;
        *ret_path_name = path_name;
        *ret_channel_name = channel_name;
        /* Move ownership to caller */
index 5ff6280509a2119291df7065a01af7d2d5bd1122..915b2eb64a41a84acca565cf8b5135bf786d770b 100644 (file)
@@ -58,7 +58,7 @@ int cmd_recv_stream_2_2(const struct lttng_buffer_view *payload,
                ERR("Path name too long");
                goto error;
        }
-       path_name = create_output_path(stream_info.pathname);
+       path_name = strdup(stream_info.pathname);
        if (!path_name) {
                PERROR("Path name allocation");
                ret = -ENOMEM;
index 4ca6dba1e40c489bdd92f6a0a90636d5841dd94e..fdd0a5d0d9d6d52c9075df7deb5867cf03d50c1b 100644 (file)
@@ -54,6 +54,8 @@ void ctf_trace_destroy(struct ctf_trace *trace)
        assert(cds_list_empty(&trace->stream_list));
        session_put(trace->session);
        trace->session = NULL;
+       free(trace->path);
+       trace->path = NULL;
        call_rcu(&trace->rcu_node, rcu_destroy_ctf_trace);
 }
 
@@ -85,23 +87,26 @@ bool ctf_trace_get(struct ctf_trace *trace)
  * put their reference, its refcount drops to 0.
  */
 static struct ctf_trace *ctf_trace_create(struct relay_session *session,
-               char *path_name)
+               const char *subpath)
 {
        struct ctf_trace *trace;
 
        trace = zmalloc(sizeof(*trace));
        if (!trace) {
-               PERROR("ctf_trace alloc");
-               goto error;
+               PERROR("Failed to allocate ctf_trace");
+               goto end;
        }
+       urcu_ref_init(&trace->ref);
 
        if (!session_get(session)) {
-               ERR("Cannot get session");
-               free(trace);
-               trace = NULL;
+               ERR("Failed to acquire session reference");
                goto error;
        }
        trace->session = session;
+       trace->path = strdup(subpath);
+       if (!trace->path) {
+               goto error;
+       }
 
        CDS_INIT_LIST_HEAD(&trace->stream_list);
 
@@ -109,17 +114,21 @@ static struct ctf_trace *ctf_trace_create(struct relay_session *session,
        trace->id = ++last_relay_ctf_trace_id;
        pthread_mutex_unlock(&last_relay_ctf_trace_id_lock);
 
-       lttng_ht_node_init_str(&trace->node, path_name);
+       lttng_ht_node_init_str(&trace->node, trace->path);
        trace->session = session;
-       urcu_ref_init(&trace->ref);
        pthread_mutex_init(&trace->lock, NULL);
        pthread_mutex_init(&trace->stream_list_lock, NULL);
        lttng_ht_add_str(session->ctf_traces_ht, &trace->node);
 
-       DBG("Created ctf_trace %" PRIu64 " with path: %s", trace->id, path_name);
+       DBG("Created ctf_trace %" PRIu64 "of session \"%s\" from host \"%s\" with path: %s",
+                       trace->id, session->session_name, session->hostname,
+                       subpath);
 
-error:
+end:
        return trace;
+error:
+       ctf_trace_put(trace);
+       return NULL;
 }
 
 /*
@@ -128,17 +137,17 @@ error:
  * ctf_trace_put().
  */
 struct ctf_trace *ctf_trace_get_by_path_or_create(struct relay_session *session,
-               char *path_name)
+               const char *subpath)
 {
        struct lttng_ht_node_str *node;
        struct lttng_ht_iter iter;
        struct ctf_trace *trace = NULL;
 
        rcu_read_lock();
-       lttng_ht_lookup(session->ctf_traces_ht, (void *) path_name, &iter);
+       lttng_ht_lookup(session->ctf_traces_ht, subpath, &iter);
        node = lttng_ht_iter_get_node_str(&iter);
        if (!node) {
-               DBG("CTF Trace path %s not found", path_name);
+               DBG("CTF Trace path %s not found", subpath);
                goto end;
        }
        trace = caa_container_of(node, struct ctf_trace, node);
@@ -149,7 +158,7 @@ end:
        rcu_read_unlock();
        if (!trace) {
                /* Try to create */
-               trace = ctf_trace_create(session, path_name);
+               trace = ctf_trace_create(session, subpath);
        }
        return trace;
 }
index 9903d38e874a4e86760e25ee01a7f2605cc789b8..8efd1e430cf6b18841e600552221ed9b69f90b5c 100644 (file)
@@ -33,6 +33,10 @@ struct ctf_trace {
        struct urcu_ref ref;            /* Every stream has a ref on the trace. */
        struct relay_session *session;  /* Back ref to trace session */
 
+       /* Trace sub-folder relative to the session output path. */
+       char *path;
+       bool index_folder_created;
+
        /*
         * The ctf_trace lock nests inside the session lock.
         */
@@ -57,7 +61,7 @@ struct ctf_trace {
 };
 
 struct ctf_trace *ctf_trace_get_by_path_or_create(struct relay_session *session,
-               char *path_name);
+               const char *subpath);
 bool ctf_trace_get(struct ctf_trace *trace);
 void ctf_trace_put(struct ctf_trace *trace);
 
index c0e9d76dfd79550d920a021e3f2b3018cf387483..dddc2a2b4f77b25c9ba968826460147302f25e0a 100644 (file)
@@ -1207,6 +1207,34 @@ static void publish_connection_local_streams(struct relay_connection *conn)
        pthread_mutex_unlock(&session->lock);
 }
 
+static int conform_channel_path(char *channel_path)
+{
+       int ret = 0;
+
+       if (strstr("../", channel_path)) {
+               ERR("Refusing channel path as it walks up the path hierarchy: \"%s\"",
+                               channel_path);
+               ret = -1;
+               goto end;
+       }
+
+       if (*channel_path == '/') {
+               const size_t len = strlen(channel_path);
+
+               /*
+                * Channel paths from peers prior to 2.11 are expressed as an
+                * absolute path that is, in reality, relative to the relay
+                * daemon's output directory. Remove the leading slash so it
+                * is correctly interpreted as a relative path later on.
+                *
+                * len (and not len - 1) is used to copy the trailing NULL.
+                */
+               bcopy(channel_path + 1, channel_path, len);
+       }
+end:
+       return ret;
+}
+
 /*
  * relay_add_stream: allocate a new stream for a session
  */
@@ -1223,7 +1251,7 @@ static int relay_add_stream(const struct lttcomm_relayd_hdr *recv_hdr,
        uint64_t stream_handle = -1ULL;
        char *path_name = NULL, *channel_name = NULL;
        uint64_t tracefile_size = 0, tracefile_count = 0;
-       struct relay_stream_chunk_id stream_chunk_id = { 0 };
+       LTTNG_OPTIONAL(uint64_t) stream_chunk_id = {};
 
        if (!session || !conn->version_check_done) {
                ERR("Trying to add a stream before version check");
@@ -1251,6 +1279,10 @@ static int relay_add_stream(const struct lttcomm_relayd_hdr *recv_hdr,
                goto send_reply;
        }
 
+       if (conform_channel_path(path_name)) {
+               goto send_reply;
+       }
+
        trace = ctf_trace_get_by_path_or_create(session, path_name);
        if (!trace) {
                goto send_reply;
@@ -1263,8 +1295,7 @@ static int relay_add_stream(const struct lttcomm_relayd_hdr *recv_hdr,
 
        /* We pass ownership of path_name and channel_name. */
        stream = stream_create(trace, stream_handle, path_name,
-               channel_name, tracefile_size, tracefile_count,
-               &stream_chunk_id);
+               channel_name, tracefile_size, tracefile_count);
        path_name = NULL;
        channel_name = NULL;
 
@@ -1560,11 +1591,13 @@ end:
  */
 static
 int create_rotate_index_file(struct relay_stream *stream,
-               const char *stream_path)
+               const char *channel_path)
 {
        int ret;
        uint32_t major, minor;
 
+       ASSERT_LOCKED(stream->lock);
+
        /* Put ref on previous index_file. */
        if (stream->index_file) {
                lttng_index_file_put(stream->index_file);
@@ -1572,12 +1605,26 @@ int create_rotate_index_file(struct relay_stream *stream,
        }
        major = stream->trace->session->major;
        minor = stream->trace->session->minor;
-       stream->index_file = lttng_index_file_create(stream_path,
-                       stream->channel_name,
-                       -1, -1, stream->tracefile_size,
-                       tracefile_array_get_file_index_head(stream->tfa),
+       if (!stream->trace->index_folder_created) {
+               char *index_subpath = NULL;
+
+               ret = asprintf(&index_subpath, "%s/%s", channel_path, DEFAULT_INDEX_DIR);
+               if (ret < 0) {
+                       goto end;
+               }
+
+               ret = lttng_trace_chunk_create_subdirectory(stream->trace_chunk, index_subpath);
+               free(index_subpath);
+               if (ret) {
+                       goto end;
+               }
+               stream->trace->index_folder_created = true;
+       }
+       stream->index_file = lttng_index_file_create_from_trace_chunk(
+                       stream->trace_chunk, channel_path, stream->channel_name,
+                       stream->tracefile_size, stream->tracefile_count,
                        lttng_to_index_major(major, minor),
-                       lttng_to_index_minor(major, minor));
+                       lttng_to_index_minor(major, minor), true);
        if (!stream->index_file) {
                ret = -1;
                goto end;
@@ -2618,9 +2665,6 @@ static int relay_rotate_session_stream(const struct lttcomm_relayd_hdr *recv_hdr
                goto end_stream_unlock;
        }
 
-       assert(stream->current_chunk_id.is_set);
-       stream->current_chunk_id.value = stream_info.new_chunk_id;
-
        if (stream->is_metadata) {
                /*
                 * Metadata streams have no index; consider its rotation
@@ -2679,10 +2723,21 @@ static int init_session_output_directory_handle(struct relay_session *session,
         * e.g. /home/user/lttng-traces/hostname/session_name
         */
        char *full_session_path = NULL;
+       char creation_time_str[16];
+       struct tm *timeinfo;
+
+       assert(session->creation_time.is_set);
+       timeinfo = localtime(&session->creation_time.value);
+       if (!timeinfo) {
+               ret = -1;
+               goto end;
+       }
+       strftime(creation_time_str, sizeof(creation_time_str), "%Y%m%d-%H%M%S",
+                       timeinfo);
 
        pthread_mutex_lock(&session->lock);
-       ret = asprintf(&session_directory, "%s/%s", session->hostname,
-                       session->session_name);
+       ret = asprintf(&session_directory, "%s/%s-%s", session->hostname,
+                       session->session_name, creation_time_str);
        pthread_mutex_unlock(&session->lock);
        if (ret < 0) {
                PERROR("Failed to format session directory name");
index 4716f9d7923f8d5ddd4ea8a2cf6ee52c790bf846..6650700838fc27596e8c8f086cc7815c8a14a098 100644 (file)
@@ -29,6 +29,9 @@
 #include "stream.h"
 #include "viewer-stream.h"
 
+#include <sys/types.h>
+#include <fcntl.h>
+
 /* Should be called with RCU read-side lock held. */
 bool stream_get(struct relay_stream *stream)
 {
@@ -62,18 +65,88 @@ end:
        return stream;
 }
 
+static int stream_create_data_output_file(struct relay_stream *stream)
+{
+       int ret, fd;
+       enum lttng_trace_chunk_status status;
+       const int flags = O_RDWR | O_CREAT | O_TRUNC;
+       const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+       char stream_path[LTTNG_PATH_MAX];
+
+       ASSERT_LOCKED(stream->lock);
+       assert(stream->trace_chunk);
+
+       if (stream->stream_fd) {
+               stream_fd_put(stream->stream_fd);
+               stream->stream_fd = NULL;
+       }
+
+       ret = utils_stream_file_path(stream->path_name, stream->channel_name,
+                       stream->tracefile_size, stream->tracefile_count, NULL,
+                       stream_path, sizeof(stream_path));
+       if (ret < 0) {
+               goto end;
+       }
+
+       DBG("Opening stream output file \"%s\"", stream_path);
+       status = lttng_trace_chunk_open_file(
+                       stream->trace_chunk, stream_path, flags, mode, &fd);
+       if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+               ERR("Failed to open stream file \"%s\"", stream->channel_name);
+               ret = -1;
+               goto end;
+       }
+
+       stream->stream_fd = stream_fd_create(fd);
+       if (!stream->stream_fd) {
+               if (close(ret)) {
+                       PERROR("Error closing stream file descriptor %d", ret);
+               }
+               ret = -1;
+               goto end;
+       }
+end:
+       return ret;
+}
+
+static int stream_set_trace_chunk(struct relay_stream *stream,
+               struct lttng_trace_chunk *chunk)
+{
+       int ret = 0;
+       enum lttng_trace_chunk_status status;
+       bool acquired_reference;
+
+       pthread_mutex_lock(&stream->lock);
+       status = lttng_trace_chunk_create_subdirectory(chunk,
+                       stream->path_name);
+       if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+               ret = -1;
+               goto end;
+       }
+
+       lttng_trace_chunk_put(stream->trace_chunk);
+       acquired_reference = lttng_trace_chunk_get(chunk);
+       assert(acquired_reference);
+       stream->trace_chunk = chunk;
+       ret = stream_create_data_output_file(stream);
+end:
+       pthread_mutex_unlock(&stream->lock);
+       return ret;
+}
+
 /*
  * We keep ownership of path_name and channel_name.
  */
 struct relay_stream *stream_create(struct ctf_trace *trace,
        uint64_t stream_handle, char *path_name,
        char *channel_name, uint64_t tracefile_size,
-       uint64_t tracefile_count,
-       const struct relay_stream_chunk_id *chunk_id)
+       uint64_t tracefile_count)
 {
        int ret;
        struct relay_stream *stream = NULL;
        struct relay_session *session = trace->session;
+       bool acquired_reference = false;
+       struct lttng_trace_chunk *current_trace_chunk;
 
        stream = zmalloc(sizeof(struct relay_stream));
        if (stream == NULL) {
@@ -98,37 +171,32 @@ struct relay_stream *stream_create(struct ctf_trace *trace,
        urcu_ref_init(&stream->ref);
        ctf_trace_get(trace);
        stream->trace = trace;
-       stream->current_chunk_id = *chunk_id;
 
-       stream->indexes_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
-       if (!stream->indexes_ht) {
-               ERR("Cannot created indexes_ht");
+       pthread_mutex_lock(&trace->session->lock);
+       current_trace_chunk = trace->session->current_trace_chunk;
+       if (current_trace_chunk) {
+               acquired_reference = lttng_trace_chunk_get(current_trace_chunk);
+       }
+       pthread_mutex_unlock(&trace->session->lock);
+       if (!acquired_reference) {
+               ERR("Cannot create stream for channel \"%s\" as a reference to the session's current trace chunk could not be acquired",
+                               channel_name);
                ret = -1;
                goto end;
        }
 
-       ret = utils_mkdir_recursive(stream->path_name, S_IRWXU | S_IRWXG,
-                       -1, -1);
-       if (ret < 0) {
-               ERR("relay creating output directory");
+       stream->indexes_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+       if (!stream->indexes_ht) {
+               ERR("Cannot created indexes_ht");
+               ret = -1;
                goto end;
        }
 
-       /*
-        * No need to use run_as API here because whatever we receive,
-        * the relayd uses its own credentials for the stream files.
-        */
-       ret = utils_create_stream_file(stream->path_name, stream->channel_name,
-                       stream->tracefile_size, 0, -1, -1, NULL);
-       if (ret < 0) {
-               ERR("Create output file");
-               goto end;
-       }
-       stream->stream_fd = stream_fd_create(ret);
-       if (!stream->stream_fd) {
-               if (close(ret)) {
-                       PERROR("Error closing file %d", ret);
-               }
+       ret = stream_set_trace_chunk(stream, current_trace_chunk);
+       if (ret) {
+               ERR("Failed to set the current trace chunk of session \"%s\" on newly created stream of channel \"%s\"",
+                               trace->session->session_name,
+                               stream->channel_name);
                ret = -1;
                goto end;
        }
@@ -137,16 +205,9 @@ struct relay_stream *stream_create(struct ctf_trace *trace,
                ret = -1;
                goto end;
        }
-       if (stream->tracefile_size) {
-               DBG("Tracefile %s/%s_0 created", stream->path_name, stream->channel_name);
-       } else {
-               DBG("Tracefile %s/%s created", stream->path_name, stream->channel_name);
-       }
-
-       if (!strncmp(stream->channel_name, DEFAULT_METADATA_NAME, LTTNG_NAME_MAX)) {
-               stream->is_metadata = 1;
-       }
 
+       stream->is_metadata = !strcmp(stream->channel_name,
+                       DEFAULT_METADATA_NAME);
        stream->in_recv_list = true;
 
        /*
@@ -178,6 +239,7 @@ end:
                stream_put(stream);
                stream = NULL;
        }
+       lttng_trace_chunk_put(current_trace_chunk);
        return stream;
 
 error_no_alloc:
@@ -306,6 +368,8 @@ static void stream_release(struct urcu_ref *ref)
                ctf_trace_put(stream->trace);
                stream->trace = NULL;
        }
+       lttng_trace_chunk_put(stream->trace_chunk);
+       stream->trace_chunk = NULL;
 
        call_rcu(&stream->rcu_node, stream_destroy_rcu);
 }
index 5e23e7339cf4fcf7495f2ae4825fcdfdd57641d1..a4a6461e69cf218cfa2d573437ada85b12bb3a7d 100644 (file)
 #include <urcu/list.h>
 
 #include <common/hashtable/hashtable.h>
+#include <common/trace-chunk.h>
 
 #include "session.h"
 #include "stream-fd.h"
 #include "tracefile-array.h"
 
-struct relay_stream_chunk_id {
-       bool is_set;
-       uint64_t value;
-};
-
 /*
  * Represents a stream in the relay
  */
@@ -175,23 +171,16 @@ struct relay_stream {
        bool data_rotated;
        bool index_rotated;
        /*
-        * This is the id of the chunk where we are writing to if no rotation is
-        * pending (rotate_at_seq_num == -1ULL). If a rotation is pending, this
-        * is the chunk_id we will have after the rotation. It must be updated
-        * atomically with rotate_at_seq_num.
-        *
-        * Always access with stream lock held.
-        *
-        * This attribute is not set if the stream is created by a pre-2.11
-        * consumer.
+        * `trace_chunk` is the trace chunk to which the file currently
+        * being produced (if any) belongs.
         */
-       struct relay_stream_chunk_id current_chunk_id;
+       struct lttng_trace_chunk *trace_chunk;
 };
 
 struct relay_stream *stream_create(struct ctf_trace *trace,
        uint64_t stream_handle, char *path_name,
        char *channel_name, uint64_t tracefile_size,
-       uint64_t tracefile_count, const struct relay_stream_chunk_id *chunk_id);
+       uint64_t tracefile_count);
 
 struct relay_stream *stream_get_by_id(uint64_t stream_id);
 bool stream_get(struct relay_stream *stream);
index b76941648bd50d4a8ddafa6bc2afa8460b8e74b5..3bb3aced586edbb2f07da3c117ae5428942a2356 100644 (file)
@@ -2583,7 +2583,7 @@ int cmd_start_trace(struct ltt_session *session)
                struct lttng_trace_chunk *trace_chunk;
 
                trace_chunk = session_create_new_trace_chunk(
-                               session, NULL, NULL);
+                               session, NULL, NULL, NULL);
                if (!trace_chunk) {
                        ret = LTTNG_ERR_CREATE_DIR_FAIL;
                        goto error;
@@ -4201,8 +4201,7 @@ end:
  * Return LTTNG_OK on success or a LTTNG_ERR code.
  */
 static enum lttng_error_code set_relayd_for_snapshot(
-               struct consumer_output *consumer,
-               const struct snapshot_output *snap_output,
+               struct consumer_output *output,
                const struct ltt_session *session)
 {
        enum lttng_error_code status = LTTNG_OK;
@@ -4210,17 +4209,18 @@ static enum lttng_error_code set_relayd_for_snapshot(
        struct consumer_socket *socket;
        LTTNG_OPTIONAL(uint64_t) current_chunk_id = {};
 
-       assert(consumer);
-       assert(snap_output);
+       assert(output);
        assert(session);
 
        DBG2("Set relayd object from snapshot output");
 
        if (session->current_trace_chunk) {
-               enum lttng_trace_chunk_status status = lttng_trace_chunk_get_id(
-                               session->current_trace_chunk, &current_chunk_id.value);
+               enum lttng_trace_chunk_status chunk_status =
+                               lttng_trace_chunk_get_id(
+                                               session->current_trace_chunk,
+                                               &current_chunk_id.value);
 
-               if (status == LTTNG_TRACE_CHUNK_STATUS_OK) {
+               if (chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK) {
                        current_chunk_id.is_set = true;
                } else {
                        ERR("Failed to get current trace chunk id");
@@ -4230,7 +4230,7 @@ static enum lttng_error_code set_relayd_for_snapshot(
        }
 
        /* Ignore if snapshot consumer output is not network. */
-       if (snap_output->consumer->type != CONSUMER_DST_NET) {
+       if (output->type != CONSUMER_DST_NET) {
                goto error;
        }
 
@@ -4239,11 +4239,11 @@ static enum lttng_error_code set_relayd_for_snapshot(
         * snapshot output.
         */
        rcu_read_lock();
-       cds_lfht_for_each_entry(snap_output->consumer->socks->ht, &iter.iter,
+       cds_lfht_for_each_entry(output->socks->ht, &iter.iter,
                        socket, node.node) {
                pthread_mutex_lock(socket->lock);
                status = send_consumer_relayd_sockets(0, session->id,
-                               snap_output->consumer, socket,
+                               output, socket,
                                session->name, session->hostname,
                                session->live_timer,
                                current_chunk_id.is_set ? &current_chunk_id.value : NULL,
@@ -4267,44 +4267,18 @@ error:
  */
 static enum lttng_error_code record_kernel_snapshot(
                struct ltt_kernel_session *ksess,
-               const struct snapshot_output *output,
+               const struct consumer_output *output,
                const struct ltt_session *session,
                int wait, uint64_t nb_packets_per_stream)
 {
-       int ret;
        enum lttng_error_code status;
 
        assert(ksess);
        assert(output);
        assert(session);
 
-       /*
-        * Copy kernel session sockets so we can communicate with the right
-        * consumer for the snapshot record command.
-        */
-       ret = consumer_copy_sockets(output->consumer, ksess->consumer);
-       if (ret < 0) {
-               status = LTTNG_ERR_NOMEM;
-               goto error;
-       }
-
-       status = set_relayd_for_snapshot(ksess->consumer, output, session);
-       if (status != LTTNG_OK) {
-               goto error_snapshot;
-       }
-
-       status = kernel_snapshot_record(ksess, output, wait, nb_packets_per_stream);
-       if (status != LTTNG_OK) {
-               goto error_snapshot;
-       }
-
-       goto end;
-
-error_snapshot:
-       /* Clean up copied sockets so this output can use some other later on. */
-       consumer_destroy_output_sockets(output->consumer);
-error:
-end:
+       status = kernel_snapshot_record(
+                       ksess, output, wait, nb_packets_per_stream);
        return status;
 }
 
@@ -4314,45 +4288,18 @@ end:
  * Returns LTTNG_OK on success or a LTTNG_ERR error code.
  */
 static enum lttng_error_code record_ust_snapshot(struct ltt_ust_session *usess,
-               const struct snapshot_output *output,
-               const struct ltt_session *session, int wait,
-               uint64_t nb_packets_per_stream)
+               const struct consumer_output *output,
+               const struct ltt_session *session,
+               int wait, uint64_t nb_packets_per_stream)
 {
-       int ret;
        enum lttng_error_code status;
 
        assert(usess);
        assert(output);
        assert(session);
 
-       /*
-        * Copy UST session sockets so we can communicate with the right
-        * consumer for the snapshot record command.
-        */
-       ret = consumer_copy_sockets(output->consumer, usess->consumer);
-       if (ret < 0) {
-               status = LTTNG_ERR_NOMEM;
-               goto error;
-       }
-
-       status = set_relayd_for_snapshot(usess->consumer, output, session);
-       if (status != LTTNG_OK) {
-               goto error_snapshot;
-       }
-
-       status = ust_app_snapshot_record(usess, output, wait,
-                       nb_packets_per_stream);
-       if (status != LTTNG_OK) {
-               goto error_snapshot;
-       }
-
-       goto end;
-
-error_snapshot:
-       /* Clean up copied sockets so this output can use some other later on. */
-       consumer_destroy_output_sockets(output->consumer);
-error:
-end:
+       status = ust_app_snapshot_record(
+                       usess, output, wait, nb_packets_per_stream);
        return status;
 }
 
@@ -4448,63 +4395,122 @@ static
 enum lttng_error_code snapshot_record(struct ltt_session *session,
                const struct snapshot_output *snapshot_output, int wait)
 {
-       int fmt_ret;
        int64_t nb_packets_per_stream;
        char snapshot_chunk_name[LTTNG_NAME_MAX];
-       enum lttng_error_code ret = LTTNG_OK;
+       int ret;
+       enum lttng_error_code ret_code = LTTNG_OK;
        struct lttng_trace_chunk *snapshot_trace_chunk;
+       struct consumer_output *original_ust_consumer_output = NULL;
+       struct consumer_output *original_kernel_consumer_output = NULL;
+       struct consumer_output *snapshot_ust_consumer_output = NULL;
+       struct consumer_output *snapshot_kernel_consumer_output = NULL;
 
-       fmt_ret = snprintf(snapshot_chunk_name, sizeof(snapshot_chunk_name),
+       ret = snprintf(snapshot_chunk_name, sizeof(snapshot_chunk_name),
                        "%s-%s-%" PRIu64,
                        snapshot_output->name,
                        snapshot_output->datetime,
                        snapshot_output->nb_snapshot);
-       if (fmt_ret < 0 || fmt_ret >= sizeof(snapshot_chunk_name)) {
+       if (ret < 0 || ret >= sizeof(snapshot_chunk_name)) {
                ERR("Failed to format snapshot name");
-               ret = LTTNG_ERR_INVALID;
-               goto end;
+               ret_code = LTTNG_ERR_INVALID;
+               goto error;
        }
        DBG("Recording snapshot \"%s\" for session \"%s\" with chunk name \"%s\"",
                        snapshot_output->name, session->name,
                        snapshot_chunk_name);
+       if (!session->kernel_session && !session->ust_session) {
+               ERR("Failed to record snapshot as no channels exist");
+               ret_code = LTTNG_ERR_NO_CHANNEL;
+               goto error;
+       }
+
+       if (session->kernel_session) {
+               original_kernel_consumer_output =
+                               session->kernel_session->consumer;
+               snapshot_kernel_consumer_output =
+                               consumer_copy_output(snapshot_output->consumer);
+               ret = consumer_copy_sockets(snapshot_kernel_consumer_output,
+                               original_kernel_consumer_output);
+               if (ret < 0) {
+                       ERR("Failed to copy consumer sockets from snapshot output configuration");
+                       ret_code = LTTNG_ERR_NOMEM;
+                       goto error;
+               }
+               ret_code = set_relayd_for_snapshot(
+                               snapshot_kernel_consumer_output, session);
+               if (ret_code != LTTNG_OK) {
+                       ERR("Failed to setup relay daemon for kernel tracer snapshot");
+                       goto error;
+               }
+               session->kernel_session->consumer =
+                               snapshot_kernel_consumer_output;
+       }
+       if (session->ust_session) {
+               original_ust_consumer_output = session->ust_session->consumer;
+               snapshot_ust_consumer_output =
+                               consumer_copy_output(snapshot_output->consumer);
+               ret = consumer_copy_sockets(snapshot_ust_consumer_output,
+                               original_ust_consumer_output);
+               if (ret < 0) {
+                       ERR("Failed to copy consumer sockets from snapshot output configuration");
+                       ret_code = LTTNG_ERR_NOMEM;
+                       goto error;
+               }
+               ret_code = set_relayd_for_snapshot(
+                               snapshot_ust_consumer_output, session);
+               if (ret_code != LTTNG_OK) {
+                       ERR("Failed to setup relay daemon for userspace tracer snapshot");
+                       goto error;
+               }
+               session->ust_session->consumer =
+                               snapshot_ust_consumer_output;
+       }
+
        snapshot_trace_chunk = session_create_new_trace_chunk(session,
-                       snapshot_output_get_base_path(snapshot_output),
+                       snapshot_kernel_consumer_output ?:
+                                       snapshot_ust_consumer_output,
+                       consumer_output_get_base_path(
+                                       snapshot_output->consumer),
                        snapshot_chunk_name);
        if (!snapshot_trace_chunk) {
-               ret = LTTNG_ERR_CREATE_DIR_FAIL;
-               goto end;
+               ERR("Failed to create temporary trace chunk to record a snapshot of session \"%s\"",
+                               session->name);
+               ret_code = LTTNG_ERR_CREATE_DIR_FAIL;
+               goto error;
        }
        assert(!session->current_trace_chunk);
        ret = session_set_trace_chunk(session, snapshot_trace_chunk, NULL);
        lttng_trace_chunk_put(snapshot_trace_chunk);
        snapshot_trace_chunk = NULL;
        if (ret) {
-               ret = LTTNG_ERR_CREATE_TRACE_CHUNK_FAIL_CONSUMER;
-               goto end;
+               ERR("Failed to set temporary trace chunk to record a snapshot of session \"%s\"",
+                               session->name);
+               ret_code = LTTNG_ERR_CREATE_TRACE_CHUNK_FAIL_CONSUMER;
+               goto error;
        }
 
        nb_packets_per_stream = get_session_nb_packets_per_stream(session,
                        snapshot_output->max_size);
        if (nb_packets_per_stream < 0) {
-               ret = LTTNG_ERR_MAX_SIZE_INVALID;
-               goto end;
+               ret_code = LTTNG_ERR_MAX_SIZE_INVALID;
+               goto error;
        }
 
        if (session->kernel_session) {
-               ret = record_kernel_snapshot(session->kernel_session,
-                               snapshot_output, session,
+               ret_code = record_kernel_snapshot(session->kernel_session,
+                               snapshot_kernel_consumer_output, session,
                                wait, nb_packets_per_stream);
-               if (ret != LTTNG_OK) {
-                       goto end;
+               if (ret_code != LTTNG_OK) {
+                       goto error;
                }
        }
 
        if (session->ust_session) {
-               ret = record_ust_snapshot(session->ust_session,
-                               snapshot_output, session,
+               ret_code = record_ust_snapshot(session->ust_session,
+                               snapshot_ust_consumer_output, session,
                                wait, nb_packets_per_stream);
-               if (ret != LTTNG_OK) {
-                       goto end;
+               if (ret_code != LTTNG_OK) {
+                       goto error;
                }
        }
 
@@ -4516,15 +4522,24 @@ enum lttng_error_code snapshot_record(struct ltt_session *session,
                 */
                ERR("Failed to close snapshot trace chunk of session \"%s\"",
                                session->name);
-               ret = -1;
+               ret_code = LTTNG_ERR_CLOSE_TRACE_CHUNK_FAIL_CONSUMER;
        }
        if (session_set_trace_chunk(session, NULL, NULL)) {
                ERR("Failed to release the current trace chunk of session \"%s\"",
                                session->name);
-               ret = -1;
+               ret_code = LTTNG_ERR_UNK;
        }
-end:
-       return ret;
+error:
+       if (original_ust_consumer_output) {
+               session->ust_session->consumer = original_ust_consumer_output;
+       }
+       if (original_kernel_consumer_output) {
+               session->kernel_session->consumer =
+                               original_kernel_consumer_output;
+       }
+       consumer_output_put(snapshot_ust_consumer_output);
+       consumer_output_put(snapshot_kernel_consumer_output);
+       return ret_code;
 }
 
 /*
@@ -4743,7 +4758,7 @@ int cmd_rotate_session(struct ltt_session *session,
        session->rotation_state = LTTNG_ROTATION_STATE_ONGOING;
 
        if (session->active) {
-               new_trace_chunk = session_create_new_trace_chunk(session,
+               new_trace_chunk = session_create_new_trace_chunk(session, NULL,
                                NULL, NULL);
                if (!new_trace_chunk) {
                        cmd_ret = LTTNG_ERR_CREATE_DIR_FAIL;
index 10152864e9940beb0e6b3d4423fdd4a7e6013fcd..9246dc7ced5045986363355a4e67bcc30c151110 100644 (file)
@@ -315,7 +315,7 @@ error:
  * object reference is not needed anymore.
  */
 struct consumer_socket *consumer_find_socket_by_bitness(int bits,
-               struct consumer_output *consumer)
+               const struct consumer_output *consumer)
 {
        int consumer_fd;
        struct consumer_socket *socket = NULL;
@@ -348,7 +348,7 @@ end:
  * returned consumer_socket.
  */
 struct consumer_socket *consumer_find_socket(int key,
-               struct consumer_output *consumer)
+               const struct consumer_output *consumer)
 {
        struct lttng_ht_iter iter;
        struct lttng_ht_node_ulong *node;
@@ -405,7 +405,7 @@ void consumer_add_socket(struct consumer_socket *sock,
 }
 
 /*
- * Delte consumer socket to consumer output object. Read side lock must be
+ * Delete consumer socket to consumer output object. Read side lock must be
  * acquired before calling this function.
  */
 void consumer_del_socket(struct consumer_socket *sock,
@@ -1441,7 +1441,7 @@ end:
  * Returns LTTNG_OK on success or else an LTTng error code.
  */
 enum lttng_error_code consumer_snapshot_channel(struct consumer_socket *socket,
-               uint64_t key, const struct snapshot_output *output, int metadata,
+               uint64_t key, const struct consumer_output *output, int metadata,
                uid_t uid, gid_t gid, const char *channel_path, int wait,
                uint64_t nb_packets_per_stream)
 {
@@ -1451,7 +1451,6 @@ enum lttng_error_code consumer_snapshot_channel(struct consumer_socket *socket,
 
        assert(socket);
        assert(output);
-       assert(output->consumer);
 
        DBG("Consumer snapshot channel key %" PRIu64, key);
 
@@ -1461,9 +1460,9 @@ enum lttng_error_code consumer_snapshot_channel(struct consumer_socket *socket,
        msg.u.snapshot_channel.nb_packets_per_stream = nb_packets_per_stream;
        msg.u.snapshot_channel.metadata = metadata;
 
-       if (output->consumer->type == CONSUMER_DST_NET) {
+       if (output->type == CONSUMER_DST_NET) {
                msg.u.snapshot_channel.relayd_id =
-                               output->consumer->net_seq_index;
+                               output->net_seq_index;
                msg.u.snapshot_channel.use_relayd = 1;
        } else {
                msg.u.snapshot_channel.relayd_id = (uint64_t) -1ULL;
index 59585eda34ca17134ebd8a2c8e21582aa197436e..6fc17ad53737706f3edca3f49bd267d7c7cbe826 100644 (file)
@@ -182,9 +182,9 @@ struct consumer_output {
 };
 
 struct consumer_socket *consumer_find_socket(int key,
-               struct consumer_output *consumer);
+               const struct consumer_output *consumer);
 struct consumer_socket *consumer_find_socket_by_bitness(int bits,
-               struct consumer_output *consumer);
+               const struct consumer_output *consumer);
 struct consumer_socket *consumer_allocate_socket(int *fd);
 void consumer_add_socket(struct consumer_socket *sock,
                struct consumer_output *consumer);
@@ -301,7 +301,7 @@ int consumer_get_lost_packets(uint64_t session_id, uint64_t channel_key,
 
 /* Snapshot command. */
 enum lttng_error_code consumer_snapshot_channel(struct consumer_socket *socket,
-               uint64_t key, const struct snapshot_output *output, int metadata,
+               uint64_t key, const struct consumer_output *output, int metadata,
                uid_t uid, gid_t gid, const char *channel_path, int wait,
                uint64_t nb_packets_per_stream);
 
index c395f425542abe4bffe9f6ecfcf28a6f97e67be0..4fdc34bad23fb329edf97b893ca8d103c4982cd6 100644 (file)
@@ -1242,7 +1242,7 @@ void kernel_destroy_channel(struct ltt_kernel_channel *kchan)
  */
 enum lttng_error_code kernel_snapshot_record(
                struct ltt_kernel_session *ksess,
-               const struct snapshot_output *output, int wait,
+               const struct consumer_output *output, int wait,
                uint64_t nb_packets_per_stream)
 {
        int err, ret, saved_metadata_fd;
@@ -1276,24 +1276,14 @@ enum lttng_error_code kernel_snapshot_record(
        }
 
        /* 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) {
                        status = LTTNG_ERR_KERN_META_FAIL;
                        goto error_consumer;
index e62cfecd627e159ce264f568cea982c7ef56a22e..978e4cb93517485a5463c316f9b53ba6f8e73a15 100644 (file)
@@ -61,7 +61,7 @@ void kernel_destroy_session(struct ltt_kernel_session *ksess);
 void kernel_destroy_channel(struct ltt_kernel_channel *kchan);
 enum lttng_error_code kernel_snapshot_record(
                struct ltt_kernel_session *ksess,
-               const struct snapshot_output *output, int wait,
+               const struct consumer_output *output, int wait,
                uint64_t nb_packets_per_stream);
 int kernel_syscall_mask(int chan_fd, char **syscall_mask, uint32_t *nr_bits);
 enum lttng_error_code kernel_rotate_session(struct ltt_session *session);
index 4b5c22bfb8626ef8f52b48ebbb75a77d9b4b05e8..20edd47e4c707a109b350795c0eb1d725406b7bf 100644 (file)
@@ -565,21 +565,11 @@ error:
 }
 
 static
-bool output_supports_trace_chunks(const struct ltt_session *session)
+bool output_supports_trace_chunks(const struct consumer_output *output)
 {
-       if (session->consumer->type == CONSUMER_DST_LOCAL) {
+       if (output->type == CONSUMER_DST_LOCAL) {
                return true;
        } else {
-               struct consumer_output *output;
-
-               if (session->ust_session) {
-                       output = session->ust_session->consumer;
-               } else if (session->kernel_session) {
-                       output = session->kernel_session->consumer;
-               } else {
-                       abort();
-               }
-
                if (output->relay_major_version > 2) {
                        return true;
                } else if (output->relay_major_version == 2 &&
@@ -591,7 +581,8 @@ bool output_supports_trace_chunks(const struct ltt_session *session)
 }
 
 struct lttng_trace_chunk *session_create_new_trace_chunk(
-               struct ltt_session *session,
+               const struct ltt_session *session,
+               const struct consumer_output *consumer_output_override,
                const char *session_base_path_override,
                const char *chunk_name_override)
 {
@@ -599,16 +590,28 @@ struct lttng_trace_chunk *session_create_new_trace_chunk(
        struct lttng_trace_chunk *trace_chunk = NULL;
        enum lttng_trace_chunk_status chunk_status;
        const time_t chunk_creation_ts = time(NULL);
-       const bool is_local_trace =
-                       session->consumer->type == CONSUMER_DST_LOCAL;
-       const char *base_path = session_base_path_override ? :
-                       session_get_base_path(session);
+       bool is_local_trace;
+       const char *base_path;
        struct lttng_directory_handle session_output_directory;
        const struct lttng_credentials session_credentials = {
                .uid = session->uid,
                .gid = session->gid,
        };
        uint64_t next_chunk_id;
+       const struct consumer_output *output;
+
+       if (consumer_output_override) {
+               output = consumer_output_override;
+       } else {
+               assert(session->ust_session || session->kernel_session);
+               output = session->ust_session ?
+                                        session->ust_session->consumer :
+                                        session->kernel_session->consumer;
+       }
+
+       is_local_trace = output->type == CONSUMER_DST_LOCAL;
+       base_path = session_base_path_override ? :
+                       consumer_output_get_base_path(output);
 
        if (chunk_creation_ts == (time_t) -1) {
                PERROR("Failed to sample time while creation session \"%s\" trace chunk",
@@ -616,7 +619,7 @@ struct lttng_trace_chunk *session_create_new_trace_chunk(
                goto error;
        }
 
-       if (!output_supports_trace_chunks(session)) {
+       if (!output_supports_trace_chunks(output)) {
                goto end;
        }
        next_chunk_id = session->most_recent_chunk_id.is_set ?
index 0750e1bcd83427cdd7cce518a2935d80759b0ab2..03d90c2c5ae8041b58572eb8329321bdfe303a74 100644 (file)
@@ -224,7 +224,8 @@ int session_reset_rotation_state(struct ltt_session *session,
 
 /* Create a new trace chunk object from the session's configuration. */
 struct lttng_trace_chunk *session_create_new_trace_chunk(
-               struct ltt_session *session,
+               const struct ltt_session *session,
+               const struct consumer_output *consumer_output_override,
                const char *session_base_path_override,
                const char *chunk_name_override);
 
index d2edfd5ce4248062457432ff123498b582a9dfba..e01d43caf024ec61f3311ad323c4d3f7254afade 100644 (file)
@@ -5877,7 +5877,7 @@ void ust_app_destroy(struct ust_app *app)
  */
 enum lttng_error_code ust_app_snapshot_record(
                const struct ltt_ust_session *usess,
-               const struct snapshot_output *output, int wait,
+               const struct consumer_output *output, int wait,
                uint64_t nb_packets_per_stream)
 {
        int ret = 0;
@@ -5965,7 +5965,7 @@ enum lttng_error_code ust_app_snapshot_record(
 
                        /* Get the right consumer socket for the application. */
                        socket = consumer_find_socket_by_bitness(app->bits_per_long,
-                                       output->consumer);
+                                       output);
                        if (!socket) {
                                status = LTTNG_ERR_INVALID;
                                goto error;
index dcdc784cf58c613d183b15db91ab86a5718774a4..59db98e6ec6911e7233e3fbab746adf4586d4fa6 100644 (file)
@@ -341,7 +341,7 @@ ssize_t ust_app_push_metadata(struct ust_registry_session *registry,
 void ust_app_destroy(struct ust_app *app);
 enum lttng_error_code ust_app_snapshot_record(
                const struct ltt_ust_session *usess,
-               const struct snapshot_output *output, int wait,
+               const struct consumer_output *output, int wait,
                uint64_t nb_packets_per_stream);
 uint64_t ust_app_get_size_one_more_packet_per_stream(
                const struct ltt_ust_session *usess, uint64_t cur_nr_packets);
@@ -531,7 +531,7 @@ void ust_app_destroy(struct ust_app *app)
 }
 static inline
 enum lttng_error_code ust_app_snapshot_record(struct ltt_ust_session *usess,
-               struct snapshot_output *output, int wait, uint64_t max_stream_size)
+               struct consumer_output *output, int wait, uint64_t max_stream_size)
 {
        return 0;
 }
index 5207bfa74f740200d10dcaa50a6c5d6c98710069..f9a29e49ecd2625f8e6503a8a66a812d1bb72957 100644 (file)
@@ -62,19 +62,19 @@ static char *setup_channel_trace_path(struct consumer_output *consumer,
        }
 
        /* Get correct path name destination */
-       if (consumer->type == CONSUMER_DST_LOCAL) {
-               /* Set application path to the destination path */
-               ret = snprintf(pathname, LTTNG_PATH_MAX, "%s%s",
-                               consumer->domain_subdir, ua_sess->path);
-               DBG3("Userspace local consumer trace path relative to current trace chunk: \"%s\"",
-                               pathname);
-       } else {
+       if (consumer->type == CONSUMER_DST_NET &&
+                       consumer->relay_major_version == 2 &&
+                       consumer->relay_minor_version < 11) {
                ret = snprintf(pathname, LTTNG_PATH_MAX, "%s%s/%s%s",
                                consumer->dst.net.base_dir,
-                               consumer->chunk_path,
-                               consumer->domain_subdir,
+                               consumer->chunk_path, consumer->domain_subdir,
                                ua_sess->path);
+       } else {
+               ret = snprintf(pathname, LTTNG_PATH_MAX, "%s%s",
+                               consumer->domain_subdir, ua_sess->path);
        }
+       DBG3("Userspace consumer trace path relative to current trace chunk: \"%s\"",
+                       pathname);
        if (ret < 0) {
                PERROR("Failed to format channel path");
                goto error;
@@ -85,7 +85,6 @@ static char *setup_channel_trace_path(struct consumer_output *consumer,
        }
 
        return pathname;
-
 error:
        free(pathname);
        return NULL;
index 51fdc99335054362e7a08011ba467cfe26bab1b6..978af5883e2fe0b532897379ca0bd3486ddf7e3b 100644 (file)
@@ -99,15 +99,12 @@ int loglevels_match(int a_loglevel_type, int a_loglevel_value,
 
 const char *session_get_base_path(const struct ltt_session *session)
 {
-       return session->net_handle > 0 ?
-                       session->consumer->dst.net.base_dir :
-                       session->consumer->dst.session_root_path;
+       return consumer_output_get_base_path(session->consumer);
 }
 
-const char *snapshot_output_get_base_path(
-               const struct snapshot_output *snapshot_output)
+const char *consumer_output_get_base_path(const struct consumer_output *output)
 {
-       return snapshot_output->consumer->type == CONSUMER_DST_LOCAL ?
-                       snapshot_output->consumer->dst.session_root_path :
-                       snapshot_output->consumer->dst.net.base_dir;
+       return output->type == CONSUMER_DST_LOCAL ?
+                       output->dst.session_root_path :
+                       output->dst.net.base_dir;
 }
index 34aa257842dd2d30e508f21d8d488b3092ce73b4..50fc221e4e3c403e83c5e7ea90dd65b663cea11f 100644 (file)
@@ -20,7 +20,7 @@
 
 struct lttng_ht;
 struct ltt_session;
-struct snapshot_output;
+struct consumer_output;
 
 const char *get_home_dir(void);
 int notify_thread_pipe(int wpipe);
@@ -28,7 +28,6 @@ void ht_cleanup_push(struct lttng_ht *ht);
 int loglevels_match(int a_loglevel_type, int a_loglevel_value,
        int b_loglevel_type, int b_loglevel_value, int loglevel_all_type);
 const char *session_get_base_path(const struct ltt_session *session);
-const char *snapshot_output_get_base_path(
-               const struct snapshot_output *snapshot_output);
+const char *consumer_output_get_base_path(const struct consumer_output *output);
 
 #endif /* _LTT_UTILS_H */
index a0b81c6fae82634393fc9f2d6e8d2205d2dc2de8..599ce451c00580a042049d468d30b26be99561cf 100644 (file)
@@ -124,7 +124,17 @@ struct lttng_consumer_channel {
         * a session with per-PID buffers.
         */
        uint64_t session_id_per_pid;
-       /* Channel trace file path name. */
+       /*
+        * In the case of local streams, this field contains the channel's
+        * output path; a path relative to the session's output path.
+        *   e.g. ust/uid/1000/64-bit
+        *
+        * In the case of remote streams, the contents of this field depends
+        * on the version of the relay daemon peer. For 2.11+ peers, the
+        * contents are the same as in the local case. However, for legacy
+        * peers, this contains a path of the form:
+        *   /hostname/session_path/ust/uid/1000/64-bit
+        */
        char pathname[PATH_MAX];
        /* Channel name. */
        char name[LTTNG_SYMBOL_NAME_LEN];
index 694e3d18698dd3dfe142bc9e199026a9a8f6c9b4..f7e4e9054258a1febfacb8b161386e4942c7124d 100644 (file)
 
 #include "index.h"
 
-/*
- * Create the index file associated with a trace file.
- *
- * Return allocated struct lttng_index_file, NULL on error.
- */
-struct lttng_index_file *lttng_index_file_create(const char *path_name,
-               char *stream_name, int uid, int gid,
-               uint64_t size, uint64_t count, uint32_t major, uint32_t minor)
-{
-       struct lttng_index_file *index_file;
-       int ret, fd = -1;
-       ssize_t size_ret;
-       struct ctf_packet_index_file_hdr hdr;
-       char fullpath[PATH_MAX];
-       uint32_t element_len = ctf_packet_index_len(major, minor);
-
-       index_file = zmalloc(sizeof(*index_file));
-       if (!index_file) {
-               PERROR("allocating lttng_index_file");
-               goto error;
-       }
-
-       ret = snprintf(fullpath, sizeof(fullpath), "%s/" DEFAULT_INDEX_DIR,
-                       path_name);
-       if (ret < 0) {
-               PERROR("snprintf index path");
-               goto error;
-       }
-
-       /* Create index directory if necessary. */
-       ret = utils_mkdir(fullpath, S_IRWXU | S_IRWXG, uid, gid);
-       if (ret < 0) {
-               if (errno != EEXIST) {
-                       PERROR("Index trace directory creation error");
-                       goto error;
-               }
-       }
-
-       /*
-        * For tracefile rotation. We need to unlink the old
-        * file if present to synchronize with the tail of the
-        * live viewer which could be working on this same file.
-        * By doing so, any reference to the old index file
-        * stays valid even if we re-create a new file with the
-        * same name afterwards.
-        */
-       ret = utils_unlink_stream_file(fullpath, stream_name, size, count, uid,
-                       gid, DEFAULT_INDEX_FILE_SUFFIX);
-       if (ret < 0 && errno != ENOENT) {
-               goto error;
-       }
-       ret = utils_create_stream_file(fullpath, stream_name, size, count, uid,
-                       gid, DEFAULT_INDEX_FILE_SUFFIX);
-       if (ret < 0) {
-               goto error;
-       }
-       fd = ret;
-
-       ctf_packet_index_file_hdr_init(&hdr, major, minor);
-       size_ret = lttng_write(fd, &hdr, sizeof(hdr));
-       if (size_ret < sizeof(hdr)) {
-               PERROR("write index header");
-               goto error;
-       }
-       index_file->fd = fd;
-       index_file->major = major;
-       index_file->minor = minor;
-       index_file->element_len = element_len;
-       urcu_ref_init(&index_file->ref);
-
-       return index_file;
-
-error:
-       if (fd >= 0) {
-               int close_ret;
-
-               close_ret = close(fd);
-               if (close_ret < 0) {
-                       PERROR("close index fd");
-               }
-       }
-       free(index_file);
-       return NULL;
-}
-
 struct lttng_index_file *lttng_index_file_create_from_trace_chunk(
                struct lttng_trace_chunk *chunk,
                const char *channel_path, char *stream_name,
@@ -165,12 +80,14 @@ struct lttng_index_file *lttng_index_file_create_from_trace_chunk(
                 * stays valid even if we re-create a new file with the
                 * same name afterwards.
                 */
-               chunk_status = lttng_trace_chunk_unlink_file(chunk,
-                               index_file_path);
-               if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+               chunk_status = lttng_trace_chunk_unlink_file(
+                               chunk, index_file_path);
+               if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK &&
+                               !(chunk_status == LTTNG_TRACE_CHUNK_STATUS_ERROR &&
+                                               errno == ENOENT)) {
                        goto error;
                }
-        }
+       }
 
        chunk_status = lttng_trace_chunk_open_file(chunk, index_file_path,
                        flags, mode, &fd);
index 469a870abe18312e84c1340d79d17e1317ef1dce..a999a83d9b74aef5bcc7ca79d0b2185db39127db 100644 (file)
@@ -38,9 +38,6 @@ struct lttng_index_file {
  * create and open have refcount of 1. Use put to decrement the
  * refcount. Destroys when reaching 0. Use "get" to increment refcount.
  */
-struct lttng_index_file *lttng_index_file_create(const char *path_name,
-               char *stream_name, int uid, int gid, uint64_t size,
-               uint64_t count, uint32_t major, uint32_t minor);
 struct lttng_index_file *lttng_index_file_create_from_trace_chunk(
                struct lttng_trace_chunk *chunk,
                const char *channel_path, char *stream_name,
index 87782e99477af6b3321ca40d597ed7b5c521f9b0..91cbf762f90989809aaafd17623bee095492f4f9 100644 (file)
@@ -408,7 +408,7 @@ static int relayd_add_stream_2_11(struct lttcomm_relayd_sock *rsock,
 
        msg->tracefile_size = htobe64(tracefile_size);
        msg->tracefile_count = htobe64(tracefile_count);
-       msg->trace_archive_id = htobe64(trace_archive_id);
+       msg->trace_chunk_id = htobe64(trace_archive_id);
 
        /* Send command */
        ret = send_command(rsock, RELAYD_ADD_STREAM, (void *) msg, msg_length, 0);
index 2ae94b3655ba262d57a71f9182f4f5ab2f64ceb5..47f1d5cd738327290e91b27a91ee8b765522cde3 100644 (file)
@@ -92,7 +92,7 @@ struct lttcomm_relayd_add_stream_2_11 {
        uint32_t pathname_len;
        uint64_t tracefile_size;
        uint64_t tracefile_count;
-       uint64_t trace_archive_id;
+       uint64_t trace_chunk_id;
        char names[];
 } LTTNG_PACKED;
 
This page took 0.05316 seconds and 5 git commands to generate.