[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v8 01/17] libxl: Enhance libxl__sendmsg_fds to deal with EINTR and EWOULDBLOCK
This patch change the behavior of libxl__sendmsg_fds to retry sendmsg on EINTR error and return an error on short writes. This patch allow a caller of libxl__sendmsg_fds to deal with EWOULDBLOCK and short writes. The function now requires to send only 1 byte of data so that when dealing with non-blocking fds a EWOULDBLOCK error would mean that the fds haven't been sent yet. Current caller already send only 1 byte. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> Acked-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> --- Notes: v8: Acked, but: - there is a follow-up patch to get rid of datalen param. - commit message have been modified a bit to talk about short write in general. v7: always assert datalen == 1, but only fail when sendmsg haven't send everything (r != datalen) check sendmsg return value on success as well (check for short write) tools/libxl/libxl_internal.h | 5 ++++- tools/libxl/libxl_utils.c | 25 ++++++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 67f3f6ac76..aa9059ffec 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1876,7 +1876,10 @@ _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 */ +/* `datalen` should be 1 byte + * When dealing with a non-blocking fd, it returns + * ERROR_NOT_READY on EWOULDBLOCK + * logs on other failures. */ int libxl__sendmsg_fds(libxl__gc *gc, int carrier, const void *data, size_t datalen, int nfds, const int fds[], const char *what); diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c index 5854717b11..d53db8c37d 100644 --- a/tools/libxl/libxl_utils.c +++ b/tools/libxl/libxl_utils.c @@ -1070,6 +1070,8 @@ int libxl__sendmsg_fds(libxl__gc *gc, int carrier, struct iovec iov; int r; + assert(datalen == 1); + iov.iov_base = (void*)data; iov.iov_len = datalen; @@ -1088,11 +1090,24 @@ int libxl__sendmsg_fds(libxl__gc *gc, int carrier, 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; - } + while (1) { + r = sendmsg(carrier, &msg, 0); + if (r < 0) { + if (errno == EINTR) + continue; + if (errno == EWOULDBLOCK) { + return ERROR_NOT_READY; + } + LOGE(ERROR, "failed to send fd-carrying message (%s)", what); + return ERROR_FAIL; + } + if (r != datalen) { + LOG(ERROR, "sendmsg have written %d instead of %ld", + r, datalen); + return ERROR_FAIL; + } + break; + }; return 0; } -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |