[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