Extend the rotation API to provide network trace archive locations
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Sat, 7 Apr 2018 20:07:56 +0000 (16:07 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sat, 7 Apr 2018 21:16:45 +0000 (17:16 -0400)
The current lttng-ctl rotation API does not allow a user to
differentiate between a network or local trace archive location.

The API currently only provides a "path" which is absolute when
a local rotation is completed, and relative (to an unknown location)
when the trace is streamed to a relay daemon.

This change introduces the lttng_trace_archive_location interface
to express these locations unambiguously. It is currently only
used by the rotation control API, but the intention is to also use
it for future interfaces which need to express a location description.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/lttng/rotate-internal.h
include/lttng/rotation.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/session.c
src/bin/lttng-sessiond/session.h
src/bin/lttng/commands/rotate.c
src/lib/lttng-ctl/rotate.c

index f5e4dc950b4875ef5e239e2ec497042d34643c59..74c85b0b648c5093eda2336552b52979e8d012d0 100644 (file)
@@ -69,10 +69,7 @@ struct lttng_rotation_handle {
         * Where the rotated (readable) trace has been stored when the
         * rotation is completed.
         */
-       struct {
-               bool is_set;
-               char path[LTTNG_PATH_MAX];
-       } archive_location;
+       struct lttng_trace_archive_location *archive_location;
 };
 
 /*
@@ -89,7 +86,26 @@ struct lttng_rotate_session_return {
 struct lttng_rotation_get_info_return {
        /* Represents values defined in enum lttng_rotation_state. */
        int32_t status;
-       char path[LTTNG_PATH_MAX];
+       /* Represents values defined in enum lttng_rotation_state. */
+       uint8_t location_type;
+       union {
+               struct {
+                       char absolute_path[LTTNG_PATH_MAX];
+               } LTTNG_PACKED local;
+               struct {
+                       char host[LTTNG_HOST_NAME_MAX];
+                       /*
+                        * Represents values defined in
+                        * enum lttng_trace_archive_location_relay_protocol_type.
+                        */
+                       uint8_t protocol;
+                       struct {
+                               uint16_t control;
+                               uint16_t data;
+                       } LTTNG_PACKED ports;
+                       char relative_path[LTTNG_PATH_MAX];
+               } LTTNG_PACKED relay;
+       } location;
 } LTTNG_PACKED;
 
 /* For the LTTNG_SESSION_GET_CURRENT_OUTPUT command. */
index 0b4b2ad2f5eb8f92c01e60f9a484e8d23c3b19fd..dbc0183da7e856a26df927c454df439b2e5f3a37 100644 (file)
@@ -20,6 +20,7 @@
 #define LTTNG_ROTATION_H
 
 #include <stdint.h>
+#include <lttng/location.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -162,16 +163,14 @@ extern enum lttng_rotation_status lttng_rotation_handle_get_state(
  * Get the location of the rotation's resulting archive.
  *
  * The rotation must be completed in order for this call to succeed.
- * The path returned is owned by the rotation handle.
+ * The location returned remains owned by the rotation handle.
  *
- * Note that path will not be set in case of error, or if the session
- * rotation has expired.
- *
- * FIXME: Return an lttng_location object instead of a path.
+ * Note that location will not be set in case of error, or if the session
+ * rotation handle has expired.
  */
-extern enum lttng_rotation_status lttng_rotation_handle_get_completed_archive_location(
+extern enum lttng_rotation_status lttng_rotation_handle_get_archive_location(
                struct lttng_rotation_handle *rotation_handle,
-               const char **path);
+               const struct lttng_trace_archive_location **location);
 
 /*
  * Destroy an lttng_rotate_session handle.
index e0a8db9b2cc13a2b5c77407e0b14938fa565a587..534f191a8b447d0763d56ec62d4aba42a0c3af70 100644 (file)
@@ -4635,16 +4635,59 @@ int cmd_rotate_get_info(struct ltt_session *session,
                                rotation_id, session->name);
                break;
        case LTTNG_ROTATION_STATE_COMPLETED:
-               ret = lttng_strncpy(info_return->path,
+       {
+               char *current_tracing_path_reply;
+               size_t current_tracing_path_reply_len;
+
+               switch (session_get_consumer_destination_type(session)) {
+               case CONSUMER_DST_LOCAL:
+                       current_tracing_path_reply =
+                                       info_return->location.local.absolute_path;
+                       current_tracing_path_reply_len =
+                                       sizeof(info_return->location.local.absolute_path);
+                       info_return->location_type =
+                                       (uint8_t) LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL;
+                       break;
+               case CONSUMER_DST_NET:
+                       current_tracing_path_reply =
+                                       info_return->location.relay.relative_path;
+                       current_tracing_path_reply_len =
+                                       sizeof(info_return->location.relay.relative_path);
+                       /* Currently the only supported relay protocol. */
+                       info_return->location.relay.protocol =
+                                       (uint8_t) LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP;
+
+                       ret = lttng_strncpy(info_return->location.relay.host,
+                                       session_get_net_consumer_hostname(session),
+                                       sizeof(info_return->location.relay.host));
+                       if (ret) {
+                               ERR("Failed to host name to rotate_get_info reply");
+                               info_return->status = LTTNG_ROTATION_STATUS_ERROR;
+                               ret = -LTTNG_ERR_UNK;
+                               goto end;
+                       }
+
+                       session_get_net_consumer_ports(session,
+                                       &info_return->location.relay.ports.control,
+                                       &info_return->location.relay.ports.data);
+                       info_return->location_type =
+                                       (uint8_t) LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY;
+                       break;
+               default:
+                       abort();
+               }
+               ret = lttng_strncpy(current_tracing_path_reply,
                                session->rotation_chunk.current_rotate_path,
-                               sizeof(info_return->path));
+                               current_tracing_path_reply_len);
                if (ret) {
-                       ERR("Failed to copy active tracing path to rotate_get_info reply");
+                       ERR("Failed to copy current tracing path to rotate_get_info reply");
                        info_return->status = LTTNG_ROTATION_STATUS_ERROR;
                        ret = -LTTNG_ERR_UNK;
                        goto end;
                }
+
                break;
+       }
        case LTTNG_ROTATION_STATE_ERROR:
                DBG("Reporting that an error occurred during rotation %" PRIu64 " of session %s",
                                rotation_id, session->name);
index 2b7d65eaa1b61fbae82a230ee2a6b7247505d0ac..01cdfdc00b670757e5fc46c842cdd5293aafc6b5 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "session.h"
 #include "utils.h"
+#include "trace-ust.h"
 
 /*
  * NOTES:
@@ -141,6 +142,74 @@ void session_unlock_list(void)
        pthread_mutex_unlock(&ltt_session_list.lock);
 }
 
+/*
+ * Get the session's consumer destination type.
+ *
+ * The caller must hold the session lock.
+ */
+enum consumer_dst_type session_get_consumer_destination_type(
+               const struct ltt_session *session)
+{
+       /*
+        * The output information is duplicated in both of those session types.
+        * Hence, it doesn't matter from which it is retrieved. However, it is
+        * possible for only one of them to be set.
+        */
+       return session->kernel_session ?
+                       session->kernel_session->consumer->type :
+                       session->ust_session->consumer->type;
+}
+
+/*
+ * Get the session's consumer network hostname.
+ * The caller must ensure that the destination is of type "net".
+ *
+ * The caller must hold the session lock.
+ */
+const char *session_get_net_consumer_hostname(const struct ltt_session *session)
+{
+       const char *hostname = NULL;
+       const struct consumer_output *output;
+
+       output = session->kernel_session ?
+                       session->kernel_session->consumer :
+                       session->ust_session->consumer;
+
+       /*
+        * hostname is assumed to be the same for both control and data
+        * connections.
+        */
+       switch (output->dst.net.control.dtype) {
+       case LTTNG_DST_IPV4:
+               hostname = output->dst.net.control.dst.ipv4;
+               break;
+       case LTTNG_DST_IPV6:
+               hostname = output->dst.net.control.dst.ipv6;
+               break;
+       default:
+               abort();
+       }
+       return hostname;
+}
+
+/*
+ * Get the session's consumer network control and data ports.
+ * The caller must ensure that the destination is of type "net".
+ *
+ * The caller must hold the session lock.
+ */
+void session_get_net_consumer_ports(const struct ltt_session *session,
+               uint16_t *control_port, uint16_t *data_port)
+{
+       const struct consumer_output *output;
+
+       output = session->kernel_session ?
+                       session->kernel_session->consumer :
+                       session->ust_session->consumer;
+       *control_port = output->dst.net.control.port;
+       *data_port = output->dst.net.data.port;
+}
+
 /*
  * Allocate the ltt_sessions_ht_by_id HT.
  *
index ab9b1a9a4355edf8aa98ecb29d7350802d96fb26..b8c7890810ab966d23860805cabfff5be62426e9 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "snapshot.h"
 #include "trace-kernel.h"
+#include "consumer.h"
 
 struct ltt_ust_session;
 
@@ -202,6 +203,14 @@ void session_lock_list(void);
 void session_unlock(struct ltt_session *session);
 void session_unlock_list(void);
 
+enum consumer_dst_type session_get_consumer_destination_type(
+               const struct ltt_session *session);
+const char *session_get_net_consumer_hostname(
+               const struct ltt_session *session);
+void session_get_net_consumer_ports(
+               const struct ltt_session *session,
+               uint16_t *control_port, uint16_t *data_port);
+
 struct ltt_session *session_find_by_name(const char *name);
 struct ltt_session *session_find_by_id(uint64_t id);
 struct ltt_session_list *session_get_list(void);
index 5a00d699416b164df72d5d9659e3745e994d7256..05e55bf3cc39d1eb8a138641061b33d69f886fc1 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "../command.h"
 #include <lttng/rotation.h>
+#include <lttng/location.h>
 
 static char *opt_session_name;
 static int opt_no_wait;
@@ -100,6 +101,111 @@ end:
        return ret;
 }
 
+static int output_trace_archive_location(
+               const struct lttng_trace_archive_location *location,
+               const char *session_name)
+{
+       int ret = 0;
+       enum lttng_trace_archive_location_type location_type;
+       enum lttng_trace_archive_location_status status;
+       bool printed_location = false;
+
+       location_type = lttng_trace_archive_location_get_type(location);
+
+       _MSG("Trace chunk archive for session %s is now readable",
+                       session_name);
+       switch (location_type) {
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
+       {
+               const char *absolute_path;
+
+               status = lttng_trace_archive_location_local_get_absolute_path(
+                               location, &absolute_path);
+               if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
+                       ret = -1;
+                       goto end;
+               }
+               MSG(" at %s", absolute_path);
+               ret = mi_output_rotate("completed", absolute_path,
+                               session_name);
+               if (ret) {
+                       goto end;
+               }
+               printed_location = true;
+               break;
+       }
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
+       {
+               uint16_t control_port, data_port;
+               const char *host, *relative_path, *protocol_str;
+               enum lttng_trace_archive_location_relay_protocol_type protocol;
+
+               /* Fetch all relay location parameters. */
+               status = lttng_trace_archive_location_relay_get_protocol_type(
+                               location, &protocol);
+               if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
+                       ret = -1;
+                       goto end;
+               }
+
+               status = lttng_trace_archive_location_relay_get_host(
+                               location, &host);
+               if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
+                       ret = -1;
+                       goto end;
+               }
+
+               status = lttng_trace_archive_location_relay_get_control_port(
+                               location, &control_port);
+               if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
+                       ret = -1;
+                       goto end;
+               }
+
+               status = lttng_trace_archive_location_relay_get_data_port(
+                               location, &data_port);
+               if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
+                       ret = -1;
+                       goto end;
+               }
+
+               status = lttng_trace_archive_location_relay_get_relative_path(
+                               location, &relative_path);
+               if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
+                       ret = -1;
+                       goto end;
+               }
+
+               switch (protocol) {
+               case LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP:
+                       protocol_str = "tcp";
+                       break;
+               default:
+                       protocol_str = "unknown";
+                       break;
+               }
+
+               MSG(" on relay %s://%s/%s [control port %" PRIu16 ", data port %"
+                               PRIu16 "]", protocol_str, host,
+                               relative_path, control_port, data_port);
+               printed_location = true;
+               ret = mi_output_rotate("completed", relative_path,
+                               session_name);
+               if (ret) {
+                       goto end;
+               }
+               break;
+       }
+       default:
+               break;
+       }
+end:
+       if (!printed_location) {
+               MSG(" at an unknown location");
+       }
+       return ret;
+}
+
 static int rotate_tracing(char *session_name)
 {
        int ret;
@@ -176,17 +282,15 @@ static int rotate_tracing(char *session_name)
        switch (rotation_state) {
        case LTTNG_ROTATION_STATE_COMPLETED:
        {
-               const char *path;
+               const struct lttng_trace_archive_location *location;
 
-               rotation_status = lttng_rotation_handle_get_completed_archive_location(
-                               handle, &path);
+               rotation_status = lttng_rotation_handle_get_archive_location(
+                               handle, &location);
                if (rotation_status != LTTNG_ROTATION_STATUS_OK) {
                        ERR("Failed to retrieve the rotation's completed chunk archive location");
                        goto error;
                }
-               MSG("Trace chunk archive for session %s is now readable at %s",
-                               session_name, path);
-               ret = mi_output_rotate("completed", path, session_name);
+               ret = output_trace_archive_location(location, session_name);
                if (ret) {
                        goto error;
                }
index 4b7c2f9162c69ba18e837dbcfbdab72404bf9411..bdce8d8574a82f5bb1872a332d7023a79c47bac8 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <lttng/lttng-error.h>
 #include <lttng/rotation.h>
+#include <lttng/location-internal.h>
 #include <lttng/rotate-internal.h>
 #include <common/sessiond-comm/sessiond-comm.h>
 #include <common/macros.h>
@@ -155,13 +156,39 @@ void lttng_rotation_schedule_attr_set_size(
        attr->size = size;
 }
 
+static
+struct lttng_trace_archive_location *
+create_trace_archive_location_from_get_info(
+               const struct lttng_rotation_get_info_return *info)
+{
+       struct lttng_trace_archive_location *location;
+
+       switch (info->location_type) {
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
+               location = lttng_trace_archive_location_local_create(
+                               info->location.local.absolute_path);
+               break;
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
+               location = lttng_trace_archive_location_relay_create(
+                               info->location.relay.host,
+                               info->location.relay.protocol,
+                               info->location.relay.ports.control,
+                               info->location.relay.ports.data,
+                               info->location.relay.relative_path);
+               break;
+       default:
+               location = NULL;
+               break;
+       }
+       return location;
+}
+
 enum lttng_rotation_status lttng_rotation_handle_get_state(
                struct lttng_rotation_handle *rotation_handle,
                enum lttng_rotation_state *state)
 {
        enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
        struct lttng_rotation_get_info_return *info = NULL;
-       int ret;
 
        if (!rotation_handle || !state) {
                status = LTTNG_ROTATION_STATUS_INVALID;
@@ -174,7 +201,7 @@ enum lttng_rotation_status lttng_rotation_handle_get_state(
        }
 
        *state = (enum lttng_rotation_state) info->status;
-       if (rotation_handle->archive_location.is_set ||
+       if (rotation_handle->archive_location ||
                        *state != LTTNG_ROTATION_STATE_COMPLETED) {
                /*
                 * The path is only provided by the sessiond once
@@ -187,35 +214,32 @@ enum lttng_rotation_status lttng_rotation_handle_get_state(
         * Cache the location since the rotation may expire before the user
         * has a chance to query it.
         */
-       ret = lttng_strncpy(rotation_handle->archive_location.path,
-                       info->path,
-                       sizeof(rotation_handle->archive_location.path));
-       if (ret) {
+       rotation_handle->archive_location =
+                       create_trace_archive_location_from_get_info(info);
+       if (!rotation_handle->archive_location) {
                status = LTTNG_ROTATION_STATUS_ERROR;
                goto end;
        }
-       rotation_handle->archive_location.is_set = true;
 end:
        free(info);
        return status;
 }
 
-enum lttng_rotation_status lttng_rotation_handle_get_completed_archive_location(
+enum lttng_rotation_status lttng_rotation_handle_get_archive_location(
                struct lttng_rotation_handle *rotation_handle,
-               const char **path)
+               const struct lttng_trace_archive_location **location)
 {
-       int ret;
        enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
        struct lttng_rotation_get_info_return *info = NULL;
 
-       if (!rotation_handle || !path) {
+       if (!rotation_handle || !location) {
                status = LTTNG_ROTATION_STATUS_INVALID;
                goto end;
        }
 
        /* Use the cached location we got from a previous query. */
-       if (rotation_handle->archive_location.is_set) {
-               *path = rotation_handle->archive_location.path;
+       if (rotation_handle->archive_location) {
+               *location = rotation_handle->archive_location;
                goto end;
        }
 
@@ -230,14 +254,12 @@ enum lttng_rotation_status lttng_rotation_handle_get_completed_archive_location(
                goto end;
        }
 
-       ret = lttng_strncpy(rotation_handle->archive_location.path,
-                       info->path,
-                       sizeof(rotation_handle->archive_location.path));
-       if (ret) {
+       rotation_handle->archive_location =
+                       create_trace_archive_location_from_get_info(info);
+       if (!rotation_handle->archive_location) {
                status = LTTNG_ROTATION_STATUS_ERROR;
                goto end;
        }
-       rotation_handle->archive_location.is_set = true;
 end:
        free(info);
        return status;
@@ -246,6 +268,7 @@ end:
 void lttng_rotation_handle_destroy(
                struct lttng_rotation_handle *rotation_handle)
 {
+       lttng_trace_archive_location_destroy(rotation_handle->archive_location);
        free(rotation_handle);
 }
 
This page took 0.034766 seconds and 4 git commands to generate.