* 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,
};
/*
session->rotate_count++;
session->rotate_pending = 1;
+ session->rotate_status = LTTNG_ROTATE_STARTED;
/*
* Create the path name for the next chunk.
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;
*/
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;
}
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];
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) {
new_path);
if (ret) {
ERR("Rename ust session");
- ret = -1;
- goto end;
+ ret = 0;
+ goto error;
}
}
} else {
new_path, 0);
if (ret) {
ERR("Session rename");
- ret = -1;
- goto end;
+ ret = 0;
+ goto error;
}
}
"%s", new_path);
session->rotate_pending = 0;
+ goto end;
+
+error:
+ session->rotate_status = LTTNG_ROTATE_ERROR;
end:
free(new_path);
return ret;
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;
}
*/
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
*/
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;
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);
/* 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) {
break;
}
+ if (nr_app == 0 && nr_channels == 0) {
+ session->rotate_pending = 0;
+ session->rotate_status = LTTNG_ROTATE_EMPTY;
+ }
+
ret = LTTNG_OK;
error:
}
}
+ ret = CMD_SUCCESS;
+ goto end;
+ case LTTNG_ROTATE_EMPTY:
+ MSG("Empty session, nothing to rotate.");
ret = CMD_SUCCESS;
goto end;
}
}
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),
* 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);
}
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;
}
}
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: