mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-08 22:15:21 +00:00
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
|
||||
|
||||
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:
|
||||
* @cmd: the command to modify
|
||||
@ -2174,7 +2229,7 @@ virCommandProcessIO(virCommandPtr cmd)
|
||||
goto cleanup;
|
||||
ret = -1;
|
||||
|
||||
if (VIR_ALLOC_N(fds, 3) < 0)
|
||||
if (VIR_ALLOC_N(fds, 3 + virCommandGetNumSendBuffers(cmd)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
for (;;) {
|
||||
@ -2200,6 +2255,8 @@ virCommandProcessIO(virCommandPtr cmd)
|
||||
nfds++;
|
||||
}
|
||||
|
||||
nfds += virCommandSendBuffersFillPollfd(cmd, fds, nfds);
|
||||
|
||||
if (nfds == 0)
|
||||
break;
|
||||
|
||||
@ -2272,6 +2329,9 @@ virCommandProcessIO(virCommandPtr cmd)
|
||||
if (inoff == inlen)
|
||||
VIR_FORCE_CLOSE(cmd->inpipe);
|
||||
}
|
||||
} else if (fds[i].revents & (POLLOUT | POLLHUP | POLLERR)) {
|
||||
if (virCommandSendBuffersHandlePoll(cmd, &fds[i]) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user