[PATCHES] Some messaging-related patches

Volker Lendecke Volker.Lendecke at SerNet.DE
Mon Jul 28 08:34:43 MDT 2014


Hi!

Attached find some patches that have piled up in my trees. A
bit unsorted, mostly cleanups. The ctdb_packet thingy is
something that I've wanted to do for ages. It survives smoke
tests here, I haven't run it in a heavily loaded cluster
yet. But the mechanisms are pretty simple.

Review would be appreciated!

Thanks,

Volker

-- 
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
-------------- next part --------------
From 1b36c51cfc6cf82a9c37ce40030b7bc1a928a049 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sun, 27 Jul 2014 19:08:52 +0200
Subject: [PATCH 01/10] lib: Simplify directory_create_or_exist with an early
 return

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 lib/util/util.c |   47 ++++++++++++++++++++++++-----------------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/lib/util/util.c b/lib/util/util.c
index b6f60c4..d0449e3 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -196,35 +196,36 @@ _PUBLIC_ bool directory_create_or_exist(const char *dname,
 {
 	int ret;
 	struct stat st;
+	mode_t old_umask;
 
 	ret = lstat(dname, &st);
-	if (ret == -1) {
-		mode_t old_umask;
+	if (ret == 0) {
+		return true;
+	}
 
-		if (errno != ENOENT) {
-			DEBUG(0, ("lstat failed on directory %s: %s\n",
-				  dname, strerror(errno)));
-			return false;
-		}
+	if (errno != ENOENT) {
+		DEBUG(0, ("lstat failed on directory %s: %s\n",
+			  dname, strerror(errno)));
+		return false;
+	}
 
-		/* Create directory */
-		old_umask = umask(0);
-		ret = mkdir(dname, dir_perms);
-		if (ret == -1 && errno != EEXIST) {
-			DEBUG(0, ("mkdir failed on directory "
-				  "%s: %s\n", dname,
-				  strerror(errno)));
-			umask(old_umask);
-			return false;
-		}
+	/* Create directory */
+	old_umask = umask(0);
+	ret = mkdir(dname, dir_perms);
+	if (ret == -1 && errno != EEXIST) {
+		DEBUG(0, ("mkdir failed on directory "
+			  "%s: %s\n", dname,
+			  strerror(errno)));
 		umask(old_umask);
+		return false;
+	}
+	umask(old_umask);
 
-		ret = lstat(dname, &st);
-		if (ret == -1) {
-			DEBUG(0, ("lstat failed on created directory %s: %s\n",
-				  dname, strerror(errno)));
-			return false;
-		}
+	ret = lstat(dname, &st);
+	if (ret == -1) {
+		DEBUG(0, ("lstat failed on created directory %s: %s\n",
+			  dname, strerror(errno)));
+		return false;
 	}
 
 	return true;
-- 
1.7.9.5


From c49563ac32a32db7a0ddb495898bd9c30a710e45 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sun, 27 Jul 2014 19:18:09 +0200
Subject: [PATCH 02/10] lib: directory_create_or_exist() does not use "uid"
 parameter

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 lib/param/util.c                  |    4 ++--
 lib/util/samba_util.h             |    3 +--
 lib/util/util.c                   |    3 +--
 source3/lib/dumpcore.c            |    2 +-
 source3/lib/eventlog/eventlog.c   |    2 +-
 source3/nmbd/nmbd.c               |    4 ++--
 source3/printing/nt_printing.c    |    6 ++----
 source3/printing/printing.c       |    2 +-
 source3/registry/reg_perfcount.c  |    2 +-
 source3/rpc_server/rpc_server.c   |    4 ++--
 source3/smbd/server.c             |    2 +-
 source3/winbindd/winbindd.c       |    4 ++--
 source4/ldap_server/ldap_server.c |    2 +-
 source4/smbd/service_named_pipe.c |    2 +-
 14 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/lib/param/util.c b/lib/param/util.c
index 232e85b..faf161d 100644
--- a/lib/param/util.c
+++ b/lib/param/util.c
@@ -91,7 +91,7 @@ static char *lpcfg_common_path(TALLOC_CTX* mem_ctx,
 	}
 	trim_string(dname,"","/");
 
-	ok = directory_create_or_exist(dname, geteuid(), 0755);
+	ok = directory_create_or_exist(dname, 0755);
 	if (!ok) {
 		DEBUG(1, ("Unable to create directory %s for file %s. "
 			  "Error was %s\n", dname, name, strerror(errno)));
@@ -231,7 +231,7 @@ char *smbd_tmp_path(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
-	ok = directory_create_or_exist(dname, geteuid(), 0755);
+	ok = directory_create_or_exist(dname, 0755);
 	if (!ok) {
 		return NULL;
 	}
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index 251ddc2..2ffe028 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -649,8 +649,7 @@ _PUBLIC_ bool file_check_permissions(const char *fname,
  * @retval true if the directory already existed and has the right permissions 
  * or was successfully created.
  */
-_PUBLIC_ bool directory_create_or_exist(const char *dname, uid_t uid, 
-			       mode_t dir_perms);
+_PUBLIC_ bool directory_create_or_exist(const char *dname, mode_t dir_perms);
 
 _PUBLIC_ bool directory_create_or_exist_strict(const char *dname,
 					       uid_t uid,
diff --git a/lib/util/util.c b/lib/util/util.c
index d0449e3..1f75266 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -191,7 +191,6 @@ _PUBLIC_ bool directory_exist(const char *dname)
  * or was successfully created.
  */
 _PUBLIC_ bool directory_create_or_exist(const char *dname,
-					uid_t uid,
 					mode_t dir_perms)
 {
 	int ret;
@@ -254,7 +253,7 @@ _PUBLIC_ bool directory_create_or_exist_strict(const char *dname,
 	bool ok;
 	int rc;
 
-	ok = directory_create_or_exist(dname, uid, dir_perms);
+	ok = directory_create_or_exist(dname, dir_perms);
 	if (!ok) {
 		return false;
 	}
diff --git a/source3/lib/dumpcore.c b/source3/lib/dumpcore.c
index f284ea4..487ccec 100644
--- a/source3/lib/dumpcore.c
+++ b/source3/lib/dumpcore.c
@@ -67,7 +67,7 @@ static char *get_default_corepath(const char *logbase, const char *progname)
 		goto err_out;
 	}
 
-	if (!directory_create_or_exist(tmp_corepath, uid, mode)) {
+	if (!directory_create_or_exist(tmp_corepath, mode)) {
 		DEBUG(0, ("Failed to create %s for user %d with mode 0%o\n",
 			  tmp_corepath, (int)uid, (int)mode));
 		goto err_out;
diff --git a/source3/lib/eventlog/eventlog.c b/source3/lib/eventlog/eventlog.c
index 0cc0240..4c6767d 100644
--- a/source3/lib/eventlog/eventlog.c
+++ b/source3/lib/eventlog/eventlog.c
@@ -373,7 +373,7 @@ ELOG_TDB *elog_open_tdb( const char *logname, bool force_clear, bool read_only )
 	/* make sure that the eventlog dir exists */
 
 	eventlogdir = state_path( "eventlog" );
-	ok = directory_create_or_exist(eventlogdir, geteuid(), 0755);
+	ok = directory_create_or_exist(eventlogdir, 0755);
 	if (!ok) {
 		return NULL;
 	}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 8c66d75..50b18e5 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -973,12 +973,12 @@ static bool open_sockets(bool isdaemon, int port)
 	}
 #endif
 
-	ok = directory_create_or_exist(lp_lock_directory(), geteuid(), 0755);
+	ok = directory_create_or_exist(lp_lock_directory(), 0755);
 	if (!ok) {
 		exit_daemon("Failed to create directory for lock files, check 'lock directory'", errno);
 	}
 
-	ok = directory_create_or_exist(lp_pid_directory(), geteuid(), 0755);
+	ok = directory_create_or_exist(lp_pid_directory(), 0755);
 	if (!ok) {
 		exit_daemon("Failed to create directory for pid files, check 'pid directory'", errno);
 	}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 6a5f2d7..b76badf 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -95,7 +95,7 @@ static bool print_driver_directories_init(void)
 		return false;
 	}
 
-	ok = directory_create_or_exist(driver_path, sec_initial_uid(), 0755);
+	ok = directory_create_or_exist(driver_path, 0755);
 	if (!ok) {
 		DEBUG(1, ("Failed to create printer driver directory %s\n",
 			  driver_path));
@@ -115,9 +115,7 @@ static bool print_driver_directories_init(void)
 			return false;
 		}
 
-		ok = directory_create_or_exist(arch_path,
-					       sec_initial_uid(),
-					       0755);
+		ok = directory_create_or_exist(arch_path, 0755);
 		if (!ok) {
 			DEBUG(1, ("Failed to create printer driver "
 				  "architecture directory %s\n",
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index fa4a2fc..dcfd2a2 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -203,7 +203,7 @@ bool print_backend_init(struct messaging_context *msg_ctx)
 		return false;
 	}
 
-	ok = directory_create_or_exist(cache_path("printing"), geteuid(), 0755);
+	ok = directory_create_or_exist(cache_path("printing"), 0755);
 	if (!ok) {
 		return false;
 	}
diff --git a/source3/registry/reg_perfcount.c b/source3/registry/reg_perfcount.c
index 82e5624..b875067 100644
--- a/source3/registry/reg_perfcount.c
+++ b/source3/registry/reg_perfcount.c
@@ -48,7 +48,7 @@ static char *counters_directory(const char *dbname)
 	TALLOC_CTX *ctx = talloc_tos();
 
 	path = state_path(PERFCOUNTDIR);
-	if (!directory_create_or_exist(path, geteuid(), 0755)) {
+	if (!directory_create_or_exist(path, 0755)) {
 		return NULL;
 	}
 
diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c
index 2ac29e1..01a854c 100644
--- a/source3/rpc_server/rpc_server.c
+++ b/source3/rpc_server/rpc_server.c
@@ -106,7 +106,7 @@ int create_named_pipe_socket(const char *pipe_name)
 	 * lp_ncalrpc_dir()/np should have 0700, we need to
 	 * create lp_ncalrpc_dir() first.
 	 */
-	if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
+	if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
 		DEBUG(0, ("Failed to create pipe directory %s - %s\n",
 			  lp_ncalrpc_dir(), strerror(errno)));
 		goto out;
@@ -773,7 +773,7 @@ int create_dcerpc_ncalrpc_socket(const char *name)
 		name = "DEFAULT";
 	}
 
-	if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
+	if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
 		DEBUG(0, ("Failed to create ncalrpc directory %s - %s\n",
 			  lp_ncalrpc_dir(), strerror(errno)));
 		return -1;
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index dd1e20a..ec9348c 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1488,7 +1488,7 @@ extern void build_options(bool screen);
 	/* This MUST be done before start_epmd() because otherwise
 	 * start_epmd() forks and races against dcesrv_ep_setup() to
 	 * call directory_create_or_exist() */
-	if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
+	if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
 		DEBUG(0, ("Failed to create pipe directory %s - %s\n",
 			  lp_ncalrpc_dir(), strerror(errno)));
 		return -1;
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index cb61646..a51a172 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -1519,14 +1519,14 @@ int main(int argc, const char **argv)
 		exit(1);
 	}
 
-	ok = directory_create_or_exist(lp_lock_directory(), geteuid(), 0755);
+	ok = directory_create_or_exist(lp_lock_directory(), 0755);
 	if (!ok) {
 		DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
 			  lp_lock_directory(), strerror(errno)));
 		exit(1);
 	}
 
-	ok = directory_create_or_exist(lp_pid_directory(), geteuid(), 0755);
+	ok = directory_create_or_exist(lp_pid_directory(), 0755);
 	if (!ok) {
 		DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
 			  lp_pid_directory(), strerror(errno)));
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index d59668b..691266c 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -1007,7 +1007,7 @@ static void ldapsrv_task_init(struct task_server *task)
 	 * Make sure the directory for the privileged ldapi socket exists, and
 	 * is of the correct permissions
 	 */
-	if (!directory_create_or_exist(priv_dir, geteuid(), 0750)) {
+	if (!directory_create_or_exist(priv_dir, 0750)) {
 		task_server_terminate(task, "Cannot create ldap "
 				      "privileged ldapi directory", true);
 		return;
diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c
index 6aa984d..f9907b2 100644
--- a/source4/smbd/service_named_pipe.c
+++ b/source4/smbd/service_named_pipe.c
@@ -200,7 +200,7 @@ NTSTATUS tstream_setup_named_pipe(TALLOC_CTX *mem_ctx,
 		goto fail;
 	}
 
-	if (!directory_create_or_exist(lpcfg_ncalrpc_dir(lp_ctx), geteuid(), 0755)) {
+	if (!directory_create_or_exist(lpcfg_ncalrpc_dir(lp_ctx), 0755)) {
 		status = map_nt_error_from_unix_common(errno);
 		DEBUG(0,(__location__ ": Failed to create ncalrpc pipe directory '%s' - %s\n",
 			 lpcfg_ncalrpc_dir(lp_ctx), nt_errstr(status)));
-- 
1.7.9.5


From 08f9fa176c21704293581b4a5af734548006018d Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 28 Jul 2014 12:02:12 +0000
Subject: [PATCH 03/10] unix_msg: Use empty arrays in structs

Just a simple style update

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/unix_msg/unix_msg.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/source3/lib/unix_msg/unix_msg.c b/source3/lib/unix_msg/unix_msg.c
index f3185a3..6728fc9 100644
--- a/source3/lib/unix_msg/unix_msg.c
+++ b/source3/lib/unix_msg/unix_msg.c
@@ -43,7 +43,7 @@ struct unix_dgram_msg {
 	ssize_t sent;
 	int sys_errno;
 	size_t buflen;
-	uint8_t buf[1];
+	uint8_t buf[];
 };
 
 struct unix_dgram_send_queue {
@@ -51,7 +51,7 @@ struct unix_dgram_send_queue {
 	struct unix_dgram_ctx *ctx;
 	int sock;
 	struct unix_dgram_msg *msgs;
-	char path[1];
+	char path[];
 };
 
 struct unix_dgram_ctx {
@@ -72,7 +72,7 @@ struct unix_dgram_ctx {
 	struct poll_watch *pool_read_watch;
 
 	uint8_t *recv_buf;
-	char path[1];
+	char path[];
 };
 
 static ssize_t iov_buflen(const struct iovec *iov, int iovlen);
-- 
1.7.9.5


From 2f47bc193a98b59837cd9f77c16cf16630dbf718 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 28 Jul 2014 11:54:16 +0000
Subject: [PATCH 04/10] unix_msg: Use struct initializers

Saves a few lines and bytes of .text

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/unix_msg/unix_msg.c |   64 +++++++++++++++++++--------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/source3/lib/unix_msg/unix_msg.c b/source3/lib/unix_msg/unix_msg.c
index 6728fc9..2da8b6f 100644
--- a/source3/lib/unix_msg/unix_msg.c
+++ b/source3/lib/unix_msg/unix_msg.c
@@ -163,20 +163,19 @@ static int unix_dgram_init(const struct sockaddr_un *addr, size_t max_msg,
 		ctx->path[0] = '\0';
 	}
 
+	*ctx = (struct unix_dgram_ctx) {
+		.max_msg = max_msg,
+		.ev_funcs = ev_funcs,
+		.recv_callback = recv_callback,
+		.private_data = private_data,
+		.created_pid = (pid_t)-1
+	};
+
 	ctx->recv_buf = malloc(max_msg);
 	if (ctx->recv_buf == NULL) {
 		free(ctx);
 		return ENOMEM;
 	}
-	ctx->max_msg = max_msg;
-	ctx->ev_funcs = ev_funcs;
-	ctx->recv_callback = recv_callback;
-	ctx->private_data = private_data;
-	ctx->sock_read_watch = NULL;
-	ctx->send_pool = NULL;
-	ctx->pool_read_watch = NULL;
-	ctx->send_queues = NULL;
-	ctx->created_pid = (pid_t)-1;
 
 	ctx->sock = socket(AF_UNIX, SOCK_DGRAM, 0);
 	if (ctx->sock == -1) {
@@ -486,15 +485,12 @@ static int unix_dgram_send(struct unix_dgram_ctx *ctx,
 	 * Try a cheap nonblocking send
 	 */
 
-	msg.msg_name = discard_const_p(struct sockaddr_un, dst);
-	msg.msg_namelen = sizeof(*dst);
-	msg.msg_iov = discard_const_p(struct iovec, iov);
-	msg.msg_iovlen = iovlen;
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-#endif
-	msg.msg_flags = 0;
+	msg = (struct msghdr) {
+		.msg_name = discard_const_p(struct sockaddr_un, dst),
+		.msg_namelen = sizeof(*dst),
+		.msg_iov = discard_const_p(struct iovec, iov),
+		.msg_iovlen = iovlen
+	};
 
 	ret = sendmsg(ctx->sock, &msg, 0);
 	if (ret >= 0) {
@@ -620,6 +616,13 @@ int unix_msg_init(const struct sockaddr_un *addr,
 		return ENOMEM;
 	}
 
+	*ctx = (struct unix_msg_ctx) {
+		.fragment_len = fragment_len,
+		.cookie = cookie,
+		.recv_callback = recv_callback,
+		.private_data = private_data
+	};
+
 	ret = unix_dgram_init(addr, fragment_len, ev_funcs,
 			      unix_msg_recv, ctx, &ctx->dgram);
 	if (ret != 0) {
@@ -627,12 +630,6 @@ int unix_msg_init(const struct sockaddr_un *addr,
 		return ret;
 	}
 
-	ctx->fragment_len = fragment_len;
-	ctx->cookie = cookie;
-	ctx->recv_callback = recv_callback;
-	ctx->private_data = private_data;
-	ctx->msgs = NULL;
-
 	*result = ctx;
 	return 0;
 }
@@ -670,9 +667,11 @@ int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
 		return unix_dgram_send(ctx->dgram, dst, tmp_iov, iovlen+1);
 	}
 
-	hdr.msglen = msglen;
-	hdr.pid = getpid();
-	hdr.sock = unix_dgram_sock(ctx->dgram);
+	hdr = (struct unix_msg_hdr) {
+		.msglen = msglen,
+		.pid = getpid(),
+		.sock = unix_dgram_sock(ctx->dgram)
+	};
 
 	iov_copy = malloc(sizeof(struct iovec) * (iovlen + 2));
 	if (iov_copy == NULL) {
@@ -790,11 +789,12 @@ static void unix_msg_recv(struct unix_dgram_ctx *dgram_ctx,
 		if (msg == NULL) {
 			return;
 		}
-		msg->msglen = hdr.msglen;
-		msg->received = 0;
-		msg->sender_pid = hdr.pid;
-		msg->sender_sock = hdr.sock;
-		msg->cookie = cookie;
+		*msg = (struct unix_msg) {
+			.msglen = hdr.msglen,
+			.sender_pid = hdr.pid,
+			.sender_sock = hdr.sock,
+			.cookie = cookie
+		};
 		DLIST_ADD(ctx->msgs, msg);
 	}
 
-- 
1.7.9.5


From 08515b902c98a4c7b20a4a5edfe7827fc6bd92e7 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 24 Jul 2014 14:59:33 +0000
Subject: [PATCH 05/10] unix_msg: simplify unix_msg_send

We have a variable array inside one-fragment fast path anyway. Moving
that to the toplevel of the function saves us a malloc/free pair.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/unix_msg/unix_msg.c |   17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/source3/lib/unix_msg/unix_msg.c b/source3/lib/unix_msg/unix_msg.c
index 2da8b6f..00438ce 100644
--- a/source3/lib/unix_msg/unix_msg.c
+++ b/source3/lib/unix_msg/unix_msg.c
@@ -640,7 +640,7 @@ int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
 	ssize_t msglen;
 	size_t sent;
 	int ret = 0;
-	struct iovec *iov_copy;
+	struct iovec iov_copy[iovlen+2];
 	struct unix_msg_hdr hdr;
 	struct iovec src_iov;
 
@@ -654,17 +654,16 @@ int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
 	}
 
 	if (msglen <= (ctx->fragment_len - sizeof(uint64_t))) {
-		struct iovec tmp_iov[iovlen+1];
 		uint64_t cookie = 0;
 
-		tmp_iov[0].iov_base = &cookie;
-		tmp_iov[0].iov_len = sizeof(cookie);
+		iov_copy[0].iov_base = &cookie;
+		iov_copy[0].iov_len = sizeof(cookie);
 		if (iovlen > 0) {
-			memcpy(&tmp_iov[1], iov,
+			memcpy(&iov_copy[1], iov,
 			       sizeof(struct iovec) * iovlen);
 		}
 
-		return unix_dgram_send(ctx->dgram, dst, tmp_iov, iovlen+1);
+		return unix_dgram_send(ctx->dgram, dst, iov_copy, iovlen+1);
 	}
 
 	hdr = (struct unix_msg_hdr) {
@@ -673,10 +672,6 @@ int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
 		.sock = unix_dgram_sock(ctx->dgram)
 	};
 
-	iov_copy = malloc(sizeof(struct iovec) * (iovlen + 2));
-	if (iov_copy == NULL) {
-		return ENOMEM;
-	}
 	iov_copy[0].iov_base = &ctx->cookie;
 	iov_copy[0].iov_len = sizeof(ctx->cookie);
 	iov_copy[1].iov_base = &hdr;
@@ -730,8 +725,6 @@ int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
 		}
 	}
 
-	free(iov_copy);
-
 	ctx->cookie += 1;
 	if (ctx->cookie == 0) {
 		ctx->cookie += 1;
-- 
1.7.9.5


From 6b987d031a3b253022369c0c6efb7f3daf580150 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 6 May 2014 12:21:42 +0200
Subject: [PATCH 06/10] ctdbd_conn: Remove ctdb_packet dependency

This was an early, failed attempt at async socket handling

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/ctdbd_conn.c |  553 ++++++++++++++++++----------------------------
 1 file changed, 219 insertions(+), 334 deletions(-)

diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 201c700..29482a0 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -22,8 +22,8 @@
 #include "util_tdb.h"
 #include "serverid.h"
 #include "ctdbd_conn.h"
+#include "system/select.h"
 
-#include "ctdb_packet.h"
 #include "messages.h"
 
 /*
@@ -54,7 +54,7 @@ struct ctdbd_connection {
 	uint32_t reqid;
 	uint32_t our_vnn;
 	uint64_t rand_srvid;
-	struct ctdb_packet_context *pkt;
+	int fd;
 	struct tevent_fd *fde;
 
 	bool (*release_ip_handler)(const char *ip_addr, void *private_data);
@@ -208,10 +208,8 @@ const char *lp_ctdbd_socket(void)
  * Get us a ctdb connection
  */
 
-static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx,
-			      struct ctdb_packet_context **presult)
+static int ctdbd_connect(int *pfd)
 {
-	struct ctdb_packet_context *result;
 	const char *sockname = lp_ctdbd_socket();
 	struct sockaddr_un addr = { 0, };
 	int fd;
@@ -219,61 +217,26 @@ static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx,
 
 	fd = socket(AF_UNIX, SOCK_STREAM, 0);
 	if (fd == -1) {
-		DEBUG(3, ("Could not create socket: %s\n", strerror(errno)));
-		return map_nt_error_from_unix(errno);
+		int err = errno;
+		DEBUG(3, ("Could not create socket: %s\n", strerror(err)));
+		return err;
 	}
 
 	addr.sun_family = AF_UNIX;
 	snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", sockname);
 
 	salen = sizeof(struct sockaddr_un);
+
 	if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
+		int err = errno;
 		DEBUG(1, ("connect(%s) failed: %s\n", sockname,
-			  strerror(errno)));
-		close(fd);
-		return map_nt_error_from_unix(errno);
-	}
-
-	if (!(result = ctdb_packet_init(mem_ctx, fd))) {
+			  strerror(err)));
 		close(fd);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	*presult = result;
-	return NT_STATUS_OK;
-}
-
-/*
- * Do we have a complete ctdb packet in the queue?
- */
-
-static bool ctdb_req_complete(const uint8_t *buf, size_t available,
-			      size_t *length,
-			      void *private_data)
-{
-	uint32_t msglen;
-
-	if (available < sizeof(msglen)) {
-		return False;
-	}
-
-	msglen = *((const uint32_t *)buf);
-
-	DEBUG(11, ("msglen = %d\n", msglen));
-
-	if (msglen < sizeof(struct ctdb_req_header)) {
-		DEBUG(0, ("Got invalid msglen: %d, expected at least %d for "
-			  "the req_header\n", (int)msglen,
-			  (int)sizeof(struct ctdb_req_header)));
-		cluster_fatal("ctdbd protocol error\n");
-	}
-
-	if (available < msglen) {
-		return false;
+		return err;
 	}
 
-	*length = msglen;
-	return true;
+	*pfd = fd;
+	return 0;
 }
 
 /*
@@ -303,25 +266,6 @@ static void deferred_message_dispatch(struct tevent_context *event_ctx,
 	TALLOC_FREE(te);
 }
 
-struct req_pull_state {
-	TALLOC_CTX *mem_ctx;
-	DATA_BLOB req;
-};
-
-/*
- * Pull a ctdb request out of the incoming ctdb_packet queue
- */
-
-static NTSTATUS ctdb_req_pull(uint8_t *buf, size_t length,
-			      void *private_data)
-{
-	struct req_pull_state *state = (struct req_pull_state *)private_data;
-
-	state->req.data = talloc_move(state->mem_ctx, &buf);
-	state->req.length = length;
-	return NT_STATUS_OK;
-}
-
 /*
  * Fetch a messaging_rec from an incoming ctdb style message
  */
@@ -367,14 +311,55 @@ static struct messaging_rec *ctdb_pull_messaging_rec(TALLOC_CTX *mem_ctx,
 	return result;
 }
 
-static NTSTATUS ctdb_packet_fd_read_sync(struct ctdb_packet_context *ctx)
+static NTSTATUS ctdb_read_packet(int fd, TALLOC_CTX *mem_ctx,
+				 struct ctdb_req_header **result)
 {
 	int timeout = lp_ctdb_timeout();
+	struct ctdb_req_header *req;
+	int ret, revents;
+	uint32_t msglen;
+	NTSTATUS status;
 
 	if (timeout == 0) {
 		timeout = -1;
 	}
-	return ctdb_packet_fd_read_sync_timeout(ctx, timeout);
+
+	ret = poll_one_fd(fd, POLLIN, timeout, &revents);
+	if (ret == -1) {
+		return map_nt_error_from_unix(errno);
+	}
+	if (ret == 0) {
+		return NT_STATUS_IO_TIMEOUT;
+	}
+	if (ret != 1) {
+		return NT_STATUS_UNEXPECTED_IO_ERROR;
+	}
+
+	status = read_data(fd, (char *)&msglen, sizeof(msglen));
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	if (msglen < sizeof(struct ctdb_req_header)) {
+		return NT_STATUS_UNEXPECTED_IO_ERROR;
+	}
+
+	req = talloc_size(mem_ctx, msglen);
+	if (req == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	talloc_set_name_const(req, "struct ctdb_req_header");
+
+	req->length = msglen;
+
+	status = read_data(fd, ((char *)req) + sizeof(msglen),
+			   msglen - sizeof(msglen));
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	*result = req;
+	return NT_STATUS_OK;
 }
 
 /*
@@ -383,44 +368,20 @@ static NTSTATUS ctdb_packet_fd_read_sync(struct ctdb_packet_context *ctx)
  */
 
 static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32_t reqid,
-			      TALLOC_CTX *mem_ctx, void *result)
+			      TALLOC_CTX *mem_ctx,
+			      struct ctdb_req_header **result)
 {
 	struct ctdb_req_header *hdr;
-	struct req_pull_state state;
 	NTSTATUS status;
 
  next_pkt:
-	ZERO_STRUCT(state);
-	state.mem_ctx = mem_ctx;
-
-	while (!ctdb_packet_handler(conn->pkt, ctdb_req_complete,
-				    ctdb_req_pull, &state, &status)) {
-		/*
-		 * Not enough data
-		 */
-		status = ctdb_packet_fd_read_sync(conn->pkt);
-
-		if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_BUSY)) {
-			/* EAGAIN */
-			continue;
-		} else if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
-			/* EAGAIN */
-			continue;
-		}
-
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("packet_fd_read failed: %s\n", nt_errstr(status)));
-			cluster_fatal("ctdbd died\n");
-		}
-	}
 
+	status = ctdb_read_packet(conn->fd, mem_ctx, &hdr);
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("Could not read ctdb_packet: %s\n", nt_errstr(status)));
+		DEBUG(0, ("ctdb_read_packet failed: %s\n", nt_errstr(status)));
 		cluster_fatal("ctdbd died\n");
 	}
 
-	hdr = (struct ctdb_req_header *)state.req.data;
-
 	DEBUG(11, ("Received ctdb packet\n"));
 	ctdb_packet_dump(hdr);
 
@@ -481,7 +442,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32_t reqid,
 		}
 
 		if (!(msg_state->rec = ctdb_pull_messaging_rec(
-			      msg_state, state.req.length, msg))) {
+			      msg_state, msg->hdr.length, msg))) {
 			DEBUG(0, ("ctdbd_pull_messaging_rec failed\n"));
 			TALLOC_FREE(msg_state);
 			TALLOC_FREE(hdr);
@@ -519,11 +480,16 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32_t reqid,
 		goto next_pkt;
 	}
 
-	*((void **)result) = talloc_move(mem_ctx, &hdr);
+	*result = talloc_move(mem_ctx, &hdr);
 
 	return NT_STATUS_OK;
 }
 
