[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue Dec 12 23:45:05 UTC 2017


The branch, master has been updated
       via  6c9ac73 pthreadpool: Add some asserts
       via  74aa416 pthreadpool: Simplify the logic in add_job a bit
       via  35eb496 smbd: Enable async I/O by default
       via  18c2c59 vfs_aio_fork: Use a shorter random delay
       via  4091179 vfs_aio_fork: Fix vfs_aio_pwrite
       via  c73195e vfs_aio_fork: Fix vfs_aio_pread
       via  f2dcec9 vfs_aio_fork: Fix a crash in aio_fork
       via  d25e6c3 vfs_aio_fork: Drop "volatile" from the mmap area in aio_fork
       via  3190cd1 smbd: Fix async large read
       via  5a48f5b torture: Check messaging_send_all
       via  5f31c91 messaging: Ignore messages from ourselves
       via  a3a4d9c messaging: Don't do self-sends in messaging_send_all
       via  70f9202 Remove unsupported colon from configure msg.
      from  2ab9847 Added smbc_SetLogCallback which lets third party code to capture libsmbclient logs

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 6c9ac731df4099a061789448d19bcc93d25b0107
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 12 13:58:48 2017 +0100

    pthreadpool: Add some asserts
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed Dec 13 00:44:57 CET 2017 on sn-devel-144

commit 74aa416be7805547b4c8227032c24afe114631d9
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 12 13:52:56 2017 +0100

    pthreadpool: Simplify the logic in add_job a bit
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 35eb4962a01c02919226714f7cdd959c923f4045
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Dec 4 15:39:10 2017 +0100

    smbd: Enable async I/O by default
    
    We've had this code in for long enough that we should enable it by default.
    Modern clients do overlapping I/O, we should utilize that if possible.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 18c2c5918e70a5a1eeaf72aa6e6b4cc47334d093
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Dec 11 17:32:40 2017 +0100

    vfs_aio_fork: Use a shorter random delay
    
    Otherwise the rw2 test takes ages for no good reason
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 4091179ca890b095ef17f59b2bf008ae0a13a3bf
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 8 14:07:47 2017 +0100

    vfs_aio_fork: Fix vfs_aio_pwrite
    
    Make the data to write available to the child
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit c73195eff326447d91f7b1cbda94ac2ce00213a1
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 8 14:07:06 2017 +0100

    vfs_aio_fork: Fix vfs_aio_pread
    
    Copy the data that the child read into the caller's buffer. This can't
    have been used in half a decade at least...
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit f2dcec97a897cd54c9d71fcd91e76da518b1e98e
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 7 20:53:18 2017 +0100

    vfs_aio_fork: Fix a crash in aio_fork
    
    Since the introduction of the vfs_aio_fork:erratic_testing_mode this
    crashed reliably, as we had two different structs behind
    SMB_VFS_HANDLE_SET_DATA. I had always believed that due to the fact that
    we have specific aio_fork tests in our autobuild, this would have been
    tested. But it was not, because the share definition missed the the "aio
    read/write size = 1" to actually use the async code in vfs_aio_fork.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit d25e6c3441498f05746a8307d0237fed92aef58c
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 8 14:30:46 2017 +0100

    vfs_aio_fork: Drop "volatile" from the mmap area in aio_fork
    
    We don't do that in tdb either, and the mmap/memcpy prototypes don't
    have it either
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 3190cd15b697c1b14f92fcefc9893e1dc2dbf82a
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 7 18:12:28 2017 +0100

    smbd: Fix async large read
    
    We also do the 128k reads asynchronously, just not the huge 24MB
    ones. smb_setlen does not work well for >64k.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 5a48f5b20f4857673519b0775aee9bdbe2652384
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Dec 11 15:58:26 2017 +0100

    torture: Check messaging_send_all
    
    We must make sure not to receive our own broadcast
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5f31c911d1149a74f942292c623e8b213c587758
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 8 17:21:37 2017 +0100

    messaging: Ignore messages from ourselves
    
    For non-clustered messaging this should have never gone through the socket, we
    should have caught it before in messaging_send_iov_from.
    
    It can come in on a socket from ctdb when broadcasting in clustered mode. There
    ctdb does the broadcasting.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a3a4d9ccc09181885ef0b01db5fc5d306c8c7bf4
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 8 17:18:33 2017 +0100

    messaging: Don't do self-sends in messaging_send_all
    
    This leads to cleanupd doing endless MSG_SMB_UNLOCK calls, as it triggers
    itself in the send_all. This worked correctly before the serverid.tdb removal
    because cleanupd did not register in serverid.tdb (which was a bug, but it
    helped us there).
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 70f92025ae504cda97ff3a130f19035450967836
Author: Zentaro Kavanagh <zentaro at chromium.org>
Date:   Mon Dec 11 12:41:16 2017 -0800

    Remove unsupported colon from configure msg.
    
    - When cross-compiling an answers file must be supplied via
      --cross-compile --cross-answers=<path to answers>.
    - The lines in the answer file have the form;
        Config Msg: Answer
    - The colon is used to delimit the msg and the answer when reading
      the answers file.
    - WAF doesn't support the message containing a colon.
    - It's not possible to override this variable so cross compile fails.
    
    Signed-off-by: Zentaro Kavanagh <zentaro at google.com>
    Reviewed-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 docs-xml/smbdotconf/tuning/aioreadsize.xml  |   4 +-
 docs-xml/smbdotconf/tuning/aiowritesize.xml |   4 +-
 lib/param/loadparm.c                        |   2 +
 lib/pthreadpool/pthreadpool.c               |  46 +++--
 source3/lib/messages.c                      |  10 +
 source3/modules/vfs_aio_fork.c              |  66 ++++---
 source3/param/loadparm.c                    |   4 +-
 source3/selftest/tests.py                   |   1 +
 source3/smbd/aio.c                          |   2 +-
 source3/torture/proto.h                     |   1 +
 source3/torture/test_messaging_send_all.c   | 279 ++++++++++++++++++++++++++++
 source3/torture/torture.c                   |   1 +
 source3/wscript_build                       |   1 +
 wscript_configure_system_mitkrb5            |   2 +-
 14 files changed, 368 insertions(+), 55 deletions(-)
 create mode 100644 source3/torture/test_messaging_send_all.c


Changeset truncated at 500 lines:

diff --git a/docs-xml/smbdotconf/tuning/aioreadsize.xml b/docs-xml/smbdotconf/tuning/aioreadsize.xml
index c6028b8..4785d2a 100644
--- a/docs-xml/smbdotconf/tuning/aioreadsize.xml
+++ b/docs-xml/smbdotconf/tuning/aioreadsize.xml
@@ -13,7 +13,7 @@
   <related>aio write size</related>
 </description>
 
-<value type="default">0</value>
-<value type="example">1<comment>Always do reads asynchronously
+<value type="default">1</value>
+<value type="example">0<comment>Always do reads synchronously
   </comment></value>
 </samba:parameter>
diff --git a/docs-xml/smbdotconf/tuning/aiowritesize.xml b/docs-xml/smbdotconf/tuning/aiowritesize.xml
index 8f42284..1d649fe 100644
--- a/docs-xml/smbdotconf/tuning/aiowritesize.xml
+++ b/docs-xml/smbdotconf/tuning/aiowritesize.xml
@@ -18,7 +18,7 @@
   <related>aio read size</related>
 </description>
 
-<value type="default">0</value>
-<value type="example">1<comment>Always do writes asynchronously
+<value type="default">1</value>
+<value type="example">0<comment>Always do writes synchronously
     </comment></value>
 </samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 73b7901..508fa5a 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2590,6 +2590,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 	lp_ctx->sDefault->force_create_mode = 0000;
 	lp_ctx->sDefault->directory_mask = 0755;
 	lp_ctx->sDefault->force_directory_mode = 0000;
+	lp_ctx->sDefault->aio_read_size = 1;
+	lp_ctx->sDefault->aio_write_size = 1;
 
 	DEBUG(3, ("Initialising global parameters\n"));
 
diff --git a/lib/pthreadpool/pthreadpool.c b/lib/pthreadpool/pthreadpool.c
index b70694a..92a88c9 100644
--- a/lib/pthreadpool/pthreadpool.c
+++ b/lib/pthreadpool/pthreadpool.c
@@ -652,11 +652,13 @@ int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
 	 * Add job to the end of the queue
 	 */
 	if (!pthreadpool_put_job(pool, job_id, fn, private_data)) {
-		pthread_mutex_unlock(&pool->mutex);
+		res = pthread_mutex_unlock(&pool->mutex);
+		assert(res == 0);
 		return ENOMEM;
 	}
 
 	if (pool->num_idle > 0) {
+		int unlock_res;
 		/*
 		 * We have idle threads, wake one.
 		 */
@@ -664,7 +666,8 @@ int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
 		if (res != 0) {
 			pthreadpool_undo_put_job(pool);
 		}
-		pthread_mutex_unlock(&pool->mutex);
+		unlock_res = pthread_mutex_unlock(&pool->mutex);
+		assert(unlock_res == 0);
 		return res;
 	}
 
@@ -673,32 +676,39 @@ int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
 		/*
 		 * No more new threads, we just queue the request
 		 */
-		pthread_mutex_unlock(&pool->mutex);
+		res = pthread_mutex_unlock(&pool->mutex);
+		assert(res == 0);
 		return 0;
 	}
 
 	res = pthreadpool_create_thread(pool);
