Eliminate large stack buffer in doTunnelSendAll

doTunnelSendAll function (used by QEMU migration) uses a 64k buffer on
the stack, which could be problematic. This patch replaces that with a
buffer from the heap.

While in the neighborhood, this patch also improves error reporting in
the case that saferead fails - previously, virStreamAbort() was called
(resetting errno) before reporting the error. It's been changed to
report the error first.

* src/qemu/qemu_driver.c: fix doTunnelSendAll() to use a malloc'ed
  buffer
This commit is contained in:
Laine Stump 2010-03-08 15:01:52 +01:00 committed by Daniel Veillard
parent 2e56fb2bcc
commit ecb5cf7cb2

View File

@ -8654,19 +8654,28 @@ cleanup:
} }
#define TUNNEL_SEND_BUF_SIZE 65536
static int doTunnelSendAll(virStreamPtr st, static int doTunnelSendAll(virStreamPtr st,
int sock) int sock)
{ {
char buffer[65536]; char *buffer;
int nbytes = sizeof(buffer); int nbytes = TUNNEL_SEND_BUF_SIZE;
if (VIR_ALLOC_N(buffer, TUNNEL_SEND_BUF_SIZE) < 0) {
virReportOOMError();
virStreamAbort(st);
return -1;
}
/* XXX should honour the 'resource' parameter here */ /* XXX should honour the 'resource' parameter here */
for (;;) { for (;;) {
nbytes = saferead(sock, buffer, nbytes); nbytes = saferead(sock, buffer, nbytes);
if (nbytes < 0) { if (nbytes < 0) {
virStreamAbort(st);
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("tunnelled migration failed to read from qemu")); _("tunnelled migration failed to read from qemu"));
virStreamAbort(st);
VIR_FREE(buffer);
return -1; return -1;
} }
else if (nbytes == 0) else if (nbytes == 0)
@ -8676,10 +8685,13 @@ static int doTunnelSendAll(virStreamPtr st,
if (virStreamSend(st, buffer, nbytes) < 0) { if (virStreamSend(st, buffer, nbytes) < 0) {
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("Failed to write migration data to remote libvirtd")); _("Failed to write migration data to remote libvirtd"));
VIR_FREE(buffer);
return -1; return -1;
} }
} }
VIR_FREE(buffer);
if (virStreamFinish(st) < 0) if (virStreamFinish(st) < 0)
/* virStreamFinish set the error for us */ /* virStreamFinish set the error for us */
return -1; return -1;