Skip to content

Commit

Permalink
relayd protocol: reply path for close chunk and create session 2.11
Browse files Browse the repository at this point in the history
Since the relay daemon is expected to be able to move the target
destination of the trace, reply the chunk and session path so session
can have relevant data rather than guessing their location.

The session daemon now use this information to send the path back to
the client for rotation and destroy commands, as well as for
rotation completion notifications.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
  • Loading branch information
compudj authored and jgalar committed Sep 4, 2019
1 parent 64da855 commit ac5cb7d
Show file tree
Hide file tree
Showing 17 changed files with 392 additions and 163 deletions.
165 changes: 77 additions & 88 deletions src/bin/lttng-relayd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ static int relay_create_session(const struct lttcomm_relayd_hdr *recv_hdr,
int ret = 0;
ssize_t send_ret;
struct relay_session *session = NULL;
struct lttcomm_relayd_status_session reply = {};
struct lttcomm_relayd_create_session_reply_2_11 reply = {};
char session_name[LTTNG_NAME_MAX] = {};
char hostname[LTTNG_HOST_NAME_MAX] = {};
uint32_t live_timer = 0;
Expand Down Expand Up @@ -1133,21 +1133,46 @@ static int relay_create_session(const struct lttcomm_relayd_hdr *recv_hdr,
conn->session = session;
DBG("Created session %" PRIu64, session->id);

reply.session_id = htobe64(session->id);
reply.generic.session_id = htobe64(session->id);

send_reply:
if (ret < 0) {
reply.ret_code = htobe32(LTTNG_ERR_FATAL);
reply.generic.ret_code = htobe32(LTTNG_ERR_FATAL);
} else {
reply.ret_code = htobe32(LTTNG_OK);
reply.generic.ret_code = htobe32(LTTNG_OK);
}

send_ret = conn->sock->ops->sendmsg(conn->sock, &reply, sizeof(reply), 0);
if (send_ret < (ssize_t) sizeof(reply)) {
ERR("Failed to send \"create session\" command reply (ret = %zd)",
send_ret);
ret = -1;
if (conn->minor < 11) {
/* From 2.1 to 2.10 */
send_ret = conn->sock->ops->sendmsg(conn->sock, &reply.generic,
sizeof(reply.generic), 0);
if (send_ret < (ssize_t) sizeof(reply.generic)) {
ERR("Failed to send \"create session\" command reply (ret = %zd)",
send_ret);
ret = -1;
}
} else {
const uint32_t output_path_length =
strlen(session->output_path) + 1;

reply.output_path_length = htobe32(output_path_length);
send_ret = conn->sock->ops->sendmsg(conn->sock, &reply,
sizeof(reply), 0);
if (send_ret < (ssize_t) sizeof(reply)) {
ERR("Failed to send \"create session\" command reply (ret = %zd)",
send_ret);
ret = -1;
goto end;
}
send_ret = conn->sock->ops->sendmsg(conn->sock, session->output_path,
output_path_length, 0);
if (send_ret < output_path_length) {
ERR("Failed to send \"create session\" command reply output path (ret = %zd)",
send_ret);
ret = -1;
}
}
end:
if (ret < 0 && session) {
session_put(session);
}
Expand Down Expand Up @@ -2195,6 +2220,7 @@ static int relay_rotate_session_streams(
} else {
chunk_id_str = chunk_id_buf;
}
session->has_rotated = true;
}

DBG("Rotate %" PRIu32 " streams of session \"%s\" to chunk \"%s\"",
Expand Down Expand Up @@ -2266,87 +2292,14 @@ static int init_session_output_directory_handle(struct relay_session *session,
struct lttng_directory_handle *handle)
{
int ret;
/*
* session_directory:
*
* if base_path is \0'
* hostname/session_name
* else
* hostname/base_path
*/
char *session_directory = NULL;
/*
* relayd_output_path/session_directory
* e.g. /home/user/lttng-traces/hostname/session_name
*/
char *full_session_path = NULL;

/*
* If base path is set, it overrides the session name for the
* session relative base path. No timestamp is appended if the
* base path is overridden.
*
* If the session name already contains the creation time (e.g.
* auto-<timestamp>, don't append yet another timestamp after
* the session name in the generated path.
*
* Otherwise, generate the path with session_name-<timestamp>.
*/
if (session->base_path[0] != '\0') {
pthread_mutex_lock(&session->lock);
ret = asprintf(&session_directory, "%s/%s", session->hostname,
session->base_path);
pthread_mutex_unlock(&session->lock);
} else if (session->session_name_contains_creation_time) {
pthread_mutex_lock(&session->lock);
ret = asprintf(&session_directory, "%s/%s", session->hostname,
session->session_name);
pthread_mutex_unlock(&session->lock);
} else {
char session_creation_datetime[16];
size_t strftime_ret;
struct tm *timeinfo;
time_t creation_time;

/*
* The 2.11+ protocol guarantees that a creation time
* is provided for a session. This would indicate a
* protocol error or an improper use of this util.
*/
if (!session->creation_time.is_set) {
ERR("Creation time missing for session \"%s\" (protocol error)",
session->session_name);
ret = -1;
goto end;
}
creation_time = LTTNG_OPTIONAL_GET(session->creation_time);

timeinfo = localtime(&creation_time);
if (!timeinfo) {
ERR("Failed to get timeinfo while initializing session output directory handle");
ret = -1;
goto end;
}
strftime_ret = strftime(session_creation_datetime,
sizeof(session_creation_datetime),
"%Y%m%d-%H%M%S", timeinfo);
if (strftime_ret == 0) {
ERR("Failed to format session creation timestamp while initializing session output directory handle");
ret = -1;
goto end;
}
pthread_mutex_lock(&session->lock);
ret = asprintf(&session_directory, "%s/%s-%s",
session->hostname, session->session_name,
session_creation_datetime);
pthread_mutex_unlock(&session->lock);
}
if (ret < 0) {
PERROR("Failed to format session directory name");
goto end;
}

full_session_path = create_output_path(session_directory);
pthread_mutex_lock(&session->lock);
full_session_path = create_output_path(session->output_path);
if (!full_session_path) {
ret = -1;
goto end;
Expand All @@ -2365,7 +2318,7 @@ static int init_session_output_directory_handle(struct relay_session *session,
goto end;
}
end:
free(session_directory);
pthread_mutex_unlock(&session->lock);
free(full_session_path);
return ret;
}
Expand Down Expand Up @@ -2540,14 +2493,17 @@ static int relay_close_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr,
ssize_t send_ret;
struct relay_session *session = conn->session;
struct lttcomm_relayd_close_trace_chunk *msg;
struct lttcomm_relayd_generic_reply reply = {};
struct lttcomm_relayd_close_trace_chunk_reply reply = {};
struct lttng_buffer_view header_view;
struct lttng_trace_chunk *chunk = NULL;
enum lttng_error_code reply_code = LTTNG_OK;
enum lttng_trace_chunk_status chunk_status;
uint64_t chunk_id;
LTTNG_OPTIONAL(enum lttng_trace_chunk_command_type) close_command = {};
time_t close_timestamp;
char path[LTTNG_PATH_MAX];
uint32_t path_length = 0;
const char *chunk_name = NULL;

if (!session || !conn->version_check_done) {
ERR("Trying to close a trace chunk before version check");
Expand Down Expand Up @@ -2623,6 +2579,30 @@ static int relay_close_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr,
goto end_unlock_session;
}
}
chunk_status = lttng_trace_chunk_get_name(chunk, &chunk_name, NULL);
if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
ERR("Failed to get chunk name");
ret = -1;
reply_code = LTTNG_ERR_UNK;
goto end_unlock_session;
}
if (!session->has_rotated && !session->snapshot) {
strncpy(path, session->output_path, LTTNG_PATH_MAX);
path[sizeof(path) - 1] = '\0';
} else {
if (session->snapshot) {
ret = snprintf(path, sizeof(path), "%s/%s",
session->output_path,
chunk_name);
} else {
ret = snprintf(path, sizeof(path), "%s/"
DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY "/%s",
session->output_path,
chunk_name);
}
}
DBG("Reply chunk path on close: %s", path);
path_length = strlen(path) + 1;

if (session->current_trace_chunk == chunk) {
/*
Expand All @@ -2642,15 +2622,24 @@ static int relay_close_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr,
pthread_mutex_unlock(&session->lock);

end:
reply.ret_code = htobe32((uint32_t) reply_code);
reply.generic.ret_code = htobe32((uint32_t) reply_code);
reply.path_length = htobe32((uint32_t) path_length);
send_ret = conn->sock->ops->sendmsg(conn->sock,
&reply,
sizeof(struct lttcomm_relayd_generic_reply),
sizeof(reply),
0);
if (send_ret < (ssize_t) sizeof(reply)) {
ERR("Failed to send \"create trace chunk\" command reply (ret = %zd)",
send_ret);
ret = -1;
goto end_no_reply;
}
send_ret = conn->sock->ops->sendmsg(conn->sock,
path, path_length, 0);
if (send_ret < path_length) {
ERR("Failed to send \"create trace chunk\" command reply path (ret = %zd)",
send_ret);
ret = -1;
}
end_no_reply:
lttng_trace_chunk_put(chunk);
Expand Down
92 changes: 92 additions & 0 deletions src/bin/lttng-relayd/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,94 @@
static uint64_t last_relay_session_id;
static pthread_mutex_t last_relay_session_id_lock = PTHREAD_MUTEX_INITIALIZER;

static int init_session_output_path(struct relay_session *session)
{
/*
* session_directory:
*
* if base_path is \0'
* hostname/session_name
* else
* hostname/base_path
*/
char *session_directory = NULL;
int ret = 0;

if (session->output_path[0] != '\0') {
goto end;
}
/*
* If base path is set, it overrides the session name for the
* session relative base path. No timestamp is appended if the
* base path is overridden.
*
* If the session name already contains the creation time (e.g.
* auto-<timestamp>, don't append yet another timestamp after
* the session name in the generated path.
*
* Otherwise, generate the path with session_name-<timestamp>.
*/
if (session->base_path[0] != '\0') {
ret = asprintf(&session_directory, "%s/%s", session->hostname,
session->base_path);
} else if (session->session_name_contains_creation_time) {
ret = asprintf(&session_directory, "%s/%s", session->hostname,
session->session_name);
} else {
char session_creation_datetime[16];
size_t strftime_ret;
struct tm *timeinfo;
time_t creation_time;

/*
* The 2.11+ protocol guarantees that a creation time
* is provided for a session. This would indicate a
* protocol error or an improper use of this util.
*/
if (!session->creation_time.is_set) {
ERR("Creation time missing for session \"%s\" (protocol error)",
session->session_name);
ret = -1;
goto end;
}
creation_time = LTTNG_OPTIONAL_GET(session->creation_time);

timeinfo = localtime(&creation_time);
if (!timeinfo) {
ERR("Failed to get timeinfo while initializing session output directory handle");
ret = -1;
goto end;
}
strftime_ret = strftime(session_creation_datetime,
sizeof(session_creation_datetime),
"%Y%m%d-%H%M%S", timeinfo);
if (strftime_ret == 0) {
ERR("Failed to format session creation timestamp while initializing session output directory handle");
ret = -1;
goto end;
}
ret = asprintf(&session_directory, "%s/%s-%s",
session->hostname, session->session_name,
session_creation_datetime);
}
if (ret < 0) {
PERROR("Failed to format session directory name");
goto end;
}

if (strlen(session_directory) >= LTTNG_PATH_MAX) {
ERR("session directory too long");
ret = -1;
goto end;
}
strcpy(session->output_path, session_directory);
ret = 0;

end:
free(session_directory);
return ret;
}

static int session_set_anonymous_chunk(struct relay_session *session)
{
int ret = 0;
Expand Down Expand Up @@ -183,6 +271,10 @@ struct relay_session *session_create(const char *session_name,
LTTNG_OPTIONAL_SET(&session->id_sessiond, *id_sessiond);
}

ret = init_session_output_path(session);
if (ret) {
goto error;
}
ret = sessiond_trace_chunk_registry_session_created(
sessiond_trace_chunk_registry, sessiond_uuid);
if (ret) {
Expand Down
4 changes: 4 additions & 0 deletions src/bin/lttng-relayd/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ struct relay_session {
char session_name[LTTNG_NAME_MAX];
char hostname[LTTNG_HOST_NAME_MAX];
char base_path[LTTNG_PATH_MAX];
/* Session output path relative to relayd's output path. */
char output_path[LTTNG_PATH_MAX];
uint32_t live_timer;

/* Session in snapshot mode. */
Expand Down Expand Up @@ -88,6 +90,8 @@ struct relay_session {
bool aborted;

bool session_name_contains_creation_time;
/* Whether session has performed an explicit rotation. */
bool has_rotated;

/* Contains ctf_trace object of that session indexed by path name. */
struct lttng_ht *ctf_traces_ht;
Expand Down
Loading

0 comments on commit ac5cb7d

Please sign in to comment.