Re: [libvirt] [PATCH v2 13/21] utils: Implement function to pass a buffer to send via a fd to virCommand

2019-07-11 Thread Stefan Berger

On 7/11/19 7:02 AM, Stefan Berger wrote:

On 7/10/19 4:09 PM, Marc-André Lureau wrote:

On Wed, Jul 10, 2019 at 10:12 PM Stefan Berger
 wrote:

Implement virCommandSetSendBuffer() that allows the caller to pass a
file descriptor and buffer to virCommand. virCommand will write the
buffer into the file descriptor. That file descriptor could be the
write end of a pipe or one of the file descriptors of a socketpair.
The other file descriptor should be passed to the launched process to
read the data from.

Only implement the function to allocate memory for send buffers
and to free them later on.

Signed-off-by: Stefan Berger 

that looks fine,
Reviewed-by: Marc-André Lureau 



I may need to modify this patch here to set the file descriptor's 
O_NONBLOCK flag...



The poll behavior of a pipe is that it gets POLLOUT for as long as there 
is room  left to write, so we will fill it up in more or less passes 
through the loop. I don't know how one could find out how much space 
there is left to write on a pipe so that the loop at least would quiet 
down after filling it up completely because this seems inefficient


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

Re: [libvirt] [PATCH v2 13/21] utils: Implement function to pass a buffer to send via a fd to virCommand

2019-07-11 Thread Stefan Berger

On 7/10/19 4:09 PM, Marc-André Lureau wrote:

On Wed, Jul 10, 2019 at 10:12 PM Stefan Berger
 wrote:

Implement virCommandSetSendBuffer() that allows the caller to pass a
file descriptor and buffer to virCommand. virCommand will write the
buffer into the file descriptor. That file descriptor could be the
write end of a pipe or one of the file descriptors of a socketpair.
The other file descriptor should be passed to the launched process to
read the data from.

Only implement the function to allocate memory for send buffers
and to free them later on.

Signed-off-by: Stefan Berger 

that looks fine,
Reviewed-by: Marc-André Lureau 



I may need to modify this patch here to set the file descriptor's 
O_NONBLOCK flag...



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

Re: [libvirt] [PATCH v2 13/21] utils: Implement function to pass a buffer to send via a fd to virCommand

2019-07-10 Thread Marc-André Lureau
On Wed, Jul 10, 2019 at 10:12 PM Stefan Berger
 wrote:
>
> Implement virCommandSetSendBuffer() that allows the caller to pass a
> file descriptor and buffer to virCommand. virCommand will write the
> buffer into the file descriptor. That file descriptor could be the
> write end of a pipe or one of the file descriptors of a socketpair.
> The other file descriptor should be passed to the launched process to
> read the data from.
>
> Only implement the function to allocate memory for send buffers
> and to free them later on.
>
> Signed-off-by: Stefan Berger 

that looks fine,
Reviewed-by: Marc-André Lureau 

