X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fplugins%2Ftext%2Fdmesg%2Fdmesg.c;h=801acf91654deb2d1c025870d305d19f3cbe8d5f;hb=903b999e63e4649c358001400a06ef834734072e;hp=49fba13f80221c9522aa033024017df7932beb93;hpb=19bbdc9bfcbbfabb1f04dad12ff1df5d7075bf11;p=babeltrace.git diff --git a/src/plugins/text/dmesg/dmesg.c b/src/plugins/text/dmesg/dmesg.c index 49fba13f..801acf91 100644 --- a/src/plugins/text/dmesg/dmesg.c +++ b/src/plugins/text/dmesg/dmesg.c @@ -1,30 +1,16 @@ /* + * SPDX-License-Identifier: MIT + * * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation * Copyright 2017 Philippe Proulx - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. */ #define BT_COMP_LOG_SELF_COMP (dmesg_comp->self_comp) #define BT_LOG_OUTPUT_LEVEL (dmesg_comp->log_level) #define BT_LOG_TAG "PLUGIN/SRC.TEXT.DMESG" -#include "plugins/comp-logging.h" +#include "logging/comp-logging.h" + +#include "dmesg.h" #include #include @@ -36,6 +22,7 @@ #include "compat/utc.h" #include "compat/stdio.h" #include +#include "plugins/common/param-validation/param-validation.h" #define NSEC_PER_USEC 1000UL #define NSEC_PER_MSEC 1000000UL @@ -46,7 +33,10 @@ struct dmesg_component; struct dmesg_msg_iter { struct dmesg_component *dmesg_comp; - bt_self_message_iterator *pc_msg_iter; /* Weak */ + + /* Weak */ + bt_self_message_iterator *self_msg_iter; + char *linebuf; size_t linebuf_len; FILE *fp; @@ -196,57 +186,56 @@ end: } static -int handle_params(struct dmesg_component *dmesg_comp, +struct bt_param_validation_map_value_entry_descr dmesg_params[] = { + { "no-extract-timestamp", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } }, + { "path", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_STRING } }, + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END +}; + +static +bt_component_class_initialize_method_status handle_params( + struct dmesg_component *dmesg_comp, const bt_value *params) { const bt_value *no_timestamp = NULL; const bt_value *path = NULL; - const char *path_str; - int ret = 0; + bt_component_class_initialize_method_status status; + enum bt_param_validation_status validation_status; + gchar *validate_error = NULL; + + validation_status = bt_param_validation_validate(params, + dmesg_params, &validate_error); + if (validation_status == BT_PARAM_VALIDATION_STATUS_MEMORY_ERROR) { + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto end; + } else if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) { + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(dmesg_comp->self_comp, + "%s", validate_error); + goto end; + } no_timestamp = bt_value_map_borrow_entry_value_const(params, "no-extract-timestamp"); if (no_timestamp) { - if (!bt_value_is_bool(no_timestamp)) { - BT_COMP_LOGE("Expecting a boolean value for the `no-extract-timestamp` parameter: " - "type=%s", - bt_common_value_type_string( - bt_value_get_type(no_timestamp))); - goto error; - } - dmesg_comp->params.no_timestamp = bt_value_bool_get(no_timestamp); } path = bt_value_map_borrow_entry_value_const(params, "path"); if (path) { - if (dmesg_comp->params.read_from_stdin) { - BT_COMP_LOGE_STR("Cannot specify both `read-from-stdin` and `path` parameters."); - goto error; - } + const char *path_str = bt_value_string_get(path); - if (!bt_value_is_string(path)) { - BT_COMP_LOGE("Expecting a string value for the `path` parameter: " - "type=%s", - bt_common_value_type_string( - bt_value_get_type(path))); - goto error; - } - - path_str = bt_value_string_get(path); g_string_assign(dmesg_comp->params.path, path_str); } else { dmesg_comp->params.read_from_stdin = true; } - goto end; - -error: - ret = -1; - + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; end: - return ret; + g_free(validate_error); + + return status; } static @@ -354,50 +343,25 @@ void destroy_dmesg_component(struct dmesg_component *dmesg_comp) g_free(dmesg_comp); } -static -bt_component_class_init_method_status create_port( - bt_self_component_source *self_comp) -{ - bt_component_class_init_method_status status; - bt_self_component_add_port_status add_port_status; - - add_port_status = bt_self_component_source_add_output_port(self_comp, - "out", NULL, NULL); - switch (add_port_status) { - case BT_SELF_COMPONENT_ADD_PORT_STATUS_OK: - status = BT_COMPONENT_CLASS_INIT_METHOD_STATUS_OK; - break; - case BT_SELF_COMPONENT_ADD_PORT_STATUS_ERROR: - status = BT_COMPONENT_CLASS_INIT_METHOD_STATUS_ERROR; - break; - case BT_SELF_COMPONENT_ADD_PORT_STATUS_MEMORY_ERROR: - status = BT_COMPONENT_CLASS_INIT_METHOD_STATUS_MEMORY_ERROR; - break; - default: - abort(); - } - - return status; -} - BT_HIDDEN -bt_component_class_init_method_status dmesg_init( +bt_component_class_initialize_method_status dmesg_init( bt_self_component_source *self_comp_src, - bt_value *params, void *init_method_data) + bt_self_component_source_configuration *config, + const bt_value *params, void *init_method_data) { - int ret = 0; struct dmesg_component *dmesg_comp = g_new0(struct dmesg_component, 1); - bt_component_class_init_method_status status = - BT_COMPONENT_CLASS_INIT_METHOD_STATUS_OK; + bt_component_class_initialize_method_status status; bt_self_component *self_comp = bt_self_component_source_as_self_component(self_comp_src); const bt_component *comp = bt_self_component_as_component(self_comp); bt_logging_level log_level = bt_component_get_logging_level(comp); + bt_self_component_add_port_status add_port_status; if (!dmesg_comp) { /* Implicit log level is not available here */ BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, "Failed to allocate one dmesg component structure."); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; goto error; } @@ -407,12 +371,14 @@ bt_component_class_init_method_status dmesg_init( dmesg_comp->params.path = g_string_new(NULL); if (!dmesg_comp->params.path) { BT_COMP_LOGE_STR("Failed to allocate a GString."); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; goto error; } - ret = handle_params(dmesg_comp, params); - if (ret) { + status = handle_params(dmesg_comp, params); + if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { BT_COMP_LOGE("Invalid parameters: comp-addr=%p", self_comp); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; goto error; } @@ -422,26 +388,27 @@ bt_component_class_init_method_status dmesg_init( BT_COMP_LOGE("Input path is not a regular file: " "comp-addr=%p, path=\"%s\"", self_comp, dmesg_comp->params.path->str); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; goto error; } - status = create_port(self_comp_src); - if (status != BT_COMPONENT_CLASS_INIT_METHOD_STATUS_OK) { + add_port_status = bt_self_component_source_add_output_port( + self_comp_src, "out", NULL, NULL); + if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { + status = (int) add_port_status; goto error; } bt_self_component_set_data(self_comp, dmesg_comp); BT_COMP_LOGI_STR("Component initialized."); + + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; goto end; error: destroy_dmesg_component(dmesg_comp); bt_self_component_set_data(self_comp, NULL); - if (status >= 0) { - status = BT_COMPONENT_CLASS_INIT_METHOD_STATUS_ERROR; - } - end: return status; } @@ -509,7 +476,7 @@ bt_message *create_init_event_msg_from_line( if (has_timestamp) { /* Set new start for the message portion of the line */ *new_start = strchr(line, ']'); - BT_ASSERT(*new_start); + BT_ASSERT_DBG(*new_start); (*new_start)++; if ((*new_start)[0] == ' ') { @@ -531,11 +498,11 @@ skip_ts: if (dmesg_comp->clock_class) { msg = bt_message_event_create_with_default_clock_snapshot( - msg_iter->pc_msg_iter, + msg_iter->self_msg_iter, dmesg_comp->event_class, dmesg_comp->stream, ts); msg_iter->last_clock_value = ts; } else { - msg = bt_message_event_create(msg_iter->pc_msg_iter, + msg = bt_message_event_create(msg_iter->self_msg_iter, dmesg_comp->event_class, dmesg_comp->stream); } @@ -545,7 +512,7 @@ skip_ts: } event = bt_message_event_borrow_event(msg); - BT_ASSERT(event); + BT_ASSERT_DBG(event); goto end; error: @@ -565,7 +532,7 @@ int fill_event_payload_from_line(struct dmesg_component *dmesg_comp, int ret; ep_field = bt_event_borrow_payload_field(event); - BT_ASSERT(ep_field); + BT_ASSERT_DBG(ep_field); str_field = bt_field_structure_borrow_member_field_by_index( ep_field, 0); if (!str_field) { @@ -614,7 +581,7 @@ bt_message *create_msg_from_line( } event = bt_message_event_borrow_event(msg); - BT_ASSERT(event); + BT_ASSERT_DBG(event); ret = fill_event_payload_from_line(dmesg_comp, new_start, event); if (ret) { BT_COMP_LOGE("Cannot fill event payload field from line: " @@ -634,12 +601,14 @@ end: static void destroy_dmesg_msg_iter(struct dmesg_msg_iter *dmesg_msg_iter) { - struct dmesg_component *dmesg_comp = dmesg_msg_iter->dmesg_comp; + struct dmesg_component *dmesg_comp; if (!dmesg_msg_iter) { return; } + dmesg_comp = dmesg_msg_iter->dmesg_comp; + if (dmesg_msg_iter->fp && dmesg_msg_iter->fp != stdin) { if (fclose(dmesg_msg_iter->fp)) { BT_COMP_LOGE_ERRNO("Cannot close input file", "."); @@ -654,17 +623,18 @@ void destroy_dmesg_msg_iter(struct dmesg_msg_iter *dmesg_msg_iter) BT_HIDDEN -bt_component_class_message_iterator_init_method_status dmesg_msg_iter_init( +bt_message_iterator_class_initialize_method_status dmesg_msg_iter_init( bt_self_message_iterator *self_msg_iter, - bt_self_component_source *self_comp, + bt_self_message_iterator_configuration *config, bt_self_component_port_output *self_port) { - struct dmesg_component *dmesg_comp = bt_self_component_get_data( - bt_self_component_source_as_self_component(self_comp)); + bt_self_component *self_comp = + bt_self_message_iterator_borrow_component(self_msg_iter); + struct dmesg_component *dmesg_comp = bt_self_component_get_data(self_comp); struct dmesg_msg_iter *dmesg_msg_iter = g_new0(struct dmesg_msg_iter, 1); - bt_component_class_message_iterator_init_method_status status = - BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK; + bt_message_iterator_class_initialize_method_status status = + BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; if (!dmesg_msg_iter) { BT_COMP_LOGE_STR("Failed to allocate on dmesg message iterator structure."); @@ -673,7 +643,7 @@ bt_component_class_message_iterator_init_method_status dmesg_msg_iter_init( BT_ASSERT(dmesg_comp); dmesg_msg_iter->dmesg_comp = dmesg_comp; - dmesg_msg_iter->pc_msg_iter = self_msg_iter; + dmesg_msg_iter->self_msg_iter = self_msg_iter; if (dmesg_comp->params.read_from_stdin) { dmesg_msg_iter->fp = stdin; @@ -694,7 +664,7 @@ error: destroy_dmesg_msg_iter(dmesg_msg_iter); bt_self_message_iterator_set_data(self_msg_iter, NULL); if (status >= 0) { - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_ERROR; + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; } end: @@ -710,21 +680,20 @@ void dmesg_msg_iter_finalize( } static -bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next_one( +bt_message_iterator_class_next_method_status dmesg_msg_iter_next_one( struct dmesg_msg_iter *dmesg_msg_iter, bt_message **msg) { ssize_t len; struct dmesg_component *dmesg_comp; - bt_component_class_message_iterator_next_method_status status = - BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; + bt_message_iterator_class_next_method_status status; - BT_ASSERT(dmesg_msg_iter); + BT_ASSERT_DBG(dmesg_msg_iter); dmesg_comp = dmesg_msg_iter->dmesg_comp; - BT_ASSERT(dmesg_comp); + BT_ASSERT_DBG(dmesg_comp); if (dmesg_msg_iter->state == STATE_DONE) { - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_END; + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; goto end; } @@ -741,13 +710,15 @@ bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next_one( &dmesg_msg_iter->linebuf_len, dmesg_msg_iter->fp); if (len < 0) { if (errno == EINVAL) { - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + goto end; } else if (errno == ENOMEM) { - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_MEMORY_ERROR; + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; + goto end; } else { if (dmesg_msg_iter->state == STATE_EMIT_STREAM_BEGINNING) { /* Stream did not even begin */ - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_END; + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; goto end; } else { /* End stream now */ @@ -756,15 +727,13 @@ bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next_one( goto handle_state; } } - - goto end; } - BT_ASSERT(dmesg_msg_iter->linebuf); + BT_ASSERT_DBG(dmesg_msg_iter->linebuf); /* Ignore empty lines, once trimmed */ for (ch = dmesg_msg_iter->linebuf; *ch != '\0'; ch++) { - if (!isspace(*ch)) { + if (!isspace((unsigned char) *ch)) { only_spaces = false; break; } @@ -781,27 +750,28 @@ bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next_one( BT_COMP_LOGE("Cannot create event message from line: " "dmesg-comp-addr=%p, line=\"%s\"", dmesg_comp, dmesg_msg_iter->linebuf); + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; goto end; } handle_state: - BT_ASSERT(dmesg_comp->trace); + BT_ASSERT_DBG(dmesg_comp->trace); switch (dmesg_msg_iter->state) { case STATE_EMIT_STREAM_BEGINNING: - BT_ASSERT(dmesg_msg_iter->tmp_event_msg); + BT_ASSERT_DBG(dmesg_msg_iter->tmp_event_msg); *msg = bt_message_stream_beginning_create( - dmesg_msg_iter->pc_msg_iter, dmesg_comp->stream); + dmesg_msg_iter->self_msg_iter, dmesg_comp->stream); dmesg_msg_iter->state = STATE_EMIT_EVENT; break; case STATE_EMIT_EVENT: - BT_ASSERT(dmesg_msg_iter->tmp_event_msg); + BT_ASSERT_DBG(dmesg_msg_iter->tmp_event_msg); *msg = dmesg_msg_iter->tmp_event_msg; dmesg_msg_iter->tmp_event_msg = NULL; break; case STATE_EMIT_STREAM_END: *msg = bt_message_stream_end_create( - dmesg_msg_iter->pc_msg_iter, dmesg_comp->stream); + dmesg_msg_iter->self_msg_iter, dmesg_comp->stream); dmesg_msg_iter->state = STATE_DONE; break; default: @@ -811,15 +781,17 @@ handle_state: if (!*msg) { BT_COMP_LOGE("Cannot create message: dmesg-comp-addr=%p", dmesg_comp); - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + goto end; } + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; end: return status; } BT_HIDDEN -bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next( +bt_message_iterator_class_next_method_status dmesg_msg_iter_next( bt_self_message_iterator *self_msg_iter, bt_message_array_const msgs, uint64_t capacity, uint64_t *count) @@ -827,18 +799,18 @@ bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next( struct dmesg_msg_iter *dmesg_msg_iter = bt_self_message_iterator_get_data( self_msg_iter); - bt_component_class_message_iterator_next_method_status status = - BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; + bt_message_iterator_class_next_method_status status = + BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; uint64_t i = 0; while (i < capacity && - status == BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK) { + status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK) { bt_message *priv_msg = NULL; status = dmesg_msg_iter_next_one(dmesg_msg_iter, &priv_msg); msgs[i] = priv_msg; - if (status == BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK) { + if (status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK) { i++; } } @@ -857,25 +829,28 @@ bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next( * message, in which case we'll return it. */ *count = i; - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; } return status; } BT_HIDDEN -bt_bool dmesg_msg_iter_can_seek_beginning( - bt_self_message_iterator *self_msg_iter) +bt_message_iterator_class_can_seek_beginning_method_status +dmesg_msg_iter_can_seek_beginning( + bt_self_message_iterator *self_msg_iter, bt_bool *can_seek) { struct dmesg_msg_iter *dmesg_msg_iter = bt_self_message_iterator_get_data(self_msg_iter); /* Can't seek the beginning of the standard input stream */ - return !dmesg_msg_iter->dmesg_comp->params.read_from_stdin; + *can_seek = !dmesg_msg_iter->dmesg_comp->params.read_from_stdin; + + return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_OK; } BT_HIDDEN -bt_component_class_message_iterator_seek_beginning_method_status +bt_message_iterator_class_seek_beginning_method_status dmesg_msg_iter_seek_beginning( bt_self_message_iterator *self_msg_iter) { @@ -887,5 +862,5 @@ dmesg_msg_iter_seek_beginning( BT_MESSAGE_PUT_REF_AND_RESET(dmesg_msg_iter->tmp_event_msg); dmesg_msg_iter->last_clock_value = 0; dmesg_msg_iter->state = STATE_EMIT_STREAM_BEGINNING; - return BT_COMPONENT_CLASS_MESSAGE_ITERATOR_SEEK_BEGINNING_METHOD_STATUS_OK; + return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_OK; }