+static int ctdbd_connection_destructor(struct ctdbd_connection *c)
+{
+	close(c->fd);
+	return 0;
+}
 /*
  * Get us a ctdbd connection
  */
@@ -532,6 +498,7 @@ static NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx,
 				      struct ctdbd_connection **pconn)
 {
 	struct ctdbd_connection *conn;
+	int ret;
 	NTSTATUS status;
 
 	if (!(conn = talloc_zero(mem_ctx, struct ctdbd_connection))) {
@@ -539,12 +506,13 @@ static NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = ctdbd_connect(conn, &conn->pkt);
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(10, ("ctdbd_connect failed: %s\n", nt_errstr(status)));
+	ret = ctdbd_connect(&conn->fd);
+	if (ret != 0) {
+		status = map_nt_error_from_unix(errno);
+		DEBUG(10, ("ctdbd_connect failed: %s\n", strerror(errno)));
 		goto fail;
 	}
+	talloc_set_destructor(conn, ctdbd_connection_destructor);
 
 	status = get_cluster_vnn(conn, &conn->our_vnn);
 
@@ -624,29 +592,27 @@ struct messaging_context *ctdb_conn_msg_ctx(struct ctdbd_connection *conn)
 
 int ctdbd_conn_get_fd(struct ctdbd_connection *conn)
 {
-	return ctdb_packet_get_fd(conn->pkt);
+	return conn->fd;
 }
 
 /*
  * Packet handler to receive and handle a ctdb message
  */
-static NTSTATUS ctdb_handle_message(uint8_t *buf, size_t length,
-				    void *private_data)
+static NTSTATUS ctdb_handle_message(struct messaging_context *msg_ctx,
+				    struct ctdbd_connection *conn,
+				    struct ctdb_req_header *hdr)
 {
-	struct ctdbd_connection *conn = talloc_get_type_abort(
-		private_data, struct ctdbd_connection);
 	struct ctdb_req_message *msg;
 	struct messaging_rec *msg_rec;
 
-	msg = (struct ctdb_req_message *)buf;
-
-	if (msg->hdr.operation != CTDB_REQ_MESSAGE) {
+	if (hdr->operation != CTDB_REQ_MESSAGE) {
 		DEBUG(0, ("Received async msg of type %u, discarding\n",
-			  msg->hdr.operation));
-		TALLOC_FREE(buf);
+			  hdr->operation));
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
+	msg = (struct ctdb_req_message *)hdr;
+
 	if ((conn->release_ip_handler != NULL)
 	    && (msg->srvid == CTDB_SRVID_RELEASE_IP)) {
 		bool ret;
@@ -664,7 +630,6 @@ static NTSTATUS ctdb_handle_message(uint8_t *buf, size_t length,
 			conn->release_ip_handler = NULL;
 			conn->release_ip_priv = NULL;
 		}
-		TALLOC_FREE(buf);
 		return NT_STATUS_OK;
 	}
 
@@ -682,7 +647,6 @@ static NTSTATUS ctdb_handle_message(uint8_t *buf, size_t length,
 			       messaging_server_id(conn->msg_ctx),
 			       MSG_SMB_BRL_VALIDATE, &data_blob_null);
 
-		TALLOC_FREE(buf);
 		return NT_STATUS_OK;
 	}
 
@@ -690,20 +654,15 @@ static NTSTATUS ctdb_handle_message(uint8_t *buf, size_t length,
 	if (msg->srvid != getpid() && msg->srvid != MSG_SRVID_SAMBA) {
 		DEBUG(0,("Got unexpected message with srvid=%llu\n", 
 			 (unsigned long long)msg->srvid));
-		TALLOC_FREE(buf);
 		return NT_STATUS_OK;
 	}
 
-	if (!(msg_rec = ctdb_pull_messaging_rec(NULL, length, msg))) {
+	msg_rec = ctdb_pull_messaging_rec(talloc_tos(), msg->hdr.length, msg);
+	if (msg_rec == NULL) {
 		DEBUG(10, ("ctdb_pull_messaging_rec failed\n"));
-		TALLOC_FREE(buf);
 		return NT_STATUS_NO_MEMORY;
 	}
-
 	messaging_dispatch_rec(conn->msg_ctx, msg_rec);
-
-	TALLOC_FREE(msg_rec);
-	TALLOC_FREE(buf);
 	return NT_STATUS_OK;
 }
 
@@ -718,22 +677,19 @@ static void ctdbd_socket_handler(struct tevent_context *event_ctx,
 {
 	struct ctdbd_connection *conn = talloc_get_type_abort(
 		private_data, struct ctdbd_connection);
-
+	struct ctdb_req_header *hdr;
 	NTSTATUS status;
 
-	status = ctdb_packet_fd_read(conn->pkt);
-
+	status = ctdb_read_packet(conn->fd, talloc_tos(), &hdr);
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("packet_fd_read failed: %s\n", nt_errstr(status)));
+		DEBUG(0, ("ctdb_read_packet failed: %s\n", nt_errstr(status)));
 		cluster_fatal("ctdbd died\n");
 	}
 
-	while (ctdb_packet_handler(conn->pkt, ctdb_req_complete,
-			      ctdb_handle_message, conn, &status)) {
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(10, ("could not handle incoming message: %s\n",
-				   nt_errstr(status)));
-		}
+	status = ctdb_handle_message(conn->msg_ctx, conn, hdr);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(10, ("could not handle incoming message: %s\n",
+			   nt_errstr(status)));
 	}
 }
 
@@ -749,7 +705,7 @@ NTSTATUS ctdbd_register_msg_ctx(struct ctdbd_connection *conn,
 
 	if (!(conn->fde = tevent_add_fd(messaging_tevent_context(msg_ctx),
 				       conn,
-				       ctdb_packet_get_fd(conn->pkt),
+				       conn->fd,
 				       TEVENT_FD_READ,
 				       ctdbd_socket_handler,
 				       conn))) {
@@ -795,7 +751,8 @@ NTSTATUS ctdbd_messaging_send_blob(struct ctdbd_connection *conn,
 				   const uint8_t *buf, size_t buflen)
 {
 	struct ctdb_req_message r;
-	NTSTATUS status;
+	struct iovec iov[2];
+	ssize_t nwritten;
 
 	r.hdr.length = offsetof(struct ctdb_req_message, data) + buflen;
 	r.hdr.ctdb_magic = CTDB_MAGIC;
@@ -811,21 +768,17 @@ NTSTATUS ctdbd_messaging_send_blob(struct ctdbd_connection *conn,
 	DEBUG(10, ("ctdbd_messaging_send: Sending ctdb packet\n"));
 	ctdb_packet_dump(&r.hdr);
 
-	status = ctdb_packet_send(
-		conn->pkt, 2,
-		data_blob_const(&r, offsetof(struct ctdb_req_message, data)),
-		data_blob_const(buf, buflen));
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("ctdb_packet_send failed: %s\n", nt_errstr(status)));
-		return status;
-	}
+	iov[0].iov_base = &r;
+	iov[0].iov_len = offsetof(struct ctdb_req_message, data);
+	iov[1].iov_base = discard_const_p(uint8_t, buf);
+	iov[1].iov_len = buflen;
 
-	status = ctdb_packet_flush(conn->pkt);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status)));
+	nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
+	if (nwritten == -1) {
+		DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
 		cluster_fatal("cluster dispatch daemon msg write error\n");
 	}
