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