Prevent unintended sharing of parsing info

When a single GWBUF was split into two with gwbuf_split, the new GWBUF
would point to the start of the shared data and the old one to the
end. Data-wise, this is fine but as the parsing info for queries is stored
in the shared buffer it causes problems when multiple packets get read in
one network payload. The end result would be that only the first query in
the lot would get parsed and the rest would get the same classification as
the first one.

To properly fix this without the need to deep clone the buffer would
require a reorganization of the buffer mechanism in MaxScale.

This commit alone doesn't fix the queued query routing problems in
readwritesplit. The commit from 2.2 which fixes the ordering problems with
queued queries is also required for a fully functional queued query
mechanism.
This commit is contained in:
Markus Mäkelä 2019-03-15 20:51:51 +02:00
parent 4dda31ffe3
commit dd99cadfd2
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19

View File

@ -220,18 +220,19 @@ GWBUF* gwbuf_clone(GWBUF* buf)
return rval;
}
GWBUF* gwbuf_deep_clone(const GWBUF* buf)
static GWBUF* gwbuf_deep_clone_portion(const GWBUF* buf, size_t length)
{
mxb_assert(buf->owner == RoutingWorker::get_current_id());
GWBUF* rval = NULL;
if (buf)
{
size_t buflen = gwbuf_length(buf);
rval = gwbuf_alloc(buflen);
rval = gwbuf_alloc(length);
if (rval && gwbuf_copy_data(buf, 0, buflen, GWBUF_DATA(rval)) == buflen)
if (rval && gwbuf_copy_data(buf, 0, length, GWBUF_DATA(rval)) == length)
{
// The copying of the type is done to retain the type characteristic of the buffer without
// having a link the orginal data or parsing info.
rval->gwbuf_type = buf->gwbuf_type;
}
else
@ -244,7 +245,12 @@ GWBUF* gwbuf_deep_clone(const GWBUF* buf)
return rval;
}
static GWBUF* gwbuf_clone_portion(GWBUF* buf,
GWBUF* gwbuf_deep_clone(const GWBUF* buf)
{
return gwbuf_deep_clone_portion(buf, gwbuf_length(buf));
}
static GWBUF *gwbuf_clone_portion(GWBUF* buf,
size_t start_offset,
size_t length)
{
@ -311,7 +317,7 @@ GWBUF* gwbuf_split(GWBUF** buf, size_t length)
if (length > 0)
{
mxb_assert(GWBUF_LENGTH(buffer) > length);
GWBUF* partial = gwbuf_clone_portion(buffer, 0, length);
GWBUF* partial = gwbuf_deep_clone_portion(buffer, length);
/** If the head points to the original head of the buffer chain
* and we are splitting a contiguous buffer, we only need to return