-	if (res != 0) {
-		if (pool->num_threads == 0) {
-			/*
-			 * No thread could be created to run job,
-			 * fallback to sync call.
-			 */
-			pthreadpool_undo_put_job(pool);
-			pthread_mutex_unlock(&pool->mutex);
-
-			fn(private_data);
-			return pool->signal_fn(job_id, fn, private_data,
-					       pool->signal_fn_private_data);
-		}
+	if (res == 0) {
+		res = pthread_mutex_unlock(&pool->mutex);
+		assert(res == 0);
+		return 0;
+	}
 
+	if (pool->num_threads != 0) {
 		/*
 		 * At least one thread is still available, let
 		 * that one run the queued job.
 		 */
-		res = 0;
+		res = pthread_mutex_unlock(&pool->mutex);
+		assert(res == 0);
+		return 0;
 	}
 
-	pthread_mutex_unlock(&pool->mutex);
+	/*
+	 * No thread could be created to run job, fallback to sync
+	 * call.
+	 */
+	pthreadpool_undo_put_job(pool);
+
+	res = pthread_mutex_unlock(&pool->mutex);
+	assert(res == 0);
+
+	fn(private_data);
+	res = pool->signal_fn(job_id, fn, private_data,
+			      pool->signal_fn_private_data);
 	return res;
 }
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index a0a3f9f..464233f 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -399,6 +399,11 @@ static void messaging_recv_cb(struct tevent_context *ev,
 		  (unsigned)rec.msg_type, rec.buf.length, num_fds,
 		  server_id_str_buf(rec.src, &idbuf));
 
+	if (server_id_same_process(&rec.src, &msg_ctx->id)) {
+		DBG_DEBUG("Ignoring self-send\n");
+		goto close_fail;
+	}
+
 	messaging_dispatch_rec(msg_ctx, ev, &rec);
 	return;
 
@@ -857,6 +862,11 @@ static int send_all_fn(pid_t pid, void *private_data)
 	struct send_all_state *state = private_data;
 	NTSTATUS status;
 
+	if (pid == getpid()) {
+		DBG_DEBUG("Skip ourselves in messaging_send_all\n");
+		return 0;
+	}
+
 	status = messaging_send_buf(state->msg_ctx, pid_to_procid(pid),
 				    state->msg_type, state->buf, state->len);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c
index 8e47531..a0b1429 100644
--- a/source3/modules/vfs_aio_fork.c
+++ b/source3/modules/vfs_aio_fork.c
@@ -41,13 +41,16 @@
 #define MAP_FILE 0
 #endif
 
+struct aio_child_list;
+
 struct aio_fork_config {
 	bool erratic_testing_mode;
+	struct aio_child_list *children;
 };
 
 struct mmap_area {
 	size_t size;
-	volatile void *ptr;
+	void *ptr;
 };
 
 static int mmap_area_destructor(struct mmap_area *area)
@@ -149,11 +152,6 @@ struct aio_child_list {
 	struct tevent_timer *cleanup_event;
 };
 
