From a7a2e194b1a546031e58eb6ec8a42f28e056e842 Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Fri, 16 Sep 2022 14:53:55 +0300 Subject: ........S. [ZBX-21616] fixed error due to non-existent macros in custom expressions (cherry picked from commit c0f76dd026b98b1d65597910e2a3bcde4caf58d4) --- src/zabbix_server/lld/lld.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c index 2bda0af3091..667176f4f33 100644 --- a/src/zabbix_server/lld/lld.c +++ b/src/zabbix_server/lld/lld.c @@ -216,7 +216,7 @@ static int lld_filter_load(lld_filter_t *filter, zbx_uint64_t lld_ruleid, const * * ******************************************************************************/ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths, - const lld_condition_t *condition, char **info) + const lld_condition_t *condition, char **info, zbx_vector_str_t *non_existent_macro) { char *value = NULL; int ret; @@ -248,9 +248,17 @@ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx } else if (CONDITION_OPERATOR_EXIST != condition->op) { - *info = zbx_strdcatf(*info, - "Cannot accurately apply filter: no value received for macro \"%s\".\n", - condition->macro); + if (NULL != non_existent_macro && SUCCEED == zbx_vector_str_search(non_existent_macro, + condition->macro, ZBX_DEFAULT_STR_COMPARE_FUNC)) + { + ret = SUCCEED; + } + else + { + *info = zbx_strdcatf(*info, + "Cannot accurately apply filter: no value received for macro \"%s\".\n", + condition->macro); + } } zbx_free(value); @@ -284,7 +292,7 @@ static int filter_evaluate_and_or(const lld_filter_t *filter, const struct zbx_j int rc; const lld_condition_t *condition = (lld_condition_t *)filter->conditions.values[i]; - rc = filter_condition_match(jp_row, lld_macro_paths, condition, info); + rc = filter_condition_match(jp_row, lld_macro_paths, condition, info, NULL); /* check if a new condition group has started */ if (NULL == lastmacro || 0 != strcmp(lastmacro, condition->macro)) { @@ -332,7 +340,7 @@ static int filter_evaluate_and(const lld_filter_t *filter, const struct zbx_json { /* if any of conditions are false the evaluation returns false */ if (SUCCEED != (ret = filter_condition_match(jp_row, lld_macro_paths, - (lld_condition_t *)filter->conditions.values[i], info))) + (lld_condition_t *)filter->conditions.values[i], info, NULL))) { break; } @@ -367,7 +375,7 @@ static int filter_evaluate_or(const lld_filter_t *filter, const struct zbx_json_ { /* if any of conditions are true the evaluation returns true */ if (SUCCEED == (ret = filter_condition_match(jp_row, lld_macro_paths, - (lld_condition_t *)filter->conditions.values[i], info))) + (lld_condition_t *)filter->conditions.values[i], info, NULL))) { break; } @@ -399,19 +407,25 @@ static int filter_evaluate_or(const lld_filter_t *filter, const struct zbx_json_ static int filter_evaluate_expression(const lld_filter_t *filter, const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths, char **info) { - int i, ret = FAIL, id_len; - char *expression, id[ZBX_MAX_UINT64_LEN + 2], *p, error[256]; - double result; + int i, ret = FAIL, id_len; + char *expression, id[ZBX_MAX_UINT64_LEN + 2], *p, error[256]; + double result; + zbx_vector_str_t non_existent_macros; zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:%s", __func__, filter->expression); expression = zbx_strdup(NULL, filter->expression); + zbx_vector_str_create(&non_existent_macros); + for (i = 0; i < filter->conditions.values_num; i++) { const lld_condition_t *condition = (lld_condition_t *)filter->conditions.values[i]; - ret = filter_condition_match(jp_row, lld_macro_paths, condition, info); + ret = filter_condition_match(jp_row, lld_macro_paths, condition, info, &non_existent_macros); + + if (CONDITION_OPERATOR_EXIST == condition->op && ret == FAIL) + zbx_vector_str_append(&non_existent_macros, condition->macro); zbx_snprintf(id, sizeof(id), "{" ZBX_FS_UI64 "}", condition->id); @@ -430,6 +444,7 @@ static int filter_evaluate_expression(const lld_filter_t *filter, const struct z ret = (SUCCEED != zbx_double_compare(result, 0) ? SUCCEED : FAIL); zbx_free(expression); + zbx_vector_str_destroy(&non_existent_macros); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret)); -- cgit v1.2.3 From fe2e8fdb8c5c6403d9ea33bbcfe6056d1f6ae7c2 Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Thu, 6 Oct 2022 08:54:44 -0400 Subject: ........S. [ZBX-21616] refactored and reimplemented parsing logics (cherry picked from commit 3e179e8e2ea78c744dd81c18a8079ca4449cc232) --- src/zabbix_server/lld/lld.c | 247 ++++++++++++++++++++++++-------------------- 1 file changed, 134 insertions(+), 113 deletions(-) diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c index 667176f4f33..91471a70e39 100644 --- a/src/zabbix_server/lld/lld.c +++ b/src/zabbix_server/lld/lld.c @@ -216,48 +216,50 @@ static int lld_filter_load(lld_filter_t *filter, zbx_uint64_t lld_ruleid, const * * ******************************************************************************/ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths, - const lld_condition_t *condition, char **info, zbx_vector_str_t *non_existent_macro) + const lld_condition_t *condition, int *result, char **info) { char *value = NULL; - int ret; + int ret = SUCCEED; - if (SUCCEED == (ret = zbx_lld_macro_value_by_name(jp_row, lld_macro_paths, condition->macro, &value))) + if (SUCCEED == zbx_lld_macro_value_by_name(jp_row, lld_macro_paths, condition->macro, &value)) { if (CONDITION_OPERATOR_NOT_EXIST == condition->op) { - ret = FAIL; + *result = 0; } - else if (CONDITION_OPERATOR_EXIST != condition->op) + if (CONDITION_OPERATOR_EXIST == condition->op) + { + *result = 1; + } + else { switch (regexp_match_ex(&condition->regexps, value, condition->regexp, ZBX_CASE_SENSITIVE)) { case ZBX_REGEXP_MATCH: - ret = (CONDITION_OPERATOR_REGEXP == condition->op ? SUCCEED : FAIL); + *result = (CONDITION_OPERATOR_REGEXP == condition->op ? 1 : 0); break; case ZBX_REGEXP_NO_MATCH: - ret = (CONDITION_OPERATOR_NOT_REGEXP == condition->op ? SUCCEED : FAIL); + *result = (CONDITION_OPERATOR_NOT_REGEXP == condition->op ? 1 : 0); break; default: ret = FAIL; } } } - else if (CONDITION_OPERATOR_NOT_EXIST == condition->op) - { - ret = SUCCEED; - } - else if (CONDITION_OPERATOR_EXIST != condition->op) + else { - if (NULL != non_existent_macro && SUCCEED == zbx_vector_str_search(non_existent_macro, - condition->macro, ZBX_DEFAULT_STR_COMPARE_FUNC)) + switch (condition->op) { - ret = SUCCEED; - } - else - { - *info = zbx_strdcatf(*info, - "Cannot accurately apply filter: no value received for macro \"%s\".\n", - condition->macro); + case CONDITION_OPERATOR_NOT_EXIST: + *result = 1; + break; + case CONDITION_OPERATOR_EXIST: + *result = 0; + break; + default: + *info = zbx_strdcatf(*info, "Cannot accurately apply filter: no value received for " + "macro \"%s\".\n", condition->macro); + ret = FAIL; } } @@ -268,7 +270,7 @@ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx /****************************************************************************** * * - * Purpose: check if the lld data passes filter evaluation by and/or rule * + * Purpose: check if the lld data passes filter evaluation by and rule * * * * Parameters: filter - [IN] the lld filter * * jp_row - [IN] the lld data row * @@ -279,108 +281,105 @@ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx * FAIL - otherwise * * * ******************************************************************************/ -static int filter_evaluate_and_or(const lld_filter_t *filter, const struct zbx_json_parse *jp_row, +static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths, char **info) { - int i, ret = SUCCEED; - char *lastmacro = NULL; + int i, ret = SUCCEED, error_num = 0, res; + double result; + char *lastmacro = NULL; + lld_condition_t *condition; + char *ops[] = {NULL, "and", "or"}, error[256], value[16], id[ZBX_MAX_UINT64_LEN + 2], *p, + *expression = NULL, *eval_expr = NULL, *errmsg = NULL; + size_t expression_alloc = 0, expression_offset = 0, id_len, value_len; + size_t eval_expr_alloc = 0, eval_expr_offset = 0; + zbx_vector_ptr_t errmsgs; - zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); + zbx_vector_ptr_create(&errmsgs); for (i = 0; i < filter->conditions.values_num; i++) { - int rc; - const lld_condition_t *condition = (lld_condition_t *)filter->conditions.values[i]; + condition = (lld_condition_t *)filter->conditions.values[i]; - rc = filter_condition_match(jp_row, lld_macro_paths, condition, info, NULL); - /* check if a new condition group has started */ - if (NULL == lastmacro || 0 != strcmp(lastmacro, condition->macro)) + if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype) { - /* if any of condition groups are false the evaluation returns false */ - if (FAIL == ret) - break; + if (NULL == lastmacro) + { + zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, '('); + } + else if (0 != strcmp(lastmacro, condition->macro)) + { + zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, ") and "); + } + else + zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, " or "); - ret = rc; + lastmacro = condition->macro; } - else + else if (0 != i) { - if (SUCCEED == rc) - ret = rc; + zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ' '); + zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, ops[filter->evaltype]); + zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ' '); } - lastmacro = condition->macro; + zbx_snprintf_alloc(&expression, &expression_alloc, &expression_offset, "{" ZBX_FS_UI64 "}", + condition->id); } - zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret)); - - return ret; -} + if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype) + zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ')'); -/****************************************************************************** - * * - * Purpose: check if the lld data passes filter evaluation by and rule * - * * - * Parameters: filter - [IN] the lld filter * - * jp_row - [IN] the lld data row * - * lld_macro_paths - [IN] use json path to extract from jp_row * - * info - [OUT] the warning description * - * * - * Return value: SUCCEED - the lld data passed filter evaluation * - * FAIL - otherwise * - * * - ******************************************************************************/ -static int filter_evaluate_and(const lld_filter_t *filter, const struct zbx_json_parse *jp_row, - const zbx_vector_ptr_t *lld_macro_paths, char **info) -{ - int i, ret = SUCCEED; + zbx_strcpy_alloc(&eval_expr, &eval_expr_alloc, &eval_expr_offset, expression); - zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); + /* include trailing zero */ + eval_expr_offset++; for (i = 0; i < filter->conditions.values_num; i++) { - /* if any of conditions are false the evaluation returns false */ - if (SUCCEED != (ret = filter_condition_match(jp_row, lld_macro_paths, - (lld_condition_t *)filter->conditions.values[i], info, NULL))) + condition = (lld_condition_t *)filter->conditions.values[i]; + + if (SUCCEED == (ret = filter_condition_match(jp_row, lld_macro_paths, condition, &res, &errmsg))) { - break; + zbx_snprintf(value, sizeof(value), "%d", res); + } + else + { + zbx_snprintf(value, sizeof(value), ZBX_UNKNOWN_STR "%d", error_num++); + zbx_vector_ptr_append(&errmsgs, errmsg); + errmsg = NULL; } - } - zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret)); + zbx_snprintf(id, sizeof(id), "{" ZBX_FS_UI64 "}", condition->id); - return ret; -} + value_len = strlen(value); + id_len = strlen(id); -/****************************************************************************** - * * - * Purpose: check if the lld data passes filter evaluation by or rule * - * * - * Parameters: filter - [IN] the lld filter * - * jp_row - [IN] the lld data row * - * lld_macro_paths - [IN] use json path to extract from jp_row * - * info - [OUT] the warning description * - * * - * Return value: SUCCEED - the lld data passed filter evaluation * - * FAIL - otherwise * - * * - ******************************************************************************/ -static int filter_evaluate_or(const lld_filter_t *filter, const struct zbx_json_parse *jp_row, - const zbx_vector_ptr_t *lld_macro_paths, char **info) -{ - int i, ret = SUCCEED; + for (p = strstr(eval_expr, id); NULL != p; p = strstr(p, id)) + { + size_t id_pos = p - eval_expr; - zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); + zbx_replace_mem_dyn(&eval_expr, &eval_expr_alloc, &eval_expr_offset, id_pos, id_len, + value, value_len); - for (i = 0; i < filter->conditions.values_num; i++) - { - /* if any of conditions are true the evaluation returns true */ - if (SUCCEED == (ret = filter_condition_match(jp_row, lld_macro_paths, - (lld_condition_t *)filter->conditions.values[i], info, NULL))) - { - break; + p = eval_expr + id_pos + value_len - id_len; } } + if (SUCCEED == zbx_evaluate(&result, eval_expr, error, sizeof(error), &errmsgs)) + { + ret = (SUCCEED != zbx_double_compare(result, 0) ? SUCCEED : FAIL); + } + else + { + *info = zbx_strdcat(*info, error); + ret = FAIL; + } + + zbx_free(expression); + zbx_free(eval_expr); + zbx_vector_ptr_clear_ext(&errmsgs, zbx_ptr_free); + zbx_vector_ptr_destroy(&errmsgs); + zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret)); return ret; @@ -407,44 +406,66 @@ static int filter_evaluate_or(const lld_filter_t *filter, const struct zbx_json_ static int filter_evaluate_expression(const lld_filter_t *filter, const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths, char **info) { - int i, ret = FAIL, id_len; - char *expression, id[ZBX_MAX_UINT64_LEN + 2], *p, error[256]; + int i, ret = FAIL, res, error_num = 0; + char *expression = NULL, id[ZBX_MAX_UINT64_LEN + 2], *p, error[256], value[16], + *errmsg = NULL; double result; - zbx_vector_str_t non_existent_macros; + zbx_vector_ptr_t errmsgs; + size_t expression_alloc = 0, expression_offset = 0, id_len, value_len; zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:%s", __func__, filter->expression); - expression = zbx_strdup(NULL, filter->expression); + zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, filter->expression); - zbx_vector_str_create(&non_existent_macros); + /* include trailing zero */ + expression_offset++; + + zbx_vector_ptr_create(&errmsgs); for (i = 0; i < filter->conditions.values_num; i++) { const lld_condition_t *condition = (lld_condition_t *)filter->conditions.values[i]; - ret = filter_condition_match(jp_row, lld_macro_paths, condition, info, &non_existent_macros); - - if (CONDITION_OPERATOR_EXIST == condition->op && ret == FAIL) - zbx_vector_str_append(&non_existent_macros, condition->macro); + if (SUCCEED == (ret = filter_condition_match(jp_row, lld_macro_paths, condition, &res, &errmsg))) + { + zbx_snprintf(value, sizeof(value), "%d", res); + } + else + { + zbx_snprintf(value, sizeof(value), ZBX_UNKNOWN_STR "%d", error_num++); + zbx_vector_ptr_append(&errmsgs, errmsg); + errmsg = NULL; + } zbx_snprintf(id, sizeof(id), "{" ZBX_FS_UI64 "}", condition->id); + value_len = strlen(value); id_len = strlen(id); - p = expression; - while (NULL != (p = strstr(p, id))) + for (p = strstr(expression, id); NULL != p; p = strstr(p, id)) { - *p = (SUCCEED == ret ? '1' : '0'); - memset(p + 1, ' ', id_len - 1); - p += id_len; + size_t id_pos = p - expression; + + zbx_replace_mem_dyn(&expression, &expression_alloc, &expression_offset, id_pos, id_len, + value, value_len); + + p = expression + id_pos + value_len - id_len; } } - if (SUCCEED == zbx_evaluate(&result, expression, error, sizeof(error), NULL)) + if (SUCCEED == zbx_evaluate(&result, expression, error, sizeof(error), &errmsgs)) + { ret = (SUCCEED != zbx_double_compare(result, 0) ? SUCCEED : FAIL); + } + else + { + *info = zbx_strdcat(*info, error); + ret = FAIL; + } zbx_free(expression); - zbx_vector_str_destroy(&non_existent_macros); + zbx_vector_ptr_clear_ext(&errmsgs, zbx_ptr_free); + zbx_vector_ptr_destroy(&errmsgs); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret)); @@ -470,11 +491,11 @@ static int filter_evaluate(const lld_filter_t *filter, const struct zbx_json_par switch (filter->evaltype) { case CONDITION_EVAL_TYPE_AND_OR: - return filter_evaluate_and_or(filter, jp_row, lld_macro_paths, info); + ZBX_FALLTHROUGH; case CONDITION_EVAL_TYPE_AND: - return filter_evaluate_and(filter, jp_row, lld_macro_paths, info); + ZBX_FALLTHROUGH; case CONDITION_EVAL_TYPE_OR: - return filter_evaluate_or(filter, jp_row, lld_macro_paths, info); + return filter_evaluate_and_or_andor(filter, jp_row, lld_macro_paths, info); case CONDITION_EVAL_TYPE_EXPRESSION: return filter_evaluate_expression(filter, jp_row, lld_macro_paths, info); } -- cgit v1.2.3 From beb783a43efffa6949c44de0538474857e2cb222 Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Thu, 6 Oct 2022 08:56:41 -0400 Subject: .......... [ZBX-21616] added changelog (cherry picked from commit 8740298888214a3cf21ec95704c73ec442eaaba2) --- ChangeLog.d/bugfix/ZBX-21616 | 1 + 1 file changed, 1 insertion(+) create mode 100644 ChangeLog.d/bugfix/ZBX-21616 diff --git a/ChangeLog.d/bugfix/ZBX-21616 b/ChangeLog.d/bugfix/ZBX-21616 new file mode 100644 index 00000000000..93a28c3c416 --- /dev/null +++ b/ChangeLog.d/bugfix/ZBX-21616 @@ -0,0 +1 @@ +........S. [ZBX-21616] fixed error due to non-existent macros in custom expressions (dgoloscapov, wiper) \ No newline at end of file -- cgit v1.2.3 From 7df2c9f296ab1defa2c8295c1923eaa86bcb7b48 Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Thu, 6 Oct 2022 08:57:07 -0400 Subject: .......... [ZBX-21616] added changelog (cherry picked from commit ef329568c65d87c5e38780619114c23de19bcfb6) --- ChangeLog.d/bugfix/ZBX-21616 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/bugfix/ZBX-21616 b/ChangeLog.d/bugfix/ZBX-21616 index 93a28c3c416..fcabe90b876 100644 --- a/ChangeLog.d/bugfix/ZBX-21616 +++ b/ChangeLog.d/bugfix/ZBX-21616 @@ -1 +1 @@ -........S. [ZBX-21616] fixed error due to non-existent macros in custom expressions (dgoloscapov, wiper) \ No newline at end of file +........S. [ZBX-21616] fixed error due to non-existent macros in custom expressions (dgoloscapov, wiper) -- cgit v1.2.3 From e3cc07d97b4e87bad658f215d7a6a7665dc94e6f Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Mon, 24 Oct 2022 07:38:31 -0400 Subject: ........S. [ZBX-21616] optimized (cherry picked from commit 3f5ba2086d944f8dfdd3e7343ba876e49a0f7b77) --- src/zabbix_server/lld/lld.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c index 91471a70e39..bccd9adace3 100644 --- a/src/zabbix_server/lld/lld.c +++ b/src/zabbix_server/lld/lld.c @@ -289,11 +289,12 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct char *lastmacro = NULL; lld_condition_t *condition; char *ops[] = {NULL, "and", "or"}, error[256], value[16], id[ZBX_MAX_UINT64_LEN + 2], *p, - *expression = NULL, *eval_expr = NULL, *errmsg = NULL; + *expression = NULL, *errmsg = NULL; size_t expression_alloc = 0, expression_offset = 0, id_len, value_len; - size_t eval_expr_alloc = 0, eval_expr_offset = 0; zbx_vector_ptr_t errmsgs; + zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); + zbx_vector_ptr_create(&errmsgs); for (i = 0; i < filter->conditions.values_num; i++) @@ -324,19 +325,14 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct zbx_snprintf_alloc(&expression, &expression_alloc, &expression_offset, "{" ZBX_FS_UI64 "}", condition->id); - } - - if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype) - zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ')'); - zbx_strcpy_alloc(&eval_expr, &eval_expr_alloc, &eval_expr_offset, expression); - - /* include trailing zero */ - eval_expr_offset++; + if (filter->conditions.values_num == i + 1) + { + if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype) + zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ')'); - for (i = 0; i < filter->conditions.values_num; i++) - { - condition = (lld_condition_t *)filter->conditions.values[i]; + expression_offset++; + } if (SUCCEED == (ret = filter_condition_match(jp_row, lld_macro_paths, condition, &res, &errmsg))) { @@ -354,18 +350,18 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct value_len = strlen(value); id_len = strlen(id); - for (p = strstr(eval_expr, id); NULL != p; p = strstr(p, id)) + for (p = strstr(expression, id); NULL != p; p = strstr(p, id)) { - size_t id_pos = p - eval_expr; + size_t id_pos = p - expression; - zbx_replace_mem_dyn(&eval_expr, &eval_expr_alloc, &eval_expr_offset, id_pos, id_len, + zbx_replace_mem_dyn(&expression, &expression_alloc, &expression_offset, id_pos, id_len, value, value_len); - p = eval_expr + id_pos + value_len - id_len; + p = expression + id_pos + value_len - id_len; } } - if (SUCCEED == zbx_evaluate(&result, eval_expr, error, sizeof(error), &errmsgs)) + if (SUCCEED == zbx_evaluate(&result, expression, error, sizeof(error), &errmsgs)) { ret = (SUCCEED != zbx_double_compare(result, 0) ? SUCCEED : FAIL); } @@ -376,7 +372,6 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct } zbx_free(expression); - zbx_free(eval_expr); zbx_vector_ptr_clear_ext(&errmsgs, zbx_ptr_free); zbx_vector_ptr_destroy(&errmsgs); -- cgit v1.2.3 From 24a6aedbef5b711eb59741977fe265bfa777ecf2 Mon Sep 17 00:00:00 2001 From: Andris Zeila Date: Mon, 24 Oct 2022 20:00:49 +0300 Subject: ........S. [ZBX-21616] added more optimizations to LLD filter processing (cherry picked from commit 97429f6c1938fcf5b6708286fa28eebc183b5ceb) --- src/zabbix_server/lld/lld.c | 89 ++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c index bccd9adace3..45b6e79a86f 100644 --- a/src/zabbix_server/lld/lld.c +++ b/src/zabbix_server/lld/lld.c @@ -242,6 +242,8 @@ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx *result = (CONDITION_OPERATOR_NOT_REGEXP == condition->op ? 1 : 0); break; default: + *info = zbx_strdcatf(*info, "Cannot accurately apply filter: invalid regular " + "expression \"%s\".\n", condition->regexp); ret = FAIL; } } @@ -288,9 +290,8 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct double result; char *lastmacro = NULL; lld_condition_t *condition; - char *ops[] = {NULL, "and", "or"}, error[256], value[16], id[ZBX_MAX_UINT64_LEN + 2], *p, - *expression = NULL, *errmsg = NULL; - size_t expression_alloc = 0, expression_offset = 0, id_len, value_len; + char *ops[] = {NULL, "and", "or"}, error[256], *expression = NULL, *errmsg = NULL; + size_t expression_alloc = 0, expression_offset = 0; zbx_vector_ptr_t errmsgs; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); @@ -301,63 +302,56 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct { condition = (lld_condition_t *)filter->conditions.values[i]; - if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype) - { - if (NULL == lastmacro) - { - zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, '('); - } - else if (0 != strcmp(lastmacro, condition->macro)) - { - zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, ") and "); - } - else - zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, " or "); - - lastmacro = condition->macro; - } - else if (0 != i) + switch (filter->evaltype) { - zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ' '); - zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, ops[filter->evaltype]); - zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ' '); - } - - zbx_snprintf_alloc(&expression, &expression_alloc, &expression_offset, "{" ZBX_FS_UI64 "}", - condition->id); - - if (filter->conditions.values_num == i + 1) - { - if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype) - zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ')'); + case CONDITION_EVAL_TYPE_AND_OR: + if (NULL == lastmacro) + { + zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, '('); + } + else if (0 != strcmp(lastmacro, condition->macro)) + { + zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, ") and "); + } + else + zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, " or "); - expression_offset++; + lastmacro = condition->macro; + break; + case CONDITION_EVAL_TYPE_AND: + case CONDITION_EVAL_TYPE_OR: + if (0 != i) + { + zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ' '); + zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, + ops[filter->evaltype]); + zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ' '); + } + break; + default: + *info = zbx_strdcatf(*info, "Cannot accurately apply filter: invalid condition " + "type \"%d\".\n", filter->evaltype); + goto out; } if (SUCCEED == (ret = filter_condition_match(jp_row, lld_macro_paths, condition, &res, &errmsg))) { - zbx_snprintf(value, sizeof(value), "%d", res); + zbx_snprintf_alloc(&expression, &expression_alloc, &expression_offset, "%d", res); } else { - zbx_snprintf(value, sizeof(value), ZBX_UNKNOWN_STR "%d", error_num++); + zbx_snprintf_alloc(&expression, &expression_alloc, &expression_offset, ZBX_UNKNOWN_STR "%d", + error_num++); zbx_vector_ptr_append(&errmsgs, errmsg); errmsg = NULL; } - zbx_snprintf(id, sizeof(id), "{" ZBX_FS_UI64 "}", condition->id); - - value_len = strlen(value); - id_len = strlen(id); - - for (p = strstr(expression, id); NULL != p; p = strstr(p, id)) + if (filter->conditions.values_num == i + 1) { - size_t id_pos = p - expression; - - zbx_replace_mem_dyn(&expression, &expression_alloc, &expression_offset, id_pos, id_len, - value, value_len); + if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype) + zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ')'); - p = expression + id_pos + value_len - id_len; + expression_offset++; } } @@ -370,7 +364,7 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct *info = zbx_strdcat(*info, error); ret = FAIL; } - +out: zbx_free(expression); zbx_vector_ptr_clear_ext(&errmsgs, zbx_ptr_free); zbx_vector_ptr_destroy(&errmsgs); @@ -483,6 +477,9 @@ static int filter_evaluate_expression(const lld_filter_t *filter, const struct z static int filter_evaluate(const lld_filter_t *filter, const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths, char **info) { + if (0 == filter->conditions.values_num) + return SUCCEED; + switch (filter->evaltype) { case CONDITION_EVAL_TYPE_AND_OR: -- cgit v1.2.3 From e2e7db04ced25690ac129bda737856a72e5a5f39 Mon Sep 17 00:00:00 2001 From: Andris Zeila Date: Tue, 25 Oct 2022 10:38:11 +0300 Subject: ........S. [ZBX-21616] fixed offseet calculation when replacing condition ids with values (cherry picked from commit c2410666d7f047930d3297f6b4b546d8929624f1) --- src/zabbix_server/lld/lld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c index 45b6e79a86f..8f9ca3edca2 100644 --- a/src/zabbix_server/lld/lld.c +++ b/src/zabbix_server/lld/lld.c @@ -438,7 +438,7 @@ static int filter_evaluate_expression(const lld_filter_t *filter, const struct z zbx_replace_mem_dyn(&expression, &expression_alloc, &expression_offset, id_pos, id_len, value, value_len); - p = expression + id_pos + value_len - id_len; + p = expression + id_pos + value_len; } } -- cgit v1.2.3 From 0d16c28d403d98dba4c43add7207316615d84d01 Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Thu, 3 Nov 2022 16:05:21 -0400 Subject: .......... [ZBX-21616] code style fix (cherry picked from commit 45aa479dacdba3c14093b05fcf97394f967ee118) --- src/zabbix_server/lld/lld.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c index 8f9ca3edca2..275e9a082b9 100644 --- a/src/zabbix_server/lld/lld.c +++ b/src/zabbix_server/lld/lld.c @@ -209,6 +209,7 @@ static int lld_filter_load(lld_filter_t *filter, zbx_uint64_t lld_ruleid, const * Parameters: jp_row - [IN] the lld data row * * lld_macro_paths - [IN] use json path to extract from jp_row * * condition - [IN] the lld filter condition * + * result - [OUT] the result of evaluation * * info - [OUT] the warning description * * * * Return value: SUCCEED - the lld data passed filter evaluation * -- cgit v1.2.3 From 078ae28959e305248b8a1b1ee13eb0b9347646b5 Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Wed, 9 Nov 2022 04:23:54 -0500 Subject: ........S. [ZBX-21616] got rid of ZBX_FALLTROUGH (cherry picked from commit 0ed587970fb1bdcc5b390718f0dd1d961db30e4d) --- src/zabbix_server/lld/lld.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c index 275e9a082b9..8c2f8115985 100644 --- a/src/zabbix_server/lld/lld.c +++ b/src/zabbix_server/lld/lld.c @@ -484,9 +484,7 @@ static int filter_evaluate(const lld_filter_t *filter, const struct zbx_json_par switch (filter->evaltype) { case CONDITION_EVAL_TYPE_AND_OR: - ZBX_FALLTHROUGH; case CONDITION_EVAL_TYPE_AND: - ZBX_FALLTHROUGH; case CONDITION_EVAL_TYPE_OR: return filter_evaluate_and_or_andor(filter, jp_row, lld_macro_paths, info); case CONDITION_EVAL_TYPE_EXPRESSION: -- cgit v1.2.3 From 78966773ca31e6740989eb394796b9f144944a57 Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Wed, 9 Nov 2022 05:52:09 -0500 Subject: ........S. [ZBX-21616] fixed function description comment (cherry picked from commit 8aac0f7b3ed2d906f6612a3e94ef71b66999d4fc) --- src/zabbix_server/lld/lld.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c index 8c2f8115985..0748a0109bf 100644 --- a/src/zabbix_server/lld/lld.c +++ b/src/zabbix_server/lld/lld.c @@ -271,19 +271,19 @@ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx return ret; } -/****************************************************************************** - * * - * Purpose: check if the lld data passes filter evaluation by and rule * - * * - * Parameters: filter - [IN] the lld filter * - * jp_row - [IN] the lld data row * - * lld_macro_paths - [IN] use json path to extract from jp_row * - * info - [OUT] the warning description * - * * - * Return value: SUCCEED - the lld data passed filter evaluation * - * FAIL - otherwise * - * * - ******************************************************************************/ +/**************************************************************************************** + * * + * Purpose: check if the lld data passes filter evaluation by and/or/andor rules * + * * + * Parameters: filter - [IN] the lld filter * + * jp_row - [IN] the lld data row * + * lld_macro_paths - [IN] use json path to extract from jp_row * + * info - [OUT] the warning description * + * * + * Return value: SUCCEED - the lld data passed filter evaluation * + * FAIL - otherwise * + * * + ****************************************************************************************/ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths, char **info) { -- cgit v1.2.3