utils: Extend virCommandProcessIO to include the send buffers
Extend virCommandProcessIO to include the send buffers in the poll loop. Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
7f940d7497
commit
986b02ffd9
@ -1820,6 +1820,61 @@ virCommandSetSendBuffer(virCommandPtr cmd,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
virCommandSendBuffersFillPollfd(virCommandPtr cmd,
|
||||||
|
struct pollfd *fds,
|
||||||
|
int startidx)
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < virCommandGetNumSendBuffers(cmd); i++) {
|
||||||
|
if (cmd->sendBuffers[i].fd >= 0) {
|
||||||
|
fds[startidx + j].fd = cmd->sendBuffers[i].fd;
|
||||||
|
fds[startidx + j].events = POLLOUT;
|
||||||
|
fds[startidx + j].revents = 0;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virCommandSendBuffersHandlePoll(virCommandPtr cmd,
|
||||||
|
struct pollfd *fds)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
ssize_t done;
|
||||||
|
|
||||||
|
for (i = 0; i < virCommandGetNumSendBuffers(cmd); i++) {
|
||||||
|
if (fds->fd == cmd->sendBuffers[i].fd)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == virCommandGetNumSendBuffers(cmd))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
done = write(fds->fd,
|
||||||
|
cmd->sendBuffers[i].buffer + cmd->sendBuffers[i].offset,
|
||||||
|
cmd->sendBuffers[i].buflen - cmd->sendBuffers[i].offset);
|
||||||
|
if (done < 0) {
|
||||||
|
if (errno == EPIPE) {
|
||||||
|
VIR_DEBUG("child closed PIPE early, ignoring EPIPE "
|
||||||
|
"on fd %d", cmd->sendBuffers[i].fd);
|
||||||
|
VIR_FORCE_CLOSE(cmd->sendBuffers[i].fd);
|
||||||
|
} else if (errno != EINTR && errno != EAGAIN) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("unable to write to child input"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cmd->sendBuffers[i].offset += done;
|
||||||
|
if (cmd->sendBuffers[i].offset == cmd->sendBuffers[i].buflen)
|
||||||
|
VIR_FORCE_CLOSE(cmd->sendBuffers[i].fd);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virCommandSetInputBuffer:
|
* virCommandSetInputBuffer:
|
||||||
* @cmd: the command to modify
|
* @cmd: the command to modify
|
||||||
@ -2174,7 +2229,7 @@ virCommandProcessIO(virCommandPtr cmd)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
if (VIR_ALLOC_N(fds, 3) < 0)
|
if (VIR_ALLOC_N(fds, 3 + virCommandGetNumSendBuffers(cmd)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -2200,6 +2255,8 @@ virCommandProcessIO(virCommandPtr cmd)
|
|||||||
nfds++;
|
nfds++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfds += virCommandSendBuffersFillPollfd(cmd, fds, nfds);
|
||||||
|
|
||||||
if (nfds == 0)
|
if (nfds == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2272,6 +2329,9 @@ virCommandProcessIO(virCommandPtr cmd)
|
|||||||
if (inoff == inlen)
|
if (inoff == inlen)
|
||||||
VIR_FORCE_CLOSE(cmd->inpipe);
|
VIR_FORCE_CLOSE(cmd->inpipe);
|
||||||
}
|
}
|
||||||
|
} else if (fds[i].revents & (POLLOUT | POLLHUP | POLLERR)) {
|
||||||
|
if (virCommandSendBuffersHandlePoll(cmd, &fds[i]) < 0)
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user