[ZBX-11223] Server creates impossible calculated items Created: 2016 Sep 16 Updated: 2019 Mar 11 Resolved: 2017 Feb 06 |
|
Status: | Closed |
Project: | ZABBIX BUGS AND ISSUES |
Component/s: | Server (S) |
Affects Version/s: | 2.2.15rc1, 3.0.5rc1, 3.2.1rc1, 3.4.0alpha1 |
Fix Version/s: | 2.2.16rc1, 3.0.6rc1, 3.2.2rc1, 3.4.0alpha1 |
Type: | Incident report | Priority: | Minor |
Reporter: | Glebs Ivanovskis (Inactive) | Assignee: | Unassigned |
Resolution: | Fixed | Votes: | 0 |
Labels: | calculateditems, lld | ||
Remaining Estimate: | Not Specified | ||
Time Spent: | Not Specified | ||
Original Estimate: | Not Specified |
Description |
Suppose I have a calculated item prototype with such formula: count(item,10m,{#LLD_MACRO}) and LLD rule which gives back {#LLD_MACRO} value starting with whitespace and ending with '\'. Server quotes macro value in parameter (because of leading whitespace) but then fails to process resulting calculated item (because quoted parameters can't end with a backslash). |
Comments |
Comment by Aleksandrs Saveljevs [ 2016 Sep 20 ] |
Discussed a bit in ZBX-10590. |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 21 ] |
I think for now we need to fail creation of such calculated items like we do for regular items after |
Comment by Sergejs Paskevics [ 2016 Sep 23 ] |
Similar problem was in {{echo.sh[{$MACRO}]}} Macro: a\ Result: echo.sh[{$MACRO}] |
Comment by Sergejs Paskevics [ 2016 Sep 28 ] |
Fixed in development branch svn://svn.zabbix.com/branches/dev/ZBX-11223. Quoted parameters can't end with a backslash and now LLD rules don't create items if it's syntax is wrong. |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 29 ] |
(1) That's not your fault, but comment regarding quote_key_param() return codes does not seem to be right. Or at least FAIL part, parameter ending with backslash does not always result in failure. s.paskevics RESOLVED in r62870, r62879. glebs.ivanovskis Thank you! Slightly improved (hopefully) wording in r63326. Have a look. Still RESOLVED s.paskevics Looks good. |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 29 ] |
(2) Let's add more examples resulting in FAIL to the comment of substitute_key_macros() (I mean macros containing "]" and ",", not just leading whitespace). Is it possible to squeeze the comment into usual comment width by shrinking "macro" column? s.paskevics RESOLVED in r62879. glebs.ivanovskis Looks good, reordered and added few more examples in r63325. Please have a look. Still RESOLVED. s.paskevics Looks good. |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 29 ] |
(3) Currently making of LLD calculated item formula looks like so:
And these two loops are separated into different functions (substitute_formula_macros() and zbx_function_tostr()) and even different files. This is not convenient. Also we do double work of parsing with zbx_function_parse() and function_parse_name()/function_parse_param(). Would be nice to put everything in one place. It will eliminate the need of passing quoted in zbx_function_t. s.paskevics RESOLVED in r62870. glebs.ivanovskis Seems that workflow is the same and double work is still there. Am I looking in the wrong place? s.paskevics I refactored zbx_function_tostr() function. Now this function quites and converts from f_function_t to string without double parsing. Function zbx_function_parse() is called only once from substitute_formula_macros() glebs.ivanovskis I revised a whole function parsing ecosystem in r63411 and r63419. Quick summary:
Still RESOLVED glebs.ivanovskis Further improvements in r63466. Now calculated item evaluation uses the same parser as calculated item LLD. Still RESOLVED
glebs.ivanovskis This subissue is getting difficult to manage:
Let's consider this one |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 29 ] |
(4) s.paskevics RESOLVED in r62870. glebs.ivanovskis You forgot that if parameter was quoted initially it needs to get quoted back. Currently only "value-induced" quoting occurs. s.paskevics I changed the code. How quoting should work properly. RESOLVED in r63012. glebs.ivanovskis Good! |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 29 ] |
(5) Parsing and quoting rules for item key parameters and function parameters are very similar ("]" -> ")" is the only difference). Can we adapt quote_key_param() and unquote_key_param() to work for both keys and functions and throw function_quote_param_dyn() away? The only caveat here is that quote_key_param() is used in DB upgrades. We must be careful. glebs.ivanovskis There is a difference in forced quoting rules not reflected in quote_key_param() currently. See s.paskevics RESOLVED in r62870. glebs.ivanovskis Looks good! The only thing remaining is to pass parameter string and quoted/unquoted state as separate parameters. s.paskevics The function parameter is zbx_func_param_t. quoted/unquoted flag already exists in this structure. Should it be changed? glebs.ivanovskis What I actually meant is that this function is in str.c where we mostly have functions working with strings, not complex structures. Anyway, see what happened to it in r63419. s.paskevics |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Oct 04 ] |
(6) By the way, do we feel like fixing s.paskevics Please check it. RESOLVED in r63012. glebs.ivanovskis Opening bracket is treated as array beginning only if it is the first character or is preceded by spaces. So we don't need to check the whole parameter for '[', just the very first character. Leading space will force quoting on its own. New case when we force item key parameter quoting deserves a mention in substitute_key_macros() comment. Would be nice to check the result of parse_item_key() in get_value_simple() as well. This would save us from crashes in case of corrupted database and finally would make Coverity happy. REOPENED s.paskevics RESOLVED in r63408. glebs.ivanovskis Exactly what we need! Added my $0.02 in r63426. |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Oct 24 ] |
(7) Shouldn't we fail in substitute_formula_macros() if function has no parameters or if parse_host_key() returns FAIL according to "fail as soon as possible" rule? glebs.ivanovskis According to sasha, server should not validate formula syntax during discovery rule processing, frontend should validate calculated item prototype formula instead. Story for another issue. |
Comment by Sergejs Paskevics [ 2016 Oct 31 ] |
(8) Found new error, if macros value is empty and item or function parameter is quoted (for example - key("{$MACRO}") then zabbix tries to read data outside of the array. sz_src = strlen(*param); //sz_src = 0
if ('\\' == (*param)[sz_src - 1]) // error return FAIL; Warning message from valgrind: ==16616== Invalid read of size 1 ==16616== at 0x44EEC9: quote_key_param (sysinfo.c:1075) ==16616== by 0x462614: replace_key_param_cb (expression.c:4810) ==16616== by 0x49515B: replace_key_param (str.c:1616) ==16616== by 0x4955DC: replace_key_params_dyn (str.c:1759) ==16616== by 0x45BA06: substitute_key_macros (expression.c:4863) ==16616== by 0x42C610: get_values (poller.c:398) ==16616== by 0x42D837: poller_thread (poller.c:707) s.paskevics RESOLVED. See r63451. glebs.ivanovskis Looks good! |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 07 ] |
(9) Moved from (3.1): s.paskevics If first function parameter contain LLD macro then substitute_formula_macros() parse incorrectly. glebs.ivanovskis What happens there is that first parameter cannot be parsed as <host:>key and macro substitution fails for the whole formula. Although I admit that error "Cannot create item: Invalid item key at position 0." is way too cryptic. Attempted to improve error message in r63546. s.paskevics |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 07 ] |
(10) Moved from (3.2): s.paskevics Evaluate function works correctly only with expressions without white spaces. See my fix c63494 glebs.ivanovskis Please see my correction in r63496, should be fine now. s.paskevics |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 07 ] |
(11) Moved from (3.3): s.paskevics Need to update comments for following functions:
glebs.ivanovskis RESOLVED in r63558. s.paskevics |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 07 ] |
(12) Moved from (3.4): s.paskevics About this check in get_trigger_function_value(): if (SUCCEED != zbx_function_find(p, &f_pos, &par_l, &par_r) || 0 != f_pos || '}' != p[par_r + 1]) goto fail; I think better to move 0 != f_pos inside zbx_function_find() glebs.ivanovskis I agree. Your solution in r63533 looked like we try to squeeze two functions into one body, so I decided to make two functions. s.paskevics Looks good. |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 07 ] |
(13) Thank you that you noticed that leading whitespace counting problem. s.paskevics |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 07 ] |
(14) Let's move parse_host_key() call and related code from calcitem_evaluate_expression() to calcitem_parse_expression(). The latter will then resemble substitute_formula_macros() and we won't need to remove_param() explicitly. s.paskevics RESOLVED in r63557. glebs.ivanovskis Compilation warnings: checks_calculated.c: In function ‘calcitem_parse_expression’: checks_calculated.c:92:34: warning: unused variable ‘nparam’ [-Wunused-variable] int functionid, ret = SUCCEED, nparam = 0, quoted; ^ checks_calculated.c: In function ‘calcitem_evaluate_expression’: checks_calculated.c:262:1: warning: label ‘out’ defined but not used [-Wunused-label] out: ^ s.paskevics RESOLVED in r63561. glebs.ivanovskis A few flaws in your implementation:
See my fixes in r63579. s.paskevics |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 07 ] |
(15) Suspicious code: if (i == items->values_num) /* no item found */ { ... item->snmp_oid = zbx_strdup(NULL, snmp_oid_proto); item->snmp_oid_orig = NULL; if (ITEM_TYPE_SNMPv1 == type || ITEM_TYPE_SNMPv2c == type || ITEM_TYPE_SNMPv3 == type) { if (FAIL == substitute_key_macros(&item->snmp_oid, NULL, NULL, jp_row, MACRO_TYPE_SNMP_OID, err, sizeof(err))) { goto out; } zbx_lrtrim(item->snmp_oid, ZBX_WHITESPACE); } ... } else { ... if (ITEM_TYPE_SNMPv1 == type || ITEM_TYPE_SNMPv2c == type || ITEM_TYPE_SNMPv3 == type) { buffer = zbx_strdup(buffer, snmp_oid_proto); if (FAIL == substitute_key_macros(&buffer, NULL, NULL, jp_row, MACRO_TYPE_SNMP_OID, err, sizeof(err))) { goto out; } zbx_lrtrim(buffer, ZBX_WHITESPACE); if (0 != strcmp(item->snmp_oid, buffer)) { item->snmp_oid_orig = item->snmp_oid; item->snmp_oid = buffer; buffer = NULL; item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_OID; } } ... } Why do we zbx_strdup(..., snmp_oid_proto) outside of the if for new LLD items and inside the if for existing ones? snmp_oid_proto comes from the database every time we process LLD data, theoretically it may change from time to time. Shouldn't we do zbx_lrtrim(..., ZBX_WHITESPACE) outside of the if as well? I understand, that it won't make any difference what exactly is stored in snmp_oid for non-SNMP items, but almost identical code can catch an eye of the reader and drive him crazy before it realizes that this subtle difference has no effect. s.paskevics These checks are removed in r63575. This problem will be considered and resolved under different issue. glebs.ivanovskis Nice! The rest |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 07 ] |
(16) In case of error in substitute_formula_macros() we leave '\0' in the original formula. s.paskevics |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 08 ] |
Successfully tested. Let's merge! |
Comment by Sergejs Paskevics [ 2016 Nov 08 ] |
Fixed in:
|
Comment by Sergejs Paskevics [ 2016 Nov 09 ] |
(17) Absence of error message about the failed item update from prototype (how it is done for item creation). Created new dev branch for this fix - svn://svn.zabbix.com/branches/dev/ZBX-11223-2 s.paskevics RESOLVED in r63655. glebs.ivanovskis If item creation or update failed in two possible places (key and formula) shouldn't we show both error messages so that user can solve both issues before the next LLD run? glebs.ivanovskis On update we show error message for every field we failed to update for some reason. On new item creation failure we show only the first error message. Still REOPENED, but before continuing on this subissue let's test and merge svn://svn.zabbix.com/branches/dev/ZBX-11223-3 s.paskevics Changes in svn://svn.zabbix.com/branches/dev/ZBX-11223-3 successfully tested. glebs.ivanovskis Ported necessary changes to svn://svn.zabbix.com/branches/dev/ZBX-11223-2 s.paskevics Looks good. |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 09 ] |
(18) I guess it's not good to goto out; in the middle of item creation or update. We can leak memory or end up with half-updated item. Applicable to 2.2 as well. glebs.ivanovskis Yes, we definitely leaked item when failed to create new item. As to half-updated items, we actually do such things. If only one field is invalid we fail to update that particular field and successfully update the others. Fixed for 2.2 in svn://svn.zabbix.com/branches/dev/ZBX-11223-3 r63845 and r63846. s.paskevics Successfully tested. |
Comment by Sandis Neilands (Inactive) [ 2016 Nov 10 ] |
Note: a coding issue was found by Coverity. See |
Comment by Viktors Tjarve [ 2016 Nov 16 ] |
(19) Compilation warnings. lld_item.c: In function ‘substitute_formula_macros’: lld_item.c:874:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] for (p = e + par_l + 1; p - e < par_r ; p += sep_pos + 1) ^ lld_item.c:891:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] if (p - e == par_l + 1) ^ In 3.2 and later additionally to warnings above also this warning: macrofunc.c: In function ‘zbx_calculate_macro_function’: macrofunc.c:131:28: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] for (ptr = buf; ptr - buf < buf_offset; ptr += sep_pos + 1) ^ glebs.ivanovskis RESOLVED for 2.2 in svn://svn.zabbix.com/branches/dev/ZBX-11223-3 r63842 s.paskevics Successfully tested. |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Nov 24 ] |
(18) and (19) fixed in:
(17), (18) and (19) fixed in:
|
Comment by Sergejs Paskevics [ 2016 Nov 25 ] |
Documented in:
glebs.ivanovskis Wording "in case macros resolving is not correct" is a bit confusing in my opinion. I would say "in case macro resolving cannot be fully accomplished" or even "in case necessary item and function parameter quoting after macro resolving cannot be accomplished" for more details. Maybe martins-v and VSI have a better idea, let's consult them. s.paskevics I think that the common phrase fits best ("in case macro resolving cannot be fully accomplished"), because there are several kind of errors (not only quoting), but main idea is that we have begun notify users that the LLD does not create incorrect items. glebs.ivanovskis please check my changes in documentation. martins-v I've moved the entry together with daemon improvements, because it is not a major LLD improvement. glebs.ivanovskis Thank you, martins-v! Looks good. |
Comment by Sandis Neilands (Inactive) [ 2016 Dec 02 ] |
(20) [S] Another compilation warning in 3.3. checks_calculated.c:166:50: warning: unused parameter 'dc_item' [-Wunused-parameter] static int calcitem_evaluate_expression(DC_ITEM *dc_item, expression_t *exp, char *error, size_t max_error_len, ^ 1 warning generated. s.paskevics This warning is fixed in |