* 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;
};
/*
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. */
#define LTTNG_ROTATION_H
#include <stdint.h>
+#include <lttng/location.h>
#ifdef __cplusplus
extern "C" {
* 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.
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);
#include "session.h"
#include "utils.h"
+#include "trace-ust.h"
/*
* NOTES:
pthread_mutex_unlock(<t_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.
*
#include "snapshot.h"
#include "trace-kernel.h"
+#include "consumer.h"
struct ltt_ust_session;
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);
#include "../command.h"
#include <lttng/rotation.h>
+#include <lttng/location.h>
static char *opt_session_name;
static int opt_no_wait;
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;
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;
}
#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>
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;
}
*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
* 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;
}
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;
void lttng_rotation_handle_destroy(
struct lttng_rotation_handle *rotation_handle)
{
+ lttng_trace_archive_location_destroy(rotation_handle->archive_location);
free(rotation_handle);
}