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

Marc-André Lureau marcandre.lureau at redhat.com
Wed Jul 10 20:09:11 UTC 2019


On Wed, Jul 10, 2019 at 10:12 PM Stefan Berger
<stefanb at linux.vnet.ibm.com> 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 <stefanb at linux.ibm.com>

that looks fine,
Reviewed-by: Marc-André Lureau <marcandre.lureau at redhat.com>

> ---
>  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
>




More information about the libvir-list mailing list