[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 18/20] libxl: Introduce libxl__sendmsg_fds and libxl__recvmsg_fds



On Fri, 2012-03-16 at 16:26 +0000, Ian Jackson wrote:
> We will want to reuse the fd-sending code, so break it out into its
> own function, and provide the corresponding sending function.
> 
> Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>

Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

> ---
>  tools/libxl/libxl_internal.h |   11 ++++
>  tools/libxl/libxl_qmp.c      |   31 ++-----------
>  tools/libxl/libxl_utils.c    |  104 
> ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 119 insertions(+), 27 deletions(-)
> 
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index 0a344cf..d486af2 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -1108,6 +1108,17 @@ _hidden void libxl__qmp_cleanup(libxl__gc *gc, 
> uint32_t domid);
>  _hidden int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid,
>                                         const libxl_domain_config 
> *guest_config);
>  
> +/* on failure, logs */
> +int libxl__sendmsg_fds(libxl__gc *gc, int carrier,
> +                       const void *data, size_t datalen,
> +                       int nfds, const int fds[], const char *what);
> +
> +/* Insists on receiving exactly nfds and datalen.  On failure, logs
> + * and leaves *fds untouched. */
> +int libxl__recvmsg_fds(libxl__gc *gc, int carrier,
> +                       void *databuf, size_t datalen,
> +                       int nfds, int fds[], const char *what);
> +
>  /* from libxl_json */
>  #include <yajl/yajl_gen.h>
>  
> diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
> index f5a3edc..83c22b3 100644
> --- a/tools/libxl/libxl_qmp.c
> +++ b/tools/libxl/libxl_qmp.c
> @@ -544,38 +544,15 @@ static int qmp_send_fd(libxl__gc *gc, 
> libxl__qmp_handler *qmp,
>                         qmp_request_context *context,
>                         int fd)
>  {
> -    struct msghdr msg = { 0 };
> -    struct cmsghdr *cmsg;
> -    char control[CMSG_SPACE(sizeof (fd))];
> -    struct iovec iov;
>      char *buf = NULL;
> +    int rc;
>  
>      buf = qmp_send_prepare(gc, qmp, "getfd", args, callback, opaque, 
> context);
>  
> -    /* Response data */
> -    iov.iov_base = buf;
> -    iov.iov_len  = strlen(buf);
> -
> -    /* compose the message */
> -    msg.msg_iov = &iov;
> -    msg.msg_iovlen = 1;
> -    msg.msg_control = control;
> -    msg.msg_controllen = sizeof (control);
> -
> -    /* attach open fd */
> -    cmsg = CMSG_FIRSTHDR(&msg);
> -    cmsg->cmsg_level = SOL_SOCKET;
> -    cmsg->cmsg_type = SCM_RIGHTS;
> -    cmsg->cmsg_len = CMSG_LEN(sizeof (fd));
> -    *(int *)CMSG_DATA(cmsg) = fd;
> -
> -    msg.msg_controllen = cmsg->cmsg_len;
> +    rc = libxl__sendmsg_fds(gc, qmp->qmp_fd, buf, strlen(buf), 1, &fd,
> +                            "QMP message to QEMU");
> +    if (rc) return rc;
>  
> -    if (sendmsg(qmp->qmp_fd, &msg, 0) < 0) {
> -        LIBXL__LOG_ERRNO(qmp->ctx, LIBXL__LOG_ERROR,
> -                         "Failed to send a QMP message to QEMU.");
> -        return ERROR_FAIL;
> -    }
>      if (libxl_write_exactly(qmp->ctx, qmp->qmp_fd, "\r\n", 2,
>                              "CRLF", "QMP socket")) {
>          return ERROR_FAIL;
> diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
> index 0cbd85e..d23ae05 100644
> --- a/tools/libxl/libxl_utils.c
> +++ b/tools/libxl/libxl_utils.c
> @@ -500,6 +500,110 @@ void libxl_cputopology_list_free(libxl_cputopology 
> *list, int nr)
>      free(list);
>  }
>  
> +int libxl__sendmsg_fds(libxl__gc *gc, int carrier,
> +                       const void *data, size_t datalen,
> +                       int nfds, const int fds[], const char *what) {
> +    struct msghdr msg = { 0 };
> +    struct cmsghdr *cmsg;
> +    size_t spaceneeded = nfds * sizeof(fds[0]);
> +    char control[CMSG_SPACE(spaceneeded)];
> +    struct iovec iov;
> +    int r;
> +
> +    iov.iov_base = (void*)data;
> +    iov.iov_len  = datalen;
> +
> +    /* compose the message */
> +    msg.msg_iov = &iov;
> +    msg.msg_iovlen = 1;
> +    msg.msg_control = control;
> +    msg.msg_controllen = sizeof(control);
> +
> +    /* attach open fd */
> +    cmsg = CMSG_FIRSTHDR(&msg);
> +    cmsg->cmsg_level = SOL_SOCKET;
> +    cmsg->cmsg_type = SCM_RIGHTS;
> +    cmsg->cmsg_len = CMSG_LEN(spaceneeded);
> +    memcpy(CMSG_DATA(cmsg), fds, spaceneeded);
> +
> +    msg.msg_controllen = cmsg->cmsg_len;
> +
> +    r = sendmsg(carrier, &msg, 0);
> +    if (r < 0) {
> +        LOGE(ERROR, "failed to send fd-carrying message (%s)", what);
> +        return ERROR_FAIL;
> +    }
> +
> +    return 0;
> +}
> +
> +int libxl__recvmsg_fds(libxl__gc *gc, int carrier,
> +                       void *databuf, size_t datalen,
> +                       int nfds, int fds[], const char *what)
> +{
> +    struct msghdr msg = { 0 };
> +    struct cmsghdr *cmsg;
> +    size_t spaceneeded = nfds * sizeof(fds[0]);
> +    char control[CMSG_SPACE(spaceneeded)];
> +    struct iovec iov;
> +    int r;
> +
> +    iov.iov_base = databuf;
> +    iov.iov_len  = datalen;
> +
> +    msg.msg_iov = &iov;
> +    msg.msg_iovlen = 1;
> +    msg.msg_control = control;
> +    msg.msg_controllen = sizeof(control);
> +
> +    for (;;) {
> +        r = recvmsg(carrier, &msg, 0);
> +        if (r < 0) {
> +            if (errno == EINTR) continue;
> +            if (errno == EWOULDBLOCK) return -1;
> +            LOGE(ERROR,"recvmsg failed (%s)", what);
> +            return ERROR_FAIL;
> +        }
> +        if (r == 0) {
> +            LOG(ERROR,"recvmsg got EOF (%s)", what);
> +            return ERROR_FAIL;
> +        }
> +        cmsg = CMSG_FIRSTHDR(&msg);
> +        if (cmsg->cmsg_len <= CMSG_LEN(0)) {
> +            LOG(ERROR,"recvmsg got no control msg"
> +                " when expecting fds (%s)", what);
> +            return ERROR_FAIL;
> +        }
> +        if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) 
> {
> +            LOG(ERROR, "recvmsg got unexpected"
> +                " cmsg_level %d (!=%d) or _type %d (!=%d) (%s)",
> +                cmsg->cmsg_level, SOL_SOCKET,
> +                cmsg->cmsg_type, SCM_RIGHTS,
> +                what);
> +            return ERROR_FAIL;
> +        }
> +        if (cmsg->cmsg_len != CMSG_LEN(spaceneeded) ||
> +            msg.msg_controllen != cmsg->cmsg_len) {
> +            LOG(ERROR, "recvmsg got unexpected"
> +                " number of fds or extra control data"
> +                " (%ld bytes' worth, expected %ld) (%s)",
> +                (long)CMSG_LEN(spaceneeded), (long)cmsg->cmsg_len,
> +                what);
> +            int i, fd;
> +            unsigned char *p;
> +            for (i=0, p=CMSG_DATA(cmsg);
> +                 CMSG_SPACE(i * sizeof(fds[0]));
> +                 i++, i+=sizeof(fd)) {
> +                memcpy(&fd, p, sizeof(fd));
> +                close(fd);
> +            }
> +            return ERROR_FAIL;
> +        }
> +        memcpy(fds, CMSG_DATA(cmsg), spaceneeded);
> +        return 0;
> +    }
> +}         
> +
>  void libxl_dominfo_list_free(libxl_dominfo *list, int nr)
>  {
>      int i;



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.