+
 	return NT_STATUS_OK;
 }
 
@@ -840,8 +793,11 @@ static NTSTATUS ctdbd_control(struct ctdbd_connection *conn,
 			      int *cstatus)
 {
 	struct ctdb_req_control req;
+	struct ctdb_req_header *hdr;
 	struct ctdb_reply_control *reply = NULL;
 	struct ctdbd_connection *new_conn = NULL;
+	struct iovec iov[2];
+	ssize_t nwritten;
 	NTSTATUS status;
 
 	if (conn == NULL) {
@@ -871,21 +827,15 @@ static NTSTATUS ctdbd_control(struct ctdbd_connection *conn,
 	DEBUG(10, ("ctdbd_control: Sending ctdb packet\n"));
 	ctdb_packet_dump(&req.hdr);
 
-	status = ctdb_packet_send(
-		conn->pkt, 2,
-		data_blob_const(&req, offsetof(struct ctdb_req_control, data)),
-		data_blob_const(data.dptr, data.dsize));
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(3, ("ctdb_packet_send failed: %s\n", nt_errstr(status)));
-		goto fail;
-	}
+	iov[0].iov_base = &req;
+	iov[0].iov_len = offsetof(struct ctdb_req_control, data);
+	iov[1].iov_base = data.dptr;
+	iov[1].iov_len = data.dsize;
 
-	status = ctdb_packet_flush(conn->pkt);
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status)));
-		cluster_fatal("cluster dispatch daemon control write error\n");
+	nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
+	if (nwritten == -1) {
+		DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
+		cluster_fatal("cluster dispatch daemon msg write error\n");
 	}
 
 	if (flags & CTDB_CTRL_FLAG_NOREPLY) {
@@ -896,17 +846,18 @@ static NTSTATUS ctdbd_control(struct ctdbd_connection *conn,
 		return NT_STATUS_OK;
 	}
 
-	status = ctdb_read_req(conn, req.hdr.reqid, NULL, (void *)&reply);
+	status = ctdb_read_req(conn, req.hdr.reqid, NULL, &hdr);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(10, ("ctdb_read_req failed: %s\n", nt_errstr(status)));
 		goto fail;
 	}
 
