[PATCH] messaging: Fix queueing on FreeBSD

Jeremy Allison jra at samba.org
Tue Jun 20 16:46:00 UTC 2017


On Tue, Jun 20, 2017 at 04:55:48PM +0200, Volker Lendecke via samba-technical wrote:
> Hi!
> 
> Without this the local.messaging tests fail on FreeBSD, in particular
> the overflow one.
> 
> Review appreciated!

Nice catch (and fix :-). Reviewed-by: Jeremy Allison <jra at samba.org>

> -- 
> SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
> phone: +49-551-370000-0, fax: +49-551-370000-9
> AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
> http://www.sernet.de, mailto:kontakt at sernet.de

> From 8f190bb68c96e20b569666861c35fbb291816c16 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Wed, 23 Nov 2016 16:51:25 +0100
> Subject: [PATCH] messaging: Fix queueing on FreeBSD
> 
> FreeBSD does not do the nice blocking send that Linux does. Instead,
> it returns ENOBUFS if the dst socket is full. According to the
> manpage you have to do polling. Try with exponential backoff, at
> the end try once a second forever.
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/lib/messages_dgm.c | 37 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c
> index 095a319..f29180d 100644
> --- a/source3/lib/messages_dgm.c
> +++ b/source3/lib/messages_dgm.c
> @@ -541,9 +541,35 @@ static void messaging_dgm_out_threaded_job(void *private_data)
>  	struct iovec iov = { .iov_base = state->buf,
>  			     .iov_len = talloc_get_size(state->buf) };
>  	size_t num_fds = talloc_array_length(state->fds);
> +	int msec = 1;
>  
> -	state->sent = messaging_dgm_sendmsg(state->sock, &iov, 1,
> +	while (true) {
> +		int ret;
> +
> +		state->sent = messaging_dgm_sendmsg(state->sock, &iov, 1,
>  					    state->fds, num_fds, &state->err);
> +
> +		if (state->sent != -1) {
> +			return;
> +		}
> +		if (errno != ENOBUFS) {
> +			return;
> +		}
> +
> +		/*
> +		 * ENOBUFS is the FreeBSD way of saying "Try
> +		 * again". We have to do polling.
> +		 */
> +		do {
> +			ret = poll(NULL, 0, msec);
> +		} while ((ret == -1) && (errno == EINTR));
> +
> +		/*
> +		 * Exponential backoff up to once a second
> +		 */
> +		msec *= 2;
> +		msec = MIN(msec, 1000);
> +	}
>  }
>  
>  /*
> @@ -619,6 +645,15 @@ static int messaging_dgm_out_send_fragment(
>  			return 0;
>  		}
>  
> +		if (err == ENOBUFS) {
> +			/*
> +			 * FreeBSD's way of telling us the dst socket
> +			 * is full. EWOULDBLOCK makes us spawn a
> +			 * polling helper thread.
> +			 */
> +			err = EWOULDBLOCK;
> +		}
> +
>  		if (err != EWOULDBLOCK) {
>  			return err;
>  		}
> -- 
> 2.1.4
> 




More information about the samba-technical mailing list