-
Notifications
You must be signed in to change notification settings - Fork 292
CA-250858: Fix bugs when cut out WLB health check report from WLB response #3005
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
Conversation
@jonludlam could you please have a look and merge it if possible? |
Please expand the log message what the problem was and why this is fixing it. The ticket doesn't contain it either. |
ocaml/xapi/wlb_reports.ml
Outdated
if send_len > 0 then | ||
begin | ||
send (String.sub s 0 send_len); | ||
Buffer.add_substring recv_buf s send_len end_str_len |
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.
Previously, no data was added to recv_buf
but now it is. Could you explain why? The same is happening below at Buffer.add_string recv_buf s
when |s| <= |end_str|
.
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.
I will update the ticket to add more info about the scenario.
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.
When we receive the end_str
in two recv operations, we should not miss it.
For example, we receive the data as following:
<XmlDataSet>......</XmlData
Set><OtherTag>....</OtherTag>
Actually we receive theend_str
</XmlDataSet>
, but the old code miss it.
ocaml/xapi/wlb_reports.ml
Outdated
begin | ||
let s = Buffer.contents recv_buf in | ||
(* debug "%s %d" s !recv_state; *) | ||
debug "state:%d, content len: %d, contents: %s" !recv_state (String.length s) s; |
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.
For consistency, a space could be added after state:
.
ocaml/xapi/wlb_reports.ml
Outdated
| [] -> | ||
send s; | ||
Buffer.clear recv_buf | ||
(* send data as much as possiable, just keep the length of `end_str` data to avoid broken tag *) |
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.
possible* ... also send as much data as possible
would be better here I think
@lindig |
I think this tries to fix a problem resulting from bad design: trying to parse a XML file that is read in blocks with some hand-crafted scanner. The problem at hand is parsing at block boundaries. I have little confidence that this will really solve the issue. It would be better to implement the functionality with either an XML parser, or an automaton-based scanner (generated with OCamlLex or Menhir) that takes care of buffering. |
@lindig
So I think we cannot implement this parse work with an XML parser since it may need more than 16M buffer. Regarding the state machine, it just has 3 states and works fine these years, so I think it's not complicated enough that we should generate the state machine with lex&yacc. |
The 16M limit is no longer relevant now we've switched to a 64 bit dom0. |
@jonludlam If so, I think we can refine the parser code in BTW, I'm interested in the 16M limit, can you give more details about it? |
There's a bit here about it: https://rwmj.wordpress.com/2009/08/05/ocaml-internals-part-2-strings-and-other-types/ I think we should stop worrying about the 16MiB thing and get rid of these functions and use the standard parser. I'd much rather see a pull request for that than to accept this one. |
OCaml uses 10 header bits, leaving 22 bits on a 32-bit architecture and 54 bits on a 64-bit architecture. These (22, 54) bits are the number of words. On 32-bit, a word is 4 bytes and on 64-bit, 8 bytes. So on 32-bits you have |
Hi @lindig @jonludlam @Frezzle , I have refined the code by using XML parser instead of the handwritten state machine to parse the XML response. Regression test passed in Job 1752871 and 1752872. Please help review this PR, thanks. |
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.
I would like to see a commit message that explains what problem this re-factoring solves.
let send_state = ref 1 in | ||
let entity = ref "" in | ||
|
||
let fill () = |
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.
Why do we need a fixed-size string to read input? Would using Buffer
not be better such that we read all input into a Buffer.t
value and grow it as needed? I'm not familiar with the Xml parser but can't the XML parser read a file directly? My understanding was that using a fixed-size buffer created the problem of parsing across buffer boundaries in the first place.
The code is fine. The 16k block is only used to build the Buffer with the entire input and the parser only sees the final result, not the blocks.
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.
I will refine the commit message.
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.
Commit message has been refined. Please have a look @lindig
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.
I would like to suggest the following commit message:
This commit refactors the parsing of WLB XML messages.
* It avoids a problem with the previous disign: XML was read in blocks and parsing it could fail at block boundaries
* Parsing of XML is now delegated to an XML parser.
* The "send" function no longer escapes special characters and emits the message as is
…k report from WLB response was cut 1. Refactor parser code. Replace hand-written state machine with OCaml XML parser 2. Refine the code of `send`, since XML parser has escape the content, there is no need to manually escape the content in `send` Signed-off-by: Yang Qian <yang.qian@citrix.com>
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.
If this code passes the tests, I'm happy to accept it. Using an XML parser improved the design considerably.
Yup, this looks a lot nicer now. |
This PR aim to fix a potential bug of WLB in xapi.
For more details please refer to CA-250858 and check the two test cases that created to reproduce and verify the fix of this issue.
Signed-off-by: Yang Qian yang.qian@citrix.com