X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fconditions%2Fevent-rule.c;h=dcc31ef8622ccdc823d5f85e2ed382d55666fc12;hp=9640b36a12d02fefbb1ea4aa1e63cb17ebc99347;hb=51dbe9857c314b9b0dc53b4f9c367f7db659a6b4;hpb=116a02e33a6aba03128c268c333e1c35584848d2 diff --git a/src/common/conditions/event-rule.c b/src/common/conditions/event-rule.c index 9640b36a1..dcc31ef86 100644 --- a/src/common/conditions/event-rule.c +++ b/src/common/conditions/event-rule.c @@ -7,14 +7,16 @@ #include #include +#include #include #include #include +#include #include #include #include #include -#include +#include #include #include #include @@ -192,12 +194,46 @@ end: return ret; } +static +struct lttng_capture_descriptor * +lttng_condition_event_rule_get_internal_capture_descriptor_at_index( + const struct lttng_condition *condition, unsigned int index) +{ + const struct lttng_condition_event_rule *event_rule_cond = + container_of(condition, + const struct lttng_condition_event_rule, + parent); + struct lttng_capture_descriptor *desc = NULL; + unsigned int count; + enum lttng_condition_status status; + + if (!condition || !IS_EVENT_RULE_CONDITION(condition)) { + goto end; + } + + status = lttng_condition_event_rule_get_capture_descriptor_count( + condition, &count); + if (status != LTTNG_CONDITION_STATUS_OK) { + goto end; + } + + if (index >= count) { + goto end; + } + + desc = lttng_dynamic_pointer_array_get_pointer( + &event_rule_cond->capture_descriptors, index); +end: + return desc; +} + static int lttng_condition_event_rule_serialize( const struct lttng_condition *condition, struct lttng_payload *payload) { int ret; struct lttng_condition_event_rule *event_rule; + enum lttng_condition_status status; /* Used for iteration and communication (size matters). */ uint32_t i, capture_descr_count; @@ -216,8 +252,13 @@ static int lttng_condition_event_rule_serialize( goto end; } - capture_descr_count = lttng_dynamic_pointer_array_get_count( - &event_rule->capture_descriptors); + status = lttng_condition_event_rule_get_capture_descriptor_count( + condition, &capture_descr_count); + if (status != LTTNG_CONDITION_STATUS_OK) { + ret = -1; + goto end; + }; + DBG("Serializing event rule condition's capture descriptor count: %" PRIu32, capture_descr_count); ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_descr_count, @@ -227,13 +268,13 @@ static int lttng_condition_event_rule_serialize( } for (i = 0; i < capture_descr_count; i++) { - const struct lttng_event_expr *expr = - lttng_dynamic_pointer_array_get_pointer( - &event_rule->capture_descriptors, i); + const struct lttng_capture_descriptor *desc = + lttng_condition_event_rule_get_internal_capture_descriptor_at_index( + condition, i); DBG("Serializing event rule condition's capture descriptor %" PRIu32, i); - ret = serialize_event_expr(expr, payload); + ret = serialize_event_expr(desc->event_expression, payload); if (ret) { goto end; } @@ -245,18 +286,26 @@ end: static bool capture_descriptors_are_equal( - const struct lttng_condition_event_rule *condition_a, - const struct lttng_condition_event_rule *condition_b) + const struct lttng_condition *condition_a, + const struct lttng_condition *condition_b) { bool is_equal = true; - size_t capture_descr_count_a; - size_t capture_descr_count_b; + unsigned int capture_descr_count_a; + unsigned int capture_descr_count_b; size_t i; + enum lttng_condition_status status; + + status = lttng_condition_event_rule_get_capture_descriptor_count( + condition_a, &capture_descr_count_a); + if (status != LTTNG_CONDITION_STATUS_OK) { + goto not_equal; + } - capture_descr_count_a = lttng_dynamic_pointer_array_get_count( - &condition_a->capture_descriptors); - capture_descr_count_b = lttng_dynamic_pointer_array_get_count( - &condition_b->capture_descriptors); + status = lttng_condition_event_rule_get_capture_descriptor_count( + condition_b, &capture_descr_count_b); + if (status != LTTNG_CONDITION_STATUS_OK) { + goto not_equal; + } if (capture_descr_count_a != capture_descr_count_b) { goto not_equal; @@ -264,12 +313,12 @@ bool capture_descriptors_are_equal( for (i = 0; i < capture_descr_count_a; i++) { const struct lttng_event_expr *expr_a = - lttng_dynamic_pointer_array_get_pointer( - &condition_a->capture_descriptors, + lttng_condition_event_rule_get_capture_descriptor_at_index( + condition_a, i); const struct lttng_event_expr *expr_b = - lttng_dynamic_pointer_array_get_pointer( - &condition_b->capture_descriptors, + lttng_condition_event_rule_get_capture_descriptor_at_index( + condition_b, i); if (!lttng_event_expr_is_equal(expr_a, expr_b)) { @@ -307,7 +356,7 @@ static bool lttng_condition_event_rule_is_equal( goto end; } - is_equal = capture_descriptors_are_equal(a, b); + is_equal = capture_descriptors_are_equal(_a, _b); end: return is_equal; @@ -327,9 +376,14 @@ static void lttng_condition_event_rule_destroy( } static -void destroy_event_expr(void *ptr) +void destroy_capture_descriptor(void *ptr) { - lttng_event_expr_destroy(ptr); + struct lttng_capture_descriptor *desc = + (struct lttng_capture_descriptor *) ptr; + + lttng_event_expr_destroy(desc->event_expression); + free(desc->bytecode); + free(desc); } struct lttng_condition *lttng_condition_event_rule_create( @@ -359,7 +413,7 @@ struct lttng_condition *lttng_condition_event_rule_create( rule = NULL; lttng_dynamic_pointer_array_init(&condition->capture_descriptors, - destroy_event_expr); + destroy_capture_descriptor); parent = &condition->parent; end: @@ -567,9 +621,9 @@ ssize_t lttng_condition_event_rule_create_from_payload( /* Capture descriptors. */ for (i = 0; i < capture_descr_count; i++) { + enum lttng_condition_status status; struct lttng_event_expr *expr = event_expr_from_payload( view, &offset); - enum lttng_condition_status status; if (!expr) { goto error; @@ -647,6 +701,7 @@ lttng_condition_event_rule_append_capture_descriptor( struct lttng_condition_event_rule *event_rule_cond = container_of(condition, struct lttng_condition_event_rule, parent); + struct lttng_capture_descriptor *descriptor = NULL; /* Only accept l-values. */ if (!condition || !IS_EVENT_RULE_CONDITION(condition) || !expr || @@ -655,14 +710,26 @@ lttng_condition_event_rule_append_capture_descriptor( goto end; } + descriptor = malloc(sizeof(*descriptor)); + if (descriptor == NULL) { + status = LTTNG_CONDITION_STATUS_ERROR; + goto end; + } + + descriptor->event_expression = expr; + descriptor->bytecode = NULL; + ret = lttng_dynamic_pointer_array_add_pointer( - &event_rule_cond->capture_descriptors, expr); + &event_rule_cond->capture_descriptors, descriptor); if (ret) { status = LTTNG_CONDITION_STATUS_ERROR; goto end; } + /* Ownership is transfered to the internal capture_descriptors array */ + descriptor = NULL; end: + free(descriptor); return status; } @@ -692,20 +759,15 @@ const struct lttng_event_expr * lttng_condition_event_rule_get_capture_descriptor_at_index( const struct lttng_condition *condition, unsigned int index) { - const struct lttng_condition_event_rule *event_rule_cond = - container_of(condition, - const struct lttng_condition_event_rule, - parent); const struct lttng_event_expr *expr = NULL; + const struct lttng_capture_descriptor *desc = NULL; - if (!condition || !IS_EVENT_RULE_CONDITION(condition) || - index >= lttng_dynamic_pointer_array_get_count( - &event_rule_cond->capture_descriptors)) { + desc = lttng_condition_event_rule_get_internal_capture_descriptor_at_index( + condition, index); + if (desc == NULL) { goto end; } - - expr = lttng_dynamic_pointer_array_get_pointer( - &event_rule_cond->capture_descriptors, index); + expr = desc->event_expression; end: return expr; @@ -862,3 +924,90 @@ enum lttng_evaluation_status lttng_evaluation_event_rule_get_trigger_name( end: return status; } + +LTTNG_HIDDEN +enum lttng_error_code +lttng_condition_event_rule_generate_capture_descriptor_bytecode( + struct lttng_condition *condition) +{ + enum lttng_error_code ret; + enum lttng_condition_status status; + unsigned int capture_count, i; + + if (!condition || !IS_EVENT_RULE_CONDITION(condition)) { + ret = LTTNG_ERR_FATAL; + goto end; + } + + status = lttng_condition_event_rule_get_capture_descriptor_count( + condition, &capture_count); + if (status != LTTNG_CONDITION_STATUS_OK) { + ret = LTTNG_ERR_FATAL; + goto end; + } + + for (i = 0; i < capture_count; i++) { + struct lttng_capture_descriptor *local_capture_desc = + lttng_condition_event_rule_get_internal_capture_descriptor_at_index( + condition, i); + + if (local_capture_desc == NULL) { + ret = LTTNG_ERR_FATAL; + goto end; + } + + /* Generate the bytecode. */ + status = lttng_event_expr_to_bytecode( + local_capture_desc->event_expression, + &local_capture_desc->bytecode); + if (status < 0 || local_capture_desc->bytecode == NULL) { + ret = LTTNG_ERR_INVALID_CAPTURE_EXPRESSION; + goto end; + } + } + + /* Everything went better than expected */ + ret = LTTNG_OK; + +end: + return ret; +} + +LTTNG_HIDDEN +const struct lttng_bytecode * +lttng_condition_event_rule_get_capture_bytecode_at_index( + const struct lttng_condition *condition, unsigned int index) +{ + const struct lttng_condition_event_rule *event_rule_cond = + container_of(condition, + const struct lttng_condition_event_rule, + parent); + struct lttng_capture_descriptor *desc = NULL; + struct lttng_bytecode *bytecode = NULL; + unsigned int count; + enum lttng_condition_status status; + + if (!condition || !IS_EVENT_RULE_CONDITION(condition)) { + goto end; + } + + status = lttng_condition_event_rule_get_capture_descriptor_count( + condition, &count); + if (status != LTTNG_CONDITION_STATUS_OK) { + goto end; + } + + if (index >= count) { + goto end; + } + + desc = lttng_dynamic_pointer_array_get_pointer( + &event_rule_cond->capture_descriptors, index); + if (desc == NULL) { + goto end; + } + + bytecode = desc->bytecode; +end: + return bytecode; +}