> ---
>  src/libvirt_private.syms |  1 +
>  src/util/vircommand.c| 62 
>  src/util/vircommand.h|  5 
>  3 files changed, 68 insertions(+)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index d2045895a1..3feb862fb4 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1734,6 +1734,7 @@ virCommandSetOutputBuffer;
>  virCommandSetOutputFD;
>  virCommandSetPidFile;
>  virCommandSetPreExecHook;
> +virCommandSetSendBuffer;
>  virCommandSetSELinuxLabel;
>  virCommandSetUID;
>  virCommandSetUmask;
> diff --git a/src/util/vircommand.c b/src/util/vircommand.c
> index 8695c98d1b..e32377497b 100644
> --- a/src/util/vircommand.c
> +++ b/src/util/vircommand.c
> @@ -77,6 +77,16 @@ struct _virCommandFD {
>  unsigned int flags;
>  };
>
> +typedef struct _virCommandSendBuffer virCommandSendBuffer;
> +typedef virCommandSendBuffer *virCommandSendBufferPtr;
> +
> +struct _virCommandSendBuffer {
> +int fd;
> +unsigned char *buffer;
> +size_t buflen;
> +off_t offset;
> +};
> +
>  struct _virCommand {
>  int has_error; /* ENOMEM on allocation failure, -1 for anything else.  */
>
> @@ -136,6 +146,9 @@ struct _virCommand {
>  char *appArmorProfile;
>  #endif
>  int mask;
> +
> +virCommandSendBufferPtr sendBuffers;
> +size_t numSendBuffers;
>  };
>
>  /* See virCommandSetDryRun for description for this variable */
> @@ -1741,6 +1754,53 @@ virCommandSetWorkingDirectory(virCommandPtr cmd, const 
> char *pwd)
>  }
>
>
> +static void
> +virCommandFreeSendBuffers(virCommandPtr cmd)
> +{
> +size_t i;
> +
> +for (i = 0; i < cmd->numSendBuffers; i++) {
> +VIR_FORCE_CLOSE(cmd->sendBuffers[i].fd);
> +VIR_FREE(cmd->sendBuffers[i].buffer);
> +}
> +VIR_FREE(cmd->sendBuffers);
> +}
> +
> +
> +/**
> + * virCommandSetSendBuffer
> + * @cmd: the command to modify
> + *
> + * Pass a buffer to virCommand that will be written into the
> + * given file descriptor. The buffer will be freed automatically
> + * and the file descriptor closed.
> + */
> +int
> +virCommandSetSendBuffer(virCommandPtr cmd,
> +int fd,
> +unsigned char *buffer, size_t buflen)
> +{
> +size_t i = cmd->numSendBuffers;
> +
> +if (!cmd || cmd->has_error)
> +return -1;
> +
> +if (VIR_REALLOC_N(cmd->sendBuffers, i + 1) < 0) {
> +cmd->has_error = ENOMEM;
> +return -1;
> +}
> +
> +cmd->sendBuffers[i].fd = fd;
> +cmd->sendBuffers[i].buffer = buffer;
> +cmd->sendBuffers[i].buflen = buflen;
> +cmd->sendBuffers[i].offset = 0;
> +
> +cmd->numSendBuffers++;
> +
> +return 0;
> +}
> +
> +
>  /**
>   * virCommandSetInputBuffer:
>   * @cmd: the command to modify
> @@ -2880,6 +2940,8 @@ virCommandFree(virCommandPtr cmd)
>  VIR_FREE(cmd->appArmorProfile);
>  #endif
>
> +virCommandFreeSendBuffers(cmd);
> +
>  VIR_FREE(cmd);
>  }
>
> diff --git a/src/util/vircommand.h b/src/util/vircommand.h
> index c9a8d3c41c..716e84af3d 100644
> --- a/src/util/vircommand.h
> +++ b/src/util/vircommand.h
> @@ -148,6 +148,11 @@ void virCommandAddArgList(virCommandPtr cmd,
>  void virCommandSetWorkingDirectory(virCommandPtr cmd,
> const char *pwd) ATTRIBUTE_NONNULL(2);
>
> +int virCommandSetSendBuffer(virCommandPtr cmd,
> +int fd,
> +unsigned char *buffer, size_t buflen)
> +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
> +
>  void virCommandSetInputBuffer(virCommandPtr cmd,
>const char *inbuf) ATTRIBUTE_NONNULL(2);
>
> --
> 2.20.1
>

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

[libvirt] [PATCH v2 13/21] utils: Implement function to pass a buffer to send via a fd to virCommand

2019-07-10 Thread Stefan Berger
Implement virCommandSetSendBuffer() that allows the caller to pass a
file descriptor and buffer to virCommand. virCommand will write the
buffer into the file descriptor. That file descriptor could be the
write end of a pipe or one of the file descriptors of a socketpair.
The other file descriptor should be passed to the launched process to
read the data from.

Only implement the function to allocate memory for send buffers
and to free them later on.

Signed-off-by: Stefan Berger 
---
 src/libvirt_private.syms |  1 +
 src/util/vircommand.c| 62 
 src/util/vircommand.h|  5 
 3 files changed, 68 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d2045895a1..3feb862fb4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1734,6 +1734,7 @@ virCommandSetOutputBuffer;
 virCommandSetOutputFD;
 virCommandSetPidFile;
 virCommandSetPreExecHook;
+virCommandSetSendBuffer;
 virCommandSetSELinuxLabel;
 virCommandSetUID;
 virCommandSetUmask;
diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index 8695c98d1b..e32377497b 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -77,6 +77,16 @@ struct _virCommandFD {
 unsigned int flags;
 };
 
+typedef struct _virCommandSendBuffer virCommandSendBuffer;
+typedef virCommandSendBuffer *virCommandSendBufferPtr;
+
+struct _virCommandSendBuffer {
+int fd;
+unsigned char *buffer;
+size_t buflen;
+off_t offset;
+};
+
 struct _virCommand {
 int has_error; /* ENOMEM on allocation failure, -1 for anything else.  */
 
@@ -136,6 +146,9 @@ struct _virCommand {
 char *appArmorProfile;
 #endif
 int mask;
+
+virCommandSendBufferPtr sendBuffers;
+size_t numSendBuffers;
 };
 
 /* See virCommandSetDryRun for description for this variable */
@@ -1741,6 +1754,53 @@ virCommandSetWorkingDirectory(virCommandPtr cmd, const 
char *pwd)
 }
 
 
+static void
+virCommandFreeSendBuffers(virCommandPtr cmd)
+{
+size_t i;
+
+for (i = 0; i < cmd->numSendBuffers; i++) {
+VIR_FORCE_CLOSE(cmd->sendBuffers[i].fd);
+VIR_FREE(cmd->sendBuffers[i].buffer);
+}
+VIR_FREE(cmd->sendBuffers);
+}
+
+
+/**
+ * virCommandSetSendBuffer
+ * @cmd: the command to modify
+ *
+ * Pass a buffer to virCommand that will be written into the
+ * given file descriptor. The buffer will be freed automatically
+ * and the file descriptor closed.
+ */
+int
+virCommandSetSendBuffer(virCommandPtr cmd,
+int fd,
+unsigned char *buffer, size_t buflen)
+{
+size_t i = cmd->numSendBuffers;
+
+if (!cmd || cmd->has_error)
+return -1;
+
+if (VIR_REALLOC_N(cmd->sendBuffers, i + 1) < 0) {
+cmd->has_error = ENOMEM;
+return -1;
+}
+
+cmd->sendBuffers[i].fd = fd;
+cmd->sendBuffers[i].buffer = buffer;
+cmd->sendBuffers[i].buflen = buflen;
+cmd->sendBuffers[i].offset = 0;
+
+cmd->numSendBuffers++;
+
+return 0;
+}
+
+
 /**
  * virCommandSetInputBuffer:
  * @cmd: the command to modify
@@ -2880,6 +2940,8 @@ virCommandFree(virCommandPtr cmd)
 VIR_FREE(cmd->appArmorProfile);
 #endif
 
+virCommandFreeSendBuffers(cmd);
+
 VIR_FREE(cmd);
 }
 
diff --git a/src/util/vircommand.h b/src/util/vircommand.h
index c9a8d3c41c..716e84af3d 100644
--- a/src/util/vircommand.h
+++ b/src/util/vircommand.h
@@ -148,6 +148,11 @@ void virCommandAddArgList(virCommandPtr cmd,
 void virCommandSetWorkingDirectory(virCommandPtr cmd,
const char *pwd) ATTRIBUTE_NONNULL(2);
 
+int virCommandSetSendBuffer(virCommandPtr cmd,
+int fd,
+unsigned char *buffer, size_t buflen)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
+
 void virCommandSetInputBuffer(virCommandPtr cmd,
   const char *inbuf) ATTRIBUTE_NONNULL(2);
 
-- 
2.20.1

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