[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |