[libvirt] [PATCH v2 16/21] utils: Extend virCommandProcessIO to including the send buffers
Marc-André Lureau
marcandre.lureau at redhat.com
Wed Jul 10 20:05:47 UTC 2019
On Wed, Jul 10, 2019 at 10:12 PM Stefan Berger
<stefanb at linux.vnet.ibm.com> wrote:
>
> Signed-off-by: Stefan Berger <stefanb at linux.ibm.com>
Could you include a test?
> ---
> src/util/vircommand.c | 70 ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 69 insertions(+), 1 deletion(-)
>
> diff --git a/src/util/vircommand.c b/src/util/vircommand.c
> index 0e367eeeab..357a9888a1 100644
> --- a/src/util/vircommand.c
> +++ b/src/util/vircommand.c
> @@ -1803,6 +1803,69 @@ virCommandSetSendBuffer(virCommandPtr cmd,
> }
>
>
> +static int
> +virCommandGetNumSendBuffers(virCommandPtr cmd)
> +{
> + return cmd->numSendBuffers;
> +}
> +
That getter doesn't seem very useful, or at least you don't use it consistently.
looks good otherwise
> +
> +static int
> +virCommandAddSendBuffersFillPollfd(virCommandPtr cmd,
> + struct pollfd *fds,
> + int startidx)
> +{
> + size_t i, j;
> +
> + for (i = 0, j = 0; i < cmd->numSendBuffers; 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;
> + int done;
> +
> + for (i = 0; i < cmd->numSendBuffers; i++) {
> + if (fds->fd == cmd->sendBuffers[i].fd)
> + break;
> + }
> + if (i == cmd->numSendBuffers)
> + return 0;
> +
> + done = write(fds->fd,
> + cmd->sendBuffers[i].buffer + cmd->sendBuffers[i].offset,
> + MIN(cmd->sendBuffers[i].buflen - cmd->sendBuffers[i].offset,
> + MAX_PIPE_FEED_BYTES));
> + 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
> @@ -2157,7 +2220,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 (;;) {
> @@ -2183,6 +2246,8 @@ virCommandProcessIO(virCommandPtr cmd)
> nfds++;
> }
>
> + nfds += virCommandAddSendBuffersFillPollfd(cmd, fds, nfds);
> +
> if (nfds == 0)
> break;
>
> @@ -2255,6 +2320,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;
> }
> }
> }
> --
> 2.20.1
>
More information about the libvir-list
mailing list