uint32_t *live_timer, bool *snapshot,
uint64_t *id_sessiond, lttng_uuid sessiond_uuid,
bool *has_current_chunk, uint64_t *current_chunk_id,
- time_t *creation_time)
+ time_t *creation_time,
+ bool *session_name_contains_creation_time)
{
int ret;
struct lttcomm_relayd_create_session_2_11 header;
*current_chunk_id = header.current_chunk_id.value;
*has_current_chunk = header.current_chunk_id.is_set;
*creation_time = (time_t) header.creation_time;
+ *session_name_contains_creation_time =
+ header.session_name_contains_creation_time;
ret = 0;
uint32_t *live_timer, bool *snapshot,
uint64_t *id_sessiond, lttng_uuid sessiond_uuid,
bool *has_current_chunk, uint64_t *current_chunk_id,
- time_t *creation_time);
+ time_t *creation_time,
+ bool *session_name_contains_creation_time);
int cmd_recv_stream_2_11(const struct lttng_buffer_view *payload,
char **ret_path_name, char **ret_channel_name,
}
strncpy(hostname, session_info.hostname,
sizeof(session_info.hostname));
+
*live_timer = be32toh(session_info.live_timer);
*snapshot = be32toh(session_info.snapshot);
char hostname[LTTNG_HOST_NAME_MAX] = {};
uint32_t live_timer = 0;
bool snapshot = false;
+ bool session_name_contains_creation_timestamp = false;
/* Left nil for peers < 2.11. */
char base_path[LTTNG_PATH_MAX] = {};
lttng_uuid sessiond_uuid = {};
ret = cmd_create_session_2_11(payload, session_name, hostname,
base_path, &live_timer, &snapshot, &id_sessiond_value,
sessiond_uuid, &has_current_chunk,
- ¤t_chunk_id_value, &creation_time_value);
+ ¤t_chunk_id_value, &creation_time_value,
+ &session_name_contains_creation_timestamp);
if (lttng_uuid_is_nil(sessiond_uuid)) {
/* The nil UUID is reserved for pre-2.11 clients. */
ERR("Illegal nil UUID announced by peer in create session command");
id_sessiond.is_set ? &id_sessiond.value : NULL,
current_chunk_id.is_set ? ¤t_chunk_id.value : NULL,
creation_time.is_set ? &creation_time.value : NULL,
- conn->major, conn->minor);
+ conn->major, conn->minor,
+ session_name_contains_creation_timestamp);
if (!session) {
ret = -1;
goto send_reply;
/*
* session_directory:
*
- * if base_path is NULL
+ * if base_path is \0'
* hostname/session_name
* else
* hostname/base_path
*/
char *session_directory = NULL;
/*
- * base path + session_directory
+ * 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') {
- char creation_time_str[16];
+ 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;
- assert(session->creation_time.is_set);
- timeinfo = localtime(&session->creation_time.value);
- if (!timeinfo) {
+ /*
+ * 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;
}
- strftime(creation_time_str, sizeof(creation_time_str), "%Y%m%d-%H%M%S",
- timeinfo);
+ 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, creation_time_str);
- pthread_mutex_unlock(&session->lock);
- } else {
- pthread_mutex_lock(&session->lock);
- ret = asprintf(&session_directory, "%s/%s", session->hostname,
- session->base_path);
+ ret = asprintf(&session_directory, "%s/%s-%s",
+ session->hostname, session->session_name,
+ session_creation_datetime);
pthread_mutex_unlock(&session->lock);
}
if (ret < 0) {
const uint64_t *current_chunk_id,
const time_t *creation_time,
uint32_t major,
- uint32_t minor)
+ uint32_t minor,
+ bool session_name_contains_creation_time)
{
int ret;
struct relay_session *session = NULL;
WARN("Base path exceeds maximal allowed length");
goto error;
}
+ if (creation_time) {
+ LTTNG_OPTIONAL_SET(&session->creation_time, *creation_time);
+ }
+ session->session_name_contains_creation_time =
+ session_name_contains_creation_time;
session->ctf_traces_ht = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
if (!session->ctf_traces_ht) {
}
lttng_ht_add_unique_u64(sessions_ht, &session->session_n);
- if (creation_time) {
- LTTNG_OPTIONAL_SET(&session->creation_time, *creation_time);
- }
return session;
error:
*/
bool aborted;
+ bool session_name_contains_creation_time;
+
/* Contains ctf_trace object of that session indexed by path name. */
struct lttng_ht *ctf_traces_ht;
const uint64_t *current_chunk_id,
const time_t *creation_time,
uint32_t major,
- uint32_t minor);
+ uint32_t minor,
+ bool session_name_contains_creation_timestamp);
struct relay_session *session_get_by_id(uint64_t id);
bool session_get(struct relay_session *session);
void session_put(struct relay_session *session);
const char *session_name, const char *hostname,
const char *base_path, int session_live_timer,
const uint64_t *current_chunk_id,
- time_t session_creation_time)
+ time_t session_creation_time,
+ bool session_name_contains_creation_time)
{
int ret;
struct lttcomm_relayd_sock *rsock = NULL;
relayd_uri->stype, session_id,
session_name, hostname, base_path,
session_live_timer, current_chunk_id,
- session_creation_time);
+ session_creation_time, session_name_contains_creation_time);
if (ret < 0) {
status = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
goto close_sock;
unsigned int session_id, struct consumer_output *consumer,
struct consumer_socket *sock, const char *session_name,
const char *hostname, const char *base_path, int session_live_timer,
- const uint64_t *current_chunk_id, time_t session_creation_time)
+ const uint64_t *current_chunk_id, time_t session_creation_time,
+ bool session_name_contains_creation_time)
{
enum lttng_error_code status = LTTNG_OK;
status = send_consumer_relayd_socket(session_id,
&consumer->dst.net.control, consumer, sock,
session_name, hostname, base_path, session_live_timer,
- current_chunk_id, session_creation_time);
+ current_chunk_id, session_creation_time,
+ session_name_contains_creation_time);
if (status != LTTNG_OK) {
goto error;
}
status = send_consumer_relayd_socket(session_id,
&consumer->dst.net.data, consumer, sock,
session_name, hostname, base_path, session_live_timer,
- current_chunk_id, session_creation_time);
+ current_chunk_id, session_creation_time,
+ session_name_contains_creation_time);
if (status != LTTNG_OK) {
goto error;
}
session->base_path,
session->live_timer,
current_chunk_id.is_set ? ¤t_chunk_id.value : NULL,
- session->creation_time);
+ session->creation_time,
+ session->name_contains_creation_time);
pthread_mutex_unlock(socket->lock);
if (ret != LTTNG_OK) {
goto error;
session->base_path,
session->live_timer,
current_chunk_id.is_set ? ¤t_chunk_id.value : NULL,
- session->creation_time);
+ session->creation_time,
+ session->name_contains_creation_time);
pthread_mutex_unlock(socket->lock);
if (ret != LTTNG_OK) {
goto error;
base_path,
session->live_timer,
current_chunk_id.is_set ? ¤t_chunk_id.value : NULL,
- session->creation_time);
+ session->creation_time,
+ session->name_contains_creation_time);
pthread_mutex_unlock(socket->lock);
if (status != LTTNG_OK) {
rcu_read_unlock();
enum lttng_stream_type type, uint64_t session_id,
const char *session_name, const char *hostname,
const char *base_path, int session_live_timer,
- const uint64_t *current_chunk_id, time_t session_creation_time)
+ const uint64_t *current_chunk_id, time_t session_creation_time,
+ bool session_name_contains_creation_time)
{
int ret;
struct lttcomm_consumer_msg msg;
session_live_timer,
consumer->snapshot, session_id,
sessiond_uuid, current_chunk_id,
- session_creation_time);
+ session_creation_time,
+ session_name_contains_creation_time);
if (ret < 0) {
/* Close the control socket. */
(void) relayd_close(rsock);
enum lttng_stream_type type, uint64_t session_id,
const char *session_name, const char *hostname,
const char *base_path, int session_live_timer,
- const uint64_t *current_chunk_id, time_t session_creation_time);
+ const uint64_t *current_chunk_id, time_t session_creation_time,
+ bool session_name_contains_creation_time);
int consumer_send_channel_monitor_pipe(struct consumer_socket *consumer_sock,
int pipe);
int consumer_send_destroy_relayd(struct consumer_socket *sock,
DEFAULT_SESSION_NAME, i,
datetime);
}
+ new_session->name_contains_creation_time = true;
if (ret == -1 || ret >= sizeof(new_session->name)) {
/*
* Null-terminate in case the name is used
struct ltt_session {
char name[NAME_MAX];
bool has_auto_generated_name;
+ bool name_contains_creation_time;
char hostname[HOST_NAME_MAX]; /* Local hostname. */
time_t creation_time;
struct ltt_kernel_session *kernel_session;
const char *base_path, int session_live_timer,
unsigned int snapshot, uint64_t sessiond_session_id,
const lttng_uuid sessiond_uuid, const uint64_t *current_chunk_id,
- time_t creation_time)
+ time_t creation_time, bool session_name_contains_creation_time)
{
int ret;
struct lttcomm_relayd_create_session_2_11 *msg = NULL;
size_t msg_length;
char *dst;
- /* The two names are sent with a '\0' delimiter between them. */
+ if (!base_path) {
+ base_path = "";
+ }
+ /* The three names are sent with a '\0' delimiter between them. */
session_name_len = strlen(session_name) + 1;
hostname_len = strlen(hostname) + 1;
base_path_len = base_path ? strlen(base_path) + 1 : 0;
lttng_uuid_copy(msg->sessiond_uuid, sessiond_uuid);
msg->session_id = htobe64(sessiond_session_id);
-
+ msg->session_name_contains_creation_time = session_name_contains_creation_time;
if (current_chunk_id) {
LTTNG_OPTIONAL_SET(&msg->current_chunk_id,
htobe64(*current_chunk_id));
unsigned int snapshot, uint64_t sessiond_session_id,
const lttng_uuid sessiond_uuid,
const uint64_t *current_chunk_id,
- time_t creation_time)
+ time_t creation_time, bool session_name_contains_creation_time)
{
int ret;
struct lttcomm_relayd_status_session reply;
ret = relayd_create_session_2_11(rsock, session_name,
hostname, base_path, session_live_timer, snapshot,
sessiond_session_id, sessiond_uuid,
- current_chunk_id, creation_time);
+ current_chunk_id, creation_time,
+ session_name_contains_creation_time);
}
if (ret < 0) {
unsigned int snapshot, uint64_t sessiond_session_id,
const lttng_uuid sessiond_uuid,
const uint64_t *current_chunk_id,
- time_t creation_time);
+ time_t creation_time, bool session_name_contains_creation_time);
int relayd_add_stream(struct lttcomm_relayd_sock *sock, const char *channel_name,
const char *pathname, uint64_t *stream_id,
uint64_t tracefile_size, uint64_t tracefile_count,
uint32_t base_path_len;
uint32_t live_timer;
uint8_t snapshot;
+ uint8_t session_name_contains_creation_time;
/* Sessiond instance UUID */
lttng_uuid sessiond_uuid;
/* Sessiond session id */