Merge lp:~gl-az/percona-xtrabackup/bug1273196-2.1 into lp:percona-xtrabackup/2.1

Proposed by George Ormond Lorch III
Status: Merged
Approved by: Sergei Glushchenko
Approved revision: no longer in the source branch.
Merged at revision: 731
Proposed branch: lp:~gl-az/percona-xtrabackup/bug1273196-2.1
Merge into: lp:percona-xtrabackup/2.1
Diff against target: 121 lines (+52/-29)
1 file modified
src/xbcrypt_read.c (+52/-29)
To merge this branch: bzr merge lp:~gl-az/percona-xtrabackup/bug1273196-2.1
Reviewer Review Type Date Requested Status
Sergei Glushchenko (community) g2 Approve
Review via email: mp+206541@code.launchpad.net

Description of the change

bug 1273196 - Streaming issue with xbcrypt

xbcrypt read failures are due to partial reads happening on a stdin file because reads are not using either MY_FULL_IO nor looping and rereading on a partial (> 0) read.

To fix, simple re-read loops are added for each read point to progressively continue to read into the buffer as long as something was read.

jenkins http://jenkins.percona.com/view/PXB%202.1/job/percona-xtrabackup-2.1-param/542/

To post a comment you must log in.
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Hi George,

Looks like crypt->read use my_read to actually read data. Since MY_FULL_IO is not passed to my_read, it can return MY_FILE_ERROR in case of error (which is a big number). I think F_READ doesn't handle this case properly.

review: Needs Fixing (g2)
Revision history for this message
George Ormond Lorch III (gl-az) wrote :

Good catch Sergei, thanks! A simple fix and new jenkins run: http://jenkins.percona.com/job/percona-xtrabackup-2.1-param/547/

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Approve

review: Approve (g2)
Revision history for this message
Alexey Kopytov (akopytov) wrote :

The fix looks correct, but I don't understand the purpose of another wrapper. Why not embed all F_READ() logic into my_xb_crypt_read_callback()?

Revision history for this message
George Ormond Lorch III (gl-az) wrote :

> The fix looks correct, but I don't understand the purpose of another wrapper.
> Why not embed all F_READ() logic into my_xb_crypt_read_callback()?

That is a very good question. Why don't I? I'll get that changed up, jenkinsed and all real quick here.

Revision history for this message
Alexey Kopytov (akopytov) wrote :

George,

I took care of that in my fix for bug #1273207, because I either had to duplicate your fix, or generalize it.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/xbcrypt_read.c'
2--- src/xbcrypt_read.c 2013-10-17 01:00:57 +0000
3+++ src/xbcrypt_read.c 2014-02-25 17:15:13 +0000
4@@ -49,6 +49,27 @@
5 return crypt;
6 }
7
8+static
9+size_t
10+F_READ(xb_rcrypt_t *crypt, void *buf, size_t len)
11+{
12+ uchar *ptr;
13+ size_t bytesread;
14+ size_t bytestoread;
15+
16+ ptr = buf;
17+ bytestoread = len;
18+ while (bytestoread > 0) {
19+ bytesread = crypt->read(crypt->userdata, ptr, bytestoread, MYF(MY_WME));
20+ if (bytesread == 0 || bytesread > bytestoread) {
21+ break;
22+ }
23+ ptr += bytesread;
24+ bytestoread -= bytesread;
25+ }
26+ return len - bytestoread;
27+}
28+
29 xb_rcrypt_result_t
30 xb_crypt_read_chunk(xb_rcrypt_t *crypt, void **buf, size_t *olen, size_t *elen,
31 void **iv, size_t *ivlen)
32@@ -58,21 +79,19 @@
33 uchar *ptr;
34 ulonglong tmp;
35 ulong checksum, checksum_exp, version;
36- ssize_t bytesread;
37+ size_t bytesread;
38 xb_rcrypt_result_t result = XB_CRYPT_READ_CHUNK;
39
40- if ((bytesread = crypt->read(crypt->userdata, tmpbuf, sizeof(tmpbuf), MYF(MY_WME)))
41- != sizeof(tmpbuf)) {
42- if (bytesread == 0) {
43- result = XB_CRYPT_READ_EOF;
44- goto err;
45- } else {
46- msg("%s:%s: unable to read chunk header data at "
47- "offset 0x%llx.\n",
48- my_progname, __FUNCTION__, crypt->offset);
49- result = XB_CRYPT_READ_ERROR;
50- goto err;
51- }
52+ bytesread = F_READ(crypt, tmpbuf, sizeof(tmpbuf));
53+ if (bytesread == 0) {
54+ result = XB_CRYPT_READ_EOF;
55+ goto err;
56+ } else if (bytesread < sizeof(tmpbuf)) {
57+ msg("%s:%s: unable to read chunk header data at "
58+ "offset 0x%llx.\n",
59+ my_progname, __FUNCTION__, crypt->offset);
60+ result = XB_CRYPT_READ_ERROR;
61+ goto err;
62 }
63
64 ptr = tmpbuf;
65@@ -126,18 +145,16 @@
66 *ivlen = 0;
67 *iv = 0;
68 } else {
69- if ((bytesread = crypt->read(crypt->userdata, tmpbuf, 8,
70- MYF(MY_WME))) != 8) {
71- if (bytesread == 0) {
72- result = XB_CRYPT_READ_EOF;
73- goto err;
74- } else {
75- msg("%s:%s: unable to read chunk iv size at "
76- "offset 0x%llx.\n",
77- my_progname, __FUNCTION__, crypt->offset);
78- result = XB_CRYPT_READ_ERROR;
79- goto err;
80- }
81+ bytesread = F_READ(crypt, tmpbuf, 8);
82+ if (bytesread == 0) {
83+ result = XB_CRYPT_READ_EOF;
84+ goto err;
85+ } else if (bytesread < 8) {
86+ msg("%s:%s: unable to read chunk iv size at "
87+ "offset 0x%llx.\n",
88+ my_progname, __FUNCTION__, crypt->offset);
89+ result = XB_CRYPT_READ_ERROR;
90+ goto err;
91 }
92
93 tmp = uint8korr(tmpbuf);
94@@ -176,8 +193,11 @@
95 }
96
97 if (*ivlen > 0) {
98- if (crypt->read(crypt->userdata, crypt->ivbuffer, *ivlen, MYF(MY_WME|MY_FULL_IO))
99- != (ssize_t)*ivlen) {
100+ bytesread = F_READ(crypt, crypt->ivbuffer, *ivlen);
101+ if (bytesread == 0) {
102+ result = XB_CRYPT_READ_EOF;
103+ goto err;
104+ } else if (bytesread < *ivlen) {
105 msg("%s:%s: failed to read %lld bytes for chunk iv "
106 "at offset 0x%llx.\n", my_progname, __FUNCTION__,
107 (ulonglong)*ivlen, crypt->offset);
108@@ -212,8 +232,11 @@
109 }
110
111 if (*elen > 0) {
112- if (crypt->read(crypt->userdata, crypt->buffer, *elen, MYF(MY_WME|MY_FULL_IO))
113- != (ssize_t)*elen) {
114+ bytesread = F_READ(crypt, crypt->buffer, *elen);
115+ if (bytesread == 0) {
116+ result = XB_CRYPT_READ_EOF;
117+ goto err;
118+ } else if (bytesread < *elen) {
119 msg("%s:%s: failed to read %lld bytes for chunk payload "
120 "at offset 0x%llx.\n", my_progname, __FUNCTION__,
121 (ulonglong)*elen, crypt->offset);

Subscribers

People subscribed via source and target branches