-static void free_aio_children(void **p)
-{
-	TALLOC_FREE(*p);
-}
-
 static ssize_t read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
 {
 	struct iovec iov[1];
@@ -267,19 +265,19 @@ static void aio_child_cleanup(struct tevent_context *event_ctx,
 
 static struct aio_child_list *init_aio_children(struct vfs_handle_struct *handle)
 {
-	struct aio_child_list *data = NULL;
+	struct aio_fork_config *config;
+	struct aio_child_list *children;
 
-	if (SMB_VFS_HANDLE_TEST_DATA(handle)) {
-		SMB_VFS_HANDLE_GET_DATA(handle, data, struct aio_child_list,
-					return NULL);
-	}
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct aio_fork_config,
+				return NULL);
 
-	if (data == NULL) {
-		data = talloc_zero(NULL, struct aio_child_list);
-		if (data == NULL) {
+	if (config->children == NULL) {
+		config->children = talloc_zero(config, struct aio_child_list);
+		if (config->children == NULL) {
 			return NULL;
 		}
 	}
+	children = config->children;
 
 	/*
 	 * Regardless of whether the child_list had been around or not, make
@@ -287,22 +285,18 @@ static struct aio_child_list *init_aio_children(struct vfs_handle_struct *handle
 	 * delete itself when it finds that no children are around anymore.
 	 */
 
-	if (data->cleanup_event == NULL) {
-		data->cleanup_event = tevent_add_timer(server_event_context(), data,
-						      timeval_current_ofs(30, 0),
-						      aio_child_cleanup, data);
-		if (data->cleanup_event == NULL) {
-			TALLOC_FREE(data);
+	if (children->cleanup_event == NULL) {
+		children->cleanup_event =
+			tevent_add_timer(server_event_context(), children,
+					 timeval_current_ofs(30, 0),
+					 aio_child_cleanup, children);
+		if (children->cleanup_event == NULL) {
+			TALLOC_FREE(config->children);
 			return NULL;
 		}
 	}
 
-	if (!SMB_VFS_HANDLE_TEST_DATA(handle)) {
-		SMB_VFS_HANDLE_SET_DATA(handle, data, free_aio_children,
-					struct aio_child_list, return False);
-	}
-
-	return data;
+	return children;
 }
 
 static void aio_child_loop(int sockfd, struct mmap_area *map)
@@ -337,7 +331,7 @@ static void aio_child_loop(int sockfd, struct mmap_area *map)
 			 * common parent state
 			 */
 			generate_random_buffer(&randval, sizeof(randval));
-			msecs = randval + 20;
+			msecs = (randval%20)+1;
 			DEBUG(10, ("delaying for %u msecs\n", msecs));
 			smb_msleep(msecs);
 		}
@@ -540,6 +534,8 @@ static int get_idle_child(struct vfs_handle_struct *handle,
 
 struct aio_fork_pread_state {
 	struct aio_child *child;
+	size_t n;
+	void *data;
 	ssize_t ret;
 	struct vfs_aio_state vfs_aio_state;
 };
@@ -568,6 +564,8 @@ static struct tevent_req *aio_fork_pread_send(struct vfs_handle_struct *handle,
 	if (req == NULL) {
 		return NULL;
 	}
+	state->n = n;
+	state->data = data;
 
 	if (n > 128*1024) {
 		/* TODO: support variable buffers */
@@ -635,12 +633,20 @@ static void aio_fork_pread_done(struct tevent_req *subreq)
 		return;
 	}
 
-	state->child->busy = false;
-
 	retbuf = (struct rw_ret *)buf;
 	state->ret = retbuf->size;
 	state->vfs_aio_state.error = retbuf->ret_errno;
 	state->vfs_aio_state.duration = retbuf->duration;
+
+	if ((size_t)state->ret > state->n) {
+		tevent_req_error(req, EIO);
+		state->child->busy = false;
+		return;
+	}
+	memcpy(state->data, state->child->map->ptr, state->ret);
+
+	state->child->busy = false;
+
 	tevent_req_done(req);
 }
 
@@ -697,6 +703,8 @@ static struct tevent_req *aio_fork_pwrite_send(
 		return tevent_req_post(req, ev);
 	}
 
+	memcpy(state->child->map->ptr, data, n);
+
 	ZERO_STRUCT(cmd);
 	cmd.n = n;
 	cmd.offset = offset;
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 01c022e..a34b3db 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -238,8 +238,8 @@ static const struct loadparm_service _sDefault =
 	.acl_group_control = false,
 	.acl_allow_execute_always = false,
 	.allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
-	.aio_read_size = 0,
-	.aio_write_size = 0,
+	.aio_read_size = 1,
+	.aio_write_size = 1,
 	.map_readonly = MAP_READONLY_YES,
 	.directory_name_cache_size = 100,
 	.smb_encrypt = SMB_SIGNING_DEFAULT,
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 1b35768..f8d2a4d 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -147,6 +147,7 @@ local_tests = [
     "LOCAL-MESSAGING-FDPASS2",
     "LOCAL-MESSAGING-FDPASS2a",
     "LOCAL-MESSAGING-FDPASS2b",
+    "LOCAL-MESSAGING-SEND-ALL",
     "LOCAL-PTHREADPOOL-TEVENT",
     "LOCAL-CANONICALIZE-PATH",
     "LOCAL-DBWRAP-WATCH1",
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index d3611ba..4fc1132 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -305,7 +305,7 @@ static void aio_pread_smb1_done(struct tevent_req *req)
 			   (int)aio_ex->nbyte, (int)nread ) );
 
 	}
-	smb_setlen(outbuf, outsize - 4);
+	_smb_setlen_large(outbuf, outsize - 4);
 	show_msg(outbuf);
 	if (!srv_send_smb(aio_ex->smbreq->xconn, outbuf,
 			  true, aio_ex->smbreq->seqnum+1,
diff --git a/source3/torture/proto.h b/source3/torture/proto.h
index 83e0c74..12c76a7 100644
--- a/source3/torture/proto.h
+++ b/source3/torture/proto.h
@@ -124,6 +124,7 @@ bool run_messaging_fdpass1(int dummy);
 bool run_messaging_fdpass2(int dummy);
 bool run_messaging_fdpass2a(int dummy);
 bool run_messaging_fdpass2b(int dummy);
+bool run_messaging_send_all(int dummy);
 bool run_oplock_cancel(int dummy);
 bool run_pthreadpool_tevent(int dummy);
 bool run_g_lock1(int dummy);
diff --git a/source3/torture/test_messaging_send_all.c b/source3/torture/test_messaging_send_all.c
new file mode 100644
index 0000000..8512fa4
--- /dev/null
+++ b/source3/torture/test_messaging_send_all.c
@@ -0,0 +1,279 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Test for a messaging_send_all bug
+ * Copyright (C) Volker Lendecke 2017
+ *
+ * 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 "torture/proto.h"
+#include "lib/util/tevent_unix.h"
+#include "messages.h"
+#include "lib/async_req/async_sock.h"
+#include "lib/util/sys_rw.h"
+
+static pid_t fork_responder(struct messaging_context *msg_ctx,
+			    int exit_pipe[2])
+{
+	struct tevent_context *ev = messaging_tevent_context(msg_ctx);
+	struct tevent_req *req;
+	pid_t child_pid;
+	int ready_pipe[2];
+	char c = 0;
+	bool ok;
+	int ret, err;
+	NTSTATUS status;
+	ssize_t nwritten;
+
+	ret = pipe(ready_pipe);
+	if (ret == -1) {
+		perror("pipe failed");
+		return -1;
+	}
+
+	child_pid = fork();
+	if (child_pid == -1) {
+		perror("fork failed");
+		close(ready_pipe[0]);
+		close(ready_pipe[1]);
+		return -1;
+	}
+
+	if (child_pid != 0) {
+		ssize_t nread;
+		close(ready_pipe[1]);
+		nread = read(ready_pipe[0], &c, 1);
+		close(ready_pipe[0]);
+		if (nread != 1) {
+			perror("read failed");
+			return -1;
+		}
+		return child_pid;
+	}
+
+	close(ready_pipe[0]);
+	close(exit_pipe[1]);
+
+	status = messaging_reinit(msg_ctx);
+	if (!NT_STATUS_IS_OK(status)) {
+		fprintf(stderr, "messaging_reinit failed: %s\n",
+			nt_errstr(status));
+		close(ready_pipe[1]);
+		exit(1);
+	}
+
+	nwritten = sys_write(ready_pipe[1], &c, 1);
+	if (nwritten != 1) {
+		fprintf(stderr, "write failed: %s\n", strerror(errno));
+		exit(1);
+	}
+
+	close(ready_pipe[1]);
+
+	req = wait_for_read_send(ev, ev, exit_pipe[0], false);
+	if (req == NULL) {
+		fprintf(stderr, "wait_for_read_send failed\n");
+		exit(1);
+	}
+
+	ok = tevent_req_poll_unix(req, ev, &err);
+	if (!ok) {
+		fprintf(stderr, "tevent_req_poll_unix failed: %s\n",
+			strerror(err));
+		exit(1);
+	}
+
+	exit(0);
+}
+
+struct messaging_send_all_state {
+	struct tevent_context *ev;
+	struct messaging_context *msg;
+	pid_t *senders;
+	size_t num_received;
+};
+
+static void collect_pong_received(struct tevent_req *subreq);
+
+static struct tevent_req *collect_pong_send(TALLOC_CTX *mem_ctx,
+					    struct tevent_context *ev,
+					    struct messaging_context *msg,
+					    const pid_t *senders,
+					    size_t num_senders)
+{
+	struct tevent_req *req, *subreq;
+	struct messaging_send_all_state *state;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct messaging_send_all_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->senders = talloc_memdup(
+		state, senders, num_senders * sizeof(pid_t));
+	if (tevent_req_nomem(state->senders, req)) {
+		return tevent_req_post(req, ev);
+	}
+	state->ev = ev;
+	state->msg = msg;
+
+	subreq = messaging_read_send(state, state->ev, state->msg, MSG_PONG);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, collect_pong_received, req);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list