-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: libpe_status, xml: Support integer as rule type attribute #2135
Conversation
Alternative options:
Changing the schema seems like a tricky process due to compatibility concerns. I hit a roadblock during an initial attempt at that (mostly due to CTS's use of the rule-2.9 schema, which was last updated 3 years ago). I read over the schema readme but still not sure how to approach it if we were to go that route. |
I'm thinking we should leave the documentation as-is, and modify the schema and code to accept either "integer" or "number" interchangeably. Perhaps at a future Pacemaker major-version bump we can make "number" behave as a floating point. To modify the schema, see xml/Readme.md. This will be a compatible change. |
Another possibility would be to treat "number" as a double if it contains a '.', and an integer otherwise. That would keep backward compatibility for anyone using it as an integer currently while allowing users to start using it for floating points. In that case the documentation, code and schema could be brought in line as:
|
Ack. As we discussed in chat, the source of confusion was the use of an old rule schema in the current constraints schema.
Would this actually do anything to alleviate your concern in the RHBZ? You said:
If they're currently using integer strings (i.e., without a '.'), then they shouldn't be prone to any floating-point corner cases AFAIK. The floating point promotion would just add zeroes after the decimal place anyway. Users would only hit a floating-point corner case (e.g., a comparison failing due to a precision issue in FP arithmetic) after the suggested change if they're currently using floating-point strings (i.e., with a '.') and relying on Pacemaker to truncate the value to an int. Then after the change, those values would be parsed as doubles and may compare incorrectly, in theory. So it seems to me that parsing numbers with '.' as floating-point would be just the same as parsing ALL numbers as floating-point, when it comes to the risk of hitting unexpected behavior in a corner case. |
b9b48dd
to
a2a8b02
Compare
A bit contrived, but:
However that wouldn't affect our situation since we currently parse the values as 32-bit integers (which I didn't realize until checking just now), so technically you're right. :) Which makes me think we should indeed parse "number" as double, and start parsing "integer" with crm_parse_ll(). That would clean things up nicely and shouldn't affect any existing usage adversely. |
The best corner cases are contrived :)
Ack. So I take it we're not worrying about any odd use cases where the expected result of a comparison depends on truncation to int. I support going with double for "number" as long as you're good with it, since it is more flexible. I was working on a pcmk__scan_double() and pcmk_parse_double(). I back-burnered them to focus on commits for the main focus of this issue, after having some initial difficulty detecting overflow and underflow in a way that's reliable on both ANSI and C99. (The strtod() return value for underflow is 0 and ERANGE on ANSI, while it's "<= smallest positive normalized number and maybe ERANGE (implementation-dependent)" on C99.) If we've settled on parsing "number" as double, I'll get back to work on that and add the result to the PR. |
Yep. Using a "." and expecting an integer comparison would be twisted enough that I'd consider it a bug.
Sounds good |
a2a8b02
to
f3a3599
Compare
85a73e5
to
ebb493d
Compare
This has grown pretty large. I think I'm finished, until there's feedback on things that need to be changed. A lot of the commits are prep work (e.g., adding new utilities and their tests, copying schemas, etc.). Four of them are minor issues and opportunities I happened upon while doing the prep work. The last few commits directly address the issue. |
ebb493d
to
0a38898
Compare
One other thing: Does any of this require a feature set bump? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, very thorough. I think a feature bump is worthwhile since otherwise the behavior of floating-point attribute values could change depending on which node is DC. Also, IIRC the schema version bump protects us from the user being able to upgrade the CIB before all nodes support it, but technically users can run without schema verification, so it's best not to rely solely on that (without schema verification someone could specify integer in a mixed-version cluster and get really different behavior).
By the way, we can't rely on GCC and Clang extensions, right? GCC (and I believe Clang as well) has an extension for variadic macro arguments that would eliminate the need to pass NULL as a sentinel value to some of our newer string functions. It's not part of the standard though. |
36379c3
to
54585bf
Compare
Add new function to parse a string to a double. Modeled after crm_parse_ll(). Signed-off-by: Reid Wahl <[email protected]>
Instead of ERANGE. Also document return values for scan_ll(). Signed-off-by: Reid Wahl <[email protected]>
Signed-off-by: Reid Wahl <[email protected]>
Signed-off-by: Reid Wahl <[email protected]>
Signed-off-by: Reid Wahl <[email protected]>
Calls strchr() to check whether a character is in any of a variable argument list of strings. Signed-off-by: Reid Wahl <[email protected]>
For function pcmk_numeric_strcasecmp(). Signed-off-by: Reid Wahl <[email protected]>
Signed-off-by: Reid Wahl <[email protected]>
"...Similarly, it [g_assert()] must not be used in unit tests, otherwise the unit tests will be ineffective if compiled with G_DISABLE_ASSERT. Use g_assert_true() and related macros in unit tests instead." https://developer.gnome.org/glib/unstable/glib-Testing.html#g-assert Also remove redundant test for pcmk__str_any_of(). Signed-off-by: Reid Wahl <[email protected]>
Will be adding support for "integer" as rule "type" attribute. Signed-off-by: Reid Wahl <[email protected]>
The Pacemaker Explained doc has long described "integer" as a valid value for the "type" attribute of a rule. The rule schema includes "number" but does not include "integer" in this position. This commit adds "integer" to the schema alongside "number". Signed-off-by: Reid Wahl <[email protected]>
Signed-off-by: Reid Wahl <[email protected]>
79573e8
to
bfcf5bd
Compare
For readability and to prep for next changes. Signed-off-by: Reid Wahl <[email protected]>
bfcf5bd
to
746d391
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just a couple minor comments
For node attribute expressions in a rule. Use long long instead of int, and default to string if numbers fail to parse as integers. Signed-off-by: Reid Wahl <[email protected]>
The Pacemaker Explained doc has long described "integer" as a valid value for the "type" attribute of a rule. However, libpe_status does not support "integer" as the type attribute for a rule. Yet it parses all "number"-type values as integers. This commit updates libpe_status to accept "integer" as a rule's type attribute and to parse integers as long longs instead of as ints. "number"-type values will now be parsed as doubles. If the rule evaluation **defaults** to a numeric comparison, then the type will be set to "number" if either value contains a decimal point or to "integer" otherwise. If a numeric parse fails, then the values will be compared as strings. Bump CRM_FEATURE_SET to 3.5.0. Signed-off-by: Reid Wahl <[email protected]>
746d391
to
fb87a88
Compare
I just noticed that I updated cts-scheduler instead of cts-scheduler.in for some of the added regression tests. Going to have to rewrite the list additions and re-push. |
fb87a88
to
8e44d57
Compare
New regression tests for commit f3a3599 Signed-off-by: Reid Wahl <[email protected]>
Add "number" as an allowed value for the type attribute of a rule expression. Add description of how "integer" and "number" comparisons differ and of how a default comparison type is chosen. Signed-off-by: Reid Wahl <[email protected]>
8e44d57
to
39d78f3
Compare
Awesome :) |
The documentation specifies three potential values for the type
attribute of rule expressions:
Yet the rule.rng schema and pe__eval_attr_expr() expect "number" instead
of "integer".
This pull corrects the documentation to align with the schema and code.
Thanks @tomjelinek for reporting this.
Edited summary:
This pull does the following: