The session daemon does not report errors which occur while setting-up
a session's destruction. For instance, if the implicit rotation or
rotation to the "null" chunk fails. While the session will be
destroyed (it will no longer appear in session listings), the session
daemon could have failed to destroy it properly and it could be
corrupted/unreadable.
This reports those errors so the user does not expect the session to
be readable (but it _could_ be).
This was discovered while investigating another, unrelated, issue.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
LTTNG_ERR_TRACE_CHUNK_EXISTS_FAIL_CONSUMER = 151, /* failed to query consumer for trace chunk existence */
LTTNG_ERR_INVALID_PROTOCOL = 152, /* a protocol error occurred */
LTTNG_ERR_FILE_CREATION_ERROR = 153, /* failed to create a file */
LTTNG_ERR_TRACE_CHUNK_EXISTS_FAIL_CONSUMER = 151, /* failed to query consumer for trace chunk existence */
LTTNG_ERR_INVALID_PROTOCOL = 152, /* a protocol error occurred */
LTTNG_ERR_FILE_CREATION_ERROR = 153, /* failed to create a file */
+ LTTNG_ERR_TIMER_STOP_ERROR = 154, /* failed to stop timer. */
/* MUST be last element */
LTTNG_ERR_NR, /* Last element */
/* MUST be last element */
LTTNG_ERR_NR, /* Last element */
struct cmd_destroy_session_reply_context {
int reply_sock_fd;
bool implicit_rotation_on_destroy;
struct cmd_destroy_session_reply_context {
int reply_sock_fd;
bool implicit_rotation_on_destroy;
+ /*
+ * Indicates whether or not an error occurred while launching the
+ * destruction of a session.
+ */
+ enum lttng_error_code destruction_status;
};
static enum lttng_error_code wait_on_path(void *path);
};
static enum lttng_error_code wait_on_path(void *path);
struct lttng_trace_archive_location *location = NULL;
struct lttcomm_lttng_msg llm = {
.cmd_type = LTTNG_DESTROY_SESSION,
struct lttng_trace_archive_location *location = NULL;
struct lttcomm_lttng_msg llm = {
.cmd_type = LTTNG_DESTROY_SESSION,
+ .ret_code = reply_context->destruction_status,
.pid = UINT32_MAX,
.cmd_header_size =
sizeof(struct lttcomm_session_destroy_command_header),
.pid = UINT32_MAX,
.cmd_header_size =
sizeof(struct lttcomm_session_destroy_command_header),
+ enum lttng_error_code destruction_last_error = LTTNG_OK;
struct cmd_destroy_session_reply_context *reply_context = NULL;
if (sock_fd) {
struct cmd_destroy_session_reply_context *reply_context = NULL;
if (sock_fd) {
/* Carry on with the destruction of the session. */
ERR("Failed to stop session \"%s\" as part of its destruction: %s",
session->name, lttng_strerror(-ret));
/* Carry on with the destruction of the session. */
ERR("Failed to stop session \"%s\" as part of its destruction: %s",
session->name, lttng_strerror(-ret));
+ destruction_last_error = ret;
session)) {
ERR("Failed to stop the \"rotation schedule\" timer of session %s",
session->name);
session)) {
ERR("Failed to stop the \"rotation schedule\" timer of session %s",
session->name);
+ destruction_last_error = LTTNG_ERR_TIMER_STOP_ERROR;
if (ret != LTTNG_OK) {
ERR("Failed to perform an implicit rotation as part of the destruction of session \"%s\": %s",
session->name, lttng_strerror(-ret));
if (ret != LTTNG_OK) {
ERR("Failed to perform an implicit rotation as part of the destruction of session \"%s\": %s",
session->name, lttng_strerror(-ret));
+ destruction_last_error = -ret;
}
if (reply_context) {
reply_context->implicit_rotation_on_destroy = true;
}
if (reply_context) {
reply_context->implicit_rotation_on_destroy = true;
if (ret != LTTNG_OK) {
ERR("Failed to perform a quiet rotation as part of the destruction of session \"%s\": %s",
session->name, lttng_strerror(-ret));
if (ret != LTTNG_OK) {
ERR("Failed to perform a quiet rotation as part of the destruction of session \"%s\": %s",
session->name, lttng_strerror(-ret));
+ destruction_last_error = -ret;
*/
session_destroy(session);
if (reply_context) {
*/
session_destroy(session);
if (reply_context) {
+ reply_context->destruction_status = destruction_last_error;
ret = session_add_destroy_notifier(session,
cmd_destroy_session_reply,
(void *) reply_context);
ret = session_add_destroy_notifier(session,
cmd_destroy_session_reply,
(void *) reply_context);
goto error;
}
if (ret_code != LTTNG_OK) {
goto error;
}
if (ret_code != LTTNG_OK) {
*/
static int destroy_all_sessions(struct lttng_session *sessions, int count)
{
*/
static int destroy_all_sessions(struct lttng_session *sessions, int count)
{
- int i, ret = CMD_SUCCESS;
+ int i;
+ bool error_occurred = false;
if (count == 0) {
MSG("No session found, nothing to do.");
if (count == 0) {
MSG("No session found, nothing to do.");
- } else if (count < 0) {
- ERR("%s", lttng_strerror(ret));
- goto error;
}
for (i = 0; i < count; i++) {
}
for (i = 0; i < count; i++) {
- ret = destroy_session(&sessions[i]);
+ int ret = destroy_session(&sessions[i]);
+
+ ERR("%s during the destruction of session \"%s\"",
+ lttng_strerror(ret),
+ sessions[i].name);
+ /* Continue to next session. */
+ error_occurred = true;
+
+ return error_occurred ? CMD_ERROR : CMD_SUCCESS;
command_ret = destroy_session(&sessions[i]);
if (command_ret) {
success = 0;
command_ret = destroy_session(&sessions[i]);
if (command_ret) {
success = 0;
+ ERR("%s during the destruction of session \"%s\"",
+ lttng_strerror(command_ret),
+ sessions[i].name);
[ ERROR_INDEX(LTTNG_ERR_TRACE_CHUNK_EXISTS_FAIL_CONSUMER) ] = "Failed to query consumer for trace chunk existence",
[ ERROR_INDEX(LTTNG_ERR_INVALID_PROTOCOL) ] = "Protocol error occurred",
[ ERROR_INDEX(LTTNG_ERR_FILE_CREATION_ERROR) ] = "Failed to create file",
[ ERROR_INDEX(LTTNG_ERR_TRACE_CHUNK_EXISTS_FAIL_CONSUMER) ] = "Failed to query consumer for trace chunk existence",
[ ERROR_INDEX(LTTNG_ERR_INVALID_PROTOCOL) ] = "Protocol error occurred",
[ ERROR_INDEX(LTTNG_ERR_FILE_CREATION_ERROR) ] = "Failed to create file",
+ [ ERROR_INDEX(LTTNG_ERR_TIMER_STOP_ERROR) ] = "Failed to stop a timer",
/* Last element */
[ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"
/* Last element */
[ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"