From 91c4d516d04451cd1716fe3721748dae9e9d3753 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Thu, 16 Aug 2018 20:48:28 -0400 Subject: [PATCH] mi: serialize relay rotation locations MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau --- src/bin/lttng/commands/rotate.c | 236 +++++++++++------------------ src/common/mi-lttng-3.0.xsd | 53 ++++++- src/common/mi-lttng.c | 253 ++++++++++++++++++++++++++++++++ src/common/mi-lttng.h | 49 ++++++- 4 files changed, 433 insertions(+), 158 deletions(-) diff --git a/src/bin/lttng/commands/rotate.c b/src/bin/lttng/commands/rotate.c index 1e4677ffd..7439f4fbe 100644 --- a/src/bin/lttng/commands/rotate.c +++ b/src/bin/lttng/commands/rotate.c @@ -57,50 +57,6 @@ static struct poptOption long_options[] = { {0, 0, 0, 0, 0, 0, 0} }; -static int mi_output_rotate(const char *status, const char *path, - const char *session_name) -{ - int ret; - - if (!lttng_opt_mi) { - ret = 0; - goto end; - } - - ret = mi_lttng_writer_open_element(writer, - mi_lttng_element_rotation); - if (ret) { - goto end; - } - - ret = mi_lttng_writer_write_element_string(writer, - mi_lttng_element_session_name, session_name); - if (ret) { - goto end; - } - - ret = mi_lttng_writer_write_element_string(writer, - mi_lttng_element_rotate_status, status); - if (ret) { - goto end; - } - if (path) { - ret = mi_lttng_writer_write_element_string(writer, - config_element_path, path); - if (ret) { - goto end; - } - } - /* Close rotation element */ - ret = mi_lttng_writer_close_element(writer); - if (ret) { - goto end; - } - -end: - return ret; -} - static int output_trace_archive_location( const struct lttng_trace_archive_location *location, const char *session_name) @@ -126,11 +82,6 @@ static int output_trace_archive_location( goto end; } MSG(" at %s", absolute_path); - ret = mi_output_rotate("completed", absolute_path, - session_name); - if (ret) { - goto end; - } printed_location = true; break; } @@ -189,11 +140,6 @@ static int output_trace_archive_location( PRIu16 "]", protocol_str, host, relative_path, control_port, data_port); printed_location = true; - ret = mi_output_rotate("completed", relative_path, - session_name); - if (ret) { - goto end; - } break; } default: @@ -209,9 +155,12 @@ end: static int rotate_tracing(char *session_name) { int ret; + enum cmd_error_code cmd_ret = CMD_SUCCESS; struct lttng_rotation_handle *handle = NULL; enum lttng_rotation_status rotation_status; enum lttng_rotation_state rotation_state = LTTNG_ROTATION_STATE_ONGOING; + const struct lttng_trace_archive_location *location = NULL; + bool print_location = true; DBG("Rotating the output files of session %s", session_name); @@ -220,89 +169,95 @@ static int rotate_tracing(char *session_name) switch (-ret) { case LTTNG_ERR_SESSION_NOT_STARTED: WARN("Tracing session %s not started yet", session_name); - break; + cmd_ret = CMD_WARNING; + goto end; default: ERR("%s", lttng_strerror(ret)); - break; + goto error; } + } + + if (opt_no_wait) { + rotation_state = LTTNG_ROTATION_STATE_ONGOING; + goto skip_wait; + } + + _MSG("Waiting for rotation to complete"); + ret = fflush(stdout); + if (ret) { + PERROR("fflush"); goto error; } - if (!opt_no_wait) { - _MSG("Waiting for rotation to complete"); - ret = fflush(stdout); - if (ret) { - PERROR("fflush"); + do { + rotation_status = lttng_rotation_handle_get_state(handle, + &rotation_state); + if (rotation_status != LTTNG_ROTATION_STATUS_OK) { + ERR("Failed to query the state of the rotation."); goto error; } - do { - rotation_status = lttng_rotation_handle_get_state(handle, - &rotation_state); - if (rotation_status != LTTNG_ROTATION_STATUS_OK) { - ERR("Failed to query the state of the rotation"); + if (rotation_state == LTTNG_ROTATION_STATE_ONGOING) { + ret = usleep(DEFAULT_DATA_AVAILABILITY_WAIT_TIME); + if (ret) { + PERROR("usleep"); goto error; } + _MSG("."); - /* - * Data sleep time before retrying (in usec). Don't - * sleep if the call returned value indicates - * availability. - */ - if (rotation_state == LTTNG_ROTATION_STATE_ONGOING) { - ret = usleep(DEFAULT_DATA_AVAILABILITY_WAIT_TIME); - if (ret) { - PERROR("usleep"); - goto error; - } - _MSG("."); - - ret = fflush(stdout); - if (ret) { - PERROR("fflush"); - goto error; - } + ret = fflush(stdout); + if (ret) { + PERROR("fflush"); + goto error; } - } while (rotation_state == LTTNG_ROTATION_STATE_ONGOING); - MSG(""); - } + } + } while (rotation_state == LTTNG_ROTATION_STATE_ONGOING); + MSG(""); +skip_wait: switch (rotation_state) { case LTTNG_ROTATION_STATE_COMPLETED: - { - const struct lttng_trace_archive_location *location; - rotation_status = lttng_rotation_handle_get_archive_location( handle, &location); if (rotation_status != LTTNG_ROTATION_STATUS_OK) { - ERR("Failed to retrieve the rotation's completed chunk archive location"); - goto error; + ERR("Failed to retrieve the rotation's completed chunk archive location."); + cmd_ret = CMD_ERROR; } - ret = output_trace_archive_location(location, session_name); - if (ret) { - goto error; - } - ret = CMD_SUCCESS; - goto end; - } + break; case LTTNG_ROTATION_STATE_EXPIRED: - MSG("Session %s rotated, but handle expired", session_name); - ret = mi_output_rotate("expired", NULL, session_name); - if (ret) { - goto error; - } - ret = CMD_SUCCESS; - goto end; + break; + case LTTNG_ROTATION_STATE_ERROR: + ERR("Failed to retrieve rotation state."); + print_location = false; + goto error; + case LTTNG_ROTATION_STATE_ONGOING: + MSG("Rotation ongoing for session %s", session_name); + print_location = false; + break; default: - ERR("Unexpected rotation state received, aborting..."); + ERR("Unexpected rotation state encountered."); + print_location = false; goto error; } -error: - ret = CMD_ERROR; + if (!lttng_opt_mi && print_location) { + ret = output_trace_archive_location(location, + session_name); + } else if (lttng_opt_mi) { + ret = mi_lttng_rotate(writer, session_name, rotation_state, + location); + } + + if (ret < 0) { + cmd_ret = CMD_ERROR; + } + end: lttng_rotation_handle_destroy(handle); - return ret; + return cmd_ret; +error: + cmd_ret = CMD_ERROR; + goto end; } /* @@ -312,7 +267,8 @@ end: */ int cmd_rotate(int argc, const char **argv) { - int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; + int opt, ret; + enum cmd_error_code cmd_ret = CMD_SUCCESS; int popt_ret; static poptContext pc; char *session_name = NULL; @@ -321,9 +277,8 @@ int cmd_rotate(int argc, const char **argv) pc = poptGetContext(NULL, argc, argv, long_options, 0); popt_ret = poptReadDefaultConfig(pc, 0); if (popt_ret) { - ret = CMD_ERROR; ERR("poptReadDefaultConfig"); - goto end; + goto error; } while ((opt = poptGetNextOpt(pc)) != -1) { @@ -335,7 +290,7 @@ int cmd_rotate(int argc, const char **argv) list_cmd_options(stdout, long_options); goto end; default: - ret = CMD_UNDEFINED; + cmd_ret = CMD_UNDEFINED; goto end; } } @@ -345,7 +300,7 @@ int cmd_rotate(int argc, const char **argv) if (!opt_session_name) { session_name = get_session_name(); if (!session_name) { - goto end; + goto error; } free_session_name = true; } else { @@ -356,79 +311,60 @@ int cmd_rotate(int argc, const char **argv) if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { - ret = -LTTNG_ERR_NOMEM; - goto end; + goto error; } /* Open rotate command */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_rotate); if (ret) { - ret = CMD_ERROR; - goto end; + goto error; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { - goto end; - } - - /* Open rotations element */ - ret = mi_lttng_writer_open_element(writer, - mi_lttng_element_rotation_schedules); - if (ret) { - goto end; + goto error; } - } - command_ret = rotate_tracing(session_name); - if (command_ret) { - success = 0; - } + cmd_ret = rotate_tracing(session_name); /* Mi closing */ if (lttng_opt_mi) { - /* Close rotations element */ - ret = mi_lttng_writer_close_element(writer); - if (ret) { - goto end; - } /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { - goto end; + goto error; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, - mi_lttng_element_command_success, success); + mi_lttng_element_command_success, + cmd_ret == CMD_SUCCESS); if (ret) { - ret = CMD_ERROR; - goto end; + goto error; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { - ret = CMD_ERROR; - goto end; + goto error; } } -end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { - /* Preserve original error code */ - ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL; + goto error; } - - /* Overwrite ret if an error occurred with start_tracing */ - ret = command_ret ? command_ret : ret; +end: poptFreeContext(pc); if (free_session_name) { free(session_name); } - return ret; + + return cmd_ret; +error: + cmd_ret = CMD_ERROR; + goto end; } diff --git a/src/common/mi-lttng-3.0.xsd b/src/common/mi-lttng-3.0.xsd index 9c1a293af..b619b54c8 100644 --- a/src/common/mi-lttng-3.0.xsd +++ b/src/common/mi-lttng-3.0.xsd @@ -167,6 +167,23 @@ THE SOFTWARE. + + + + + + + + + + + + + + + + + @@ -589,12 +606,36 @@ THE SOFTWARE. + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + @@ -630,7 +671,7 @@ THE SOFTWARE. - + diff --git a/src/common/mi-lttng.c b/src/common/mi-lttng.c index d5148bcb5..084932811 100644 --- a/src/common/mi-lttng.c +++ b/src/common/mi-lttng.c @@ -195,6 +195,25 @@ LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_periodic = "p LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_periodic_time_us = "time_us"; LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_size_threshold = "size_threshold"; LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_size_threshold_bytes = "bytes"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_state = "state"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location = "location"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_local = "local"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_local_absolute_path = "absolute_path"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay = "relay"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_host = "host"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_control_port = "control_port"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_data_port = "data_port"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_protocol = "protocol"; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_relative_path = "relative_path"; + +/* String related to enum lttng_rotation_state */ +LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_ongoing = "ONGOING"; +LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_completed = "COMPLETED"; +LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_expired = "EXPIRED"; +LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_error = "ERROR"; + +/* String related to enum lttng_trace_archive_location_relay_protocol_type */ +LTTNG_HIDDEN const char * const mi_lttng_rotation_location_relay_protocol_str_tcp = "TCP"; /* String related to add-context command */ LTTNG_HIDDEN const char * const mi_lttng_element_context_symbol = "symbol"; @@ -468,6 +487,39 @@ const char *mi_lttng_buffertype_string(enum lttng_buffer_type value) } } +LTTNG_HIDDEN +const char *mi_lttng_rotation_state_string(enum lttng_rotation_state value) +{ + switch (value) { + case LTTNG_ROTATION_STATE_ONGOING: + return mi_lttng_rotation_state_str_ongoing; + case LTTNG_ROTATION_STATE_COMPLETED: + return mi_lttng_rotation_state_str_completed; + case LTTNG_ROTATION_STATE_EXPIRED: + return mi_lttng_rotation_state_str_expired; + case LTTNG_ROTATION_STATE_ERROR: + return mi_lttng_rotation_state_str_error; + default: + /* Should not have an unknow rotation state. */ + assert(0); + return NULL; + } +} + +LTTNG_HIDDEN +const char *mi_lttng_trace_archive_location_relay_protocol_type_string( + enum lttng_trace_archive_location_relay_protocol_type value) +{ + switch (value) { + case LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP: + return mi_lttng_rotation_location_relay_protocol_str_tcp; + default: + /* Should not have an unknow relay protocol. */ + assert(0); + return NULL; + } +} + LTTNG_HIDDEN struct mi_writer *mi_lttng_writer_create(int fd_output, int mi_output_type) { @@ -1948,3 +2000,204 @@ int mi_lttng_rotation_schedule_result(struct mi_writer *writer, end: return ret; } + +static +int mi_lttng_location(struct mi_writer *writer, + const struct lttng_trace_archive_location *location) +{ + int ret = 0; + enum lttng_trace_archive_location_type location_type; + enum lttng_trace_archive_location_status status; + + location_type = lttng_trace_archive_location_get_type(location); + + switch (location_type) { + case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL: + { + const char *absolute_path; + + status = lttng_trace_archive_location_local_get_absolute_path( + location, &absolute_path); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation_location_local); + if (ret) { + goto end; + } + + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_location_local_absolute_path, + absolute_path); + if (ret) { + goto end; + } + + /* Close local element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + break; + } + case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY: + { + uint16_t control_port, data_port; + const char *host, *relative_path; + enum lttng_trace_archive_location_relay_protocol_type protocol; + + /* Fetch all relay location parameters. */ + status = lttng_trace_archive_location_relay_get_protocol_type( + location, &protocol); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_host( + location, &host); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_control_port( + location, &control_port); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_data_port( + location, &data_port); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_relative_path( + location, &relative_path); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation_location_relay); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_location_relay_host, + host); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_unsigned_int(writer, + mi_lttng_element_rotation_location_relay_control_port, + control_port); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_unsigned_int(writer, + mi_lttng_element_rotation_location_relay_data_port, + data_port); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_location_relay_protocol, + mi_lttng_trace_archive_location_relay_protocol_type_string(protocol)); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_location_relay_relative_path, + relative_path); + if (ret) { + goto end; + } + + /* Close relay element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + break; + } + default: + abort(); + } +end: + return ret; +} + +LTTNG_HIDDEN +int mi_lttng_rotate(struct mi_writer *writer, + const char *session_name, + enum lttng_rotation_state rotation_state, + const struct lttng_trace_archive_location *location) +{ + int ret; + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_session_name, + session_name); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_state, + mi_lttng_rotation_state_string(rotation_state)); + if (ret) { + goto end; + } + + if (!location) { + /* Not a serialization error. */ + goto close_rotation; + } + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation_location); + if (ret) { + goto end; + } + + ret = mi_lttng_location(writer, location); + if (ret) { + goto close_location; + } + +close_location: + /* Close location element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + +close_rotation: + /* Close rotation element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } +end: + return ret; +} diff --git a/src/common/mi-lttng.h b/src/common/mi-lttng.h index 37136a8db..0540a5ba9 100644 --- a/src/common/mi-lttng.h +++ b/src/common/mi-lttng.h @@ -201,6 +201,25 @@ LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_size_threshol LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_size_threshold_bytes; LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_result; LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_results; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_state; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_local; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_local_absolute_path; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_host; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_control_port; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_data_port; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_protocol; +LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_relative_path; + +/* String related to enum lttng_rotation_state */ +LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_ongoing; +LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_completed; +LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_expired; +LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_error; + +/* String related to enum lttng_trace_archive_location_relay_protocol_type */ +LTTNG_HIDDEN const char * const mi_lttng_rotation_location_relay_protocol_str_tcp; /* String related to add-context command */ LTTNG_HIDDEN extern const char * const mi_lttng_element_context_symbol; @@ -211,6 +230,9 @@ const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value); const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type value); const char *mi_lttng_domaintype_string(enum lttng_domain_type value); const char *mi_lttng_buffertype_string(enum lttng_buffer_type value); +const char *mi_lttng_rotation_state_string(enum lttng_rotation_state value); +const char *mi_lttng_trace_archive_location_relay_protocol_type_string( + enum lttng_trace_archive_location_relay_protocol_type value); /* * Create an instance of a machine interface writer. @@ -839,8 +861,6 @@ int mi_lttng_rotation_schedule(struct mi_writer *writer, * * writer: An instance of a machine interface writer. * - * session_name: The session to which the command applies. - * * schedule: An lttng rotation schedule descriptor object. * * success: Whether the sub-command suceeded. @@ -852,4 +872,29 @@ int mi_lttng_rotation_schedule_result(struct mi_writer *writer, const struct lttng_rotation_schedule *schedule, bool success); +/* + * Machine interface of a session rotation result. + * This is an element that is part of the output of the rotate command. + * + * The machine interface provides the following information: + * - session_name: the session to be rotated. + * - state: the session rotation state. + * - location: the location of the completed chunk archive. + * + * writer: An instance of a machine interface writer. + * + * session_name: The session to which the rotate command applies. + * + * location: A location descriptor object. + * + * success: Whether the sub-command suceeded. + * + * Returns zero if the element's value could be written. + * Negative values indicate an error. + */ +int mi_lttng_rotate(struct mi_writer *writer, + const char *session_name, + enum lttng_rotation_state rotation_state, + const struct lttng_trace_archive_location *location); + #endif /* _MI_LTTNG_H */ -- 2.34.1