[PATCHES] messaging iov / recvfrom

Michael Adam obnox at samba.org
Mon May 26 09:07:44 MDT 2014


Oops, there was a bug in the first patch.
Sorry for posting prematurely...
Attaching a fixed version.

Thanks - Michael

On 2014-05-26 at 15:52 +0200, Michael Adam wrote:
> Hi,
> 
> as a result of my work towards adding support for fd-passing
> to our messaging, find attached two first preparatory patches
> that might already be useful.
> 
> The first changes the send_fn to use struct  iovec
> instead of data blob. (Volker has already looked
> over this one.)
> 
> The second one lets unix_dgram_recv_handler()
> use recvmsg() instead of recv().
> 
> Review/push/comments appreciated.
> 
> Michael

> From 279eb1d37c39c41ab00ab33c09b3603222692527 Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Tue, 13 May 2014 11:55:37 +0200
> Subject: [PATCH 1/2] s3:messaging: change messaging_backend to use iovec
>  instead of data blob in send_fn
> 
> This also changes the layering
> 
> messaging_send_iov -> messaging_send_buf -> messaging_send
> 
> to
> 
> messaging_send_buf -> messaging_send -> messaging_send_iov
> 
> Signed-off-by: Michael Adam <obnox at samba.org>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/include/messages.h   |  2 +-
>  source3/lib/messages.c       | 64 +++++++++++++++++++++++---------------------
>  source3/lib/messages_ctdbd.c | 19 +++++++++++--
>  source3/lib/messages_dgm.c   | 20 +++++++-------
>  4 files changed, 62 insertions(+), 43 deletions(-)
> 
> diff --git a/source3/include/messages.h b/source3/include/messages.h
> index 852e8a1..18362f9 100644
> --- a/source3/include/messages.h
> +++ b/source3/include/messages.h
> @@ -89,7 +89,7 @@ struct messaging_context {
>  struct messaging_backend {
>  	NTSTATUS (*send_fn)(struct messaging_context *msg_ctx,
>  			    struct server_id pid, int msg_type,
> -			    const DATA_BLOB *data,
> +			    const struct iovec *iov, int iovlen,
>  			    struct messaging_backend *backend);
>  	void *private_data;
>  };
> diff --git a/source3/lib/messages.c b/source3/lib/messages.c
> index 6778080..44062ca 100644
> --- a/source3/lib/messages.c
> +++ b/source3/lib/messages.c
> @@ -355,29 +355,12 @@ NTSTATUS messaging_send(struct messaging_context *msg_ctx,
>  			struct server_id server, uint32_t msg_type,
>  			const DATA_BLOB *data)
>  {
> -	if (server_id_is_disconnected(&server)) {
> -		return NT_STATUS_INVALID_PARAMETER_MIX;
> -	}
> -
> -	if (!procid_is_local(&server)) {
> -		return msg_ctx->remote->send_fn(msg_ctx, server,
> -						msg_type, data,
> -						msg_ctx->remote);
> -	}
> +	struct iovec iov;
>  
> -	if (messaging_is_self_send(msg_ctx, &server)) {
> -		struct messaging_rec rec;
> -		rec.msg_version = MESSAGE_VERSION;
> -		rec.msg_type = msg_type & MSG_TYPE_MASK;
> -		rec.dest = server;
> -		rec.src = msg_ctx->id;
> -		rec.buf = *data;
> -		messaging_dispatch_rec(msg_ctx, &rec);
> -		return NT_STATUS_OK;
> -	}
> +	iov.iov_base = data->data;
> +	iov.iov_len = data->length;
>  
> -	return msg_ctx->local->send_fn(msg_ctx, server, msg_type, data,
> -				       msg_ctx->local);
> +	return messaging_send_iov(msg_ctx, server, msg_type, &iov, 1);
>  }
>  
>  NTSTATUS messaging_send_buf(struct messaging_context *msg_ctx,
> @@ -392,19 +375,40 @@ NTSTATUS messaging_send_iov(struct messaging_context *msg_ctx,
>  			    struct server_id server, uint32_t msg_type,
>  			    const struct iovec *iov, int iovlen)
>  {
> -	uint8_t *buf;
> -	NTSTATUS status;
> +	if (server_id_is_disconnected(&server)) {
> +		return NT_STATUS_INVALID_PARAMETER_MIX;
> +	}
>  
> -	buf = iov_buf(talloc_tos(), iov, iovlen);
> -	if (buf == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> +	if (!procid_is_local(&server)) {
> +		return msg_ctx->remote->send_fn(msg_ctx, server,
> +						msg_type, iov, iovlen,
> +						msg_ctx->remote);
>  	}
>  
> -	status = messaging_send_buf(msg_ctx, server, msg_type,
> -				    buf, talloc_get_size(buf));
> +	if (messaging_is_self_send(msg_ctx, &server)) {
> +		struct messaging_rec rec;
> +		uint8_t *buf;
> +		DATA_BLOB data;
> +
> +		buf = iov_buf(talloc_tos(), iov, iovlen);
> +		if (buf == NULL) {
> +			return NT_STATUS_NO_MEMORY;
> +		}
> +
> +		data = data_blob_const(buf, talloc_get_size(buf));
> +
> +		rec.msg_version = MESSAGE_VERSION;
> +		rec.msg_type = msg_type & MSG_TYPE_MASK;
> +		rec.dest = server;
> +		rec.src = msg_ctx->id;
> +		rec.buf = data;
> +		messaging_dispatch_rec(msg_ctx, &rec);
> +		TALLOC_FREE(buf);
> +		return NT_STATUS_OK;
> +	}
>  
> -	TALLOC_FREE(buf);
> -	return status;
> +	return msg_ctx->local->send_fn(msg_ctx, server, msg_type, iov, iovlen,
> +				       msg_ctx->local);
>  }
>  
>  static struct messaging_rec *messaging_rec_dup(TALLOC_CTX *mem_ctx,
> diff --git a/source3/lib/messages_ctdbd.c b/source3/lib/messages_ctdbd.c
> index 230560f..e1b3ae1 100644
> --- a/source3/lib/messages_ctdbd.c
> +++ b/source3/lib/messages_ctdbd.c
> @@ -91,20 +91,35 @@ struct ctdbd_connection *messaging_ctdbd_connection(void)
>  static NTSTATUS messaging_ctdb_send(struct messaging_context *msg_ctx,
>  				    struct server_id pid, int msg_type,
>  				    const DATA_BLOB *data,
> +				    const struct iovec *iov, int iovlen,
>  				    struct messaging_backend *backend)
>  {
>  	struct messaging_ctdbd_context *ctx = talloc_get_type_abort(
>  		backend->private_data, struct messaging_ctdbd_context);
>  
>  	struct messaging_rec msg;
> +	uint8_t *buf;
> +	DATA_BLOB data;
> +	NTSTATUS status;
> +
> +	buf = iov_buf(talloc_tos(), iov, iovlen);
> +	if (buf == NULL) {
> +		return NT_STATUS_NO_MEMORY;
> +	}
> +
> +	data = data_blob_const(buf, talloc_get_size(buf));
>  
>  	msg.msg_version	= MESSAGE_VERSION;
>  	msg.msg_type	= msg_type;
>  	msg.dest	= pid;
>  	msg.src		= msg_ctx->id;
> -	msg.buf		= *data;
> +	msg.buf		= data;
> +
> +	status = ctdbd_messaging_send(ctx->conn, pid.vnn, pid.pid, &msg);
> +
> +	TALLOC_FREE(buf);
>  
> -	return ctdbd_messaging_send(ctx->conn, pid.vnn, pid.pid, &msg);
> +	return status;
>  }
>  
>  static int messaging_ctdbd_destructor(struct messaging_ctdbd_context *ctx)
> diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c
> index 55a6fcf..f01fcb8 100644
> --- a/source3/lib/messages_dgm.c
> +++ b/source3/lib/messages_dgm.c
> @@ -46,7 +46,7 @@ struct messaging_dgm_hdr {
>  
>  static NTSTATUS messaging_dgm_send(struct messaging_context *msg_ctx,
>  				   struct server_id pid, int msg_type,
> -				   const DATA_BLOB *data,
> +				   const struct iovec *iov, int iovlen,
>  				   struct messaging_backend *backend);
>  static void messaging_dgm_recv(struct unix_msg_ctx *ctx,
>  			       uint8_t *msg, size_t msg_len,
> @@ -288,7 +288,7 @@ static int messaging_dgm_context_destructor(struct messaging_dgm_context *c)
>  
>  static NTSTATUS messaging_dgm_send(struct messaging_context *msg_ctx,
>  				   struct server_id pid, int msg_type,
> -				   const DATA_BLOB *data,
> +				   const struct iovec *iov, int iovlen,
>  				   struct messaging_backend *backend)
>  {
>  	struct messaging_dgm_context *ctx = talloc_get_type_abort(
> @@ -297,9 +297,10 @@ static NTSTATUS messaging_dgm_send(struct messaging_context *msg_ctx,
>  	char buf[PATH_MAX];
>  	char *dst_sock, *to_free;
>  	struct messaging_dgm_hdr hdr;
> -	struct iovec iov[2];
> +	struct iovec iov2[iovlen + 1];
>  	ssize_t pathlen;
>  	int ret;
> +	int i;
>  
>  	fstr_sprintf(pid_str, "msg/%u", (unsigned)pid.pid);
>  
> @@ -314,17 +315,16 @@ static NTSTATUS messaging_dgm_send(struct messaging_context *msg_ctx,
>  	hdr.dst = pid;
>  	hdr.src = msg_ctx->id;
>  
> -	DEBUG(10, ("%s: Sending message 0x%x len %u to %s\n", __func__,
> -		   (unsigned)hdr.msg_type, (unsigned)data->length,
> +	DEBUG(10, ("%s: Sending message 0x%x to %s\n", __func__,
> +		   (unsigned)hdr.msg_type,
>  		   server_id_str(talloc_tos(), &pid)));
>  
> -	iov[0].iov_base = &hdr;
> -	iov[0].iov_len = sizeof(hdr);
> -	iov[1].iov_base = data->data;
> -	iov[1].iov_len = data->length;
> +	iov2[0].iov_base = &hdr;
> +	iov2[0].iov_len = sizeof(hdr);
> +	memcpy(iov2+1, iov, iovlen*sizeof(struct iovec));
>  
>  	become_root();
> -	ret = unix_msg_send(ctx->dgm_ctx, dst_sock, iov, ARRAY_SIZE(iov));
> +	ret = unix_msg_send(ctx->dgm_ctx, dst_sock, iov2, iovlen + 1);
>  	unbecome_root();
>  
>  	TALLOC_FREE(to_free);
> -- 
> 1.9.1
> 
> 
> From 810d5c5a27624602cb3e54de65290d122e476f4f Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Tue, 13 May 2014 12:42:32 +0200
> Subject: [PATCH 2/2] s3:messaging: change unix_dgram_recv_handler() to use
>  recvmsg, not recv
> 
> This is in preparation of adding fd-passing to messaging.
> 
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
>  source3/lib/unix_msg/unix_msg.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/source3/lib/unix_msg/unix_msg.c b/source3/lib/unix_msg/unix_msg.c
> index 956e3a3..bcabd28 100644
> --- a/source3/lib/unix_msg/unix_msg.c
> +++ b/source3/lib/unix_msg/unix_msg.c
> @@ -233,8 +233,22 @@ static void unix_dgram_recv_handler(struct poll_watch *w, int fd, short events,
>  {
>  	struct unix_dgram_ctx *ctx = (struct unix_dgram_ctx *)private_data;
>  	ssize_t received;
> +	struct msghdr msg;
> +	struct iovec iov;
> +
> +	iov = (struct iovec) {
> +		.iov_base = (void *)ctx->recv_buf,
> +		.iov_len = ctx->max_msg,
> +	};
> +
> +	msg = (struct msghdr) {
> +		.msg_iov = &iov,
> +		.msg_iovlen = 1,
> +		.msg_control = NULL,
> +		.msg_controllen = 0,
> +	};
>  
> -	received = recv(fd, ctx->recv_buf, ctx->max_msg, 0);
> +	received = recvmsg(fd, &msg, 0);
>  	if (received == -1) {
>  		if ((errno == EAGAIN) ||
>  #ifdef EWOULDBLOCK
> -- 
> 1.9.1
> 



-------------- next part --------------
From fae311a08cebaf6fa078717fb64583b222c3fceb Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 13 May 2014 11:55:37 +0200
Subject: [PATCH 1/2] s3:messaging: change messaging_backend to use iovec
 instead of data blob in send_fn

This also changes the layering

messaging_send_iov -> messaging_send_buf -> messaging_send

to

messaging_send_buf -> messaging_send -> messaging_send_iov

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/messages.h   |  2 +-
 source3/lib/messages.c       | 64 +++++++++++++++++++++++---------------------
 source3/lib/messages_ctdbd.c | 18 ++++++++++---
 source3/lib/messages_dgm.c   | 19 +++++++------
 4 files changed, 59 insertions(+), 44 deletions(-)

diff --git a/source3/include/messages.h b/source3/include/messages.h
index 852e8a1..18362f9 100644
--- a/source3/include/messages.h
+++ b/source3/include/messages.h
@@ -89,7 +89,7 @@ struct messaging_context {
 struct messaging_backend {
 	NTSTATUS (*send_fn)(struct messaging_context *msg_ctx,
 			    struct server_id pid, int msg_type,
-			    const DATA_BLOB *data,
+			    const struct iovec *iov, int iovlen,
 			    struct messaging_backend *backend);
 	void *private_data;
 };
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 6778080..44062ca 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -355,29 +355,12 @@ NTSTATUS messaging_send(struct messaging_context *msg_ctx,
 			struct server_id server, uint32_t msg_type,
 			const DATA_BLOB *data)
 {
-	if (server_id_is_disconnected(&server)) {
-		return NT_STATUS_INVALID_PARAMETER_MIX;
-	}
-
-	if (!procid_is_local(&server)) {
-		return msg_ctx->remote->send_fn(msg_ctx, server,
-						msg_type, data,
-						msg_ctx->remote);
-	}
+	struct iovec iov;
 
-	if (messaging_is_self_send(msg_ctx, &server)) {
-		struct messaging_rec rec;
-		rec.msg_version = MESSAGE_VERSION;
-		rec.msg_type = msg_type & MSG_TYPE_MASK;
-		rec.dest = server;
-		rec.src = msg_ctx->id;
-		rec.buf = *data;
-		messaging_dispatch_rec(msg_ctx, &rec);
-		return NT_STATUS_OK;
-	}
+	iov.iov_base = data->data;
+	iov.iov_len = data->length;
 
-	return msg_ctx->local->send_fn(msg_ctx, server, msg_type, data,
-				       msg_ctx->local);
+	return messaging_send_iov(msg_ctx, server, msg_type, &iov, 1);
 }
 
 NTSTATUS messaging_send_buf(struct messaging_context *msg_ctx,
@@ -392,19 +375,40 @@ NTSTATUS messaging_send_iov(struct messaging_context *msg_ctx,
 			    struct server_id server, uint32_t msg_type,
 			    const struct iovec *iov, int iovlen)
 {
-	uint8_t *buf;
-	NTSTATUS status;
+	if (server_id_is_disconnected(&server)) {
+		return NT_STATUS_INVALID_PARAMETER_MIX;
+	}
 
-	buf = iov_buf(talloc_tos(), iov, iovlen);
-	if (buf == NULL) {
-		return NT_STATUS_NO_MEMORY;
+	if (!procid_is_local(&server)) {
+		return msg_ctx->remote->send_fn(msg_ctx, server,
+						msg_type, iov, iovlen,
+						msg_ctx->remote);
 	}
 
-	status = messaging_send_buf(msg_ctx, server, msg_type,
-				    buf, talloc_get_size(buf));
+	if (messaging_is_self_send(msg_ctx, &server)) {
+		struct messaging_rec rec;
+		uint8_t *buf;
+		DATA_BLOB data;
+
+		buf = iov_buf(talloc_tos(), iov, iovlen);
+		if (buf == NULL) {
+			return NT_STATUS_NO_MEMORY;
+		}
+
+		data = data_blob_const(buf, talloc_get_size(buf));
+
+		rec.msg_version = MESSAGE_VERSION;
+		rec.msg_type = msg_type & MSG_TYPE_MASK;
+		rec.dest = server;
+		rec.src = msg_ctx->id;
+		rec.buf = data;
+		messaging_dispatch_rec(msg_ctx, &rec);
+		TALLOC_FREE(buf);
+		return NT_STATUS_OK;
+	}
 
-	TALLOC_FREE(buf);
-	return status;
+	return msg_ctx->local->send_fn(msg_ctx, server, msg_type, iov, iovlen,
+				       msg_ctx->local);
 }
 
 static struct messaging_rec *messaging_rec_dup(TALLOC_CTX *mem_ctx,
diff --git a/source3/lib/messages_ctdbd.c b/source3/lib/messages_ctdbd.c
index 230560f..34b3e2a 100644
--- a/source3/lib/messages_ctdbd.c
+++ b/source3/lib/messages_ctdbd.c
@@ -90,21 +90,33 @@ struct ctdbd_connection *messaging_ctdbd_connection(void)
 
 static NTSTATUS messaging_ctdb_send(struct messaging_context *msg_ctx,
 				    struct server_id pid, int msg_type,
-				    const DATA_BLOB *data,
+				    const struct iovec *iov, int iovlen,
 				    struct messaging_backend *backend)
 {
 	struct messaging_ctdbd_context *ctx = talloc_get_type_abort(
 		backend->private_data, struct messaging_ctdbd_context);
 
 	struct messaging_rec msg;
+	uint8_t *buf;
+	NTSTATUS status;
+
+	buf = iov_buf(talloc_tos(), iov, iovlen);
+	if (buf == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
 
 	msg.msg_version	= MESSAGE_VERSION;
 	msg.msg_type	= msg_type;
 	msg.dest	= pid;
 	msg.src		= msg_ctx->id;
-	msg.buf		= *data;
+	msg.buf		= data_blob_const(buf, talloc_get_size(buf));
+
+	status = ctdbd_messaging_send(ctx->conn, pid.vnn, pid.pid, &msg);
+
+	TALLOC_FREE(buf);
 
-	return ctdbd_messaging_send(ctx->conn, pid.vnn, pid.pid, &msg);
+	return status;
 }
 
 static int messaging_ctdbd_destructor(struct messaging_ctdbd_context *ctx)
diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c
index 55a6fcf..6912035 100644
--- a/source3/lib/messages_dgm.c
+++ b/source3/lib/messages_dgm.c
@@ -46,7 +46,7 @@ struct messaging_dgm_hdr {
 
 static NTSTATUS messaging_dgm_send(struct messaging_context *msg_ctx,
 				   struct server_id pid, int msg_type,
-				   const DATA_BLOB *data,
+				   const struct iovec *iov, int iovlen,
 				   struct messaging_backend *backend);
 static void messaging_dgm_recv(struct unix_msg_ctx *ctx,
 			       uint8_t *msg, size_t msg_len,
@@ -288,7 +288,7 @@ static int messaging_dgm_context_destructor(struct messaging_dgm_context *c)
 
 static NTSTATUS messaging_dgm_send(struct messaging_context *msg_ctx,
 				   struct server_id pid, int msg_type,
-				   const DATA_BLOB *data,
+				   const struct iovec *iov, int iovlen,
 				   struct messaging_backend *backend)
 {
 	struct messaging_dgm_context *ctx = talloc_get_type_abort(
@@ -297,7 +297,7 @@ static NTSTATUS messaging_dgm_send(struct messaging_context *msg_ctx,
 	char buf[PATH_MAX];
 	char *dst_sock, *to_free;
 	struct messaging_dgm_hdr hdr;
-	struct iovec iov[2];
+	struct iovec iov2[iovlen + 1];
 	ssize_t pathlen;
 	int ret;
 
@@ -314,17 +314,16 @@ static NTSTATUS messaging_dgm_send(struct messaging_context *msg_ctx,
 	hdr.dst = pid;
 	hdr.src = msg_ctx->id;
 
-	DEBUG(10, ("%s: Sending message 0x%x len %u to %s\n", __func__,
-		   (unsigned)hdr.msg_type, (unsigned)data->length,
+	DEBUG(10, ("%s: Sending message 0x%x to %s\n", __func__,
+		   (unsigned)hdr.msg_type,
 		   server_id_str(talloc_tos(), &pid)));
 
-	iov[0].iov_base = &hdr;
-	iov[0].iov_len = sizeof(hdr);
-	iov[1].iov_base = data->data;
-	iov[1].iov_len = data->length;
+	iov2[0].iov_base = &hdr;
+	iov2[0].iov_len = sizeof(hdr);
+	memcpy(iov2+1, iov, iovlen*sizeof(struct iovec));
 
 	become_root();
-	ret = unix_msg_send(ctx->dgm_ctx, dst_sock, iov, ARRAY_SIZE(iov));
+	ret = unix_msg_send(ctx->dgm_ctx, dst_sock, iov2, iovlen + 1);
 	unbecome_root();
 
 	TALLOC_FREE(to_free);
-- 
1.9.1


From af1acba1ecd68f1368612f397325d4da4f5aa742 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 13 May 2014 12:42:32 +0200
Subject: [PATCH 2/2] s3:messaging: change unix_dgram_recv_handler() to use
 recvmsg, not recv

This is in preparation of adding fd-passing to messaging.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/lib/unix_msg/unix_msg.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/source3/lib/unix_msg/unix_msg.c b/source3/lib/unix_msg/unix_msg.c
index 956e3a3..bcabd28 100644
--- a/source3/lib/unix_msg/unix_msg.c
+++ b/source3/lib/unix_msg/unix_msg.c
@@ -233,8 +233,22 @@ static void unix_dgram_recv_handler(struct poll_watch *w, int fd, short events,
 {
 	struct unix_dgram_ctx *ctx = (struct unix_dgram_ctx *)private_data;
 	ssize_t received;
+	struct msghdr msg;
+	struct iovec iov;
+
+	iov = (struct iovec) {
+		.iov_base = (void *)ctx->recv_buf,
+		.iov_len = ctx->max_msg,
+	};
+
+	msg = (struct msghdr) {
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+		.msg_control = NULL,
+		.msg_controllen = 0,
+	};
 
-	received = recv(fd, ctx->recv_buf, ctx->max_msg, 0);
+	received = recvmsg(fd, &msg, 0);
 	if (received == -1) {
 		if ((errno == EAGAIN) ||
 #ifdef EWOULDBLOCK
-- 
1.9.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20140526/3b7cdf93/attachment.pgp>


More information about the samba-technical mailing list