-	if (reply->hdr.operation != CTDB_REPLY_CONTROL) {
+	if (hdr->operation != CTDB_REPLY_CONTROL) {
 		DEBUG(0, ("received invalid reply\n"));
 		goto fail;
 	}
+	reply = (struct ctdb_reply_control *)hdr;
 
 	if (outdata) {
 		if (!(outdata->dptr = (uint8 *)talloc_memdup(
@@ -964,6 +915,8 @@ bool ctdb_processes_exist(struct ctdbd_connection *conn,
 	for (i=0; i<num_pids; i++) {
 		struct ctdb_req_control req;
 		pid_t pid;
+		struct iovec iov[2];
+		ssize_t nwritten;
 
 		results[i] = false;
 		reqids[i] = ctdbd_next_reqid(conn);
@@ -995,42 +948,39 @@ bool ctdb_processes_exist(struct ctdbd_connection *conn,
 		DEBUG(10, ("ctdbd_control: Sending ctdb packet\n"));
 		ctdb_packet_dump(&req.hdr);
 
-		status = ctdb_packet_send(
-			conn->pkt, 2,
-			data_blob_const(
-				&req, offsetof(struct ctdb_req_control, data)),
-			data_blob_const(&pid, sizeof(pid)));
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(10, ("ctdb_packet_send failed: %s\n",
-				   nt_errstr(status)));
+		iov[0].iov_base = &req;
+		iov[0].iov_len = offsetof(struct ctdb_req_control, data);
+		iov[1].iov_base = &pid;
+		iov[1].iov_len = sizeof(pid);
+
+		nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
+		if (nwritten == -1) {
+			status = map_nt_error_from_unix(errno);
+			DEBUG(10, ("write_data_iov failed: %s\n",
+				   strerror(errno)));
 			goto fail;
 		}
 	}
 
-	status = ctdb_packet_flush(conn->pkt);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(10, ("ctdb_packet_flush failed: %s\n",
-			   nt_errstr(status)));
-		goto fail;
-	}
-
 	num_received = 0;
 
 	while (num_received < num_pids) {
-		struct ctdb_reply_control *reply = NULL;
+		struct ctdb_req_header *hdr;
+		struct ctdb_reply_control *reply;
 		uint32_t reqid;
 
-		status = ctdb_read_req(conn, 0, talloc_tos(), (void *)&reply);
+		status = ctdb_read_req(conn, 0, talloc_tos(), &hdr);
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(10, ("ctdb_read_req failed: %s\n",
 				   nt_errstr(status)));
 			goto fail;
 		}
 
-		if (reply->hdr.operation != CTDB_REPLY_CONTROL) {
+		if (hdr->operation != CTDB_REPLY_CONTROL) {
 			DEBUG(10, ("Received invalid reply\n"));
 			goto fail;
 		}
+		reply = (struct ctdb_reply_control *)hdr;
 
 		reqid = reply->hdr.reqid;
 
@@ -1177,6 +1127,8 @@ bool ctdb_serverids_exist(struct ctdbd_connection *conn,
 	for (i=0; i<num_vnns; i++) {
 		struct ctdb_vnn_list *vnn = &vnns[i];
 		struct ctdb_req_control req;
+		struct iovec iov[2];
+		ssize_t nwritten;
 
 		vnn->reqid = ctdbd_next_reqid(conn);
 
@@ -1200,46 +1152,42 @@ bool ctdb_serverids_exist(struct ctdbd_connection *conn,
 		DEBUG(10, ("ctdbd_control: Sending ctdb packet\n"));
 		ctdb_packet_dump(&req.hdr);
 
-		status = ctdb_packet_send(
-			conn->pkt, 2,
-			data_blob_const(
-				&req, offsetof(struct ctdb_req_control,
-					       data)),
-			data_blob_const(vnn->srvids, req.datalen));
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(1, ("ctdb_packet_send failed: %s\n",
-				  nt_errstr(status)));
+		iov[0].iov_base = &req;
+		iov[0].iov_len = offsetof(struct ctdb_req_control, data);
+		iov[1].iov_base = vnn->srvids;
+		iov[1].iov_len = req.datalen;
+
+		nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
+		if (nwritten == -1) {
+			status = map_nt_error_from_unix(errno);
+			DEBUG(10, ("write_data_iov failed: %s\n",
+				   strerror(errno)));
 			goto fail;
 		}
 	}
 
-	status = ctdb_packet_flush(conn->pkt);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(1, ("ctdb_packet_flush failed: %s\n",
-			  nt_errstr(status)));
-		goto fail;
-	}
-
 	num_received = 0;
 
 	while (num_received < num_vnns) {
-		struct ctdb_reply_control *reply = NULL;
+		struct ctdb_req_header *hdr;
+		struct ctdb_reply_control *reply;
 		struct ctdb_vnn_list *vnn;
 		uint32_t reqid;
 		uint8_t *reply_data;
 
-		status = ctdb_read_req(conn, 0, talloc_tos(), (void *)&reply);
+		status = ctdb_read_req(conn, 0, talloc_tos(), &hdr);
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(1, ("ctdb_read_req failed: %s\n",
 				  nt_errstr(status)));
 			goto fail;
 		}
 
-		if (reply->hdr.operation != CTDB_REPLY_CONTROL) {
+		if (hdr->operation != CTDB_REPLY_CONTROL) {
 			DEBUG(1, ("Received invalid reply %u\n",
 				  (unsigned)reply->hdr.operation));
 			goto fail;
 		}
+		reply = (struct ctdb_reply_control *)hdr;
 
 		reqid = reply->hdr.reqid;
 
@@ -1394,7 +1342,9 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32_t db_id,
 		       TDB_DATA key)
 {
 	struct ctdb_req_call req;
-	struct ctdb_reply_call *reply;
+	struct ctdb_req_header *hdr;
+	struct iovec iov[2];
+	ssize_t nwritten;
 	NTSTATUS status;
 
 	ZERO_STRUCT(req);
@@ -1412,31 +1362,25 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32_t db_id,
 	DEBUG(10, ("ctdbd_migrate: Sending ctdb packet\n"));
 	ctdb_packet_dump(&req.hdr);
 
-	status = ctdb_packet_send(
-		conn->pkt, 2,
-		data_blob_const(&req, offsetof(struct ctdb_req_call, data)),
-		data_blob_const(key.dptr, key.dsize));
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(3, ("ctdb_packet_send failed: %s\n", nt_errstr(status)));
-		return status;
-	}
+	iov[0].iov_base = &req;
+	iov[0].iov_len = offsetof(struct ctdb_req_call, data);
+	iov[1].iov_base = key.dptr;
+	iov[1].iov_len = key.dsize;
 
-	status = ctdb_packet_flush(conn->pkt);
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status)));
-		cluster_fatal("cluster dispatch daemon control write error\n");
+	nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
+	if (nwritten == -1) {
+		DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
+		cluster_fatal("cluster dispatch daemon msg write error\n");
 	}
 
-	status = ctdb_read_req(conn, req.hdr.reqid, NULL, (void *)&reply);
+	status = ctdb_read_req(conn, req.hdr.reqid, NULL, &hdr);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("ctdb_read_req failed: %s\n", nt_errstr(status)));
 		goto fail;
 	}
 
-	if (reply->hdr.operation != CTDB_REPLY_CALL) {
+	if (hdr->operation != CTDB_REPLY_CALL) {
 		DEBUG(0, ("received invalid reply\n"));
 		status = NT_STATUS_INTERNAL_ERROR;
 		goto fail;
@@ -1445,7 +1389,7 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32_t db_id,
 	status = NT_STATUS_OK;
  fail:
 
-	TALLOC_FREE(reply);
+	TALLOC_FREE(hdr);
 	return status;
 }
 
@@ -1459,7 +1403,10 @@ NTSTATUS ctdbd_parse(struct ctdbd_connection *conn, uint32_t db_id,
 		     void *private_data)
 {
 	struct ctdb_req_call req;
+	struct ctdb_req_header *hdr = NULL;
 	struct ctdb_reply_call *reply;
+	struct iovec iov[2];
+	ssize_t nwritten;
 	NTSTATUS status;
 	uint32_t flags;
 
@@ -1481,35 +1428,30 @@ NTSTATUS ctdbd_parse(struct ctdbd_connection *conn, uint32_t db_id,
 	req.db_id            = db_id;
 	req.keylen           = key.dsize;
 
-	status = ctdb_packet_send(
-		conn->pkt, 2,
-		data_blob_const(&req, offsetof(struct ctdb_req_call, data)),
-		data_blob_const(key.dptr, key.dsize));
+	iov[0].iov_base = &req;
+	iov[0].iov_len = offsetof(struct ctdb_req_call, data);
+	iov[1].iov_base = key.dptr;
+	iov[1].iov_len = key.dsize;
 
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(3, ("ctdb_packet_send failed: %s\n", nt_errstr(status)));
-		return status;
-	}
-
-	status = ctdb_packet_flush(conn->pkt);
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status)));
-		cluster_fatal("cluster dispatch daemon control write error\n");
+	nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
+	if (nwritten == -1) {
+		DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
+		cluster_fatal("cluster dispatch daemon msg write error\n");
 	}
 
-	status = ctdb_read_req(conn, req.hdr.reqid, NULL, (void *)&reply);
+	status = ctdb_read_req(conn, req.hdr.reqid, NULL, &hdr);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("ctdb_read_req failed: %s\n", nt_errstr(status)));
 		goto fail;
 	}
 
-	if (reply->hdr.operation != CTDB_REPLY_CALL) {
+	if (hdr->operation != CTDB_REPLY_CALL) {
 		DEBUG(0, ("received invalid reply\n"));
 		status = NT_STATUS_INTERNAL_ERROR;
 		goto fail;
 	}
+	reply = (struct ctdb_reply_call *)hdr;
 
 	if (reply->datalen == 0) {
 		/*
@@ -1524,72 +1466,10 @@ NTSTATUS ctdbd_parse(struct ctdbd_connection *conn, uint32_t db_id,
 
 	status = NT_STATUS_OK;
  fail:
-	TALLOC_FREE(reply);
+	TALLOC_FREE(hdr);
 	return status;
 }
 
-struct ctdbd_traverse_state {
-	void (*fn)(TDB_DATA key, TDB_DATA data, void *private_data);
-	void *private_data;
-};
-
-/*
- * Handle a traverse record coming in on the ctdbd connection
- */
-
-static NTSTATUS ctdb_traverse_handler(uint8_t *buf, size_t length,
-				      void *private_data)
-{
-	struct ctdbd_traverse_state *state =
-		(struct ctdbd_traverse_state *)private_data;
-
-	struct ctdb_req_message *m;
-	struct ctdb_rec_data *d;
-	TDB_DATA key, data;
-
-	m = (struct ctdb_req_message *)buf;
-
-	if (length < sizeof(*m) || m->hdr.length != length) {
-		DEBUG(0, ("Got invalid message of length %d\n", (int)length));
-		TALLOC_FREE(buf);
-		return NT_STATUS_UNEXPECTED_IO_ERROR;
-	}
-
-	d = (struct ctdb_rec_data *)&m->data[0];
-	if (m->datalen < sizeof(uint32_t) || m->datalen != d->length) {
-		DEBUG(0, ("Got invalid traverse data of length %d\n",
-			  (int)m->datalen));
-		TALLOC_FREE(buf);
-		return NT_STATUS_UNEXPECTED_IO_ERROR;
-	}
-
-	key.dsize = d->keylen;
-	key.dptr  = &d->data[0];
-	data.dsize = d->datalen;
-	data.dptr = &d->data[d->keylen];		
-
-	if (key.dsize == 0 && data.dsize == 0) {
-		/* end of traverse */
-		return NT_STATUS_END_OF_FILE;
-	}
-
-	if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
-		DEBUG(0, ("Got invalid ltdb header length %d\n",
-			  (int)data.dsize));
-		TALLOC_FREE(buf);
-		return NT_STATUS_UNEXPECTED_IO_ERROR;
-	}
-	data.dsize -= sizeof(struct ctdb_ltdb_header);
-	data.dptr += sizeof(struct ctdb_ltdb_header);
-
-	if (state->fn) {
-		state->fn(key, data, state->private_data);
-	}
-
-	TALLOC_FREE(buf);
-	return NT_STATUS_OK;
-}
-
 /*
   Traverse a ctdb database. This uses a kind-of hackish way to open a second
   connection to ctdbd to avoid the hairy recursive and async problems with
@@ -1604,10 +1484,9 @@ NTSTATUS ctdbd_traverse(uint32_t db_id,
 	struct ctdbd_connection *conn;
 	NTSTATUS status;
 
-	TDB_DATA data;
+	TDB_DATA key, data;
 	struct ctdb_traverse_start t;
 	int cstatus;
-	struct ctdbd_traverse_state state;
 
 	become_root();
 	status = ctdbd_init_connection(NULL, &conn);
@@ -1640,57 +1519,63 @@ NTSTATUS ctdbd_traverse(uint32_t db_id,
 			 */
 			status = NT_STATUS_UNSUCCESSFUL;
 		}
-		goto done;
+		TALLOC_FREE(conn);
+		return status;
 	}
 
-	state.fn = fn;
-	state.private_data = private_data;
-
 	while (True) {
+		struct ctdb_req_header *hdr;
+		struct ctdb_req_message *m;
+		struct ctdb_rec_data *d;
 
-		status = NT_STATUS_OK;
-
-		if (ctdb_packet_handler(conn->pkt, ctdb_req_complete,
-				   ctdb_traverse_handler, &state, &status)) {
-
-			if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) {
-				status = NT_STATUS_OK;
-				break;
-			}
+		status = ctdb_read_packet(conn->fd, conn, &hdr);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("ctdb_read_packet failed: %s\n",
+				  nt_errstr(status)));
+			cluster_fatal("ctdbd died\n");
+		}
 
-			/*
-			 * There might be more in the queue
-			 */
-			continue;
+		if (hdr->operation != CTDB_REQ_MESSAGE) {
+			DEBUG(0, ("Got operation %u, expected a message\n",
+				  (unsigned)hdr->operation));
+			TALLOC_FREE(conn);
+			return NT_STATUS_UNEXPECTED_IO_ERROR;
 		}
 
-		if (!NT_STATUS_IS_OK(status)) {
-			break;
+		m = (struct ctdb_req_message *)hdr;
+		d = (struct ctdb_rec_data *)&m->data[0];
+		if (m->datalen < sizeof(uint32_t) || m->datalen != d->length) {
+			DEBUG(0, ("Got invalid traverse data of length %d\n",
+				  (int)m->datalen));
+			TALLOC_FREE(conn);
+			return NT_STATUS_UNEXPECTED_IO_ERROR;
 		}
 
-		status = ctdb_packet_fd_read_sync(conn->pkt);
+		key.dsize = d->keylen;
+		key.dptr  = &d->data[0];
+		data.dsize = d->datalen;
+		data.dptr = &d->data[d->keylen];
 
-		if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
-			/*
-			 * There might be more in the queue
-			 */
-			continue;
+		if (key.dsize == 0 && data.dsize == 0) {
+			/* end of traverse */
+			TALLOC_FREE(conn);
+			return NT_STATUS_OK;
 		}
 
-		if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) {
-			status = NT_STATUS_OK;
-			break;
+		if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
+			DEBUG(0, ("Got invalid ltdb header length %d\n",
+				  (int)data.dsize));
+			TALLOC_FREE(conn);
+			return NT_STATUS_UNEXPECTED_IO_ERROR;
 		}
+		data.dsize -= sizeof(struct ctdb_ltdb_header);
+		data.dptr += sizeof(struct ctdb_ltdb_header);
 
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("ctdb_packet_fd_read_sync failed: %s\n", nt_errstr(status)));
-			cluster_fatal("ctdbd died\n");
+		if (fn != NULL) {
+			fn(key, data, private_data);
 		}
 	}
-
- done:
-	TALLOC_FREE(conn);
-	return status;
+	return NT_STATUS_OK;
 }
 
 /*
-- 
1.7.9.5


From 3008bcad62f97172eef9b4ce430dbd8213899403 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 27 May 2014 07:50:01 +0000
Subject: [PATCH 07/10] ctdbd_conn: Remove ctdb_packet

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/include/ctdb_packet.h |   85 -------------
 source3/lib/ctdb_packet.c     |  273 -----------------------------------------
 source3/wscript_build         |    1 -
 3 files changed, 359 deletions(-)
 delete mode 100644 source3/include/ctdb_packet.h
 delete mode 100644 source3/lib/ctdb_packet.c

diff --git a/source3/include/ctdb_packet.h b/source3/include/ctdb_packet.h
deleted file mode 100644
index 026b23f..0000000
--- a/source3/include/ctdb_packet.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   CTDB Packet handling
-   Copyright (C) Volker Lendecke 2007
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * A ctdb_packet context is a wrapper around a bidirectional file descriptor,
- * hiding the handling of individual requests.
- */
-
-struct ctdb_packet_context;
-
-/*
- * Initialize a ctdb_packet context. The fd is given to the ctdb_packet context, meaning
- * that it is automatically closed when the ctdb_packet context is freed.
- */
-struct ctdb_packet_context *ctdb_packet_init(TALLOC_CTX *mem_ctx, int fd);
-
-/*
- * Pull data from the fd
- */
-NTSTATUS ctdb_packet_fd_read(struct ctdb_packet_context *ctx);
-
-/*
- * Sync read, wait for the next chunk
- */
-NTSTATUS ctdb_packet_fd_read_sync_timeout(struct ctdb_packet_context *ctx, int timeout);
-
-/*
- * Handle an incoming ctdb_packet:
- * Return False if none is available
- * Otherwise return True and store the callback result in *status
- * Callback must either talloc_move or talloc_free buf
- */
-bool ctdb_packet_handler(struct ctdb_packet_context *ctx,
-		    bool (*full_req)(const uint8_t *buf,
-				     size_t available,
-				     size_t *length,
-				     void *private_data),
-		    NTSTATUS (*callback)(uint8_t *buf, size_t length,
-					 void *private_data),
-		    void *private_data,
-		    NTSTATUS *status);
-
-/*
- * How many bytes of outgoing data do we have pending?
- */
-size_t ctdb_packet_outgoing_bytes(struct ctdb_packet_context *ctx);
-
-/*
- * Push data to the fd
- */
-NTSTATUS ctdb_packet_fd_write(struct ctdb_packet_context *ctx);
-
-/*
- * Sync flush all outgoing bytes
- */
-NTSTATUS ctdb_packet_flush(struct ctdb_packet_context *ctx);
-
-/*
- * Send a list of DATA_BLOBs
- *
- * Example:  ctdb_packet_send(ctx, 2, data_blob_const(&size, sizeof(size)),
- *			 data_blob_const(buf, size));
- */
-NTSTATUS ctdb_packet_send(struct ctdb_packet_context *ctx, int num_blobs, ...);
-
-/*
- * Get the ctdb_packet context's file descriptor
- */
-int ctdb_packet_get_fd(struct ctdb_packet_context *ctx);
diff --git a/source3/lib/ctdb_packet.c b/source3/lib/ctdb_packet.c
deleted file mode 100644
index 5ea1c25..0000000
--- a/source3/lib/ctdb_packet.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   CTDB Packet handling
-   Copyright (C) Volker Lendecke 2007
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "../lib/util/select.h"
-#include "system/filesys.h"
-#include "ctdb_packet.h"
-
-struct ctdb_packet_context {
-	int fd;
-	DATA_BLOB in, out;
-};
-
-/*
- * Close the underlying fd
- */
-static int ctdb_packet_context_destructor(struct ctdb_packet_context *ctx)
-{
-	return close(ctx->fd);
-}
-
-/*
- * Initialize a ctdb_packet context. The fd is given to the ctdb_packet context, meaning
- * that it is automatically closed when the ctdb_packet context is freed.
- */
-struct ctdb_packet_context *ctdb_packet_init(TALLOC_CTX *mem_ctx, int fd)
-{
-	struct ctdb_packet_context *result;
-
-	if (!(result = talloc_zero(mem_ctx, struct ctdb_packet_context))) {
-		return NULL;
-	}
-
-	result->fd = fd;
-	talloc_set_destructor(result, ctdb_packet_context_destructor);
-	return result;
-}
-
-/*
- * Pull data from the fd
- */
-NTSTATUS ctdb_packet_fd_read(struct ctdb_packet_context *ctx)
-{
-	int res, available;
-	size_t new_size;
-	uint8 *in;
-
-	res = ioctl(ctx->fd, FIONREAD, &available);
-
-	if (res == -1) {
-		DEBUG(10, ("ioctl(FIONREAD) failed: %s\n", strerror(errno)));
-		return map_nt_error_from_unix(errno);
-	}
-
-	SMB_ASSERT(available >= 0);
-
-	if (available == 0) {
-		return NT_STATUS_END_OF_FILE;
-	}
-
-	new_size = ctx->in.length + available;
-
-	if (new_size < ctx->in.length) {
-		DEBUG(0, ("integer wrap\n"));
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	if (!(in = talloc_realloc(ctx, ctx->in.data, uint8, new_size))) {
-		DEBUG(10, ("talloc failed\n"));
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	ctx->in.data = in;
-
-	res = recv(ctx->fd, in + ctx->in.length, available, 0);
-
-	if (res < 0) {
-		DEBUG(10, ("recv failed: %s\n", strerror(errno)));
-		return map_nt_error_from_unix(errno);
-	}
-
-	if (res == 0) {
-		return NT_STATUS_END_OF_FILE;
-	}
-
-	ctx->in.length += res;
-
-	return NT_STATUS_OK;
-}
-
-NTSTATUS ctdb_packet_fd_read_sync_timeout(struct ctdb_packet_context *ctx, int timeout)
-{
-	int res, revents;
-
-	res = poll_one_fd(ctx->fd, POLLIN|POLLHUP, timeout, &revents);
-	if (res == 0) {
-		DEBUG(10, ("poll timed out\n"));
-		return NT_STATUS_IO_TIMEOUT;
-	}
-
-	if (res == -1) {
-		DEBUG(10, ("poll returned %s\n", strerror(errno)));
-		return map_nt_error_from_unix(errno);
-	}
-	if ((revents & (POLLIN|POLLHUP|POLLERR)) == 0) {
-		DEBUG(10, ("socket not readable\n"));
-		return NT_STATUS_IO_TIMEOUT;
-	}
-
-	return ctdb_packet_fd_read(ctx);
-}
-
-bool ctdb_packet_handler(struct ctdb_packet_context *ctx,
-		    bool (*full_req)(const uint8_t *buf,
-				     size_t available,
-				     size_t *length,
-				     void *priv),
-		    NTSTATUS (*callback)(uint8_t *buf, size_t length,
-					 void *priv),
-		    void *priv, NTSTATUS *status)
-{
-	size_t length;
-	uint8_t *buf;
-
-	if (!full_req(ctx->in.data, ctx->in.length, &length, priv)) {
-		return False;
-	}
-
-	if (length > ctx->in.length) {
-		*status = NT_STATUS_INTERNAL_ERROR;
-		return true;
-	}
-
-	if (length == ctx->in.length) {
-		buf = ctx->in.data;
-		ctx->in.data = NULL;
-		ctx->in.length = 0;
-	} else {
-		buf = (uint8_t *)talloc_memdup(ctx, ctx->in.data, length);
-		if (buf == NULL) {
-			*status = NT_STATUS_NO_MEMORY;
-			return true;
-		}
-
-		memmove(ctx->in.data, ctx->in.data + length,
-			ctx->in.length - length);
-		ctx->in.length -= length;
-	}
-
-	*status = callback(buf, length, priv);
-	return True;
-}
-
-/*
- * How many bytes of outgoing data do we have pending?
- */
-size_t ctdb_packet_outgoing_bytes(struct ctdb_packet_context *ctx)
-{
-	return ctx->out.length;
-}
-
-/*
- * Push data to the fd
- */
-NTSTATUS ctdb_packet_fd_write(struct ctdb_packet_context *ctx)
-{
-	ssize_t sent;
-
-	sent = sys_send(ctx->fd, ctx->out.data, ctx->out.length, 0);
-
-	if (sent == -1) {
-		DEBUG(0, ("send failed: %s\n", strerror(errno)));
-		return map_nt_error_from_unix(errno);
-	}
-
-	memmove(ctx->out.data, ctx->out.data + sent,
-		ctx->out.length - sent);
-	ctx->out.length -= sent;
-
-	return NT_STATUS_OK;
-}
-
-/*
- * Sync flush all outgoing bytes
- */
-NTSTATUS ctdb_packet_flush(struct ctdb_packet_context *ctx)
-{
-	while (ctx->out.length != 0) {
-		NTSTATUS status = ctdb_packet_fd_write(ctx);
-		if (!NT_STATUS_IS_OK(status)) {
-			return status;
-		}
-	}
-	return NT_STATUS_OK;
-}
-
-/*
- * Send a list of DATA_BLOBs
- *
- * Example:  ctdb_packet_send(ctx, 2, data_blob_const(&size, sizeof(size)),
- *			 data_blob_const(buf, size));
- */
-NTSTATUS ctdb_packet_send(struct ctdb_packet_context *ctx, int num_blobs, ...)
-{
-	va_list ap;
-	int i;
-	size_t len;
-	uint8 *out;
-
-	len = ctx->out.length;
-
-	va_start(ap, num_blobs);
-	for (i=0; i<num_blobs; i++) {
-		size_t tmp;
-		DATA_BLOB blob = va_arg(ap, DATA_BLOB);
-
-		tmp = len + blob.length;
-		if (tmp < len) {
-			DEBUG(0, ("integer overflow\n"));
-			va_end(ap);
-			return NT_STATUS_NO_MEMORY;
-		}
-		len = tmp;
-	}
-	va_end(ap);
-
-	if (len == 0) {
-		return NT_STATUS_OK;
-	}
-
-	if (!(out = talloc_realloc(ctx, ctx->out.data, uint8, len))) {
-		DEBUG(0, ("talloc failed\n"));
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	ctx->out.data = out;
-
-	va_start(ap, num_blobs);
-	for (i=0; i<num_blobs; i++) {
-		DATA_BLOB blob = va_arg(ap, DATA_BLOB);
-
-		memcpy(ctx->out.data+ctx->out.length, blob.data, blob.length);
-		ctx->out.length += blob.length;
-	}
-	va_end(ap);
-
-	SMB_ASSERT(ctx->out.length == len);
-	return NT_STATUS_OK;
-}
-
-/*
- * Get the ctdb_packet context's file descriptor
- */
-int ctdb_packet_get_fd(struct ctdb_packet_context *ctx)
-{
-	return ctx->fd;
-}
diff --git a/source3/wscript_build b/source3/wscript_build
index 38f0d12..d6550b0 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -278,7 +278,6 @@ if bld.CONFIG_GET("CTDB_CFLAGS") and bld.CONFIG_GET("CTDB_INCLUDE"):
                      lib/cluster_support.c
                      lib/dbwrap/dbwrap_ctdb.c
                      lib/messages_ctdbd.c
-                     lib/ctdb_packet.c
                      lib/ctdbd_conn.c
                      lib/ctdb_conn.c
                      torture/test_ctdbconn.c
-- 
1.7.9.5


From 7574068aba38f90f8698036a5b0c6331031cbee8 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 21 Jul 2014 12:35:39 +0000
Subject: [PATCH 08/10] ctdbd_conn: Only poll if there's a timeout

At this point the ctdb socket is blocking, so we can save a syscall when
we wait indefinitely anyway.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/ctdbd_conn.c |   20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 29482a0..3e5e838 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -324,15 +324,17 @@ static NTSTATUS ctdb_read_packet(int fd, TALLOC_CTX *mem_ctx,
 		timeout = -1;
 	}
 
-	ret = poll_one_fd(fd, POLLIN, timeout, &revents);
-	if (ret == -1) {
-		return map_nt_error_from_unix(errno);
-	}
-	if (ret == 0) {
-		return NT_STATUS_IO_TIMEOUT;
-	}
-	if (ret != 1) {
-		return NT_STATUS_UNEXPECTED_IO_ERROR;
+	if (timeout != -1) {
+		ret = poll_one_fd(fd, POLLIN, timeout, &revents);
+		if (ret == -1) {
+			return map_nt_error_from_unix(errno);
+		}
+		if (ret == 0) {
+			return NT_STATUS_IO_TIMEOUT;
+		}
+		if (ret != 1) {
+			return NT_STATUS_UNEXPECTED_IO_ERROR;
+		}
 	}
 
 	status = read_data(fd, (char *)&msglen, sizeof(msglen));
-- 
1.7.9.5


From c527e1726c1b4040ed683e8afcca8c033cf0ffe8 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 9 Jul 2014 14:40:12 +0000
Subject: [PATCH 09/10] messaging3: messaging_array is no longer used

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/librpc/idl/messaging.idl |    5 -----
 1 file changed, 5 deletions(-)

diff --git a/source3/librpc/idl/messaging.idl b/source3/librpc/idl/messaging.idl
index a396b5b..66d4ae5 100644
--- a/source3/librpc/idl/messaging.idl
+++ b/source3/librpc/idl/messaging.idl
@@ -131,9 +131,4 @@ interface messaging
 		server_id src;
 		DATA_BLOB buf;
 	} messaging_rec;
-
-	typedef [public] struct {
-		uint32 num_messages;
-		messaging_rec messages[num_messages];
-	} messaging_array;
 }
-- 
1.7.9.5


From 2cfc3ffc630616c03940c7c4bbe31b9bae00e5c4 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sun, 20 Jul 2014 16:07:44 +0200
Subject: [PATCH 10/10] messaging4: Simplify imessaging_path

Use server_id_str_buf

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source4/lib/messaging/messaging.c |   13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index ffa668a..a67a58a 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -136,15 +136,10 @@ static NTSTATUS irpc_uptime(struct irpc_message *msg,
 */
 static char *imessaging_path(struct imessaging_context *msg, struct server_id server_id)
 {
-	TALLOC_CTX *tmp_ctx = talloc_new(msg);
-	const char *id = server_id_str(tmp_ctx, &server_id);
-	char *s;
-	if (id == NULL) {
-		return NULL;
-	}
-	s = talloc_asprintf(msg, "%s/msg.%s", msg->base_path, id);
-	talloc_steal(s, tmp_ctx);
-	return s;
+	struct server_id_buf buf;
+
+	return talloc_asprintf(msg, "%s/msg.%s", msg->base_path,
+			       server_id_str_buf(server_id, &buf));
 }
 
 /*
-- 
1.7.9.5



More information about the samba-technical mailing list