From 4a478f45caad5ae9d766fcef682f46dd640303ed Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Tue, 22 Aug 2017 17:05:14 -0400 Subject: [PATCH] handle empty sessions Signed-off-by: Julien Desfossez --- include/lttng/rotate.h | 7 +++++- src/bin/lttng-sessiond/cmd.c | 9 +++++++- src/bin/lttng-sessiond/rotate.c | 28 ++++++++++++++++-------- src/bin/lttng-sessiond/rotation-thread.c | 1 + src/bin/lttng-sessiond/session.h | 1 + src/bin/lttng-sessiond/ust-app.c | 9 +++++++- src/bin/lttng/commands/rotate.c | 4 ++++ src/common/consumer/consumer.c | 24 ++++++++++++-------- src/lib/lttng-ctl/rotate.c | 15 ++++++++++--- 9 files changed, 74 insertions(+), 24 deletions(-) diff --git a/include/lttng/rotate.h b/include/lttng/rotate.h index 65afcaac7..c340fb1c7 100644 --- a/include/lttng/rotate.h +++ b/include/lttng/rotate.h @@ -39,10 +39,15 @@ enum lttng_rotate_status { * retrieve the path for the chunk. */ LTTNG_ROTATE_EXPIRED = 2, + /* + * Nothing to rotate, it happens on the first rotation when tracing + * only in user-space and no app was started. + */ + LTTNG_ROTATE_EMPTY = 3, /* * On error. */ - LTTNG_ROTATE_ERROR = 3, + LTTNG_ROTATE_ERROR = 4, }; /* diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index ed112489b..6c815eff1 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -4192,6 +4192,7 @@ int cmd_rotate_session(struct ltt_session *session, session->rotate_count++; session->rotate_pending = 1; + session->rotate_status = LTTNG_ROTATE_STARTED; /* * Create the path name for the next chunk. @@ -4279,7 +4280,13 @@ int cmd_rotate_pending(struct ltt_session *session, goto end; } - if (session->rotate_pending) { + if (session->rotate_status == LTTNG_ROTATE_ERROR) { + DBG("An error occurred during rotation"); + (*pending_return)->status = LTTNG_ROTATE_ERROR; + } else if (session->rotate_status == LTTNG_ROTATE_EMPTY) { + DBG("Nothing to rotate"); + (*pending_return)->status = LTTNG_ROTATE_EMPTY; + } else if (session->rotate_pending) { DBG("Session %s, rotate_id %" PRIu64 " still pending", session->name, session->rotate_count); (*pending_return)->status = LTTNG_ROTATE_STARTED; diff --git a/src/bin/lttng-sessiond/rotate.c b/src/bin/lttng-sessiond/rotate.c index bcd0b828d..f1085e42e 100644 --- a/src/bin/lttng-sessiond/rotate.c +++ b/src/bin/lttng-sessiond/rotate.c @@ -169,7 +169,7 @@ int rename_first_chunk(struct ltt_session *session, */ ret = session_rename_chunk(session, tmppath, tmppath2, 1); if (ret < 0) { - PERROR("Rename first trace directory"); + ERR("Rename first trace directory"); ret = -LTTNG_ERR_ROTATE_NO_DATA; goto error; } @@ -201,13 +201,12 @@ int rename_complete_chunk(struct ltt_session *session, time_t ts) new_path = zmalloc(PATH_MAX * sizeof(char)); if (!new_path) { + session->rotate_status = LTTNG_ROTATE_ERROR; ERR("Alloc new_path"); ret = -1; goto end; } - fprintf(stderr, "COUNT: %d\n", session->rotate_count); - if (session->rotate_count == 1) { char start_time[16]; @@ -233,8 +232,15 @@ int rename_complete_chunk(struct ltt_session *session, time_t ts) new_path); if (ret) { ERR("Rename kernel session"); - ret = -1; - goto end; + /* + * This is not a fatal error for the rotation + * thread, we just need to inform the client + * that a problem occurred with the rotation. + * Returning 0, same for the other errors + * below. + */ + ret = 0; + goto error; } } if (session->ust_session) { @@ -246,8 +252,8 @@ int rename_complete_chunk(struct ltt_session *session, time_t ts) new_path); if (ret) { ERR("Rename ust session"); - ret = -1; - goto end; + ret = 0; + goto error; } } } else { @@ -268,8 +274,8 @@ int rename_complete_chunk(struct ltt_session *session, time_t ts) new_path, 0); if (ret) { ERR("Session rename"); - ret = -1; - goto end; + ret = 0; + goto error; } } @@ -282,6 +288,10 @@ int rename_complete_chunk(struct ltt_session *session, time_t ts) "%s", new_path); session->rotate_pending = 0; + goto end; + +error: + session->rotate_status = LTTNG_ROTATE_ERROR; end: free(new_path); return ret; diff --git a/src/bin/lttng-sessiond/rotation-thread.c b/src/bin/lttng-sessiond/rotation-thread.c index e50903f69..4f7ac86e5 100644 --- a/src/bin/lttng-sessiond/rotation-thread.c +++ b/src/bin/lttng-sessiond/rotation-thread.c @@ -313,6 +313,7 @@ int handle_channel_rotation_pipe(int fd, uint32_t revents, time_t now = time(NULL); if (now == (time_t) -1) { + channel_info->session->rotate_status = LTTNG_ROTATE_ERROR; ret = LTTNG_ERR_ROTATE_NOT_AVAILABLE; goto end; } diff --git a/src/bin/lttng-sessiond/session.h b/src/bin/lttng-sessiond/session.h index 9e5c3151b..41a894079 100644 --- a/src/bin/lttng-sessiond/session.h +++ b/src/bin/lttng-sessiond/session.h @@ -136,6 +136,7 @@ struct ltt_session { */ uint64_t rotate_count; unsigned int rotate_pending:1; + enum lttng_rotate_status rotate_status; /* * Number of channels waiting for a rotate. * When this number reaches 0, we can handle the rename of the chunk diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 85e2f1a7d..368e58667 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -6286,7 +6286,7 @@ int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess) */ int ust_app_rotate_session(struct ltt_session *session) { - int ret = 0; + int ret = 0, nr_channels = 0, nr_app = 0; struct lttng_ht_iter iter; struct ust_app *app; struct ltt_ust_session *usess = session->ust_session; @@ -6312,6 +6312,7 @@ int ust_app_rotate_session(struct ltt_session *session) struct buffer_reg_channel *reg_chan; struct consumer_socket *socket; + nr_channels++; /* Get consumer socket to use to push the metadata.*/ socket = consumer_find_socket_by_bitness(reg->bits_per_long, usess->consumer); @@ -6390,6 +6391,7 @@ int ust_app_rotate_session(struct ltt_session *session) /* Session not associated with this app. */ continue; } + nr_app++; ret = snprintf(pathname, PATH_MAX, DEFAULT_UST_TRACE_DIR "/%s", ua_sess->path); if (ret < 0) { @@ -6461,6 +6463,11 @@ int ust_app_rotate_session(struct ltt_session *session) break; } + if (nr_app == 0 && nr_channels == 0) { + session->rotate_pending = 0; + session->rotate_status = LTTNG_ROTATE_EMPTY; + } + ret = LTTNG_OK; error: diff --git a/src/bin/lttng/commands/rotate.c b/src/bin/lttng/commands/rotate.c index 246f39800..c2e5580fc 100644 --- a/src/bin/lttng/commands/rotate.c +++ b/src/bin/lttng/commands/rotate.c @@ -183,6 +183,10 @@ static int rotate_tracing(void) } } + ret = CMD_SUCCESS; + goto end; + case LTTNG_ROTATE_EMPTY: + MSG("Empty session, nothing to rotate."); ret = CMD_SUCCESS; goto end; } diff --git a/src/common/consumer/consumer.c b/src/common/consumer/consumer.c index ef69d65a4..240cb3e83 100644 --- a/src/common/consumer/consumer.c +++ b/src/common/consumer/consumer.c @@ -3956,6 +3956,13 @@ int lttng_consumer_rotate_channel(uint64_t key, char *path, } pthread_mutex_lock(&channel->lock); snprintf(channel->pathname, PATH_MAX, "%s", path); + ret = utils_mkdir_recursive(channel->pathname, S_IRWXU | S_IRWXG, + channel->uid, channel->gid); + if (ret < 0) { + ERR("Trace directory creation error"); + ret = -1; + goto end_unlock_channel; + } cds_lfht_for_each_entry_duplicate(ht->ht, ht->hash_fct(&channel->key, lttng_ht_seed), @@ -3969,14 +3976,6 @@ int lttng_consumer_rotate_channel(uint64_t key, char *path, * Lock stream because we are about to change its state. */ pthread_mutex_lock(&stream->lock); - ret = utils_mkdir_recursive(channel->pathname, S_IRWXU | S_IRWXG, - stream->uid, stream->gid); - if (ret < 0) { - if (errno != EEXIST) { - ERR("Trace directory creation error"); - goto end_unlock; - } - } memcpy(stream->channel_ro_pathname, channel->pathname, PATH_MAX); ret = lttng_consumer_sample_snapshot_positions(stream); @@ -4221,10 +4220,17 @@ int lttng_consumer_rotate_rename(char *current_path, char *new_path, } ret = rename(current_path, new_path); - if (ret < 0) { + /* + * If a domain has not yet created its channel, the domain-specific + * folder might not exist, but this is not an error. + */ + if (ret < 0 && errno != ENOENT) { PERROR("Rename completed rotation chunk"); + goto end; } + ret = 0; + end: return ret; } diff --git a/src/lib/lttng-ctl/rotate.c b/src/lib/lttng-ctl/rotate.c index 7a6dcbd69..49d3a26b6 100644 --- a/src/lib/lttng-ctl/rotate.c +++ b/src/lib/lttng-ctl/rotate.c @@ -188,14 +188,23 @@ int lttng_rotate_session_pending( } rotate_handle->status = pending_return->status; - if (pending_return->status == LTTNG_ROTATE_COMPLETED) { + switch(pending_return->status) { + /* Not pending anymore */ + case LTTNG_ROTATE_COMPLETED: snprintf(rotate_handle->output_path, PATH_MAX, "%s", pending_return->output_path); + case LTTNG_ROTATE_EXPIRED: + case LTTNG_ROTATE_EMPTY: ret = 0; - } else if (pending_return->status == LTTNG_ROTATE_STARTED) { + break; + /* Still pending */ + case LTTNG_ROTATE_STARTED: ret = 1; - } else { + break; + /* Error */ + default: ret = -1; + break; } end: -- 2.34.1