[libvirt] [PATCH v5 14/20] utils: Extend virCommandProcessIO to include the send buffers

Stefan Berger posted 20 patches 6 years, 7 months ago
There is a newer version of this series
[libvirt] [PATCH v5 14/20] utils: Extend virCommandProcessIO to include the send buffers
Posted by Stefan Berger 6 years, 7 months ago
Extend virCommandProcessIO to include the send buffers in the poll
loop.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 src/util/vircommand.c | 62 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index bb9ecdf348..976231444e 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -1815,6 +1815,61 @@ virCommandSetSendBuffer(virCommandPtr cmd,
 }
 
 
+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;
+    int 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
@@ -2169,7 +2224,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 (;;) {
@@ -2195,6 +2250,8 @@ virCommandProcessIO(virCommandPtr cmd)
             nfds++;
         }
 
+        nfds += virCommandSendBuffersFillPollfd(cmd, fds, nfds);
+
         if (nfds == 0)
             break;
 
@@ -2267,6 +2324,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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v5 14/20] utils: Extend virCommandProcessIO to include the send buffers
Posted by Daniel P. Berrangé 6 years, 6 months ago
On Fri, Jul 12, 2019 at 12:23:48PM -0400, Stefan Berger wrote:
> Extend virCommandProcessIO to include the send buffers in the poll
> loop.
> 
> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> ---
>  src/util/vircommand.c | 62 ++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 61 insertions(+), 1 deletion(-)
> 
> diff --git a/src/util/vircommand.c b/src/util/vircommand.c
> index bb9ecdf348..976231444e 100644
> --- a/src/util/vircommand.c
> +++ b/src/util/vircommand.c
> @@ -1815,6 +1815,61 @@ virCommandSetSendBuffer(virCommandPtr cmd,
>  }
>  
>  
> +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;
> +    int done;

ssize_t is the return type for write()

> +
> +    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);



Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v5 14/20] utils: Extend virCommandProcessIO to include the send buffers
Posted by Stefan Berger 6 years, 6 months ago
On 7/25/19 5:48 AM, Daniel P. Berrangé wrote:
> On Fri, Jul 12, 2019 at 12:23:48PM -0400, Stefan Berger wrote:
>> Extend virCommandProcessIO to include the send buffers in the poll
>> loop.
>>
>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
>> ---
>>   src/util/vircommand.c | 62 ++++++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 61 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/util/vircommand.c b/src/util/vircommand.c
>> index bb9ecdf348..976231444e 100644
>> --- a/src/util/vircommand.c
>> +++ b/src/util/vircommand.c
>> @@ -1815,6 +1815,61 @@ virCommandSetSendBuffer(virCommandPtr cmd,
>>   }
>>   
>>   
>> +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;
>> +    int done;
> ssize_t is the return type for write()


Fixed.

Regards,

    Stefan


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list