From 35a9ac4170f36547aa2ae7c19ccbb7bbb0bcf71b Mon Sep 17 00:00:00 2001 From: Francis Deslauriers Date: Mon, 7 Dec 2020 16:08:30 -0500 Subject: [PATCH] on-event: add error counter fields to condition MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Modified from proposed change: don't include error counter index in serdes The error counter index is an internal implementation detail that doesn't need to be exposed to the client (the accessor is not reacheble to them anyway). Signed-off-by: Francis Deslauriers Signed-off-by: Jérémie Galarneau Change-Id: Ibc84d4cc3bcc7e304f4b52bd45f1de010dd8b87b --- include/lttng/condition/on-event-internal.h | 24 +++ src/common/conditions/on-event.c | 202 +++++++++++++++++++- tests/unit/test_condition.c | 13 +- 3 files changed, 233 insertions(+), 6 deletions(-) diff --git a/include/lttng/condition/on-event-internal.h b/include/lttng/condition/on-event-internal.h index e22cb762a..cc8f1cdf9 100644 --- a/include/lttng/condition/on-event-internal.h +++ b/include/lttng/condition/on-event-internal.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,13 @@ struct lttng_condition_on_event { struct lttng_condition parent; struct lttng_event_rule *rule; + LTTNG_OPTIONAL(uint64_t) error_count; + /* + * Internal use only. + * Error accounting counter index. + */ + LTTNG_OPTIONAL(uint64_t) error_counter_index; + /* Array of `struct lttng_capture_descriptor *`. */ struct lttng_dynamic_pointer_array capture_descriptors; }; @@ -63,6 +71,22 @@ lttng_condition_on_event_borrow_rule_mutable( const struct lttng_condition *condition, struct lttng_event_rule **rule); +LTTNG_HIDDEN +void lttng_condition_on_event_set_error_counter_index( + struct lttng_condition *condition, uint64_t error_counter_index); + +LTTNG_HIDDEN +uint64_t lttng_condition_on_event_get_error_counter_index( + const struct lttng_condition *condition); + +LTTNG_HIDDEN +uint64_t lttng_condition_on_event_get_error_count( + const struct lttng_condition *condition); + +LTTNG_HIDDEN +void lttng_condition_on_event_set_error_count(struct lttng_condition *condition, + uint64_t error_count); + LTTNG_HIDDEN struct lttng_evaluation *lttng_evaluation_on_event_create( const struct lttng_condition_on_event *condition, diff --git a/src/common/conditions/on-event.c b/src/common/conditions/on-event.c index 9cc80772c..31d6d756b 100644 --- a/src/common/conditions/on-event.c +++ b/src/common/conditions/on-event.c @@ -27,6 +27,8 @@ (lttng_condition_get_type(condition) == \ LTTNG_CONDITION_TYPE_ON_EVENT) +typedef LTTNG_OPTIONAL(uint64_t) optional_uint64; + static bool is_on_event_evaluation(const struct lttng_evaluation *evaluation) { enum lttng_condition_type type = lttng_evaluation_get_type(evaluation); @@ -284,6 +286,7 @@ static int lttng_condition_on_event_serialize( enum lttng_condition_status status; /* Used for iteration and communication (size matters). */ uint32_t i, capture_descr_count; + LTTNG_OPTIONAL_COMM(typeof(on_event_condition->error_count.value)) error_count_comm; if (!condition || !IS_ON_EVENT_CONDITION(condition)) { ret = -1; @@ -300,6 +303,30 @@ static int lttng_condition_on_event_serialize( goto end; } + error_count_comm = (typeof(error_count_comm)) { + .is_set = on_event_condition->error_count.is_set, + .value = on_event_condition->error_count.value, + }; + + { + char error_count_value_str[MAX_INT_DEC_LEN(on_event_condition->error_count.value)]; + const int fmt_ret = snprintf(error_count_value_str, + sizeof(error_count_value_str), "%" PRIu64, + on_event_condition->error_count.value); + + assert(fmt_ret > 0); + DBG("Serializing event rule condition's error count: value = %s", + on_event_condition->error_count.is_set ? + error_count_value_str : + "(unset)"); + } + + ret = lttng_dynamic_buffer_append(&payload->buffer, &error_count_comm, + sizeof(error_count_comm)); + if (ret) { + goto end; + } + status = lttng_condition_on_event_get_capture_descriptor_count( condition, &capture_descr_count); if (status != LTTNG_CONDITION_STATUS_OK) { @@ -506,6 +533,112 @@ end: return ret; } +static +int optional_uint_from_buffer( + const struct lttng_buffer_view *view, + size_t inner_value_size, + size_t *offset, + optional_uint64 *value) +{ + int ret; + + /* + * Those cases are identical except for the optional's inner type width. + */ + switch (inner_value_size) { + case sizeof(uint8_t): + { + LTTNG_OPTIONAL_COMM(uint8_t) *value_comm; + const struct lttng_buffer_view optional_uint_view = + lttng_buffer_view_from_view(view, *offset, + sizeof(*value_comm)); + + if (!lttng_buffer_view_is_valid(&optional_uint_view)) { + ret = -1; + goto end; + } + + value_comm = (typeof(value_comm)) optional_uint_view.data; + *value = (typeof(*value)) { + .is_set = value_comm->is_set, + .value = (uint64_t) value_comm->value, + }; + + *offset += sizeof(*value_comm); + break; + } + case sizeof(uint16_t): + { + LTTNG_OPTIONAL_COMM(uint16_t) *value_comm; + const struct lttng_buffer_view optional_uint_view = + lttng_buffer_view_from_view(view, *offset, + sizeof(*value_comm)); + + if (!lttng_buffer_view_is_valid(&optional_uint_view)) { + ret = -1; + goto end; + } + + value_comm = (typeof(value_comm)) optional_uint_view.data; + *value = (typeof(*value)) { + .is_set = value_comm->is_set, + .value = (uint64_t) value_comm->value, + }; + + *offset += sizeof(*value_comm); + break; + } + case sizeof(uint32_t): + { + LTTNG_OPTIONAL_COMM(uint32_t) *value_comm; + const struct lttng_buffer_view optional_uint_view = + lttng_buffer_view_from_view(view, *offset, + sizeof(*value_comm)); + + if (!lttng_buffer_view_is_valid(&optional_uint_view)) { + ret = -1; + goto end; + } + + value_comm = (typeof(value_comm)) optional_uint_view.data; + *value = (typeof(*value)) { + .is_set = value_comm->is_set, + .value = (uint64_t) value_comm->value, + }; + + *offset += sizeof(*value_comm); + break; + } + case sizeof(uint64_t): + { + LTTNG_OPTIONAL_COMM(uint64_t) *value_comm; + const struct lttng_buffer_view optional_uint_view = + lttng_buffer_view_from_view(view, *offset, + sizeof(*value_comm)); + + if (!lttng_buffer_view_is_valid(&optional_uint_view)) { + ret = -1; + goto end; + } + + value_comm = (typeof(value_comm)) optional_uint_view.data; + *value = (typeof(*value)) { + .is_set = value_comm->is_set, + .value = (uint64_t) value_comm->value, + }; + + *offset += sizeof(*value_comm); + break; + } + default: + abort(); + } + + ret = 0; +end: + return ret; +} + static const char *str_from_buffer(const struct lttng_buffer_view *view, size_t *offset) @@ -628,10 +761,12 @@ ssize_t lttng_condition_on_event_create_from_payload( struct lttng_payload_view *view, struct lttng_condition **_condition) { + int optional_ret; ssize_t consumed_length; size_t offset = 0; ssize_t event_rule_length; uint32_t i, capture_descr_count; + optional_uint64 error_count; struct lttng_condition *condition = NULL; struct lttng_event_rule *event_rule = NULL; @@ -652,15 +787,29 @@ ssize_t lttng_condition_on_event_create_from_payload( goto error; } + offset += event_rule_length; + + /* Error count. */ + optional_ret = optional_uint_from_buffer(&view->buffer, + sizeof(error_count.value), &offset, + &error_count); + if (optional_ret) { + goto error; + } + /* Create condition (no capture descriptors yet) at this point */ condition = lttng_condition_on_event_create(event_rule); if (!condition) { goto error; } + if (error_count.is_set) { + lttng_condition_on_event_set_error_count( + condition, error_count.value); + } + /* Capture descriptor count. */ assert(event_rule_length >= 0); - offset += (size_t) event_rule_length; capture_descr_count = uint_from_buffer(&view->buffer, sizeof(uint32_t), &offset); if (capture_descr_count == UINT32_C(-1)) { goto error; @@ -738,6 +887,49 @@ enum lttng_condition_status lttng_condition_on_event_get_rule( return status; } +LTTNG_HIDDEN +void lttng_condition_on_event_set_error_counter_index( + struct lttng_condition *condition, uint64_t error_counter_index) +{ + struct lttng_condition_on_event *on_event_cond = + container_of(condition, + struct lttng_condition_on_event, parent); + + LTTNG_OPTIONAL_SET(&on_event_cond->error_counter_index, error_counter_index); +} + +LTTNG_HIDDEN +uint64_t lttng_condition_on_event_get_error_counter_index( + const struct lttng_condition *condition) +{ + const struct lttng_condition_on_event *on_event_cond = + container_of(condition, + const struct lttng_condition_on_event, parent); + + return LTTNG_OPTIONAL_GET(on_event_cond->error_counter_index); +} + +LTTNG_HIDDEN +void lttng_condition_on_event_set_error_count(struct lttng_condition *condition, + uint64_t error_count) +{ + struct lttng_condition_on_event *on_event_cond = + container_of(condition, + struct lttng_condition_on_event, parent); + + LTTNG_OPTIONAL_SET(&on_event_cond->error_count, error_count); +} + +uint64_t lttng_condition_on_event_get_error_count( + const struct lttng_condition *condition) +{ + const struct lttng_condition_on_event *on_event_cond = + container_of(condition, + const struct lttng_condition_on_event, parent); + + return LTTNG_OPTIONAL_GET(on_event_cond->error_count); +} + enum lttng_condition_status lttng_condition_on_event_append_capture_descriptor( struct lttng_condition *condition, @@ -745,7 +937,7 @@ lttng_condition_on_event_append_capture_descriptor( { int ret; enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK; - struct lttng_condition_on_event *event_rule_cond = + struct lttng_condition_on_event *on_event_cond = container_of(condition, struct lttng_condition_on_event, parent); struct lttng_capture_descriptor *descriptor = NULL; @@ -791,7 +983,7 @@ lttng_condition_on_event_append_capture_descriptor( descriptor->bytecode = NULL; ret = lttng_dynamic_pointer_array_add_pointer( - &event_rule_cond->capture_descriptors, descriptor); + &on_event_cond->capture_descriptors, descriptor); if (ret) { status = LTTNG_CONDITION_STATUS_ERROR; goto end; @@ -1479,7 +1671,7 @@ const struct lttng_bytecode * lttng_condition_on_event_get_capture_bytecode_at_index( const struct lttng_condition *condition, unsigned int index) { - const struct lttng_condition_on_event *event_rule_cond = + const struct lttng_condition_on_event *on_event_cond = container_of(condition, const struct lttng_condition_on_event, parent); @@ -1503,7 +1695,7 @@ lttng_condition_on_event_get_capture_bytecode_at_index( } desc = lttng_dynamic_pointer_array_get_pointer( - &event_rule_cond->capture_descriptors, index); + &on_event_cond->capture_descriptors, index); if (desc == NULL) { goto end; } diff --git a/tests/unit/test_condition.c b/tests/unit/test_condition.c index 864c6a840..f4bc040d0 100644 --- a/tests/unit/test_condition.c +++ b/tests/unit/test_condition.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,7 @@ int lttng_opt_quiet = 1; int lttng_opt_verbose; int lttng_opt_mi; -#define NUM_TESTS 13 +#define NUM_TESTS 14 static void test_condition_event_rule(void) @@ -46,6 +47,7 @@ void test_condition_event_rule(void) const char *pattern="my_event_*"; const char *filter="msg_id == 23 && size >= 2048"; const char *exclusions[] = { "my_event_test1", "my_event_test2", "my_event_test3" }; + uint64_t _error_count = 420, error_count; struct lttng_log_level_rule *log_level_rule_at_least_as_severe = NULL; struct lttng_payload buffer; @@ -80,6 +82,9 @@ void test_condition_event_rule(void) condition = lttng_condition_on_event_create(tracepoint); ok(condition, "Created condition"); + /* Set the error count information. */ + lttng_condition_on_event_set_error_count(condition, _error_count); + condition_status = lttng_condition_on_event_get_rule( condition, &tracepoint_tmp); ok(condition_status == LTTNG_CONDITION_STATUS_OK, @@ -102,6 +107,12 @@ void test_condition_event_rule(void) ok(lttng_condition_is_equal(condition, condition_from_buffer), "Serialized and de-serialized conditions are equal"); + /* + * Error count info is not considered in is_equal; test it separately. + */ + error_count = lttng_condition_on_event_get_error_count(condition_from_buffer); + ok(error_count == _error_count, "Error count is the same. Got %" PRIu64 " Expected %" PRIu64, error_count, _error_count); + lttng_payload_reset(&buffer); lttng_event_rule_destroy(tracepoint); lttng_condition_destroy(condition); -- 2.34.1