forked from pool/libvirt
86 lines
3.1 KiB
Diff
86 lines
3.1 KiB
Diff
|
commit 5004f121bc572c58d9721bf7bf3c3a1988720ba8
|
||
|
Author: Michal Privoznik <mprivozn@redhat.com>
|
||
|
Date: Mon Jun 5 13:22:23 2017 +0200
|
||
|
|
||
|
virFDStreamThread: Make sure we won't exceed @length
|
||
|
|
||
|
There's a problem with current streams after I switched them from
|
||
|
iohelper to thread implementation. Previously, iohelper made sure
|
||
|
not to exceed specified @length resulting in the pipe EOF
|
||
|
appearing at the exact right moment (the pipe was used to tunnel
|
||
|
the data from the iohelper to the daemon). Anyway, when switching
|
||
|
to thread I had to write the I/O code from scratch. Whilst doing
|
||
|
that I took an inspiration from the iohelper code, but since the
|
||
|
usage of pipe switched to slightly different meaning, there was
|
||
|
no 1:1 relationship between the codes.
|
||
|
|
||
|
Moreover, after introducing VIR_FDSTREAM_MSG_TYPE_HOLE, the
|
||
|
condition that should made sure we won't exceed @length was
|
||
|
completely wrong.
|
||
|
|
||
|
The fix is to:
|
||
|
|
||
|
a) account for holes for @length
|
||
|
b) cap not just data sections but holes too (if @length would be
|
||
|
exceeded)
|
||
|
|
||
|
For this purpose, the condition needs to be brought closer to the
|
||
|
code that handles holes and data sections.
|
||
|
|
||
|
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||
|
|
||
|
Index: libvirt-3.4.0/src/util/virfdstream.c
|
||
|
===================================================================
|
||
|
--- libvirt-3.4.0.orig/src/util/virfdstream.c
|
||
|
+++ libvirt-3.4.0/src/util/virfdstream.c
|
||
|
@@ -420,6 +420,8 @@ virFDStreamThreadDoRead(virFDStreamDataP
|
||
|
const int fdout,
|
||
|
const char *fdinname,
|
||
|
const char *fdoutname,
|
||
|
+ size_t length,
|
||
|
+ size_t total,
|
||
|
size_t *dataLen,
|
||
|
size_t buflen)
|
||
|
{
|
||
|
@@ -433,10 +435,18 @@ virFDStreamThreadDoRead(virFDStreamDataP
|
||
|
if (virFileInData(fdin, &inData, §ionLen) < 0)
|
||
|
goto error;
|
||
|
|
||
|
+ if (length &&
|
||
|
+ sectionLen > length - total)
|
||
|
+ sectionLen = length - total;
|
||
|
+
|
||
|
if (inData)
|
||
|
*dataLen = sectionLen;
|
||
|
}
|
||
|
|
||
|
+ if (length &&
|
||
|
+ buflen > length - total)
|
||
|
+ buflen = length - total;
|
||
|
+
|
||
|
if (VIR_ALLOC(msg) < 0)
|
||
|
goto error;
|
||
|
|
||
|
@@ -578,13 +588,6 @@ virFDStreamThread(void *opaque)
|
||
|
while (1) {
|
||
|
ssize_t got;
|
||
|
|
||
|
- if (length &&
|
||
|
- (length - total) < buflen)
|
||
|
- buflen = length - total;
|
||
|
-
|
||
|
- if (buflen == 0)
|
||
|
- break; /* End of requested data from client */
|
||
|
-
|
||
|
while (doRead == (fdst->msg != NULL) &&
|
||
|
!fdst->threadQuit) {
|
||
|
if (virCondWait(&fdst->threadCond, &fdst->parent.lock)) {
|
||
|
@@ -608,6 +611,7 @@ virFDStreamThread(void *opaque)
|
||
|
got = virFDStreamThreadDoRead(fdst, sparse,
|
||
|
fdin, fdout,
|
||
|
fdinname, fdoutname,
|
||
|
+ length, total,
|
||
|
&dataLen, buflen);
|
||
|
else
|
||
|
got = virFDStreamThreadDoWrite(fdst, sparse,
|