[RFC] Simplify async path based VFS functions: remove tevent and pthreadpool_tevent wrappers

Ralph Böhme slow at samba.org
Fri Jan 4 14:06:30 UTC 2019


On Wed, Dec 19, 2018 at 05:00:20PM +0100, Stefan Metzmacher wrote:
>I think this is a good long term goal, but it will take some
>time and might not be completed until we remove support for
>SMB1.

Attached is part1 of the patchset to remove the wrappers. The first commits 
convert SMB_VFS_GETXATTRAT_SEND/RECV() to do explicit impersonation.

The subsequent reverts remove the wrappers from pthreadpool and pthreadpool 
tevent and remove the VFS glue.

The infrastructure to cancel pthreadpool_tevent requests is also removed 
including the atomic syncronisation that was need to implement the 
cancellation. After discussing this with Volker and metze we concluded that the 
assumption is that pthreadpool_tevent will not be cancellable at the lower 
level.

Part2 would be removing the tevent wrapper, but that was already released with 
4.9 is part of the ABI, so I've left that unchanged for now. The tevent wrapper 
doesn't add much complexity to tevent core, so metze and I concluded we can live 
with that for now.

Gitlab CI is broken since some time, so I've run private autobuilds on 
sn-devel. They passed.

Please review part1 and push if happy. Part2 is only included for completeness.

-slow

-- 
Ralph Boehme, Samba Team                https://samba.org/
Samba Developer, SerNet GmbH   https://sernet.de/en/samba/
GPG-Fingerprint   FAE2C6088A24252051C559E4AA1E9B7126399E46
-------------- next part --------------
From b874688e88293e2b25a20161a3840705415ec3be Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 16 Mar 2018 19:01:20 +0100
Subject: [PATCH 01/56] s3:lib: add root_unix_token()

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/include/proto.h |  1 +
 source3/lib/util.c      | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/source3/include/proto.h b/source3/include/proto.h
index d2f9986c244..c085ee4c38c 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -415,6 +415,7 @@ bool map_open_params_to_ntcreate(const char *smb_base_fname,
 				 uint32_t *pcreate_options,
 				 uint32_t *pprivate_flags);
 struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok);
+struct security_unix_token *root_unix_token(TALLOC_CTX *mem_ctx);
 bool dir_check_ftype(uint32_t mode, uint32_t dirtype);
 
 /* The following definitions come from lib/util_builtin.c  */
diff --git a/source3/lib/util.c b/source3/lib/util.c
index a3fe7c8aea2..8ff330bcd26 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -2143,6 +2143,32 @@ struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct securi
 	return cpy;
 }
 
+/****************************************************************************
+ Return a root token
+****************************************************************************/
+
+struct security_unix_token *root_unix_token(TALLOC_CTX *mem_ctx)
+{
+	struct security_unix_token *t = NULL;
+
+	t = talloc_zero(mem_ctx, struct security_unix_token);
+	if (t == NULL) {
+		return NULL;
+	}
+
+	/*
+	 * This is not needed, but lets make it explicit, not implicit.
+	 */
+	*t = (struct security_unix_token) {
+		.uid = 0,
+		.gid = 0,
+		.ngroups = 0,
+		.groups = NULL
+	};
+
+	return t;
+}
+
 /****************************************************************************
  Check that a file matches a particular file type.
 ****************************************************************************/
-- 
2.17.2


From c1a75b8bd54ea81f21c37f23f48e3f40bbdfeca4 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 17:18:09 +0100
Subject: [PATCH 02/56] s3:smbd: add a root unix token to
 smbd_server_connection

This can be used in implementations of async VFS functions, when the
main thread has called become_root() before calling the VFS function,
and the implementation of the VFS functions runs the job in a helper
thread. The helper thread can then reference the root token and pass a
pointer to the helper thread.

This avoids creating a root token from scratch for every such use.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h | 2 ++
 source3/smbd/process.c | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 6ae57184417..3ffd921691f 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -884,6 +884,8 @@ struct smbd_server_connection {
 	struct tevent_context *guest_ev_ctx;
 	struct messaging_context *msg_ctx;
 	struct notify_context *notify_ctx;
+	struct security_unix_token *root_ut;
+
 	bool using_smb2;
 	bool aapl_zero_file_id; /* Apple-specific */
 	int trans_num;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 35b5f4df385..3d823914647 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3969,6 +3969,11 @@ void smbd_process(struct tevent_context *ev_ctx,
 		}
 	}
 
+	sconn->root_ut = root_unix_token(sconn);
+	if (sconn->root_ut == NULL) {
+		exit_server("root_unix_token failed.");
+	}
+
 	if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
 		/*
 		 * We're not making the decision here,
-- 
2.17.2


From bdd6a6f60b063a4dcf684166385314d0231990a7 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 16:32:46 +0100
Subject: [PATCH 03/56] s3:smbd: let SMB_VFS_GETXATTRAT_SEND() do explicit
 impersonation

SMB_VFS_GETXATTRAT_SEND() gets passed a raw event context and the
default implementation uses that as well a raw threadpool. Impersonation
is done explicitly instead of by the tevent and pthreadpool wrappers.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c            |   3 +-
 examples/VFS/skel_transparent.c       |   5 +-
 source3/include/vfs.h                 |   6 +-
 source3/include/vfs_macros.h          |   8 +-
 source3/modules/vfs_default.c         | 106 ++++++++++++++++++++------
 source3/modules/vfs_full_audit.c      |   5 +-
 source3/modules/vfs_not_implemented.c |   3 +-
 source3/modules/vfs_time_audit.c      |   5 +-
 source3/modules/vfs_xattr_tdb.c       |   3 +-
 source3/smbd/smb2_query_directory.c   |   9 ++-
 source3/smbd/vfs.c                    |  17 ++---
 11 files changed, 107 insertions(+), 63 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 054de50197e..b3cd83a3e42 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -873,14 +873,13 @@ struct skel_getxattrat_state {
 
 static struct tevent_req *skel_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
 			const char *xattr_name,
 			size_t alloc_hint)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct skel_getxattrat_state *state = NULL;
 
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index cff52fa185e..4e978577837 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -1094,14 +1094,13 @@ static void skel_getxattrat_done(struct tevent_req *subreq);
 
 static struct tevent_req *skel_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
 			const char *xattr_name,
 			size_t alloc_hint)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct skel_getxattrat_state *state = NULL;
 	struct tevent_req *subreq = NULL;
@@ -1113,7 +1112,7 @@ static struct tevent_req *skel_getxattrat_send(
 	}
 
 	subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
-					      evg,
+					      ev,
 					      handle,
 					      dir_fsp,
 					      smb_fname,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 4f3db694896..83ae6399a4a 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -969,7 +969,7 @@ struct vfs_fn_pointers {
 					size_t size);
 	struct tevent_req *(*getxattrat_send_fn)(
 				TALLOC_CTX *mem_ctx,
-				const struct smb_vfs_ev_glue *evg,
+				struct tevent_context *ev,
 				struct vfs_handle_struct *handle,
 				files_struct *dir_fsp,
 				const struct smb_filename *smb_fname,
@@ -1481,7 +1481,7 @@ ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
 				size_t size);
 struct tevent_req *smb_vfs_call_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
@@ -1910,7 +1910,7 @@ ssize_t vfs_not_implemented_getxattr(vfs_handle_struct *handle,
 				size_t size);
 struct tevent_req *vfs_not_implemented_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index a13680c239e..7a0f14ef08d 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -515,18 +515,18 @@
 #define SMB_VFS_NEXT_GETXATTR(handle,smb_fname,name,value,size) \
 	smb_vfs_call_getxattr((handle)->next,(smb_fname),(name),(value),(size))
 
-#define SMB_VFS_GETXATTRAT_SEND(mem_ctx,evg,dir_fsp,smb_fname, \
+#define SMB_VFS_GETXATTRAT_SEND(mem_ctx,ev,dir_fsp,smb_fname, \
 				xattr_name, alloc_hint) \
-	smb_vfs_call_getxattrat_send((mem_ctx),(evg), \
+	smb_vfs_call_getxattrat_send((mem_ctx),(ev), \
 				     (dir_fsp)->conn->vfs_handles, \
 				     (dir_fsp),(smb_fname),(xattr_name), \
 				     (alloc_hint))
 #define SMB_VFS_GETXATTRAT_RECV(req, aio_state, mem_ctx, xattr_value) \
 	smb_vfs_call_getxattrat_recv((req),(aio_state),(mem_ctx),(xattr_value))
 
-#define SMB_VFS_NEXT_GETXATTRAT_SEND(mem_ctx,evg,handle,dir_fsp,smb_fname, \
+#define SMB_VFS_NEXT_GETXATTRAT_SEND(mem_ctx,ev,handle,dir_fsp,smb_fname, \
 				     xattr_name,alloc_hint) \
-	smb_vfs_call_getxattrat_send((mem_ctx),(evg), \
+	smb_vfs_call_getxattrat_send((mem_ctx),(ev), \
 				     (handle)->next, \
 				     (dir_fsp), (smb_fname),(xattr_name), \
 				     (alloc_hint))
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index b1c4acc482d..e5eda8c94c5 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1493,7 +1493,7 @@ struct vfswrap_get_dos_attributes_state {
 	struct vfs_aio_state aio_state;
 	connection_struct *conn;
 	TALLOC_CTX *mem_ctx;
-	const struct smb_vfs_ev_glue *evg;
+	struct tevent_context *ev;
 	files_struct *dir_fsp;
 	struct smb_filename *smb_fname;
 	uint32_t dosmode;
@@ -1509,7 +1509,7 @@ static struct tevent_req *vfswrap_get_dos_attributes_send(
 			files_struct *dir_fsp,
 			struct smb_filename *smb_fname)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
+	struct tevent_context *ev = dir_fsp->conn->sconn->raw_ev_ctx;
 	struct tevent_req *req = NULL;
 	struct tevent_req *subreq = NULL;
 	struct vfswrap_get_dos_attributes_state *state = NULL;
@@ -1523,13 +1523,13 @@ static struct tevent_req *vfswrap_get_dos_attributes_send(
 	*state = (struct vfswrap_get_dos_attributes_state) {
 		.conn = dir_fsp->conn,
 		.mem_ctx = mem_ctx,
-		.evg = evg,
+		.ev = ev,
 		.dir_fsp = dir_fsp,
 		.smb_fname = smb_fname,
 	};
 
 	subreq = SMB_VFS_GETXATTRAT_SEND(state,
-					 evg,
+					 ev,
 					 dir_fsp,
 					 smb_fname,
 					 SAMBA_XATTR_DOS_ATTRIB,
@@ -1562,8 +1562,6 @@ static void vfswrap_get_dos_attributes_getxattr_done(struct tevent_req *subreq)
 					     &blob.data);
 	TALLOC_FREE(subreq);
 	if (xattr_size == -1) {
-		const struct smb_vfs_ev_glue *root_evg = NULL;
-
 		status = map_nt_error_from_unix(state->aio_state.error);
 
 		if (state->as_root) {
@@ -1576,14 +1574,15 @@ static void vfswrap_get_dos_attributes_getxattr_done(struct tevent_req *subreq)
 		}
 
 		state->as_root = true;
-		root_evg = smb_vfs_ev_glue_get_root_glue(state->evg);
 
+		become_root();
 		subreq = SMB_VFS_GETXATTRAT_SEND(state,
-						 root_evg,
+						 state->ev,
 						 state->dir_fsp,
 						 state->smb_fname,
 						 SAMBA_XATTR_DOS_ATTRIB,
 						 sizeof(fstring));
+		unbecome_root();
 		if (tevent_req_nomem(subreq, req)) {
 			return;
 		}
@@ -2903,12 +2902,14 @@ static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,
 }
 
 struct vfswrap_getxattrat_state {
-	int dirfd;
+	bool do_async;
+	files_struct *dir_fsp;
 	char *name;
 	size_t xattr_bufsize;
 	const char *xattr_name;
 	ssize_t xattr_size;
 	uint8_t *xattr_value;
+	struct security_unix_token *token;
 
 	struct vfs_aio_state vfs_aio_state;
 	SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes);
@@ -2925,18 +2926,19 @@ static void vfswrap_getxattrat_done(struct tevent_req *subreq);
 
 static struct tevent_req *vfswrap_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
 			const char *xattr_name,
 			size_t alloc_hint)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
-	struct pthreadpool_tevent *tp = smb_vfs_ev_glue_tp_chdir_safe(evg);
 	struct tevent_req *req = NULL;
 	struct tevent_req *subreq = NULL;
 	struct vfswrap_getxattrat_state *state = NULL;
+	bool have_per_thread_cwd = false;
+	bool have_per_thread_creds = false;
+	int ret;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct vfswrap_getxattrat_state);
@@ -2944,14 +2946,24 @@ static struct tevent_req *vfswrap_getxattrat_send(
 		return NULL;
 	}
 	*state = (struct vfswrap_getxattrat_state) {
-		.dirfd = dir_fsp->fh->fd,
+		.dir_fsp = dir_fsp,
 		.xattr_bufsize = alloc_hint,
 	};
 
+#ifdef HAVE_UNSHARE_CLONE_FS
+	have_per_thread_cwd = true;
+#endif
+#ifdef HAVE_LINUX_THREAD_CREDENTIALS
+	have_per_thread_creds = true;
+#endif
+	if (have_per_thread_cwd && have_per_thread_creds) {
+		state->do_async = true;
+	}
+
 	SMBPROFILE_BYTES_ASYNC_START(syscall_asys_getxattrat, profile_p,
 				     state->profile_bytes, 0);
 
-	if (state->dirfd == -1) {
+	if (dir_fsp->fh->fd == -1) {
 		DBG_ERR("Need a valid directory fd\n");
 		tevent_req_error(req, EINVAL);
 		return tevent_req_post(req, ev);
@@ -2983,13 +2995,38 @@ static struct tevent_req *vfswrap_getxattrat_send(
 		}
 	}
 
+	if (!state->do_async) {
+		ret = getxattr(state->name,
+			       state->xattr_name,
+			       state->xattr_value,
+			       alloc_hint);
+		if (ret == -1) {
+			tevent_req_error(req, errno);
+			return tevent_req_post(req, ev);
+		}
+
+		tevent_req_done(req);
+		return tevent_req_post(req, ev);
+	}
+
+	if (geteuid() == sec_initial_uid()) {
+		state->token = dir_fsp->conn->sconn->root_ut;
+	} else {
+		state->token = dir_fsp->conn->session_info->unix_token;
+	}
+	state->token = talloc_reference(state, state->token);
+	if (tevent_req_nomem(state->token, req)) {
+		return tevent_req_post(req, ev);
+	}
+
 	SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
 
-	subreq = pthreadpool_tevent_job_send(state,
-					     ev,
-					     tp,
-					     vfswrap_getxattrat_do,
-					     state);
+	subreq = pthreadpool_tevent_job_send(
+			state,
+			ev,
+			dir_fsp->conn->sconn->raw_thread_pool,
+			vfswrap_getxattrat_do,
+			state);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -3014,14 +3051,20 @@ static void vfswrap_getxattrat_do(void *private_data)
 	/*
 	 * Here we simulate a getxattrat()
 	 * call using fchdir();getxattr()
-	 *
-	 * We don't need to revert the directory
-	 * change as pthreadpool_tevent wrapper
-	 * handlers that.
 	 */
-	SMB_ASSERT(pthreadpool_tevent_current_job_per_thread_cwd());
 
-	ret = fchdir(state->dirfd);
+	/* Become the correct credential on this thread. */
+	ret = set_thread_credentials(state->token->uid,
+				     state->token->gid,
+				     (size_t)state->token->ngroups,
+				     state->token->groups);
+	if (ret != 0) {
+		state->xattr_size = -1;
+		state->vfs_aio_state.error = errno;
+		goto end_profile;
+	}
+
+	ret = fchdir(state->dir_fsp->fh->fd);
 	if (ret == -1) {
 		state->xattr_size = -1;
 		state->vfs_aio_state.error = errno;
@@ -3049,6 +3092,19 @@ static void vfswrap_getxattrat_done(struct tevent_req *subreq)
 	struct vfswrap_getxattrat_state *state = tevent_req_data(
 		req, struct vfswrap_getxattrat_state);
 	int ret;
+	bool ok;
+
+	if (state->do_async) {
+		/*
+		 * Make sure we run as the user again
+		 */
+		ok = change_to_user(state->dir_fsp->conn,
+				    state->dir_fsp->vuid);
+		if (!ok) {
+			smb_panic("Can't change to user");
+			return;
+		}
+	}
 
 	ret = pthreadpool_tevent_job_recv(subreq);
 	TALLOC_FREE(subreq);
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index bae08102b0e..7dbb6e1e628 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2523,14 +2523,13 @@ static void smb_full_audit_getxattrat_done(struct tevent_req *subreq);
 
 static struct tevent_req *smb_full_audit_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
 			const char *xattr_name,
 			size_t alloc_hint)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct tevent_req *subreq = NULL;
 	struct smb_full_audit_getxattrat_state *state = NULL;
@@ -2555,7 +2554,7 @@ static struct tevent_req *smb_full_audit_getxattrat_send(
 	};
 
 	subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
-					      evg,
+					      ev,
 					      handle,
 					      dir_fsp,
 					      smb_fname,
diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c
index e20b7eb76ed..d642a133c18 100644
--- a/source3/modules/vfs_not_implemented.c
+++ b/source3/modules/vfs_not_implemented.c
@@ -877,14 +877,13 @@ struct vfs_not_implemented_getxattrat_state {
 
 struct tevent_req *vfs_not_implemented_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
 			const char *xattr_name,
 			size_t alloc_hint)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct vfs_not_implemented_getxattrat_state *state = NULL;
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index aefea33d305..5dd6032b658 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -2456,14 +2456,13 @@ static void smb_time_audit_getxattrat_done(struct tevent_req *subreq);
 
 static struct tevent_req *smb_time_audit_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
 			const char *xattr_name,
 			size_t alloc_hint)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct tevent_req *subreq = NULL;
 	struct smb_time_audit_getxattrat_state *state = NULL;
@@ -2480,7 +2479,7 @@ static struct tevent_req *smb_time_audit_getxattrat_send(
 	};
 
 	subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
-					      evg,
+					      ev,
 					      handle,
 					      dir_fsp,
 					      smb_fname,
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
index 32968ae083f..037c4045632 100644
--- a/source3/modules/vfs_xattr_tdb.c
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -112,14 +112,13 @@ struct xattr_tdb_getxattrat_state {
 
 static struct tevent_req *xattr_tdb_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
 			const char *xattr_name,
 			size_t alloc_hint)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct xattr_tdb_getxattrat_state *state = NULL;
 	struct smb_filename *cwd = NULL;
diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c
index 68c00241a51..7efbeca8b7d 100644
--- a/source3/smbd/smb2_query_directory.c
+++ b/source3/smbd/smb2_query_directory.c
@@ -240,7 +240,6 @@ struct smbd_smb2_query_directory_state {
 	bool async_dosmode;
 	bool async_ask_sharemode;
 	int last_entry_off;
-	struct pthreadpool_tevent *tp_chdir_safe;
 	size_t max_async_dosmode_active;
 	uint32_t async_dosmode_active;
 	bool done;
@@ -279,7 +278,6 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
 	}
 	state->evg = conn->user_vfs_evg;
 	state->ev = ev;
-	state->tp_chdir_safe = smb_vfs_ev_glue_tp_chdir_safe(state->evg);
 	state->fsp = fsp;
 	state->smb2req = smb2req;
 	state->in_output_buffer_length = in_output_buffer_length;
@@ -519,13 +517,16 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
 	if (state->async_dosmode) {
 		size_t max_threads;
 
-		max_threads = pthreadpool_tevent_max_threads(state->tp_chdir_safe);
+		max_threads = pthreadpool_tevent_max_threads(conn->sconn->raw_thread_pool);
 
 		state->max_async_dosmode_active = lp_smbd_max_async_dosmode(
 							SNUM(conn));
 		if (state->max_async_dosmode_active == 0) {
 			state->max_async_dosmode_active = max_threads * 2;
 		}
+		if (!pthreadpool_tevent_per_thread_cwd(conn->sconn->raw_thread_pool)) {
+			state->max_async_dosmode_active = 1;
+		}
 	}
 
 	if (state->async_dosmode || state->async_ask_sharemode) {
@@ -664,7 +665,7 @@ static bool smb2_query_directory_next_entry(struct tevent_req *req)
 		state->async_dosmode_active++;
 
 		outstanding_aio = pthreadpool_tevent_queued_jobs(
-					state->tp_chdir_safe);
+					state->fsp->conn->sconn->raw_thread_pool);
 
 		if (outstanding_aio > state->max_async_dosmode_active) {
 			stop = true;
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 351cd0a5567..7d46ec9273b 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -3539,7 +3539,7 @@ static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
 
 struct tevent_req *smb_vfs_call_getxattrat_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			const struct smb_filename *smb_fname,
@@ -3549,7 +3549,6 @@ struct tevent_req *smb_vfs_call_getxattrat_send(
 	struct tevent_req *req = NULL;
 	struct smb_vfs_call_getxattrat_state *state = NULL;
 	struct tevent_req *subreq = NULL;
-	bool ok;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smb_vfs_call_getxattrat_state);
@@ -3560,24 +3559,18 @@ struct tevent_req *smb_vfs_call_getxattrat_send(
 	VFS_FIND(getxattrat_send);
 	state->recv_fn = handle->fns->getxattrat_recv_fn;
 
-	ok = smb_vfs_ev_glue_push_use(evg, req);
-	if (!ok) {
-		tevent_req_error(req, EIO);
-		return tevent_req_post(req, evg->return_ev);
-	}
-
 	subreq = handle->fns->getxattrat_send_fn(mem_ctx,
-						 evg->next_glue,
+						 ev,
 						 handle,
 						 dir_fsp,
 						 smb_fname,
 						 xattr_name,
 						 alloc_hint);
-	smb_vfs_ev_glue_pop_use(evg);
-
 	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, evg->return_ev);
+		return tevent_req_post(req, ev);
 	}
+	tevent_req_defer_callback(req, ev);
+
 	tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
 	return req;
 }
-- 
2.17.2


From a8540281c689cc8961e1d4b9a76ee28b5d9db8d7 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 28 Dec 2018 12:12:20 +0100
Subject: [PATCH 04/56] s3:smbd: pass (raw) ev to
 SMB_VFS_GET_DOS_ATTRIBUTES_SEND() instead of smb_vfs_ev_glue

This also removes smb_vfs_ev_glue_[push|pop]_use() as the only caller
got removed.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c            |  3 +-
 examples/VFS/skel_transparent.c       |  5 +--
 source3/include/vfs.h                 |  6 +--
 source3/modules/vfs_default.c         |  3 +-
 source3/modules/vfs_full_audit.c      |  5 +--
 source3/modules/vfs_not_implemented.c |  3 +-
 source3/modules/vfs_time_audit.c      |  5 +--
 source3/smbd/dosmode.c                |  5 ++-
 source3/smbd/vfs.c                    | 57 +++------------------------
 9 files changed, 20 insertions(+), 72 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index b3cd83a3e42..6510ef30d6f 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -714,12 +714,11 @@ struct skel_get_dos_attributes_state {
 
 static struct tevent_req *skel_get_dos_attributes_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			struct smb_filename *smb_fname)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct skel_get_dos_attributes_state *state = NULL;
 
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 4e978577837..fc892a23208 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -895,12 +895,11 @@ static void skel_get_dos_attributes_done(struct tevent_req *subreq);
 
 static struct tevent_req *skel_get_dos_attributes_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			struct smb_filename *smb_fname)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct skel_get_dos_attributes_state *state = NULL;
 	struct tevent_req *subreq = NULL;
@@ -912,7 +911,7 @@ static struct tevent_req *skel_get_dos_attributes_send(
 	}
 
 	subreq = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_SEND(mem_ctx,
-						      evg,
+						      ev,
 						      handle,
 						      dir_fsp,
 						      smb_fname);
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 83ae6399a4a..619c1a8eb94 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -903,7 +903,7 @@ struct vfs_fn_pointers {
 
 	struct tevent_req *(*get_dos_attributes_send_fn)(
 				TALLOC_CTX *mem_ctx,
-				const struct smb_vfs_ev_glue *evg,
+				struct tevent_context *ev,
 				struct vfs_handle_struct *handle,
 				files_struct *dir_fsp,
 				struct smb_filename *smb_fname);
@@ -1370,7 +1370,7 @@ NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
 					  uint32_t dosmode);
 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			struct smb_filename *smb_fname);
@@ -1852,7 +1852,7 @@ NTSTATUS vfs_not_implemented_get_dos_attributes(struct vfs_handle_struct *handle
 						uint32_t *dosmode);
 struct tevent_req *vfs_not_implemented_get_dos_attributes_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			struct smb_filename *smb_fname);
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index e5eda8c94c5..6a8245b3942 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1504,12 +1504,11 @@ static void vfswrap_get_dos_attributes_getxattr_done(struct tevent_req *subreq);
 
 static struct tevent_req *vfswrap_get_dos_attributes_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			struct smb_filename *smb_fname)
 {
-	struct tevent_context *ev = dir_fsp->conn->sconn->raw_ev_ctx;
 	struct tevent_req *req = NULL;
 	struct tevent_req *subreq = NULL;
 	struct vfswrap_get_dos_attributes_state *state = NULL;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 7dbb6e1e628..fcfb024d493 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2141,12 +2141,11 @@ static void smb_full_audit_get_dos_attributes_done(struct tevent_req *subreq);
 
 static struct tevent_req *smb_full_audit_get_dos_attributes_send(
 		TALLOC_CTX *mem_ctx,
-		const struct smb_vfs_ev_glue *evg,
+		struct tevent_context *ev,
 		struct vfs_handle_struct *handle,
 		files_struct *dir_fsp,
 		struct smb_filename *smb_fname)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct smb_full_audit_get_dos_attributes_state *state = NULL;
 	struct tevent_req *subreq = NULL;
@@ -2169,7 +2168,7 @@ static struct tevent_req *smb_full_audit_get_dos_attributes_send(
 	};
 
 	subreq = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_SEND(mem_ctx,
-						      evg,
+						      ev,
 						      handle,
 						      dir_fsp,
 						      smb_fname);
diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c
index d642a133c18..214390204a5 100644
--- a/source3/modules/vfs_not_implemented.c
+++ b/source3/modules/vfs_not_implemented.c
@@ -717,12 +717,11 @@ struct vfs_not_implemented_get_dos_attributes_state {
 
 struct tevent_req *vfs_not_implemented_get_dos_attributes_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			struct smb_filename *smb_fname)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct vfs_not_implemented_get_dos_attributes_state *state = NULL;
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 5dd6032b658..a89c6be9f71 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -1768,12 +1768,11 @@ static void smb_time_audit_get_dos_attributes_done(struct tevent_req *subreq);
 
 static struct tevent_req *smb_time_audit_get_dos_attributes_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			struct smb_filename *smb_fname)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
 	struct tevent_req *req = NULL;
 	struct smb_time_audit_get_dos_attributes_state *state = NULL;
 	struct tevent_req *subreq = NULL;
@@ -1789,7 +1788,7 @@ static struct tevent_req *smb_time_audit_get_dos_attributes_send(
 	};
 
 	subreq = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_SEND(mem_ctx,
-						      evg,
+						      ev,
 						      handle,
 						      dir_fsp,
 						      smb_fname);
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 966679a2c9c..52781ca5ab3 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -19,6 +19,7 @@
 */
 
 #include "includes.h"
+#include "globals.h"
 #include "system/filesys.h"
 #include "librpc/gen_ndr/ndr_xattr.h"
 #include "librpc/gen_ndr/ioctl.h"
@@ -764,7 +765,7 @@ struct tevent_req *dos_mode_at_send(TALLOC_CTX *mem_ctx,
 				    files_struct *dir_fsp,
 				    struct smb_filename *smb_fname)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
+	struct tevent_context *ev = dir_fsp->conn->sconn->raw_ev_ctx;
 	struct tevent_req *req = NULL;
 	struct dos_mode_at_state *state = NULL;
 	struct tevent_req *subreq = NULL;
@@ -788,7 +789,7 @@ struct tevent_req *dos_mode_at_send(TALLOC_CTX *mem_ctx,
 	}
 
 	subreq = SMB_VFS_GET_DOS_ATTRIBUTES_SEND(state,
-						 evg,
+						 ev,
 						 dir_fsp,
 						 smb_fname);
 	if (tevent_req_nomem(subreq, req)) {
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 7d46ec9273b..0cf8f8caa1d 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2284,46 +2284,6 @@ struct smb_vfs_ev_glue *smb_vfs_ev_glue_create_switch(
 	return evg_u;
 }
 
-static bool smb_vfs_ev_glue_push_use(const struct smb_vfs_ev_glue *evg,
-				     struct tevent_req *req)
-{
-	if (evg->run_ev == evg->return_ev) {
-		/*
-		 * We're already in the correct
-		 * impersonation environment.
-		 */
-		return true;
-	}
-
-	/*
-	 * Make sure that our callers callback function
-	 * will be called in the return_ev environment.
-	 */
-	tevent_req_defer_callback(req, evg->return_ev);
-
-	/*
-	 * let the event context wrapper do
-	 * the required impersonation.
-	 */
-	return tevent_context_push_use(evg->run_ev);
-}
-
-static void smb_vfs_ev_glue_pop_use(const struct smb_vfs_ev_glue *evg)
-{
-	if (evg->run_ev == evg->return_ev) {
-		/*
-		 * smb_vfs_ev_glue_push_use() didn't
-		 * change the impersonation environment.
-		 */
-		return;
-	}
-
-	/*
-	 * undo the impersonation
-	 */
-	tevent_context_pop_use(evg->run_ev);
-}
-
 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
 			 const char *service, const char *user)
 {
@@ -3265,7 +3225,7 @@ static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
 
 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
 			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct vfs_handle_struct *handle,
 			files_struct *dir_fsp,
 			struct smb_filename *smb_fname)
@@ -3273,7 +3233,6 @@ struct tevent_req *smb_vfs_call_get_dos_attributes_send(
 	struct tevent_req *req = NULL;
 	struct smb_vfs_call_get_dos_attributes_state *state = NULL;
 	struct tevent_req *subreq = NULL;
-	bool ok;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smb_vfs_call_get_dos_attributes_state);
@@ -3284,22 +3243,16 @@ struct tevent_req *smb_vfs_call_get_dos_attributes_send(
 	VFS_FIND(get_dos_attributes_send);
 	state->recv_fn = handle->fns->get_dos_attributes_recv_fn;
 
-	ok = smb_vfs_ev_glue_push_use(evg, req);
-	if (!ok) {
-		tevent_req_error(req, EIO);
-		return tevent_req_post(req, evg->return_ev);
-	}
-
 	subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
-							 evg->next_glue,
+							 ev,
 							 handle,
 							 dir_fsp,
 							 smb_fname);
-	smb_vfs_ev_glue_pop_use(evg);
-
 	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, evg->return_ev);
+		return tevent_req_post(req, ev);
 	}
+	tevent_req_defer_callback(req, ev);
+
 	tevent_req_set_callback(subreq,
 				smb_vfs_call_get_dos_attributes_done,
 				req);
-- 
2.17.2


From bae07c0cc5cbf00b2730bb527cb637b1e9517dd0 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 28 Dec 2018 12:16:27 +0100
Subject: [PATCH 05/56] s3:smbd: pass (raw) ev to dos_mode_at_send() instead of
 smb_vfs_ev_glue

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/dosmode.c              | 3 +--
 source3/smbd/proto.h                | 2 +-
 source3/smbd/smb2_query_directory.c | 4 ++--
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 52781ca5ab3..177fe68c894 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -761,11 +761,10 @@ struct dos_mode_at_state {
 static void dos_mode_at_vfs_get_dosmode_done(struct tevent_req *subreq);
 
 struct tevent_req *dos_mode_at_send(TALLOC_CTX *mem_ctx,
-				    struct smb_vfs_ev_glue *evg,
+				    struct tevent_context *ev,
 				    files_struct *dir_fsp,
 				    struct smb_filename *smb_fname)
 {
-	struct tevent_context *ev = dir_fsp->conn->sconn->raw_ev_ctx;
 	struct tevent_req *req = NULL;
 	struct dos_mode_at_state *state = NULL;
 	struct tevent_req *subreq = NULL;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index a74a79f7569..2a56c1e4346 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -264,7 +264,7 @@ uint32_t dos_mode_msdfs(connection_struct *conn,
 		      const struct smb_filename *smb_fname);
 uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname);
 struct tevent_req *dos_mode_at_send(TALLOC_CTX *mem_ctx,
-				    struct smb_vfs_ev_glue *evg,
+				    struct tevent_context *ev,
 				    files_struct *dir_fsp,
 				    struct smb_filename *smb_fname);
 NTSTATUS dos_mode_at_recv(struct tevent_req *req, uint32_t *dosmode);
diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c
index 7efbeca8b7d..2c0c82c7a5b 100644
--- a/source3/smbd/smb2_query_directory.c
+++ b/source3/smbd/smb2_query_directory.c
@@ -973,7 +973,7 @@ static struct tevent_req *fetch_dos_mode_send(
 			uint32_t info_level,
 			uint8_t *entry_marshall_buf)
 {
-	struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
+	struct tevent_context *ev = dir_fsp->conn->sconn->raw_ev_ctx;
 	struct tevent_req *req = NULL;
 	struct fetch_dos_mode_state *state = NULL;
 	struct tevent_req *subreq = NULL;
@@ -990,7 +990,7 @@ static struct tevent_req *fetch_dos_mode_send(
 
 	state->smb_fname = talloc_move(state, smb_fname);
 
-	subreq = dos_mode_at_send(state, evg, dir_fsp, state->smb_fname);
+	subreq = dos_mode_at_send(state, ev, dir_fsp, state->smb_fname);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.17.2


From 8507c1be5caf10f61942b18a499203554326491f Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 28 Dec 2018 12:19:08 +0100
Subject: [PATCH 06/56] s3:smbd: pass (raw) ev to fetch_dos_mode_send instead
 of smb_vfs_ev_glue

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smb2_query_directory.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c
index 2c0c82c7a5b..b829888ba45 100644
--- a/source3/smbd/smb2_query_directory.c
+++ b/source3/smbd/smb2_query_directory.c
@@ -208,7 +208,7 @@ static NTSTATUS fetch_write_time_recv(struct tevent_req *req);
 
 static struct tevent_req *fetch_dos_mode_send(
 	TALLOC_CTX *mem_ctx,
-	struct smb_vfs_ev_glue *evg,
+	struct tevent_context *ev,
 	struct files_struct *dir_fsp,
 	struct smb_filename **smb_fname,
 	uint32_t info_level,
@@ -277,7 +277,7 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 	state->evg = conn->user_vfs_evg;
-	state->ev = ev;
+	state->ev = fsp->conn->sconn->raw_ev_ctx;
 	state->fsp = fsp;
 	state->smb2req = smb2req;
 	state->in_output_buffer_length = in_output_buffer_length;
@@ -650,7 +650,7 @@ static bool smb2_query_directory_next_entry(struct tevent_req *req)
 		buf = (uint8_t *)state->base_data + state->last_entry_off;
 
 		subreq = fetch_dos_mode_send(state,
-					     state->evg,
+					     state->ev,
 					     state->fsp,
 					     &smb_fname,
 					     state->info_level,
@@ -967,13 +967,12 @@ static void fetch_dos_mode_done(struct tevent_req *subreq);
 
 static struct tevent_req *fetch_dos_mode_send(
 			TALLOC_CTX *mem_ctx,
-			struct smb_vfs_ev_glue *evg,
+			struct tevent_context *ev,
 			struct files_struct *dir_fsp,
 			struct smb_filename **smb_fname,
 			uint32_t info_level,
 			uint8_t *entry_marshall_buf)
 {
-	struct tevent_context *ev = dir_fsp->conn->sconn->raw_ev_ctx;
 	struct tevent_req *req = NULL;
 	struct fetch_dos_mode_state *state = NULL;
 	struct tevent_req *subreq = NULL;
-- 
2.17.2


From 358b2b008b51db0bec0845d8f596c5487d0d1563 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 28 Dec 2018 13:04:14 +0100
Subject: [PATCH 07/56] s3:smbd: remove unused evg from struct
 smbd_smb2_query_directory_state

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smb2_query_directory.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c
index b829888ba45..782ccb62d8e 100644
--- a/source3/smbd/smb2_query_directory.c
+++ b/source3/smbd/smb2_query_directory.c
@@ -217,7 +217,6 @@ static struct tevent_req *fetch_dos_mode_send(
 static NTSTATUS fetch_dos_mode_recv(struct tevent_req *req);
 
 struct smbd_smb2_query_directory_state {
-	struct smb_vfs_ev_glue *evg;
 	struct tevent_context *ev;
 	struct smbd_smb2_request *smb2req;
 	uint64_t async_sharemode_count;
@@ -276,7 +275,6 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
 	if (req == NULL) {
 		return NULL;
 	}
-	state->evg = conn->user_vfs_evg;
 	state->ev = fsp->conn->sconn->raw_ev_ctx;
 	state->fsp = fsp;
 	state->smb2req = smb2req;
-- 
2.17.2


From 91cbed6b5deef83793ddbcc6bbfbfb659b750ef6 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:12:10 +0100
Subject: [PATCH 08/56] Revert "pthreadpool: reset monitor_fd after calling
 tevent_fd_set_auto_close()"

This reverts commit f68b5ee75f002ed542a8423070fb01e3b0e83f65.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index 12148f18123..7088202d97c 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -719,7 +719,6 @@ static int pthreadpool_tevent_register_ev(
 			return ENOMEM;
 		}
 		tevent_fd_set_auto_close(glue->fde);
-		monitor_fd = -1;
 	}
 
 	/*
-- 
2.17.2


From 47d2da941a39022ba23b0ad84646d10b75c6135d Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:12:34 +0100
Subject: [PATCH 09/56] Revert "pthreadpool: ignore the return value of
 poll(NULL, 0UL, 1)"

This reverts commit 6da0d68f49bbd82f5a08427779c9f5ebd6f755aa.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index 7088202d97c..b4a9786f231 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -873,7 +873,7 @@ static void pthreadpool_tevent_job_orphan(struct pthreadpool_tevent_job *job)
 	 */
 	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
 	while (job->needs_fence.wrapper) {
-		(void)poll(NULL, 0, 1);
+		poll(NULL, 0, 1);
 		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
 	}
 	job->wrapper = NULL;
@@ -903,7 +903,7 @@ static void pthreadpool_tevent_job_orphan(struct pthreadpool_tevent_job *job)
 		if (job->needs_fence.signaled) {
 			break;
 		}
-		(void)poll(NULL, 0, 1);
+		poll(NULL, 0, 1);
 		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
 	}
 
-- 
2.17.2


From 24c822db6f8553c6eb3849377480e2ddce7bdc17 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:23:48 +0100
Subject: [PATCH 10/56] Revert "pthreadpool: we need to use
 pthreadpool_tevent_per_thread_cwd() on the callers pool"

This reverts commit ff863f2d98ac5e12073af824b794404c3d7198c5.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index b4a9786f231..f88f82d17d8 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -992,7 +992,6 @@ struct tevent_req *pthreadpool_tevent_job_send(
 	struct pthreadpool_tevent_job_state *state = NULL;
 	struct pthreadpool_tevent_job *job = NULL;
 	int ret;
-	struct pthreadpool_tevent *caller_pool = pool;
 	struct pthreadpool_tevent_wrapper *wrapper = pool->wrapper.ctx;
 
 	pthreadpool_tevent_cleanup_orphaned_jobs();
@@ -1038,7 +1037,7 @@ struct tevent_req *pthreadpool_tevent_job_send(
 		return tevent_req_post(req, ev);
 	}
 	PTHREAD_TEVENT_JOB_THREAD_FENCE_INIT(job);
-	job->per_thread_cwd = pthreadpool_tevent_per_thread_cwd(caller_pool);
+	job->per_thread_cwd = pthreadpool_tevent_per_thread_cwd(pool);
 	talloc_set_destructor(job, pthreadpool_tevent_job_destructor);
 	DLIST_ADD_END(job->pool->jobs, job);
 	job->state = state;
-- 
2.17.2


From 0ac74e0015a280b8dc93d536123a5c8908fa9e57 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:24:51 +0100
Subject: [PATCH 11/56] Revert "vfs_aio_pthread: use event context and
 threadpool from user_vfs_evg"

This reverts commit cd37badc02b3e56f974168b28447444cd54ee541.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_aio_pthread.c | 40 +++++++++++++++++--------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/source3/modules/vfs_aio_pthread.c b/source3/modules/vfs_aio_pthread.c
index cf5b7f61d5b..da1ca534907 100644
--- a/source3/modules/vfs_aio_pthread.c
+++ b/source3/modules/vfs_aio_pthread.c
@@ -51,6 +51,7 @@ struct aio_open_private_data {
 	const char *fname;
 	char *dname;
 	struct smbd_server_connection *sconn;
+	const struct security_unix_token *ux_tok;
 	uint64_t initial_allocation_size;
 	/* Returns. */
 	int ret_fd;
@@ -139,6 +140,16 @@ static void aio_open_worker(void *private_data)
 	struct aio_open_private_data *opd =
 		(struct aio_open_private_data *)private_data;
 
+	/* Become the correct credential on this thread. */
+	if (set_thread_credentials(opd->ux_tok->uid,
+				opd->ux_tok->gid,
+				(size_t)opd->ux_tok->ngroups,
+				opd->ux_tok->groups) != 0) {
+		opd->ret_fd = -1;
+		opd->ret_errno = errno;
+		return;
+	}
+
 	opd->ret_fd = openat(opd->dir_fd,
 			opd->fname,
 			opd->flags,
@@ -208,6 +219,13 @@ static struct aio_open_private_data *create_private_open_data(const files_struct
 	opd->sconn = fsp->conn->sconn;
 	opd->initial_allocation_size = fsp->initial_allocation_size;
 
+	/* Copy our current credentials. */
+	opd->ux_tok = copy_unix_token(opd, get_current_utok(fsp->conn));
+	if (opd->ux_tok == NULL) {
+		TALLOC_FREE(opd);
+		return NULL;
+	}
+
 	/*
 	 * Copy the parent directory name and the
 	 * relative path within it.
@@ -250,10 +268,6 @@ static int open_async(const files_struct *fsp,
 {
 	struct aio_open_private_data *opd = NULL;
 	struct tevent_req *subreq = NULL;
-	const struct smb_vfs_ev_glue *evg = NULL;
-	struct tevent_context *ev = NULL;
-	struct pthreadpool_tevent *tp = NULL;
-	uid_t uid = -1;
 
 	opd = create_private_open_data(fsp, flags, mode);
 	if (opd == NULL) {
@@ -261,20 +275,10 @@ static int open_async(const files_struct *fsp,
 		return -1;
 	}
 
-	evg = fsp->conn->user_vfs_evg;
-
-	uid = get_current_uid(fsp->conn);
-	if (uid == 0) {
-		/*
-		 * If we're already running as root,
-		 * so the root glue.
-		 */
-		evg = smb_vfs_ev_glue_get_root_glue(evg);
-	}
-	ev = smb_vfs_ev_glue_ev_ctx(fsp->conn->user_vfs_evg);
-	tp = smb_vfs_ev_glue_tp_path_safe(fsp->conn->user_vfs_evg);
-
-	subreq = pthreadpool_tevent_job_send(opd, ev, tp, aio_open_worker, opd);
+	subreq = pthreadpool_tevent_job_send(opd,
+					     fsp->conn->user_ev_ctx,
+					     fsp->conn->sconn->raw_thread_pool,
+					     aio_open_worker, opd);
 	if (subreq == NULL) {
 		return -1;
 	}
-- 
2.17.2


From 232e7c1322e2a8b548ec2f82faaf1d38a893d936 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:25:32 +0100
Subject: [PATCH 12/56] Revert "s3: vfs: add user_vfs_evg to connection_struct"

This reverts commit 2dd95c1c38b9e1ce32d3d1081b6ec177910087a4.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/include/vfs.h          |   3 +-
 source3/modules/vfs_readonly.c |   2 +-
 source3/smbd/conn.c            |   8 +-
 source3/smbd/msdfs.c           |  68 +--
 source3/smbd/proto.h           |  13 -
 source3/smbd/uid.c             | 754 +--------------------------------
 6 files changed, 29 insertions(+), 819 deletions(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 619c1a8eb94..6516869b24e 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -407,7 +407,7 @@ typedef struct files_struct {
 
 struct vuid_cache_entry {
 	struct auth_session_info *session_info;
-	struct smb_vfs_ev_glue *user_vfs_evg;
+	struct tevent_context *user_ev_ctx;
 	uint64_t vuid; /* SMB2 compat */
 	bool read_only;
 	uint32_t share_access;
@@ -456,7 +456,6 @@ typedef struct connection_struct {
 	 */
 	struct auth_session_info *session_info;
 	struct tevent_context *user_ev_ctx;
-	struct smb_vfs_ev_glue *user_vfs_evg;
 
 	/*
 	 * If the "force group" parameter is set, this is the primary gid that
diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c
index 37a9e806a15..e7e12747a22 100644
--- a/source3/modules/vfs_readonly.c
+++ b/source3/modules/vfs_readonly.c
@@ -84,7 +84,7 @@ static int readonly_connect(vfs_handle_struct *handle,
       for (i=0; i< VUID_CACHE_SIZE; i++) {
         struct vuid_cache_entry *ent = &conn->vuid_cache->array[i];
         ent->vuid = UID_FIELD_INVALID;
-        TALLOC_FREE(ent->user_vfs_evg);
+        TALLOC_FREE(ent->user_ev_ctx);
         TALLOC_FREE(ent->session_info);
         ent->read_only = false;
         ent->share_access = 0;
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index d8dc1c27d42..cfff6404608 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -95,12 +95,10 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid)
 		if (ent->vuid == vuid) {
 			ent->vuid = UID_FIELD_INVALID;
 
-			conn->user_ev_ctx = NULL;
-
-			if (conn->user_vfs_evg == ent->user_vfs_evg) {
-				conn->user_vfs_evg = NULL;
+			if (conn->user_ev_ctx == ent->user_ev_ctx) {
+				conn->user_ev_ctx = NULL;
 			}
-			TALLOC_FREE(ent->user_vfs_evg);
+			TALLOC_FREE(ent->user_ev_ctx);
 
 			/*
 			 * We need to keep conn->session_info around
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 880a02b0320..9b0b2de27ca 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -253,10 +253,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 	const char *vfs_user;
 	struct smbd_server_connection *sconn;
 	const char *servicename = lp_const_servicename(snum);
-	const struct security_unix_token *unix_token = NULL;
-	struct tevent_context *user_ev_ctx = NULL;
-	struct pthreadpool_tevent *user_tp_chdir_safe = NULL;
-	struct pthreadpool_tevent *root_tp_chdir_safe = NULL;
 	int ret;
 
 	sconn = talloc_zero(ctx, struct smbd_server_connection);
@@ -333,7 +329,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 			TALLOC_FREE(conn);
 			return NT_STATUS_NO_MEMORY;
 		}
-		unix_token = conn->session_info->unix_token;
 		/* unix_info could be NULL in session_info */
 		if (conn->session_info->unix_info != NULL) {
 			vfs_user = conn->session_info->unix_info->unix_name;
@@ -345,10 +340,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		vfs_user = get_current_username();
 	}
 
-	if (unix_token == NULL) {
-		unix_token = get_current_utok(conn);
-	}
-
 	/*
 	 * The impersonation has to be done by the caller
 	 * of create_conn_struct_tos[_cwd]().
@@ -362,63 +353,12 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 	 * to avoid crashes because TALLOC_FREE(conn->user_ev_ctx)
 	 * would also remove sconn->raw_ev_ctx.
 	 */
-	user_ev_ctx = smbd_impersonate_debug_create(sconn->raw_ev_ctx,
-						    "FAKE impersonation",
-						    DBGLVL_DEBUG);
-	if (user_ev_ctx == NULL) {
-		TALLOC_FREE(conn);
-		return NT_STATUS_NO_MEMORY;
-	}
-	SMB_ASSERT(talloc_reparent(sconn->raw_ev_ctx, conn, user_ev_ctx));
-
-	user_tp_chdir_safe = smbd_impersonate_tp_current_create(conn,
-						sconn->sync_thread_pool,
-						conn,
-						conn->vuid,
-						true, /* chdir_safe */
-						unix_token);
-	if (user_tp_chdir_safe == NULL) {
-		TALLOC_FREE(conn);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	root_tp_chdir_safe = smbd_impersonate_tp_become_create(conn,
-						sconn->sync_thread_pool,
-						true, /* chdir_safe */
-						become_root,
-						unbecome_root);
-	if (root_tp_chdir_safe == NULL) {
-		TALLOC_FREE(conn);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	/*
-	 * We only use the chdir_safe wrappers
-	 * for everything in order to keep
-	 * it simple.
-	 */
-	conn->user_vfs_evg = smb_vfs_ev_glue_create(conn,
-						    user_ev_ctx,
-						    user_tp_chdir_safe,
-						    user_tp_chdir_safe,
-						    user_tp_chdir_safe,
-						    sconn->root_ev_ctx,
-						    root_tp_chdir_safe,
-						    root_tp_chdir_safe,
-						    root_tp_chdir_safe);
-	if (conn->user_vfs_evg == NULL) {
-		TALLOC_FREE(conn);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	SMB_ASSERT(talloc_reparent(conn, conn->user_vfs_evg, user_ev_ctx));
-	SMB_ASSERT(talloc_reparent(conn, conn->user_vfs_evg, user_tp_chdir_safe));
-	SMB_ASSERT(talloc_reparent(conn, conn->user_vfs_evg, root_tp_chdir_safe));
-
-	conn->user_ev_ctx = smb_vfs_ev_glue_ev_ctx(conn->user_vfs_evg);
+	conn->user_ev_ctx = smbd_impersonate_debug_create(sconn->raw_ev_ctx,
+							  "FAKE impersonation",
+							  DBGLVL_DEBUG);
 	if (conn->user_ev_ctx == NULL) {
 		TALLOC_FREE(conn);
-		return NT_STATUS_INTERNAL_ERROR;
+		return NT_STATUS_NO_MEMORY;
 	}
 
 	set_conn_connectpath(conn, connpath);
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 2a56c1e4346..eb35a94862a 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1255,19 +1255,6 @@ struct tevent_context *smbd_impersonate_conn_sess_create(
 struct tevent_context *smbd_impersonate_root_create(struct tevent_context *main_ev);
 struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev);
 
-struct pthreadpool_tevent *smbd_impersonate_tp_current_create(
-				TALLOC_CTX *mem_ctx,
-				struct pthreadpool_tevent *sync_tp,
-				struct connection_struct *conn,
-				uint64_t vuid, bool chdir_safe,
-				const struct security_unix_token *unix_token);
-struct pthreadpool_tevent *smbd_impersonate_tp_become_create(
-					TALLOC_CTX *mem_ctx,
-					struct pthreadpool_tevent *sync_tp,
-					bool chdir_safe,
-					void (*become_fn)(void),
-					void (*unbecome_fn)(void));
-
 /* The following definitions come from smbd/utmp.c  */
 
 void sys_utmp_claim(const char *username, const char *hostname,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 77e5f8c83b7..0518e5254a8 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -18,7 +18,6 @@
 */
 
 #include "includes.h"
-#include "system/filesys.h"
 #include "system/passwd.h"
 #include "smbd/smbd.h"
 #include "smbd/globals.h"
@@ -28,12 +27,6 @@
 #include "auth.h"
 #include "../auth/auth_util.h"
 #include "lib/util/time_basic.h"
-#include "lib/pthreadpool/pthreadpool_tevent.h"
-
-static struct smb_vfs_ev_glue *smbd_impersonate_user_ev_glue_create(
-				struct connection_struct *conn,
-				uint64_t vuid,
-				struct auth_session_info *session_info);
 
 struct smbd_impersonate_debug_state {
 	int dbg_lvl;
@@ -314,8 +307,7 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
 		}
 	}
 	/* Not used, safe to free. */
-	conn->user_ev_ctx = NULL;
-	TALLOC_FREE(conn->user_vfs_evg);
+	TALLOC_FREE(conn->user_ev_ctx);
 	TALLOC_FREE(conn->session_info);
 }
 
@@ -441,13 +433,10 @@ static bool check_user_ok(connection_struct *conn,
 			}
 			free_conn_session_info_if_unused(conn);
 			conn->session_info = ent->session_info;
-			conn->user_vfs_evg = ent->user_vfs_evg;
+			conn->user_ev_ctx = ent->user_ev_ctx;
 			conn->read_only = ent->read_only;
 			conn->share_access = ent->share_access;
 			conn->vuid = ent->vuid;
-			conn->user_ev_ctx = smb_vfs_ev_glue_ev_ctx(
-						conn->user_vfs_evg);
-			SMB_ASSERT(conn->user_ev_ctx != NULL);
 			return(True);
 		}
 	}
@@ -493,12 +482,22 @@ static bool check_user_ok(connection_struct *conn,
 		ent->session_info->unix_token->uid = sec_initial_uid();
 	}
 
-	ent->user_vfs_evg = smbd_impersonate_user_ev_glue_create(conn,
-							vuid, ent->session_info);
-	if (ent->user_vfs_evg == NULL) {
-		TALLOC_FREE(ent->session_info);
-		ent->vuid = UID_FIELD_INVALID;
-		return false;
+	if (vuid == UID_FIELD_INVALID) {
+		ent->user_ev_ctx = smbd_impersonate_conn_sess_create(
+			conn->sconn->raw_ev_ctx, conn, ent->session_info);
+		if (ent->user_ev_ctx == NULL) {
+			TALLOC_FREE(ent->session_info);
+			ent->vuid = UID_FIELD_INVALID;
+			return false;
+		}
+	} else {
+		ent->user_ev_ctx = smbd_impersonate_conn_vuid_create(
+			conn->sconn->raw_ev_ctx, conn, vuid);
+		if (ent->user_ev_ctx == NULL) {
+			TALLOC_FREE(ent->session_info);
+			ent->vuid = UID_FIELD_INVALID;
+			return false;
+		}
 	}
 
 	/*
@@ -513,10 +512,7 @@ static bool check_user_ok(connection_struct *conn,
 	free_conn_session_info_if_unused(conn);
 	conn->session_info = ent->session_info;
 	conn->vuid = ent->vuid;
-	conn->user_vfs_evg = ent->user_vfs_evg;
-	conn->user_ev_ctx = smb_vfs_ev_glue_ev_ctx(conn->user_vfs_evg);
-	SMB_ASSERT(conn->user_ev_ctx != NULL);
-
+	conn->user_ev_ctx = ent->user_ev_ctx;
 	if (vuid == UID_FIELD_INVALID) {
 		/*
 		 * Not strictly needed, just make it really
@@ -525,7 +521,7 @@ static bool check_user_ok(connection_struct *conn,
 		ent->read_only = false;
 		ent->share_access = 0;
 		ent->session_info = NULL;
-		ent->user_vfs_evg = NULL;
+		ent->user_ev_ctx = NULL;
 	}
 
 	conn->read_only = readonly_share;
@@ -1937,713 +1933,3 @@ struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main
 
 	return ev;
 }
-
-struct smbd_impersonate_tp_current_state {
-	const void *conn_ptr;
-	uint64_t vuid; /* SMB2 compat */
-	struct security_unix_token partial_ut;
-	bool chdir_safe;
-	int saved_cwd_fd;
-};
-
-static int smbd_impersonate_tp_current_state_destructor(
-		struct smbd_impersonate_tp_current_state *state)
-{
-	if (state->saved_cwd_fd != -1) {
-		smb_panic(__location__);
-	}
-
-	return 0;
-}
-
-static bool smbd_impersonate_tp_current_before_job(struct pthreadpool_tevent *wrap,
-						   void *private_data,
-						   struct pthreadpool_tevent *main,
-						   const char *location)
-{
-	struct smbd_impersonate_tp_current_state *state =
-		talloc_get_type_abort(private_data,
-		struct smbd_impersonate_tp_current_state);
-
-	if (state->conn_ptr != current_user.conn) {
-		smb_panic(__location__);
-	}
-
-	if (state->vuid != current_user.vuid) {
-		smb_panic(__location__);
-	}
-
-	if (state->partial_ut.uid != current_user.ut.uid) {
-		smb_panic(__location__);
-	}
-
-	if (state->partial_ut.gid != current_user.ut.gid) {
-		smb_panic(__location__);
-	}
-
-	if (state->partial_ut.ngroups != current_user.ut.ngroups) {
-		smb_panic(__location__);
-	}
-
-	/*
-	 * We don't verify the group list, we should have hit
-	 * an assert before. We only want to catch programmer
-	 * errors here!
-	 *
-	 * We just have a sync pool and want to make sure
-	 * we're already in the correct state.
-	 *
-	 * So we don't do any active impersonation.
-	 */
-
-	/*
-	 * we may need to remember the current working directory
-	 * and later restore it in the after_job hook.
-	 */
-	if (state->chdir_safe) {
-		int open_flags = O_RDONLY;
-		bool ok;
-
-#ifdef O_DIRECTORY
-		open_flags |= O_DIRECTORY;
-#endif
-#ifdef O_CLOEXEC
-		open_flags |= O_CLOEXEC;
-#endif
-
-		state->saved_cwd_fd = open(".", open_flags);
-		if (state->saved_cwd_fd == -1) {
-			DBG_ERR("unable to open '.' with open_flags[0x%x] - %s\n",
-				open_flags, strerror(errno));
-			smb_panic("smbd_impersonate_tp_current_before_job: "
-				  "unable to open cwd '.'");
-			return false;
-		}
-		ok = smb_set_close_on_exec(state->saved_cwd_fd);
-		SMB_ASSERT(ok);
-	}
-
-	return true;
-}
-
-static bool smbd_impersonate_tp_current_after_job(struct pthreadpool_tevent *wrap,
-						  void *private_data,
-						  struct pthreadpool_tevent *main,
-						  const char *location)
-{
-	struct smbd_impersonate_tp_current_state *state =
-		talloc_get_type_abort(private_data,
-		struct smbd_impersonate_tp_current_state);
-	int ret;
-
-	/*
-	 * There's no impersonation to revert.
-	 *
-	 * But we may need to reset the current working directory.
-	 */
-	if (state->saved_cwd_fd == -1) {
-		return true;
-	}
-
-	ret = fchdir(state->saved_cwd_fd);
-	if (ret != 0) {
-		DBG_ERR("unable to fchdir to the original directory - %s\n",
-			strerror(errno));
-		smb_panic("smbd_impersonate_tp_current_after_job: "
-			  "unable restore cwd with fchdir.");
-		return false;
-	}
-
-	close(state->saved_cwd_fd);
-	state->saved_cwd_fd = -1;
-
-	return true;
-}
-
-static const struct pthreadpool_tevent_wrapper_ops smbd_impersonate_tp_current_ops = {
-	.name		= "smbd_impersonate_tp_current",
-	.before_job	= smbd_impersonate_tp_current_before_job,
-	.after_job	= smbd_impersonate_tp_current_after_job,
-};
-
-struct pthreadpool_tevent *smbd_impersonate_tp_current_create(
-				TALLOC_CTX *mem_ctx,
-				struct pthreadpool_tevent *sync_tp,
-				struct connection_struct *conn,
-				uint64_t vuid, bool chdir_safe,
-				const struct security_unix_token *unix_token)
-{
-	struct pthreadpool_tevent *wrap_tp = NULL;
-	struct smbd_impersonate_tp_current_state *state = NULL;
-	size_t max_threads;
-
-	max_threads = pthreadpool_tevent_max_threads(sync_tp);
-	SMB_ASSERT(max_threads == 0);
-
-	/*
-	 * We have a fake threadpool without real threads.
-	 * So we just provide a a wrapper that asserts that
-	 * we are already in the required impersonation state.
-	 */
-
-	wrap_tp = pthreadpool_tevent_wrapper_create(sync_tp,
-					mem_ctx,
-					&smbd_impersonate_tp_current_ops,
-					&state,
-					struct smbd_impersonate_tp_current_state);
-	if (wrap_tp == NULL) {
-		return NULL;
-	}
-
-	state->conn_ptr = conn;
-	state->vuid = vuid;
-	state->partial_ut = *unix_token;
-	state->partial_ut.groups = NULL;
-	state->chdir_safe = chdir_safe;
-	state->saved_cwd_fd = -1;
-
-	if (chdir_safe) {
-		pthreadpool_tevent_force_per_thread_cwd(wrap_tp, state);
-	}
-
-	talloc_set_destructor(state, smbd_impersonate_tp_current_state_destructor);
-
-	return wrap_tp;
-}
-
-struct smbd_impersonate_tp_sess_state {
-	const struct security_unix_token *unix_token;
-};
-
-static bool smbd_impersonate_tp_sess_before_job(struct pthreadpool_tevent *wrap,
-						void *private_data,
-						struct pthreadpool_tevent *main,
-						const char *location)
-{
-	struct smbd_impersonate_tp_sess_state *state =
-		talloc_get_type_abort(private_data,
-		struct smbd_impersonate_tp_sess_state);
-	int ret;
-
-	/* Become the correct credential on this thread. */
-	ret = set_thread_credentials(state->unix_token->uid,
-				     state->unix_token->gid,
-				     (size_t)state->unix_token->ngroups,
-				     state->unix_token->groups);
-	if (ret != 0) {
-		return false;
-	}
-
-	return true;
-}
-
-static bool smbd_impersonate_tp_sess_after_job(struct pthreadpool_tevent *wrap,
-					       void *private_data,
-					       struct pthreadpool_tevent *main,
-					       const char *location)
-{
-	/*
-	 * We skip the 'unbecome' here, if the following
-	 * job cares, it already called set_thread_credentials() again.
-	 *
-	 * fd based jobs on the raw pool, don't really care...
-	 */
-	return true;
-}
-
-static const struct pthreadpool_tevent_wrapper_ops smbd_impersonate_tp_sess_ops = {
-	.name		= "smbd_impersonate_tp_sess",
-	.before_job	= smbd_impersonate_tp_sess_before_job,
-	.after_job	= smbd_impersonate_tp_sess_after_job,
-};
-
-static struct pthreadpool_tevent *smbd_impersonate_tp_sess_create(
-				TALLOC_CTX *mem_ctx,
-				struct pthreadpool_tevent *main_tp,
-				struct auth_session_info *session_info)
-{
-	struct pthreadpool_tevent *wrap_tp = NULL;
-	struct smbd_impersonate_tp_sess_state *state = NULL;
-	size_t max_threads;
-
-	max_threads = pthreadpool_tevent_max_threads(main_tp);
-	SMB_ASSERT(max_threads > 0);
-
-	wrap_tp = pthreadpool_tevent_wrapper_create(main_tp,
-					mem_ctx,
-					&smbd_impersonate_tp_sess_ops,
-					&state,
-					struct smbd_impersonate_tp_sess_state);
-	if (wrap_tp == NULL) {
-		return NULL;
-	}
-
-	state->unix_token = copy_unix_token(state, session_info->unix_token);
-	if (state->unix_token == NULL) {
-		int saved_errno = errno;
-		TALLOC_FREE(wrap_tp);
-		errno = saved_errno;
-		return NULL;
-	}
-
-	return wrap_tp;
-}
-
-struct smbd_impersonate_tp_become_state {
-	void (*become_fn)(void);
-	void (*unbecome_fn)(void);
-	bool chdir_safe;
-	int saved_cwd_fd;
-};
-
-static int smbd_impersonate_tp_become_state_destructor(
-		struct smbd_impersonate_tp_become_state *state)
-{
-	if (state->saved_cwd_fd != -1) {
-		smb_panic(__location__);
-	}
-
-	return 0;
-}
-
-
-static bool smbd_impersonate_tp_become_before_job(struct pthreadpool_tevent *wrap,
-						   void *private_data,
-						   struct pthreadpool_tevent *main,
-						   const char *location)
-{
-	struct smbd_impersonate_tp_become_state *state =
-		talloc_get_type_abort(private_data,
-		struct smbd_impersonate_tp_become_state);
-
-	/*
-	 * we may need to remember the current working directory
-	 * and later restore it in the after_job hook.
-	 */
-	if (state->chdir_safe) {
-		int open_flags = O_RDONLY;
-		bool ok;
-
-#ifdef O_DIRECTORY
-		open_flags |= O_DIRECTORY;
-#endif
-#ifdef O_CLOEXEC
-		open_flags |= O_CLOEXEC;
-#endif
-
-		state->saved_cwd_fd = open(".", open_flags);
-		if (state->saved_cwd_fd == -1) {
-			DBG_ERR("unable to open '.' with open_flags[0x%x] - %s\n",
-				open_flags, strerror(errno));
-			smb_panic("smbd_impersonate_tp_current_before_job: "
-				  "unable to open cwd '.'");
-			return false;
-		}
-		ok = smb_set_close_on_exec(state->saved_cwd_fd);
-		SMB_ASSERT(ok);
-	}
-
-	/*
-	 * The function should abort on error...
-	 */
-	state->become_fn();
-
-	return true;
-}
-
-static bool smbd_impersonate_tp_become_after_job(struct pthreadpool_tevent *wrap,
-						  void *private_data,
-						  struct pthreadpool_tevent *main,
-						  const char *location)
-{
-	struct smbd_impersonate_tp_become_state *state =
-		talloc_get_type_abort(private_data,
-		struct smbd_impersonate_tp_become_state);
-	int ret;
-
-	/*
-	 * The function should abort on error...
-	 */
-	state->unbecome_fn();
-
-	/*
-	 * There's no impersonation to revert.
-	 *
-	 * But we may need to reset the current working directory.
-	 */
-	if (state->saved_cwd_fd == -1) {
-		return true;
-	}
-
-	ret = fchdir(state->saved_cwd_fd);
-	if (ret != 0) {
-		DBG_ERR("unable to fchdir to the original directory - %s\n",
-			strerror(errno));
-		smb_panic("smbd_impersonate_tp_current_after_job: "
-			  "unable restore cwd with fchdir.");
-		return false;
-	}
-
-	close(state->saved_cwd_fd);
-	state->saved_cwd_fd = -1;
-
-	return true;
-}
-
-static const struct pthreadpool_tevent_wrapper_ops smbd_impersonate_tp_become_ops = {
-	.name		= "smbd_impersonate_tp_become",
-	.before_job	= smbd_impersonate_tp_become_before_job,
-	.after_job	= smbd_impersonate_tp_become_after_job,
-};
-
-struct pthreadpool_tevent *smbd_impersonate_tp_become_create(
-					TALLOC_CTX *mem_ctx,
-					struct pthreadpool_tevent *sync_tp,
-					bool chdir_safe,
-					void (*become_fn)(void),
-					void (*unbecome_fn)(void))
-{
-	struct pthreadpool_tevent *wrap_tp = NULL;
-	struct smbd_impersonate_tp_become_state *state = NULL;
-	size_t max_threads;
-
-	max_threads = pthreadpool_tevent_max_threads(sync_tp);
-	SMB_ASSERT(max_threads == 0);
-
-	/*
-	 * We have a fake threadpool without real threads.
-	 * So we just provide a a wrapper that asserts that
-	 * we are already in the required impersonation state.
-	 */
-
-	wrap_tp = pthreadpool_tevent_wrapper_create(sync_tp,
-					mem_ctx,
-					&smbd_impersonate_tp_become_ops,
-					&state,
-					struct smbd_impersonate_tp_become_state);
-	if (wrap_tp == NULL) {
-		return NULL;
-	}
-
-	state->become_fn = become_fn;
-	state->unbecome_fn = unbecome_fn;
-	state->chdir_safe = chdir_safe;
-	state->saved_cwd_fd = -1;
-
-	if (chdir_safe) {
-		pthreadpool_tevent_force_per_thread_cwd(wrap_tp, state);
-	}
-
-	talloc_set_destructor(state, smbd_impersonate_tp_become_state_destructor);
-
-	return wrap_tp;
-}
-
-struct smbd_impersonate_tp_root_state {
-	const struct security_unix_token *fallback_token;
-};
-
-static bool smbd_impersonate_tp_root_before_job(struct pthreadpool_tevent *wrap,
-						void *private_data,
-						struct pthreadpool_tevent *main,
-						const char *location)
-{
-	int ret;
-
-	/*
-	 * Become root in this thread.
-	 */
-	ret = set_thread_credentials(0, 0, 0, NULL);
-	if (ret != 0) {
-		return false;
-	}
-
-	return true;
-}
-
-static bool smbd_impersonate_tp_root_after_job(struct pthreadpool_tevent *wrap,
-					       void *private_data,
-					       struct pthreadpool_tevent *main,
-					       const char *location)
-{
-	struct smbd_impersonate_tp_root_state *state =
-		talloc_get_type_abort(private_data,
-		struct smbd_impersonate_tp_root_state);
-	int ret;
-
-	/*
-	 * Move to a non root token again.
-	 * We just use the one of the user_ev_ctx.
-	 *
-	 * The main goal is that we don't leave
-	 * a thread arround with a root token.
-	 */
-	ret = set_thread_credentials(state->fallback_token->uid,
-				     state->fallback_token->gid,
-				     (size_t)state->fallback_token->ngroups,
-				     state->fallback_token->groups);
-	if (ret != 0) {
-		return false;
-	}
-
-	return true;
-}
-
-static const struct pthreadpool_tevent_wrapper_ops smbd_impersonate_tp_root_ops = {
-	.name		= "smbd_impersonate_tp_root",
-	.before_job	= smbd_impersonate_tp_root_before_job,
-	.after_job	= smbd_impersonate_tp_root_after_job,
-};
-
-static struct pthreadpool_tevent *smbd_impersonate_tp_root_create(
-				TALLOC_CTX *mem_ctx,
-				struct pthreadpool_tevent *main_tp,
-				int snum,
-				const struct security_unix_token *fallback_token)
-{
-	struct pthreadpool_tevent *wrap_tp = NULL;
-	struct smbd_impersonate_tp_root_state *state = NULL;
-	size_t max_threads;
-
-	max_threads = pthreadpool_tevent_max_threads(main_tp);
-	SMB_ASSERT(max_threads > 0);
-
-	wrap_tp = pthreadpool_tevent_wrapper_create(main_tp,
-				mem_ctx,
-				&smbd_impersonate_tp_root_ops,
-				&state,
-				struct smbd_impersonate_tp_root_state);
-	if (wrap_tp == NULL) {
-		return NULL;
-	}
-
-	state->fallback_token = copy_unix_token(state, fallback_token);
-	if (state->fallback_token == NULL) {
-		int saved_errno = errno;
-		TALLOC_FREE(wrap_tp);
-		errno = saved_errno;
-		return NULL;
-	}
-
-	return wrap_tp;
-}
-
-static struct smb_vfs_ev_glue *smbd_impersonate_user_ev_glue_create(
-				struct connection_struct *conn,
-				uint64_t vuid,
-				struct auth_session_info *session_info)
-{
-	TALLOC_CTX *frame = talloc_stackframe();
-	struct smb_vfs_ev_glue *user_vfs_evg = NULL;
-	struct tevent_context *user_ev_ctx = NULL;
-	struct pthreadpool_tevent *user_tp_fd_safe = NULL;
-	struct pthreadpool_tevent *user_tp_path_safe = NULL;
-	bool user_tp_path_sync = true;
-	struct pthreadpool_tevent *user_tp_chdir_safe = NULL;
-	bool user_tp_chdir_sync = true;
-	struct pthreadpool_tevent *root_tp_fd_safe = NULL;
-	struct pthreadpool_tevent *root_tp_path_safe = NULL;
-	bool root_tp_path_sync = true;
-	struct pthreadpool_tevent *root_tp_chdir_safe = NULL;
-	bool root_tp_chdir_sync = true;
-	size_t max_threads;
-
-	if (vuid == UID_FIELD_INVALID) {
-		user_ev_ctx = smbd_impersonate_conn_sess_create(
-			conn->sconn->raw_ev_ctx, conn, session_info);
-		if (user_ev_ctx == NULL) {
-			TALLOC_FREE(frame);
-			return NULL;
-		}
-	} else {
-		user_ev_ctx = smbd_impersonate_conn_vuid_create(
-			conn->sconn->raw_ev_ctx, conn, vuid);
-		if (user_ev_ctx == NULL) {
-			TALLOC_FREE(frame);
-			return NULL;
-		}
-	}
-	SMB_ASSERT(talloc_reparent(conn, frame, user_ev_ctx));
-
-#ifdef HAVE_LINUX_THREAD_CREDENTIALS
-	user_tp_path_sync = lp_parm_bool(SNUM(conn),
-					 "smbd",
-					 "force sync user path safe threadpool",
-					 false);
-	user_tp_chdir_sync = lp_parm_bool(SNUM(conn),
-					  "smbd",
-					  "force sync user chdir safe threadpool",
-					  false);
-	root_tp_path_sync = lp_parm_bool(SNUM(conn),
-					 "smbd",
-					 "force sync root path safe threadpool",
-					 false);
-	root_tp_chdir_sync = lp_parm_bool(SNUM(conn),
-					  "smbd",
-					  "force sync root chdir safe threadpool",
-					  false);
-#endif
-
-	max_threads = pthreadpool_tevent_max_threads(conn->sconn->raw_thread_pool);
-	if (max_threads == 0) {
-		/*
-		 * We don't have real threads, so we need to force
-		 * the sync versions...
-		 */
-		user_tp_path_sync = true;
-		user_tp_chdir_sync = true;
-		root_tp_path_sync = true;
-		root_tp_chdir_sync = true;
-	}
-
-	/*
-	 * fd_safe is easy :-)
-	 */
-	user_tp_fd_safe = conn->sconn->raw_thread_pool;
-	root_tp_fd_safe = conn->sconn->raw_thread_pool;
-
-	if (user_tp_path_sync) {
-		/*
-		 * We don't have support for per thread credentials,
-		 * so we just provide a sync thread pool with a wrapper
-		 * that asserts that we are already in the required
-		 * impersonation state.
-		 */
-		user_tp_path_safe = smbd_impersonate_tp_current_create(conn,
-						conn->sconn->sync_thread_pool,
-						conn,
-						vuid,
-						false, /* chdir_safe */
-						session_info->unix_token);
-		if (user_tp_path_safe == NULL) {
-			TALLOC_FREE(frame);
-			return NULL;
-		}
-	} else {
-		user_tp_path_safe = smbd_impersonate_tp_sess_create(conn,
-						conn->sconn->raw_thread_pool,
-						session_info);
-		if (user_tp_path_safe == NULL) {
-			TALLOC_FREE(frame);
-			return NULL;
-		}
-	}
-	SMB_ASSERT(talloc_reparent(conn, frame, user_tp_path_safe));
-
-	if (pthreadpool_tevent_per_thread_cwd(user_tp_path_safe)) {
-		user_tp_chdir_safe = user_tp_path_safe;
-	} else {
-		user_tp_chdir_sync = true;
-	}
-
-	if (user_tp_chdir_sync) {
-		/*
-		 * We don't have support for per thread credentials,
-		 * so we just provide a sync thread pool with a wrapper
-		 * that asserts that we are already in the required
-		 * impersonation state.
-		 *
-		 * And it needs to cleanup after [f]chdir() within
-		 * the job...
-		 */
-		user_tp_chdir_safe = smbd_impersonate_tp_current_create(conn,
-						conn->sconn->sync_thread_pool,
-						conn,
-						vuid,
-						true, /* chdir_safe */
-						session_info->unix_token);
-		if (user_tp_chdir_safe == NULL) {
-			TALLOC_FREE(frame);
-			return NULL;
-		}
-		SMB_ASSERT(talloc_reparent(conn, frame, user_tp_chdir_safe));
-	} else {
-		SMB_ASSERT(user_tp_chdir_safe != NULL);
-	}
-
-	if (root_tp_path_sync) {
-		/*
-		 * We don't have support for per thread credentials,
-		 * so we just provide a sync thread pool with a wrapper
-		 * that wrapps the job in become_root()/unbecome_root().
-		 */
-		root_tp_path_safe = smbd_impersonate_tp_become_create(conn,
-						conn->sconn->sync_thread_pool,
-						false, /* chdir_safe */
-						become_root,
-						unbecome_root);
-		if (root_tp_path_safe == NULL) {
-			TALLOC_FREE(frame);
-			return NULL;
-		}
-	} else {
-		root_tp_path_safe = smbd_impersonate_tp_root_create(conn,
-						conn->sconn->raw_thread_pool,
-						SNUM(conn),
-						session_info->unix_token);
-		if (root_tp_path_safe == NULL) {
-			TALLOC_FREE(frame);
-			return NULL;
-		}
-	}
-	SMB_ASSERT(talloc_reparent(conn, frame, root_tp_path_safe));
-
-	if (pthreadpool_tevent_per_thread_cwd(root_tp_path_safe)) {
-		root_tp_chdir_safe = root_tp_path_safe;
-	} else {
-		root_tp_chdir_sync = true;
-	}
-
-	if (root_tp_chdir_sync) {
-		/*
-		 * We don't have support for per thread credentials,
-		 * so we just provide a sync thread pool with a wrapper
-		 * that wrapps the job in become_root()/unbecome_root().
-		 *
-		 * And it needs to cleanup after [f]chdir() within
-		 * the job...
-		 */
-		root_tp_chdir_safe = smbd_impersonate_tp_become_create(conn,
-						conn->sconn->sync_thread_pool,
-						true, /* chdir_safe */
-						become_root,
-						unbecome_root);
-		if (root_tp_chdir_safe == NULL) {
-			TALLOC_FREE(frame);
-			return NULL;
-		}
-		SMB_ASSERT(talloc_reparent(conn, frame, root_tp_chdir_safe));
-	} else {
-		SMB_ASSERT(root_tp_chdir_safe != NULL);
-	}
-
-	user_vfs_evg = smb_vfs_ev_glue_create(conn,
-					      user_ev_ctx,
-					      user_tp_fd_safe,
-					      user_tp_path_safe,
-					      user_tp_chdir_safe,
-					      conn->sconn->root_ev_ctx,
-					      root_tp_fd_safe,
-					      root_tp_path_safe,
-					      root_tp_chdir_safe);
-	if (user_vfs_evg == NULL) {
-		TALLOC_FREE(frame);
-		return NULL;
-	}
-
-	/*
-	 * Make sure everything is a talloc child of user_vfs_evg
-	 */
-	SMB_ASSERT(talloc_reparent(frame, user_vfs_evg, user_ev_ctx));
-	SMB_ASSERT(talloc_reparent(frame, user_vfs_evg, user_tp_path_safe));
-	if (user_tp_path_safe != user_tp_chdir_safe) {
-		SMB_ASSERT(talloc_reparent(frame, user_vfs_evg, user_tp_chdir_safe));
-	}
-	SMB_ASSERT(talloc_reparent(frame, user_vfs_evg, root_tp_path_safe));
-	if (root_tp_path_safe != root_tp_chdir_safe) {
-		SMB_ASSERT(talloc_reparent(frame, user_vfs_evg, root_tp_chdir_safe));
-	}
-
-	TALLOC_FREE(frame);
-	return user_vfs_evg;
-}
-- 
2.17.2


From 7f2f045048c4cd6fd9c2637281454edd468c73d7 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 28 Dec 2018 13:08:14 +0100
Subject: [PATCH 13/56] Revert "s3: vfs: add smb_vfs_ev_glue"

This reverts commit 1251a536df4b1df58d9ddacab03d3ebe6f4e5b60.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/include/vfs.h |  30 --
 source3/smbd/vfs.c    | 832 ------------------------------------------
 2 files changed, 862 deletions(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 6516869b24e..959dd405915 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -257,8 +257,6 @@
 /* Version 39 - Remove struct dfree_cached_info pointer from
 		connection struct */
 /* Bump to version 40, Samba 4.10 will ship with that */
-/* Version 40 - Introduce smb_vfs_ev_glue infrastructure. */
-/* Version 40 - Add vfs_not_implemented_* helper functions. */
 /* Version 40 - Add SMB_VFS_GETXATTRAT_SEND/RECV */
 /* Version 40 - Add SMB_VFS_GET_DOS_ATTRIBUTES_SEND/RECV */
 
@@ -283,9 +281,6 @@ struct smb_file_time;
 struct blocking_lock_record;
 struct smb_filename;
 struct dfs_GetDFSReferral;
-struct tevent_context;
-struct pthreadpool_tevent;
-struct smb_vfs_ev_glue;
 
 typedef union unid_t {
 	uid_t uid;
@@ -1553,31 +1548,6 @@ void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp);
 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
 			    const char *module);
 
-/*
- * Notice the "Design of the smb_vfs_ev_glue infrastructure"
- * comment in source3/smbd/vfs.c!
- *
- * This explains smb_vfs_ev_glue infrastructure in detail.
- */
-struct tevent_context *smb_vfs_ev_glue_ev_ctx(const struct smb_vfs_ev_glue *evg);
-struct pthreadpool_tevent *smb_vfs_ev_glue_tp_fd_safe(const struct smb_vfs_ev_glue *evg);
-struct pthreadpool_tevent *smb_vfs_ev_glue_tp_path_safe(const struct smb_vfs_ev_glue *evg);
-struct pthreadpool_tevent *smb_vfs_ev_glue_tp_chdir_safe(const struct smb_vfs_ev_glue *evg);
-const struct smb_vfs_ev_glue *smb_vfs_ev_glue_get_root_glue(const struct smb_vfs_ev_glue *evg);
-struct smb_vfs_ev_glue *smb_vfs_ev_glue_create(TALLOC_CTX *mem_ctx,
-				struct tevent_context *user_ev,
-				struct pthreadpool_tevent *user_tp_fd_safe,
-				struct pthreadpool_tevent *user_tp_path_safe,
-				struct pthreadpool_tevent *user_tp_chdir_safe,
-				struct tevent_context *root_ev,
-				struct pthreadpool_tevent *root_tp_fd_safe,
-				struct pthreadpool_tevent *root_tp_path_safe,
-				struct pthreadpool_tevent *root_tp_chdir_safe);
-struct smb_vfs_ev_glue *smb_vfs_ev_glue_create_switch(
-			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *return_evg,
-			const struct smb_vfs_ev_glue *run_evg);
-
 /*
  * Helper functions from source3/modules/vfs_not_implemented.c
  */
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 0cf8f8caa1d..5e0ca091f7b 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -1452,838 +1452,6 @@ struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_S
 	return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
 }
 
-/*
- * Design of the smb_vfs_ev_glue infrastructure:
- *
- * smb_vfs_ev_glue makes it possible to pass
- * down an tevent_context and pthreadpool_tevent
- * used for impersonation through the SMB_VFS stack.
- *
- * tevent_req based function take an tevent_context as
- * there 2nd argument, e.g.:
- *
- *   struct tevent_req *something_send(TALLOC_CTX *mem_ctx,
- *                                     struct tevent_context *ev,
- *                                     ...);
- *
- * For the SMB_VFS stack we'll use the following:
- *
- *   struct tevent_req *SMB_VFS_SOMETHING_SEND(TALLOC_CTX *mem_ctx,
- *                                             const struct smb_vfs_ev_glue *evg,
- *                                             ...);
- *
- * Typically the 'evg' is just passed through the stack down
- * to vfs_default.c. In order to do real work an
- * tevent_context and pthreadpool_tevent are required
- * to do call a 'somthing()' syscall in an async fashion.
- * Therefore it will the following to get the pointer
- * back out of evg:
- *
- *   ev = smb_vfs_ev_glue_ev_ctx(evg);
- *   tp = smb_vfs_ev_glue_tp_chdir_safe(evg);
- *
- * If some function in the stack is sure it needs to run as root
- * to get some information (after careful checks!), it used
- * to frame that work into become_root()/unbecome_root().
- * This can't work when using async functions!
- * Now it's possible to use something like this (simplified!):
- *
- *   ev = smb_vfs_ev_glue_ev_ctx(evg);
- *   root_evg = smb_vfs_ev_glue_get_root_glue(evg);
- *   subreq = SMB_VFS_SOMETHING_NEXT_SEND(state, root_evg, ...);
- *   if (tevent_req_nomem(subreq, req)) {
- *        return tevent_req_post(req, ev);
- *   }
- *   tevent_req_set_callback(subreq, module_something_done, req);
- *
- *   return req;
- *
- *   static void module_something_done(struct tevent_req *subreq)
- *   {
- *      ...
- *
- *      status = SMB_VFS_SOMETHING_NEXT_RECV(subreq, &state->aio_state);
- *      TALLOC_FREE(subreq);
- *
- *      tevent_req_done(req);
- *   }
- *
- * In the code above the something_send_fn() function of the next
- * module in the stack will be called as root.
- * The smb_vfs_call_something_*() glue code, which is the magic
- * behind the SMB_VFS_SOMETHING[_NEXT]_{SEND,RECV}() macros,
- * will look like this:
- *
- *   struct smb_vfs_call_something_state {
- *       ssize_t (*recv_fn)(struct tevent_req *req,
- *                          struct vfs_aio_state *aio_state,
- *                          ...);
- *       ssize_t retval;
- *       struct vfs_aio_state vfs_aio_state;
- *       ...
- *   };
- *
- *   static void smb_vfs_call_something_done(struct tevent_req *subreq);
- *
- *   struct tevent_req *smb_vfs_call_something_send(
- *                  TALLOC_CTX *mem_ctx,
- *                  const struct smb_vfs_ev_glue *evg,
- *                  struct vfs_handle_struct *handle,
- *                  ...)
- *   {
- *       struct tevent_req *req = NULL;
- *       struct smb_vfs_call_something_state *state = NULL;
- *       struct tevent_req *subreq = NULL;
- *       bool ok;
- *
- *       req = tevent_req_create(mem_ctx, &state,
- *                               struct smb_vfs_call_something_state);
- *       if (req == NULL) {
- *           return NULL;
- *       }
- *
- *       VFS_FIND(something_send);
- *       state->recv_fn = handle->fns->something_recv_fn;
- *
- *       ok = smb_vfs_ev_glue_push_use(evg, req);
- *       if (!ok) {
- *           tevent_req_error(req, EIO);
- *           return tevent_req_post(req, evg->return_ev);
- *       }
- *
- *       subreq = handle->fns->something_send_fn(mem_ctx,
- *                                               evg->next_glue,
- *                                               handle,
- *                                               ...);
- *       smb_vfs_ev_glue_pop_use(evg);
- *
- *       if (tevent_req_nomem(subreq, req)) {
- *           return tevent_req_post(req, evg->return_ev);
- *       }
- *       tevent_req_set_callback(subreq, smb_vfs_call_something_done, req);
- *
- *       return req;
- *   }
- *
- *   static void smb_vfs_call_something_done(struct tevent_req *subreq)
- *   {
- *       struct tevent_req *req =
- *           tevent_req_callback_data(subreq,
- *           struct tevent_req);
- *       struct smb_vfs_call_something_state *state =
- *           tevent_req_data(req,
- *           struct smb_vfs_call_something_state);
- *
- *       state->retval = state->recv_fn(subreq,
- *                                      &state->vfs_aio_state,
- *                                      ....);
- *       TALLOC_FREE(subreq);
- *
- *       if (state->retval == -1) {
- *           tevent_req_error(req, state->vfs_aio_state.error);
- *           return;
- *       }
- *       tevent_req_done(req);
- *   }
- *
- *   ssize_t smb_vfs_call_something_recv(struct tevent_req *req,
- *                                        struct vfs_aio_state *aio_state,
- *                                        ....)
- *   {
- *       struct smb_vfs_call_something_state *state =
- *           tevent_req_data(req,
- *           struct smb_vfs_call_something_state);
- *       ssize_t retval = state->retval;
- *
- *       if (tevent_req_is_unix_error(req, &aio_state->error)) {
- *           tevent_req_received(req);
- *           return -1;
- *       }
- *
- *       *aio_state = state->vfs_aio_state;
- *       ...
- *
- *       tevent_req_received(req);
- *       return retval;
- *   }
- *
- * The most important details are these:
- *
- * 1. smb_vfs_ev_glue_push_use(evg, req):
- *    - is a no-op if evg->run_ev and evg->return_ev are the same,
- *      it means that we're already at the correct impersonation
- *      and don't need any additional work to be done.
- *    - Otherwise it will call tevent_req_defer_callback(req, evg->return_ev)
- *      This means that tevent_req_error() and tevent_req_done()
- *      will just trigger an immediate event on evg->return_ev.
- *      Therefore the callers callback function will be called
- *      in the impersonation of evg->return_ev! This is important
- *      in order to get the impersonation correct on the way back
- *      through the stack.
- *    - It will call tevent_context_push_use(evg->run_ev),
- *      which will start the impersonation to run_ev.
- *      So the following code run in the correct context.
- * 2. handle->fns->something_send_fn(..., evg->next_glue, ...):
- *    - We're passing evg->next_glue to the next module.
- *    - Typically evg->next_glue points to evg again.
- *    - In case evg->run_ev and evg->return_ev are not the same,
- *      next_glue will have run_ev and return_ev pointing to evg->run_ev.
- *      So that the switch from evg->run_ev to evg->return_ev
- *      happens on the correct boundary.
- * 3. smb_vfs_ev_glue_pop_use(evg):
- *    - is a no-op if evg->run_ev and evg->return_ev are the same,
- *      it means that we're already at the correct impersonation
- *      and don't need any additional work to be done.
- *    - It will call tevent_context_pop_use(evg->run_ev),
- *      which will revert the impersonation done in
- *      smb_vfs_ev_glue_push_use().
- * 4. smb_vfs_call_something_send():
- *    - The is called in the environment of evg->return_ev.
- *    - So it needs to use tevent_req_post(req, evg->return_ev)
- * 5. smb_vfs_call_something_done():
- *    - The is called in the environment of evg->run_ev
- * 6. smb_vfs_call_something_recv():
- *    - The is called in the environment of evg->return_ev again.
- *
- *
- * Here are some more complex examples:
- *
- * Example 1: only user_evg without switch to root
- *
- * SMBD: already impersonated user_evg
- *  evg'1 = smb2_req->user_evg
- *  r'1 = SMB_VFS_*_SEND(evg'1); # smb_vfs_call_*_send()
- *  |
- *  | smb_vfs_ev_glue_push_use(evg'1, r'1);
- *  | |
- *  | | # no-op run_ev == return_ev
- *  | |
- *  | evg'2 = evg'1->next_glue;
- *  | r'2 = module1_*_send(evg'2);
- *  | |
- *  | | evg'3 = evg'2
- *  | | r'3 = SMB_VFS_*_NEXT_SEND(evg'3); # smb_vfs_call_*_send()
- *  | | |
- *  | | | smb_vfs_ev_glue_push_use(evg'3, r'3);
- *  | | | |
- *  | | | | # no-op run_ev == return_ev
- *  | | | |
- *  | | | evg'4 = evg'3->next_glue;
- *  | | | r'4 = module2_*_send(evg'4);
- *  | | | |
- *  | | | | evg'5 = evg'4
- *  | | | | r'5 = SMB_VFS_*_NEXT_SEND(evg'5); # smb_vfs_call_*_send()
- *  | | | | |
- *  | | | | | smb_vfs_ev_glue_push_use(evg'5, r'5);
- *  | | | | | |
- *  | | | | | | # no-op run_ev == return_ev
- *  | | | | | |
- *  | | | | | evg'6 = evg'5->next_glue;
- *  | | | | | r'6 = default_*_send(evg'6);
- *  | | | | | |
- *  | | | | | | ev'6 = smb_vfs_ev_glue_ev_ctx(evg'6)
- *  | | | | | | tp'6 = smb_vfs_ev_glue_tp_chdir_safe(evg'6)
- *  | | | | | | r'7 = pthreadpool_tevent_send(ev'6, tp'6);
- *  | | | | | | |
- *  | | | | | | | pthread_create...
- *  | | | | | | |
- *  | | | | | | tevent_req_set_callback(r'7, default_*_done, r'6);
- *  | | | | | |
- *  | | | | | smb_vfs_ev_glue_pop_use(evg'5);
- *  | | | | | |
- *  | | | | | | # no-op run_ev == return_ev
- *  | | | | | |
- *  | | | | | tevent_req_set_callback(r'6, smb_vfs_call_*_done, r'5);
- *  | | | | |
- *  | | | | tevent_req_set_callback(r'5, module2_*_done, r'4);
- *  | | | |
- *  | | | smb_vfs_ev_glue_pop_use(evg'3);
- *  | | | |
- *  | | | | # no-op run_ev == return_ev
- *  | | | |
- *  | | | tevent_req_set_callback(r'4, smb_vfs_call_*_done, r'3);
- *  | | |
- *  | | tevent_req_set_callback(r'3, module1_*_done, r'2);
- *  | |
- *  | smb_vfs_ev_glue_pop_use(evg'1);
- *  | |
- *  | | # no-op run_ev == return_ev
- *  | |
- *  | tevent_req_set_callback(r'2, smb_vfs_call_*_done, r'1);
- *  |
- *  tevent_req_set_callback(r'1, smbd_*_done, smb2_req);
- *
- *  Worker thread finished, just one event handler processes
- *  everything as there's no impersonation change.
- *
- *  tevent_common_invoke_immediate_handler:
- *  |
- *  | before_immediate_handler(ev'6);
- *  | |
- *  | | change_to_user()
- *  | |
- *  | pthreadpool_tevent_job_done(r'7);
- *  | |
- *  | | default_*_done(r'7);
- *  | | |
- *  | | | pthreadpool_tevent_recv(r'7);
- *  | | | TALLOC_FREE(r'7);
- *  | | | tevent_req_done('r6);
- *  | | | |
- *  | | | | smb_vfs_call_*_done(r'6);
- *  | | | | |
- *  | | | | | default_*_recv(r'6);
- *  | | | | | TALLOC_FREE(r'6)
- *  | | | | | tevent_req_done(r'5);
- *  | | | | | |
- *  | | | | | | module2_*_done(r'5):
- *  | | | | | | |
- *  | | | | | | | SMB_VFS_*_recv(r'5); # smb_vfs_call_*_recv()
- *  | | | | | | | TALLOC_FREE(r'5)
- *  | | | | | | | tevent_req_done(r'4);
- *  | | | | | | | |
- *  | | | | | | | | smb_vfs_call_*_done(r'4);
- *  | | | | | | | | |
- *  | | | | | | | | | module2_*_recv(r'4);
- *  | | | | | | | | | TALLOC_FREE(r'4)
- *  | | | | | | | | | tevent_req_done(r'3);
- *  | | | | | | | | | |
- *  | | | | | | | | | | module1_*_done(r'3):
- *  | | | | | | | | | | |
- *  | | | | | | | | | | | SMB_VFS_*_recv(r'3); # smb_vfs_call_*_recv()
- *  | | | | | | | | | | | TALLOC_FREE(r'3)
- *  | | | | | | | | | | | tevent_req_done(r'2);
- *  | | | | | | | | | | | |
- *  | | | | | | | | | | | | smb_vfs_*_done(r'2);
- *  | | | | | | | | | | | | |
- *  | | | | | | | | | | | | | module1_*_recv(r'2);
- *  | | | | | | | | | | | | | TALLOC_FREE(r'2)
- *  | | | | | | | | | | | | | tevent_req_done(r'1);
- *  | | | | | | | | | | | | | |
- *  | | | | | | | | | | | | | | smbd_*_done(r'1);
- *  | | | | | | | | | | | | | | |
- *  | | | | | | | | | | | | | | | SMB_VFS_*_recv(r'1); # smb_vfs_call_*_recv()
- *  | | | | | | | | | | | | | | | TALLOC_FREE(r'1)
- *  | | | | | | | | | | | | | | | smbd_response_to_client()
- *  | | | | | | | | | | | | | | | return
- *  | | | | | | | | | | | | | | |
- *  | | | | | | | | | | | | | | return
- *  | | | | | | | | | | | | | |
- *  | | | | | | | | | | | | | return
- *  | | | | | | | | | | | | |
- *  | | | | | | | | | | | | return
- *  | | | | | | | | | | | |
- *  | | | | | | | | | | | return
- *  | | | | | | | | | | |
- *  | | | | | | | | | | return
- *  | | | | | | | | | |
- *  | | | | | | | | | return
- *  | | | | | | | | |
- *  | | | | | | | | return
- *  | | | | | | | |
- *  | | | | | | | return
- *  | | | | | | |
- *  | | | | | | return
- *  | | | | | |
- *  | | | | | return
- *  | | | | |
- *  | | | | return
- *  | | | |
- *  | | | return
- *  | | |
- *  | | return
- *  | |
- *  | after_immediate_handler(ev'6);
- *  | |
- *  | | # lazy no change_to_user()
- *  | |
- *  | return
- *
- *
- * Example 2: start with user_evg and let module1 switch to root
- *
- * SMBD: already impersonated user_evg
- *  evg'1 = smb2_req->user_evg
- *  r'1 = SMB_VFS_*_SEND(evg'1); # smb_vfs_call_*_send()
- *  |
- *  | smb_vfs_ev_glue_push_use(evg'1, r'1);
- *  | |
- *  | | # no-op run_ev == return_ev
- *  | |
- *  | evg'2 = evg'1->next_glue;
- *  | r'2 = module1_*_send(evg'2);
- *  | |
- *  | | evg'3 = smb_vfs_ev_glue_get_root_glue(evg'2)
- *  | | r'3 = SMB_VFS_*_NEXT_SEND(evg'3); # smb_vfs_call_*_send()
- *  | | |
- *  | | | smb_vfs_ev_glue_push_use(evg'3, r'3);
- *  | | | |
- *  | | | | tevent_req_defer_callback(r'3, evg'3->return_ev);
- *  | | | | tevent_context_push_use(evg'3->run_ev)
- *  | | | | |
- *  | | | | | become_root()
- *  | | | | |
- *  | | | |
- *  | | | evg'4 = evg'3->next_glue;
- *  | | | r'4 = module2_*_send(evg'4);
- *  | | | |
- *  | | | | evg'5 = smb_vfs_ev_glue_get_root_glue(evg'4)
- *  | | | | r'5 = SMB_VFS_*_NEXT_SEND(evg'5); # smb_vfs_call_*_send()
- *  | | | | |
- *  | | | | | smb_vfs_ev_glue_push_use(evg'5, r'5);
- *  | | | | | |
- *  | | | | | | # no-op run_ev == return_ev, already root
- *  | | | | | |
- *  | | | | | evg'6 = evg'5->next_glue;
- *  | | | | | r'6 = default_*_send(evg'6);
- *  | | | | | |
- *  | | | | | | ev'6 = smb_vfs_ev_glue_ev_ctx(evg'6)
- *  | | | | | | tp'6 = smb_vfs_ev_glue_tp_chdir_safe(evg'6)
- *  | | | | | | r'7 = pthreadpool_tevent_send(ev'6, tp'6);
- *  | | | | | | |
- *  | | | | | | | pthread_create...
- *  | | | | | | |
- *  | | | | | | tevent_req_set_callback(r'7, default_*_done, r'6);
- *  | | | | | |
- *  | | | | | smb_vfs_ev_glue_pop_use(evg'5);
- *  | | | | | |
- *  | | | | | | # no-op run_ev == return_ev, still stay as root
- *  | | | | | |
- *  | | | | | tevent_req_set_callback(r'6, smb_vfs_*_done, r'5);
- *  | | | | |
- *  | | | | tevent_req_set_callback(r'5, module2_*_done, r'4);
- *  | | | |
- *  | | | smb_vfs_ev_glue_pop_use(evg'3);
- *  | | | |
- *  | | | | tevent_context_pop_use(evg'3->run_ev)
- *  | | | | |
- *  | | | | | unbecome_root()
- *  | | | |
- *  | | | tevent_req_set_callback(r'4, smb_vfs_*_done, r'3);
- *  | | |
- *  | | tevent_req_set_callback(r'3, module1_*_done, r'2);
- *  | |
- *  | smb_vfs_ev_glue_pop_use(evg'1);
- *  | |
- *  | | # no-op run_ev == return_ev
- *  | |
- *  | tevent_req_set_callback(r'2, smb_vfs_*_done, r'1);
- *  |
- *  tevent_req_set_callback(r'1, smbd_*_done, smb2_req);
- *
- *  Worker thread finished, just one event handler processes
- *  everything as there's no impersonation change.
- *
- *  tevent_common_invoke_immediate_handler:
- *  |
- *  | before_immediate_handler(ev'6);
- *  | |
- *  | | become_root()
- *  | |
- *  | pthreadpool_tevent_job_done(r'7);
- *  | |
- *  | | default_*_done(r'7);
- *  | | |
- *  | | | pthreadpool_tevent_recv(r'7);
- *  | | | TALLOC_FREE(r'7);
- *  | | | tevent_req_done('r6);
- *  | | | |
- *  | | | | smb_vfs_*_done(r'6);
- *  | | | | |
- *  | | | | | default_*_recv(r'6);
- *  | | | | | TALLOC_FREE(r'6)
- *  | | | | | tevent_req_done(r'5);
- *  | | | | | |
- *  | | | | | | module2_*_done(r'5):
- *  | | | | | | |
- *  | | | | | | | SMB_VFS_*_recv(r'5);
- *  | | | | | | | TALLOC_FREE(r'5)
- *  | | | | | | | tevent_req_done(r'4);
- *  | | | | | | | |
- *  | | | | | | | | smb_vfs_*_done(r'4);
- *  | | | | | | | | |
- *  | | | | | | | | | module2_*_recv(r'4);
- *  | | | | | | | | | TALLOC_FREE(r'4)
- *  | | | | | | | | | tevent_req_done(r'3);
- *  | | | | | | | | | | return
- *  | | | | | | | | | |
- *  | | | | | | | | | return
- *  | | | | | | | | |
- *  | | | | | | | | return
- *  | | | | | | | |
- *  | | | | | | | return
- *  | | | | | | |
- *  | | | | | | return
- *  | | | | | |
- *  | | | | | return
- *  | | | | |
- *  | | | | return
- *  | | | |
- *  | | | return
- *  | | |
- *  | | return
- *  | |
- *  | |
- *  | after_immediate_handler(ev'6);
- *  | |
- *  | | unbecome_root()
- *  | |
- *  | return
- *  |
- *  tevent_common_invoke_immediate_handler:
- *  |
- *  | before_immediate_handler(ev'6);
- *  | |
- *  | | change_to_user()
- *  | |
- *  | tevent_req_trigger();
- *  | ...
- *  | _tevent_req_notify_callback(r'3)
- *  | |
- *  | | module1_*_done(r'3):
- *  | | |
- *  | | | SMB_VFS_*_recv(r'3);
- *  | | | TALLOC_FREE(r'3)
- *  | | | tevent_req_done(r'2);
- *  | | | |
- *  | | | | smb_vfs_*_done(r'2);
- *  | | | | |
- *  | | | | | module1_*_recv(r'2);
- *  | | | | | TALLOC_FREE(r'2)
- *  | | | | | tevent_req_done(r'1);
- *  | | | | | |
- *  | | | | | | smbd_*_done(r'1);
- *  | | | | | | |
- *  | | | | | | | SMB_VFS_*_recv(r'1);
- *  | | | | | | | TALLOC_FREE(r'1)
- *  | | | | | | | smbd_response_to_client()
- *  | | | | | | | return
- *  | | | | | | |
- *  | | | | | | return
- *  | | | | | |
- *  | | | | | return
- *  | | | | |
- *  | | | | return
- *  | | | |
- *  | | | return
- *  | | |
- *  | | return
- *  | |
- *  | after_immediate_handler(ev'6);
- *  | |
- *  | | # lazy no change_to_user()
- *  | |
- *  | return
- *
- */
-struct smb_vfs_ev_glue {
-	/*
-	 * The event context that should be used
-	 * to report the result back.
-	 *
-	 * The is basically the callers context.
-	 */
-	struct tevent_context *return_ev;
-
-	/*
-	 * The event context and threadpool wrappers
-	 * the current context should use.
-	 *
-	 * tp_fd_safe only allows fd based functions
-	 * which don't require impersonation, this
-	 * is basically the raw threadpool.
-	 *
-	 * tp_path_safe allows path based functions
-	 * to be called under the correct impersonation.
-	 * But chdir/fchdir is not allowed!
-	 * Typically calls like openat() or other *at()
-	 * syscalls.
-	 *
-	 * tp_chdir_safe is like path_safe, but also
-	 * allows chdir/fchdir to be called, the job
-	 * can safely return with a changed directory,
-	 * the threadpool wrapper takes care of
-	 * a cleanup if required.
-	 * This is needed if *at() syscalls need
-	 * to be simulated by fchdir();$syscall(),
-	 * e.g. getxattr().
-	 *
-	 * The distinction between these threadpool
-	 * is required because of OS limitations
-	 * (as of 2018):
-	 * - only Linux supports per thread
-	 *   credentials (seteuid....)
-	 * - only Linux supports a per thread
-	 *   current working directory,
-	 *   using unshare(CLONE_FS). But
-	 *   in some constrained container
-	 *   environments even that is not available
-	 *   on Linux.
-	 *
-	 * tp_fd_safe is typically the raw threadpool
-	 * without a wrapper.
-	 *
-	 * On Linux tp_path_safe and tp_chdir_safe
-	 * are typically the same (if unshare(CLONE_FS) is available)
-	 * they're implemented as wrappers of the raw threadpool.
-	 *
-	 * On other OSes tp_path_safe is a wrapper
-	 * arround a sync threadpool (without real threads, just blocking
-	 * the main thread), but hidden behind the pthreadpool_tevent
-	 * api in order to make the restriction transparent.
-	 *
-	 * On other OSes tp_chdir_safe is a wrapper
-	 * arround a sync threadpool (without real threads, just blocking
-	 * the main thread), but hidden behind the pthreadpool_tevent
-	 * api in order to make the restriction transparent.
-	 * It just remembers/restores the current working directory,
-	 * typically using open(".", O_RDONLY | O_DIRECTORY) and fchdir().
-	 */
-	struct tevent_context *run_ev;
-	struct pthreadpool_tevent *run_tp_fd_safe;
-	struct pthreadpool_tevent *run_tp_path_safe;
-	struct pthreadpool_tevent *run_tp_chdir_safe;
-
-	/*
-	 * The glue that should be passed down
-	 * to sub request in the stack.
-	 *
-	 * Typically this points to itself.
-	 *
-	 * But smb_vfs_ev_glue_create_switch() allows
-	 * to create context that can switch
-	 * between two user glues.
-	 */
-	const struct smb_vfs_ev_glue *next_glue;
-
-	/*
-	 * If some code path wants to run
-	 * some constraint code as root,
-	 * basically an async version of become_root()
-	 * and unbecome_root().
-	 *
-	 * The caller can call smb_vfs_ev_glue_get_root_glue()
-	 * to get a root glue that can be passed
-	 * to the SMB_VFS_*_SEND() function that
-	 * should run as root.
-	 *
-	 * Note that the callback (registered with
-	 * tevent_req_set_callback()) won't run as
-	 * root anymore!
-	 */
-	const struct smb_vfs_ev_glue *root_glue;
-};
-
-static struct smb_vfs_ev_glue *smb_vfs_ev_glue_create_internal(
-	TALLOC_CTX *mem_ctx,
-	struct tevent_context *return_ev,
-	struct tevent_context *run_ev,
-	struct pthreadpool_tevent *run_tp_fd_safe,
-	struct pthreadpool_tevent *run_tp_path_safe,
-	struct pthreadpool_tevent *run_tp_chdir_safe)
-{
-	struct smb_vfs_ev_glue *evg = NULL;
-
-	evg = talloc_zero(mem_ctx, struct smb_vfs_ev_glue);
-	if (evg == NULL) {
-		return NULL;
-	}
-	*evg = (struct smb_vfs_ev_glue) {
-		.return_ev = return_ev,
-		.run_ev = run_ev,
-		.run_tp_fd_safe = run_tp_fd_safe,
-		.run_tp_path_safe = run_tp_path_safe,
-		.run_tp_chdir_safe = run_tp_chdir_safe,
-		.next_glue = evg,
-	};
-
-	return evg;
-}
-
-struct tevent_context *smb_vfs_ev_glue_ev_ctx(const struct smb_vfs_ev_glue *evg)
-{
-	return evg->run_ev;
-}
-
-struct pthreadpool_tevent *smb_vfs_ev_glue_tp_fd_safe(const struct smb_vfs_ev_glue *evg)
-{
-	return evg->run_tp_fd_safe;
-}
-
-struct pthreadpool_tevent *smb_vfs_ev_glue_tp_path_safe(const struct smb_vfs_ev_glue *evg)
-{
-	return evg->run_tp_path_safe;
-}
-
-struct pthreadpool_tevent *smb_vfs_ev_glue_tp_chdir_safe(const struct smb_vfs_ev_glue *evg)
-{
-	return evg->run_tp_chdir_safe;
-}
-
-const struct smb_vfs_ev_glue *smb_vfs_ev_glue_get_root_glue(const struct smb_vfs_ev_glue *evg)
-{
-	return evg->root_glue;
-}
-
-struct smb_vfs_ev_glue *smb_vfs_ev_glue_create(TALLOC_CTX *mem_ctx,
-				struct tevent_context *user_ev,
-				struct pthreadpool_tevent *user_tp_fd_safe,
-				struct pthreadpool_tevent *user_tp_path_safe,
-				struct pthreadpool_tevent *user_tp_chdir_safe,
-				struct tevent_context *root_ev,
-				struct pthreadpool_tevent *root_tp_fd_safe,
-				struct pthreadpool_tevent *root_tp_path_safe,
-				struct pthreadpool_tevent *root_tp_chdir_safe)
-{
-	struct smb_vfs_ev_glue *evg_uu = NULL;
-	struct smb_vfs_ev_glue *evg_ru = NULL;
-	struct smb_vfs_ev_glue *evg_rr = NULL;
-
-	/*
-	 * The top level glue (directly returned from this function).
-	 *
-	 * It uses user_ev and user_tp_* only.
-	 */
-	evg_uu = smb_vfs_ev_glue_create_internal(mem_ctx,
-						 user_ev, /* return_ev */
-						 user_ev, /* run_ev */
-						 user_tp_fd_safe,
-						 user_tp_path_safe,
-						 user_tp_chdir_safe);
-	if (evg_uu == NULL) {
-		return NULL;
-	}
-
-	/*
-	 * The first root glue (returned by smb_vfs_ev_glue_get_root_glue()).
-	 *
-	 * It uses root_ev and root_tp, but user_ev as return ev,
-	 * which means that the caller's callback (registered with
-	 * tevent_req_set_callback()) will run as user_ev.
-	 */
-	evg_ru = smb_vfs_ev_glue_create_internal(evg_uu,
-						 user_ev, /* return_ev */
-						 root_ev, /* run_ev */
-						 root_tp_fd_safe,
-						 root_tp_path_safe,
-						 root_tp_chdir_safe);
-	if (evg_ru == NULL) {
-		TALLOC_FREE(evg_uu);
-		return NULL;
-	}
-
-	/*
-	 * The second root glue (returned by smb_vfs_ev_glue_get_root_glue() on
-	 * root glue itself. This means code can always call
-	 * smb_vfs_ev_glue_get_root_glue() and don't have to care if the
-	 * passed glue is already a root glue.
-	 *
-	 * This will then recursively point to its own root_glue pointer.
-	 *
-	 * It only uses root_ev and root_tp.
-	 */
-	evg_rr = smb_vfs_ev_glue_create_internal(evg_ru,
-						 root_ev, /* return_ev */
-						 root_ev, /* run_ev */
-						 root_tp_fd_safe,
-						 root_tp_path_safe,
-						 root_tp_chdir_safe);
-	if (evg_rr == NULL) {
-		TALLOC_FREE(evg_uu);
-		return NULL;
-	}
-
-	/*
-	 * We now setup the glue hierarchy.
-	 *
-	 * Search for "Design of the smb_vfs_ev_glue infrastructure" above
-	 * for a detailed description how the chain works.
-	 *
-	 * "Example 2: start with user_evg and let module1 switch to root"
-	 * explains it for the root_glue chaining.
-	 */
-	evg_rr->root_glue = evg_rr;
-	evg_ru->root_glue = evg_rr;
-	evg_uu->root_glue = evg_ru;
-
-	/*
-	 * As evg_ru is a boundary with
-	 * run_ev != return_ev, we need to
-	 * alter its next_glue.
-	 */
-	evg_ru->next_glue = evg_rr;
-
-	return evg_uu;
-}
-
-/*
- * This can be used to create a temporary glue
- * if you need to switch between two user contexts
- *
- * It's the caller's duty to make sure both
- * glues stay alive for the lifetime of the
- * created switch.
- */
-struct smb_vfs_ev_glue *smb_vfs_ev_glue_create_switch(
-			TALLOC_CTX *mem_ctx,
-			const struct smb_vfs_ev_glue *return_evg,
-			const struct smb_vfs_ev_glue *run_evg)
-{
-	const struct smb_vfs_ev_glue *run_root = run_evg->root_glue;
-	struct smb_vfs_ev_glue *evg_u = NULL;
-	struct smb_vfs_ev_glue *evg_r = NULL;
-
-	/*
-	 * Here we basically need to dup run_evg (and run_evg->root_glue)
-	 * and replace their return_ev with return_evg->return_ev.
-	 *
-	 * We need to put the new evgs in front of the chain...
-	 */
-	evg_u = smb_vfs_ev_glue_create_internal(mem_ctx,
-						return_evg->return_ev,
-						run_evg->run_ev,
-						run_evg->run_tp_fd_safe,
-						run_evg->run_tp_path_safe,
-						run_evg->run_tp_chdir_safe);
-	if (evg_u == NULL) {
-		return NULL;
-	}
-
-	evg_r = smb_vfs_ev_glue_create_internal(evg_u,
-						return_evg->return_ev,
-						run_root->run_ev,
-						run_root->run_tp_fd_safe,
-						run_root->run_tp_path_safe,
-						run_root->run_tp_chdir_safe);
-	if (evg_r == NULL) {
-		return NULL;
-	}
-
-	/*
-	 * evg_r is a boundary with run_ev != return_ev.
-	 * As run_root is also a boundary, we need to
-	 * use run_root->next_glue in order to get
-	 * a glue that stays as root.
-	 *
-	 * The same applies to the chaining of root
-	 * glues.
-	 */
-	evg_r->next_glue = run_root->next_glue;
-	evg_r->root_glue = run_root->root_glue;
-
-	/*
-	 * evg_r is a boundary with run_ev != return_ev.
-	 * But run_evg is typically not a boundary,
-	 * we use it directly as next_glue.
-	 *
-	 * And the root_glue is the one we constructed above.
-	 */
-	evg_u->next_glue = run_evg;
-	evg_u->root_glue = evg_r;
-
-	return evg_u;
-}
-
 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
 			 const char *service, const char *user)
 {
-- 
2.17.2


From 476bac0609ba73bfd2d96257c20c2e996416ccaf Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:34:00 +0100
Subject: [PATCH 14/56] Revert "smbd: introduce sconn->sync_thread_pool"

This reverts commit 0c97226356f2ba5f01a58d361371055caf11e2a7.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h |  1 -
 source3/smbd/msdfs.c   | 12 ------------
 source3/smbd/process.c | 16 +---------------
 3 files changed, 1 insertion(+), 28 deletions(-)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 3ffd921691f..68fc025f223 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -945,7 +945,6 @@ struct smbd_server_connection {
 		} locks;
 	} smb2;
 
-	struct pthreadpool_tevent *sync_thread_pool;
 	struct pthreadpool_tevent *raw_thread_pool;
 
 	struct smbXsrv_client *client;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 9b0b2de27ca..5283edbecfc 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -33,7 +33,6 @@
 #include "libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_dfsblobs.h"
 #include "lib/tsocket/tsocket.h"
-#include "lib/pthreadpool/pthreadpool_tevent.h"
 
 /**********************************************************************
  Parse a DFS pathname of the form \hostname\service\reqpath
@@ -253,7 +252,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 	const char *vfs_user;
 	struct smbd_server_connection *sconn;
 	const char *servicename = lp_const_servicename(snum);
-	int ret;
 
 	sconn = talloc_zero(ctx, struct smbd_server_connection);
 	if (sconn == NULL) {
@@ -277,16 +275,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	/*
-	 * We only provide sync threadpools.
-	 */
-	ret = pthreadpool_tevent_init(sconn, 0, &sconn->sync_thread_pool);
-	if (ret != 0) {
-		TALLOC_FREE(sconn);
-		return NT_STATUS_NO_MEMORY;
-	}
-	sconn->raw_thread_pool = sconn->sync_thread_pool;
-
 	sconn->msg_ctx = msg;
 
 	conn = conn_new(sconn);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 3d823914647..b15bb6d29e3 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3907,7 +3907,6 @@ void smbd_process(struct tevent_context *ev_ctx,
 	const char *locaddr = NULL;
 	const char *remaddr = NULL;
 	int ret;
-	size_t max_threads;
 	NTSTATUS status;
 	struct timeval tv = timeval_current();
 	NTTIME now = timeval_to_nttime(&tv);
@@ -3953,20 +3952,7 @@ void smbd_process(struct tevent_context *ev_ctx,
 	ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
 				      &sconn->raw_thread_pool);
 	if (ret != 0) {
-		exit_server("pthreadpool_tevent_init(raw) failed.");
-	}
-
-	max_threads = pthreadpool_tevent_max_threads(sconn->raw_thread_pool);
-	if (max_threads == 0) {
-		/*
-		 * We only have a sync pool, no need to create a 2nd one.
-		 */
-		sconn->sync_thread_pool = sconn->raw_thread_pool;
-	} else {
-		ret = pthreadpool_tevent_init(sconn, 0, &sconn->sync_thread_pool);
-		if (ret != 0) {
-			exit_server("pthreadpool_tevent_init(sync) failed.");
-		}
+		exit_server("pthreadpool_tevent_init() failed.");
 	}
 
 	sconn->root_ut = root_unix_token(sconn);
-- 
2.17.2


From 843a93835f747b44579bffb416ea394b21d52383 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:34:20 +0100
Subject: [PATCH 15/56] smbd: rename sconn->raw_thread_pool to sconn->pool

This is basically a revert of commit
2be7518ae5a3c046f5fca04ecc83f9f7044eac74.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_aio_pthread.c   | 2 +-
 source3/modules/vfs_default.c       | 9 ++++-----
 source3/smbd/globals.h              | 2 +-
 source3/smbd/process.c              | 2 +-
 source3/smbd/smb2_query_directory.c | 6 +++---
 5 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/source3/modules/vfs_aio_pthread.c b/source3/modules/vfs_aio_pthread.c
index da1ca534907..c1d1a7d518a 100644
--- a/source3/modules/vfs_aio_pthread.c
+++ b/source3/modules/vfs_aio_pthread.c
@@ -277,7 +277,7 @@ static int open_async(const files_struct *fsp,
 
 	subreq = pthreadpool_tevent_job_send(opd,
 					     fsp->conn->user_ev_ctx,
-					     fsp->conn->sconn->raw_thread_pool,
+					     fsp->conn->sconn->pool,
 					     aio_open_worker, opd);
 	if (subreq == NULL) {
 		return -1;
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 6a8245b3942..09a6eaf5477 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -686,7 +686,7 @@ static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
 	SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
 
 	subreq = pthreadpool_tevent_job_send(
-		state, ev, handle->conn->sconn->raw_thread_pool,
+		state, ev, handle->conn->sconn->pool,
 		vfs_pread_do, state);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -804,7 +804,7 @@ static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle,
 	SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
 
 	subreq = pthreadpool_tevent_job_send(
-		state, ev, handle->conn->sconn->raw_thread_pool,
+		state, ev, handle->conn->sconn->pool,
 		vfs_pwrite_do, state);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -914,8 +914,7 @@ static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle,
 	SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
 
 	subreq = pthreadpool_tevent_job_send(
-		state, ev, handle->conn->sconn->raw_thread_pool,
-		vfs_fsync_do, state);
+		state, ev, handle->conn->sconn->pool, vfs_fsync_do, state);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -3023,7 +3022,7 @@ static struct tevent_req *vfswrap_getxattrat_send(
 	subreq = pthreadpool_tevent_job_send(
 			state,
 			ev,
-			dir_fsp->conn->sconn->raw_thread_pool,
+			dir_fsp->conn->sconn->pool,
 			vfswrap_getxattrat_do,
 			state);
 	if (tevent_req_nomem(subreq, req)) {
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 68fc025f223..9b01ddda5ec 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -945,7 +945,7 @@ struct smbd_server_connection {
 		} locks;
 	} smb2;
 
-	struct pthreadpool_tevent *raw_thread_pool;
+	struct pthreadpool_tevent *pool;
 
 	struct smbXsrv_client *client;
 };
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index b15bb6d29e3..4f9e5d1d71b 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3950,7 +3950,7 @@ void smbd_process(struct tevent_context *ev_ctx,
 	sconn->msg_ctx = msg_ctx;
 
 	ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
-				      &sconn->raw_thread_pool);
+				      &sconn->pool);
 	if (ret != 0) {
 		exit_server("pthreadpool_tevent_init() failed.");
 	}
diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c
index 782ccb62d8e..65824ca4677 100644
--- a/source3/smbd/smb2_query_directory.c
+++ b/source3/smbd/smb2_query_directory.c
@@ -515,14 +515,14 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
 	if (state->async_dosmode) {
 		size_t max_threads;
 
-		max_threads = pthreadpool_tevent_max_threads(conn->sconn->raw_thread_pool);
+		max_threads = pthreadpool_tevent_max_threads(conn->sconn->pool);
 
 		state->max_async_dosmode_active = lp_smbd_max_async_dosmode(
 							SNUM(conn));
 		if (state->max_async_dosmode_active == 0) {
 			state->max_async_dosmode_active = max_threads * 2;
 		}
-		if (!pthreadpool_tevent_per_thread_cwd(conn->sconn->raw_thread_pool)) {
+		if (!pthreadpool_tevent_per_thread_cwd(conn->sconn->pool)) {
 			state->max_async_dosmode_active = 1;
 		}
 	}
@@ -663,7 +663,7 @@ static bool smb2_query_directory_next_entry(struct tevent_req *req)
 		state->async_dosmode_active++;
 
 		outstanding_aio = pthreadpool_tevent_queued_jobs(
-					state->fsp->conn->sconn->raw_thread_pool);
+					state->fsp->conn->sconn->pool);
 
 		if (outstanding_aio > state->max_async_dosmode_active) {
 			stop = true;
-- 
2.17.2


From ca4454cdc4482c0e5f031f10ac44398582e9ac58 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:42:37 +0100
Subject: [PATCH 16/56] Revert "pthreadpool: test cancelling and freeing jobs
 of a wrapped pthreadpool_tevent"

This reverts commit fb6b6cf3e43165ced4b1039f2683d19f277c0792.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/tests_cmocka.c | 573 ---------------------------------
 1 file changed, 573 deletions(-)

diff --git a/lib/pthreadpool/tests_cmocka.c b/lib/pthreadpool/tests_cmocka.c
index b5b6b4cc624..5c7f6ab6904 100644
--- a/lib/pthreadpool/tests_cmocka.c
+++ b/lib/pthreadpool/tests_cmocka.c
@@ -543,9 +543,6 @@ struct test_cancel_state {
 	struct test_cancel_job *job4;
 	struct test_cancel_job *job5;
 	struct test_cancel_job *job6;
-	struct test_cancel_job *job7;
-	struct test_cancel_job *job8;
-	struct test_cancel_job *job9;
 };
 
 static void test_cancel_job(void **private_data)
@@ -808,573 +805,6 @@ static void test_cancel_job(void **private_data)
 	TALLOC_FREE(state);
 }
 
-struct test_pthreadpool_tevent_wrap_tp_stats {
-	unsigned num_before;
-	unsigned num_after;
-	bool destroyed;
-};
-
-struct test_pthreadpool_tevent_wrap_tp_state {
-	struct test_pthreadpool_tevent_wrap_tp_state **selfptr;
-	struct test_pthreadpool_tevent_wrap_tp_stats *stats;
-};
-
-static int test_pthreadpool_tevent_wrap_tp_state_destructor(
-	struct test_pthreadpool_tevent_wrap_tp_state *state)
-{
-	state->stats->destroyed = true;
-	*state->selfptr = NULL;
-
-	return 0;
-}
-
-static bool test_pthreadpool_tevent_tp_before(struct pthreadpool_tevent *wrap,
-					      void *private_data,
-					      struct pthreadpool_tevent *main,
-					      const char *location)
-{
-	struct test_pthreadpool_tevent_wrap_tp_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_pthreadpool_tevent_wrap_tp_state);
-
-	state->stats->num_before++;
-
-	return true;
-}
-
-static bool test_pthreadpool_tevent_tp_after(struct pthreadpool_tevent *wrap,
-					     void *private_data,
-					     struct pthreadpool_tevent *main,
-					     const char *location)
-{
-	struct test_pthreadpool_tevent_wrap_tp_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_pthreadpool_tevent_wrap_tp_state);
-
-	state->stats->num_after++;
-
-	return true;
-}
-
-static const struct pthreadpool_tevent_wrapper_ops test_tp_ops = {
-	.name		= "test_pthreadpool_tevent_tp",
-	.before_job	= test_pthreadpool_tevent_tp_before,
-	.after_job	= test_pthreadpool_tevent_tp_after,
-};
-
-static void test_wrap_cancel_job(void **private_data)
-{
-	struct pthreadpool_tevent_test *t = *private_data;
-	struct tevent_context *ev = t->ev;
-	struct pthreadpool_tevent *poolw1 = NULL;
-	struct test_pthreadpool_tevent_wrap_tp_state *poolw1_state = NULL;
-	struct test_pthreadpool_tevent_wrap_tp_stats poolw1_stats = {
-		.destroyed = false,
-	};
-	struct pthreadpool_tevent *poolw2 = NULL;
-	struct test_pthreadpool_tevent_wrap_tp_state *poolw2_state = NULL;
-	struct test_pthreadpool_tevent_wrap_tp_stats poolw2_stats = {
-		.destroyed = false,
-	};
-	size_t max_threads_o;
-	size_t max_threads_w1;
-	size_t max_threads_w2;
-	bool per_thread_cwd_o;
-	bool per_thread_cwd_w1;
-	bool per_thread_cwd_w2;
-	struct test_cancel_state *state = NULL;
-	int ret;
-	bool ok;
-	int fdpair[2] = { -1, -1 };
-	char c = 0;
-
-	max_threads_o = pthreadpool_tevent_max_threads(t->opool);
-	per_thread_cwd_o = pthreadpool_tevent_per_thread_cwd(t->opool);
-
-	poolw1 = pthreadpool_tevent_wrapper_create(
-		t->opool, t, &test_tp_ops, &poolw1_state,
-		struct test_pthreadpool_tevent_wrap_tp_state);
-	assert_non_null(poolw1);
-	poolw1_state->selfptr = &poolw1_state;
-	ANNOTATE_BENIGN_RACE_SIZED(&poolw1_stats,
-				   sizeof(poolw1_stats),
-				   "protected by pthreadpool_tevent code");
-	poolw1_state->stats = &poolw1_stats;
-	talloc_set_destructor(poolw1_state,
-			      test_pthreadpool_tevent_wrap_tp_state_destructor);
-
-	poolw2 = pthreadpool_tevent_wrapper_create(
-		t->opool, t, &test_tp_ops, &poolw2_state,
-		struct test_pthreadpool_tevent_wrap_tp_state);
-	assert_non_null(poolw2);
-	poolw2_state->selfptr = &poolw2_state;
-	ANNOTATE_BENIGN_RACE_SIZED(&poolw2_stats,
-				   sizeof(poolw2_stats),
-				   "protected by pthreadpool_tevent code");
-	poolw2_state->stats = &poolw2_stats;
-	talloc_set_destructor(poolw2_state,
-			      test_pthreadpool_tevent_wrap_tp_state_destructor);
-
-	assert_false(poolw1_stats.destroyed);
-	assert_int_equal(poolw1_stats.num_before, 0);
-	assert_int_equal(poolw1_stats.num_after, 0);
-	max_threads_w1 = pthreadpool_tevent_max_threads(poolw1);
-	assert_int_equal(max_threads_w1, max_threads_o);
-	per_thread_cwd_w1 = pthreadpool_tevent_per_thread_cwd(poolw1);
-	assert_int_equal(per_thread_cwd_w1, per_thread_cwd_o);
-
-	assert_false(poolw2_stats.destroyed);
-	assert_int_equal(poolw2_stats.num_before, 0);
-	assert_int_equal(poolw2_stats.num_after, 0);
-	max_threads_w2 = pthreadpool_tevent_max_threads(poolw2);
-	assert_int_equal(max_threads_w2, max_threads_o);
-	per_thread_cwd_w2 = pthreadpool_tevent_per_thread_cwd(poolw2);
-	assert_int_equal(per_thread_cwd_w2, per_thread_cwd_o);
-
-	state = talloc_zero(t, struct test_cancel_state);
-	assert_non_null(state);
-	state->job1 = test_cancel_job_create(state);
-	assert_non_null(state->job1);
-	state->job2 = test_cancel_job_create(state);
-	assert_non_null(state->job2);
-	state->job3 = test_cancel_job_create(state);
-	assert_non_null(state->job3);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job1->fdm = fdpair[0];
-	state->job1->fdj = fdpair[1];
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(t->opool), 0);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw1), 0);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw2), 0);
-
-	will_return(__wrap_pthread_create, 0);
-	state->job1->req = pthreadpool_tevent_job_send(
-		state->job1, ev, poolw1, test_cancel_job_fn, state->job1);
-	assert_non_null(state->job1->req);
-	tevent_req_set_callback(state->job1->req,
-				test_cancel_job_done,
-				state->job1);
-
-	state->job2->req = pthreadpool_tevent_job_send(
-		state->job2, ev, poolw1, test_cancel_job_fn, NULL);
-	assert_non_null(state->job2->req);
-	tevent_req_set_callback(state->job2->req,
-				test_cancel_job_done,
-				state->job2);
-
-	state->job3->req = pthreadpool_tevent_job_send(
-		state->job3, ev, poolw1, test_cancel_job_fn, NULL);
-	assert_non_null(state->job3->req);
-	tevent_req_set_callback(state->job3->req,
-				test_cancel_job_done,
-				state->job3);
-
-	/*
-	 * Wait for the job 1 to start.
-	 */
-	ret = read(state->job1->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	/*
-	 * We cancel job 3 and destroy job2.
-	 * Both should never be executed.
-	 */
-	assert_int_equal(pthreadpool_tevent_queued_jobs(t->opool), 2);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw1), 2);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw2), 2);
-	TALLOC_FREE(state->job2->req);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(t->opool), 1);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw1), 1);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw2), 1);
-	ok = tevent_req_cancel(state->job3->req);
-	assert_true(ok);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(t->opool), 0);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw1), 0);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw2), 0);
-
-	/*
-	 * Job 3 should complete as canceled, while
-	 * job 1 is still running.
-	 */
-	test_cancel_job_wait(state->job3, ev);
-	assert_int_equal(state->job3->ret, ECANCELED);
-	assert_null(state->job3->req);
-	assert_false(state->job3->started);
-
-	/*
-	 * Now job1 is canceled while it's running,
-	 * this should let it stop it's loop.
-	 */
-	ok = tevent_req_cancel(state->job1->req);
-	assert_false(ok);
-
-	/*
-	 * Job 1 completes, It got at least one sleep
-	 * timeout loop and has state->job1->canceled set.
-	 */
-	test_cancel_job_wait(state->job1, ev);
-	assert_int_equal(state->job1->ret, 0);
-	assert_null(state->job1->req);
-	assert_true(state->job1->started);
-	assert_true(state->job1->finished);
-	assert_true(state->job1->canceled);
-	assert_false(state->job1->orphaned);
-	assert_in_range(state->job1->polls, 1, 100);
-	assert_int_equal(state->job1->timeouts, state->job1->polls);
-
-	assert_false(poolw1_stats.destroyed);
-	assert_int_equal(poolw1_stats.num_before, 1);
-	assert_int_equal(poolw1_stats.num_after, 1);
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(t->opool), 0);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw1), 0);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw2), 0);
-
-	/*
-	 * Now we create jobs 4 and 5
-	 * Both should execute.
-	 * Job 4 is orphaned while running by a TALLOC_FREE()
-	 * This should stop job 4 and let job 5 start.
-	 * We do a "normal" exit in job 5 by creating some activity
-	 * on the socketpair.
-	 */
-
-	state->job4 = test_cancel_job_create(state);
-	assert_non_null(state->job4);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job4->fdm = fdpair[0];
-	state->job4->fdj = fdpair[1];
-
-	state->job4->req = pthreadpool_tevent_job_send(
-		state->job4, ev, poolw1, test_cancel_job_fn, state->job4);
-	assert_non_null(state->job4->req);
-	tevent_req_set_callback(state->job4->req,
-				test_cancel_job_done,
-				state->job4);
-
-	state->job5 = test_cancel_job_create(state);
-	assert_non_null(state->job5);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job5->fdm = fdpair[0];
-	state->job5->fdj = fdpair[1];
-
-	state->job5->req = pthreadpool_tevent_job_send(
-		state->job5, ev, poolw1, test_cancel_job_fn, state->job5);
-	assert_non_null(state->job5->req);
-	tevent_req_set_callback(state->job5->req,
-				test_cancel_job_done,
-				state->job5);
-
-	/*
-	 * Make sure job 5 can exit as soon as possible.
-	 * It will never get a sleep/poll timeout.
-	 */
-	ret = write(state->job5->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	/*
-	 * Wait for the job 4 to start
-	 */
-	ret = read(state->job4->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	assert_false(poolw1_stats.destroyed);
-	assert_int_equal(poolw1_stats.num_before, 2);
-	assert_int_equal(poolw1_stats.num_after, 1);
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(t->opool), 1);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw1), 1);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw2), 1);
-
-	/*
-	 * destroy the request so that it's marked
-	 * as orphaned.
-	 *
-	 * As we're in the wrapper mode, the
-	 * job thread will exit and try to create
-	 * a new thread.
-	 */
-	TALLOC_FREE(state->job4->req);
-
-	/*
-	 * Job 5 completes, It got no sleep timeout loop.
-	 */
-	will_return(__wrap_pthread_create, 0);
-	test_cancel_job_wait(state->job5, ev);
-	assert_int_equal(state->job5->ret, 0);
-	assert_null(state->job5->req);
-	assert_true(state->job5->started);
-	assert_true(state->job5->finished);
-	assert_false(state->job5->canceled);
-	assert_false(state->job5->orphaned);
-	assert_int_equal(state->job5->polls, 1);
-	assert_int_equal(state->job5->timeouts, 0);
-
-	assert_false(poolw1_stats.destroyed);
-	assert_int_equal(poolw1_stats.num_before, 3);
-	assert_int_equal(poolw1_stats.num_after, 2);
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(t->opool), 0);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw1), 0);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw2), 0);
-
-	/*
-	 * Job 2 is still not executed as we did a TALLOC_FREE()
-	 * before is was scheduled.
-	 */
-	assert_false(state->job2->completed);
-	assert_false(state->job2->started);
-
-	/*
-	 * Job 4 is still wasn't completed as we did a TALLOC_FREE()
-	 * while it is was running. but it was started and has
-	 * orphaned set
-	 */
-	assert_false(state->job4->completed);
-	assert_true(state->job4->started);
-	assert_true(state->job4->finished);
-	assert_false(state->job4->canceled);
-	assert_true(state->job4->orphaned);
-	assert_in_range(state->job4->polls, 1, 100);
-	assert_int_equal(state->job4->timeouts, state->job4->polls);
-
-	assert_false(poolw1_stats.destroyed);
-	assert_int_equal(poolw1_stats.num_before, 3);
-	assert_int_equal(poolw1_stats.num_after, 2);
-
-	/*
-	 * Now we create jobs 6 and 7
-	 * Both should execute.
-	 * We destroy the pool wrapper (1) while job 6 is executing.
-	 * This should stop job 6 and let job 7 start.
-	 * Job 7 runs on the pool wrapper (2).
-	 * We do a "normal" exit in job 7 by creating some activity
-	 * on the socketpair.
-	 */
-
-	state->job6 = test_cancel_job_create(state);
-	assert_non_null(state->job6);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job6->fdm = fdpair[0];
-	state->job6->fdj = fdpair[1];
-
-	state->job6->req = pthreadpool_tevent_job_send(
-		state->job6, ev, poolw1, test_cancel_job_fn, state->job6);
-	assert_non_null(state->job6->req);
-	tevent_req_set_callback(state->job6->req,
-				test_cancel_job_done,
-				state->job6);
-
-	state->job7 = test_cancel_job_create(state);
-	assert_non_null(state->job7);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job7->fdm = fdpair[0];
-	state->job7->fdj = fdpair[1];
-
-	state->job7->req = pthreadpool_tevent_job_send(
-		state->job7, ev, poolw2, test_cancel_job_fn, state->job7);
-	assert_non_null(state->job7->req);
-	tevent_req_set_callback(state->job7->req,
-				test_cancel_job_done,
-				state->job7);
-
-	/*
-	 * Make sure job 7 can exit as soon as possible.
-	 * It will never get a sleep/poll timeout.
-	 */
-	ret = write(state->job7->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	/*
-	 * Wait for the job 6 to start
-	 */
-	ret = read(state->job6->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	assert_non_null(poolw1_state);
-	assert_false(poolw1_stats.destroyed);
-	assert_int_equal(poolw1_stats.num_before, 4);
-	assert_int_equal(poolw1_stats.num_after, 2);
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(t->opool), 1);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw1), 1);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw2), 1);
-
-	/*
-	 * destroy the request so that it's marked
-	 * as orphaned.
-	 */
-	TALLOC_FREE(poolw1);
-
-	/*
-	 * Wait until the job finished.
-	 */
-	ret = read(state->job6->fdm, &c, 1);
-	assert_int_equal(ret, 0);
-
-	assert_null(poolw1_state);
-	assert_true(poolw1_stats.destroyed);
-	assert_int_equal(poolw1_stats.num_before, 4);
-	assert_int_equal(poolw1_stats.num_after, 2);
-
-	/*
-	 * Job 6 is still dangling arround.
-	 *
-	 * We need to convince valgrind --tool={drd,helgrind}
-	 * that the read above is good enough to be
-	 * sure the job is finished and closed the other end of
-	 * the socketpair.
-	 */
-	ANNOTATE_BENIGN_RACE_SIZED(state->job6,
-				   sizeof(*state->job6),
-				   "protected by thread fence");
-	assert_non_null(state->job6->req);
-	assert_true(tevent_req_is_in_progress(state->job6->req));
-	assert_false(state->job6->completed);
-	assert_true(state->job6->started);
-	assert_true(state->job6->finished);
-	assert_false(state->job6->canceled);
-	assert_true(state->job6->orphaned);
-	assert_in_range(state->job6->polls, 1, 100);
-	assert_int_equal(state->job6->timeouts, state->job4->polls);
-
-	/*
-	 * Job 7 completes, It got no sleep timeout loop.
-	 */
-	will_return(__wrap_pthread_create, 0);
-	test_cancel_job_wait(state->job7, ev);
-	assert_int_equal(state->job7->ret, 0);
-	assert_null(state->job7->req);
-	assert_true(state->job7->started);
-	assert_true(state->job7->finished);
-	assert_false(state->job7->canceled);
-	assert_false(state->job7->orphaned);
-	assert_int_equal(state->job7->polls, 1);
-	assert_int_equal(state->job7->timeouts, 0);
-
-	assert_non_null(poolw2_state);
-	assert_false(poolw2_stats.destroyed);
-	assert_int_equal(poolw2_stats.num_before, 1);
-	assert_int_equal(poolw2_stats.num_after, 1);
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(t->opool), 0);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(poolw2), 0);
-
-	/*
-	 * Now we create jobs 8
-	 * On a new wrapper pool
-	 * We destroy the main pool while it's executing.
-	 */
-
-	state->job8 = test_cancel_job_create(state);
-	assert_non_null(state->job8);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job8->fdm = fdpair[0];
-	state->job8->fdj = fdpair[1];
-
-	state->job8->req = pthreadpool_tevent_job_send(
-		state->job8, ev, poolw2, test_cancel_job_fn, state->job8);
-	assert_non_null(state->job8->req);
-	tevent_req_set_callback(state->job8->req,
-				test_cancel_job_done,
-				state->job8);
-
-	/*
-	 * Wait for the job 8 to start
-	 */
-	ret = read(state->job8->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	assert_false(poolw2_stats.destroyed);
-	assert_int_equal(poolw2_stats.num_before, 2);
-	assert_int_equal(poolw2_stats.num_after, 1);
-
-	/*
-	 * destroy the request so that it's marked
-	 * as orphaned.
-	 */
-	TALLOC_FREE(t->opool);
-
-	/*
-	 * Wait until the job finished.
-	 */
-	ret = read(state->job8->fdm, &c, 1);
-	assert_int_equal(ret, 0);
-
-	assert_null(poolw2_state);
-	assert_true(poolw2_stats.destroyed);
-	assert_int_equal(poolw2_stats.num_before, 2);
-	assert_int_equal(poolw2_stats.num_after, 1);
-
-	/*
-	 * Job 8 is still dangling arround.
-	 *
-	 * We need to convince valgrind --tool={drd,helgrind}
-	 * that the read above is good enough to be
-	 * sure the job is finished and closed the other end of
-	 * the socketpair.
-	 */
-	ANNOTATE_BENIGN_RACE_SIZED(state->job8,
-				   sizeof(*state->job8),
-				   "protected by thread fence");
-	assert_non_null(state->job8->req);
-	assert_true(tevent_req_is_in_progress(state->job8->req));
-	assert_false(state->job8->completed);
-	assert_true(state->job8->started);
-	assert_true(state->job8->finished);
-	assert_false(state->job8->canceled);
-	assert_true(state->job8->orphaned);
-	assert_in_range(state->job8->polls, 1, 100);
-	assert_int_equal(state->job8->timeouts, state->job4->polls);
-
-	/*
-	 * Now check that adding a new job to the dangling
-	 * wrapper gives an error.
-	 */
-	state->job9 = test_cancel_job_create(state);
-	assert_non_null(state->job9);
-
-	state->job9->req = pthreadpool_tevent_job_send(
-		state->job9, ev, poolw2, test_cancel_job_fn, state->job9);
-	assert_non_null(state->job9->req);
-	tevent_req_set_callback(state->job9->req,
-				test_cancel_job_done,
-				state->job9);
-
-	/*
-	 * Job 9 completes, But with a failure.
-	 */
-	test_cancel_job_wait(state->job9, ev);
-	assert_int_equal(state->job9->ret, EINVAL);
-	assert_null(state->job9->req);
-	assert_false(state->job9->started);
-	assert_false(state->job9->finished);
-	assert_false(state->job9->canceled);
-	assert_false(state->job9->orphaned);
-	assert_int_equal(state->job9->polls, 0);
-	assert_int_equal(state->job9->timeouts, 0);
-
-	TALLOC_FREE(state);
-}
-
 int main(int argc, char **argv)
 {
 	const struct CMUnitTest tests[] = {
@@ -1387,9 +817,6 @@ int main(int argc, char **argv)
 		cmocka_unit_test_setup_teardown(test_cancel_job,
 						setup_pthreadpool_tevent,
 						teardown_pthreadpool_tevent),
-		cmocka_unit_test_setup_teardown(test_wrap_cancel_job,
-						setup_pthreadpool_tevent,
-						teardown_pthreadpool_tevent),
 	};
 
 	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
-- 
2.17.2


From 014418e64f2557c9af0ab8fce42d9454a22ecec8 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:42:53 +0100
Subject: [PATCH 17/56] Revert "pthreadpool: implement
 pthreadpool_tevent_wrapper_create() infrastructure"

This reverts commit f9745d8b5234091c38e93ed57a255120b61f3ad7.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 402 +--------------------------
 lib/pthreadpool/pthreadpool_tevent.h |  32 ---
 2 files changed, 1 insertion(+), 433 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index f88f82d17d8..b0a757aa1db 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -104,8 +104,6 @@ struct pthreadpool_tevent_glue {
 	/* Tuple we are keeping track of in this list. */
 	struct tevent_context *ev;
 	struct tevent_threaded_context *tctx;
-	/* recheck monitor fd event */
-	struct tevent_fd *fde;
 	/* Pointer to link object owned by *ev. */
 	struct pthreadpool_tevent_glue_ev_link *ev_link;
 	/* active jobs */
@@ -125,33 +123,11 @@ struct pthreadpool_tevent_glue_ev_link {
 	struct pthreadpool_tevent_glue *glue;
 };
 
-struct pthreadpool_tevent_wrapper {
-	struct pthreadpool_tevent *main_tp;
-	struct pthreadpool_tevent *wrap_tp;
-	const struct pthreadpool_tevent_wrapper_ops *ops;
-	void *private_state;
-	bool force_per_thread_cwd;
-};
-
 struct pthreadpool_tevent {
-	struct pthreadpool_tevent *prev, *next;
-
 	struct pthreadpool *pool;
 	struct pthreadpool_tevent_glue *glue_list;
 
 	struct pthreadpool_tevent_job *jobs;
-
-	struct {
-		/*
-		 * This is used on the main context
-		 */
-		struct pthreadpool_tevent *list;
-
-		/*
-		 * This is used on the wrapper context
-		 */
-		struct pthreadpool_tevent_wrapper *ctx;
-	} wrapper;
 };
 
 struct pthreadpool_tevent_job_state {
@@ -166,7 +142,6 @@ struct pthreadpool_tevent_job {
 	struct pthreadpool_tevent_job *prev, *next;
 
 	struct pthreadpool_tevent *pool;
-	struct pthreadpool_tevent_wrapper *wrapper;
 	struct pthreadpool_tevent_job_state *state;
 	struct tevent_immediate *im;
 
@@ -206,15 +181,6 @@ struct pthreadpool_tevent_job {
 		 */
 		bool started;
 
-		/*
-		 * 'wrapper'
-		 * set before calling the wrapper before_job() or
-		 * after_job() hooks.
-		 * unset again check the hook finished.
-		 * (only written by job thread!)
-		 */
-		bool wrapper;
-
 		/*
 		 * 'executed'
 		 * set once the job function returned.
@@ -244,18 +210,6 @@ struct pthreadpool_tevent_job {
 		 * (only written by job thread!)
 		 */
 		bool signaled;
-
-		/*
-		 * 'exit_thread'
-		 * maybe set during pthreadpool_tevent_job_fn()
-		 * if some wrapper related code generated an error
-		 * and the environment isn't safe anymore.
-		 *
-		 * In such a case pthreadpool_tevent_job_signal()
-		 * will pick this up and therminate the current
-		 * worker thread by returning -1.
-		 */
-		bool exit_thread; /* only written/read by job thread! */
 	} needs_fence;
 
 	bool per_thread_cwd;
@@ -314,22 +268,8 @@ int pthreadpool_tevent_init(TALLOC_CTX *mem_ctx, unsigned max_threads,
 	return 0;
 }
 
-static struct pthreadpool_tevent *pthreadpool_tevent_unwrap(
-	struct pthreadpool_tevent *pool)
-{
-	struct pthreadpool_tevent_wrapper *wrapper = pool->wrapper.ctx;
-
-	if (wrapper != NULL) {
-		return wrapper->main_tp;
-	}
-
-	return pool;
-}
-
 size_t pthreadpool_tevent_max_threads(struct pthreadpool_tevent *pool)
 {
-	pool = pthreadpool_tevent_unwrap(pool);
-
 	if (pool->pool == NULL) {
 		return 0;
 	}
@@ -339,8 +279,6 @@ size_t pthreadpool_tevent_max_threads(struct pthreadpool_tevent *pool)
 
 size_t pthreadpool_tevent_queued_jobs(struct pthreadpool_tevent *pool)
 {
-	pool = pthreadpool_tevent_unwrap(pool);
-
 	if (pool->pool == NULL) {
 		return 0;
 	}
@@ -350,14 +288,6 @@ size_t pthreadpool_tevent_queued_jobs(struct pthreadpool_tevent *pool)
 
 bool pthreadpool_tevent_per_thread_cwd(struct pthreadpool_tevent *pool)
 {
-	struct pthreadpool_tevent_wrapper *wrapper = pool->wrapper.ctx;
-
-	if (wrapper != NULL && wrapper->force_per_thread_cwd) {
-		return true;
-	}
-
-	pool = pthreadpool_tevent_unwrap(pool);
-
 	if (pool->pool == NULL) {
 		return false;
 	}
@@ -369,94 +299,21 @@ static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool)
 {
 	struct pthreadpool_tevent_job *job = NULL;
 	struct pthreadpool_tevent_job *njob = NULL;
-	struct pthreadpool_tevent *wrap_tp = NULL;
-	struct pthreadpool_tevent *nwrap_tp = NULL;
 	struct pthreadpool_tevent_glue *glue = NULL;
 	int ret;
 
-	if (pool->wrapper.ctx != NULL) {
-		struct pthreadpool_tevent_wrapper *wrapper = pool->wrapper.ctx;
-
-		pool->wrapper.ctx = NULL;
-		pool = wrapper->main_tp;
-
-		DLIST_REMOVE(pool->wrapper.list, wrapper->wrap_tp);
-
-		for (job = pool->jobs; job != NULL; job = njob) {
-			njob = job->next;
-
-			if (job->wrapper != wrapper) {
-				continue;
-			}
-
-			/*
-			 * This removes the job from the list
-			 *
-			 * Note that it waits in case
-			 * the wrapper hooks are currently
-			 * executing on the job.
-			 */
-			pthreadpool_tevent_job_orphan(job);
-		}
-
-		/*
-		 * At this point we're sure that no job
-		 * still references the pthreadpool_tevent_wrapper
-		 * structure, so we can free it.
-		 */
-		TALLOC_FREE(wrapper);
-
-		pthreadpool_tevent_cleanup_orphaned_jobs();
-		return 0;
-	}
-
-	if (pool->pool == NULL) {
-		/*
-		 * A dangling wrapper without main_tp.
-		 */
-		return 0;
-	}
-
 	ret = pthreadpool_stop(pool->pool);
 	if (ret != 0) {
 		return ret;
 	}
 
-	/*
-	 * orphan all jobs (including wrapper jobs)
-	 */
 	for (job = pool->jobs; job != NULL; job = njob) {
 		njob = job->next;
 
-		/*
-		 * The job this removes it from the list
-		 *
-		 * Note that it waits in case
-		 * the wrapper hooks are currently
-		 * executing on the job (thread).
-		 */
+		/* The job this removes it from the list */
 		pthreadpool_tevent_job_orphan(job);
 	}
 
-	/*
-	 * cleanup all existing wrappers, remember we just orphaned
-	 * all jobs (including the once of the wrappers).
-	 *
-	 * So we just mark as broken, so that
-	 * pthreadpool_tevent_job_send() won't accept new jobs.
-	 */
-	for (wrap_tp = pool->wrapper.list; wrap_tp != NULL; wrap_tp = nwrap_tp) {
-		nwrap_tp = wrap_tp->next;
-
-		/*
-		 * Just mark them as broken, so that we can't
-		 * get more jobs.
-		 */
-		TALLOC_FREE(wrap_tp->wrapper.ctx);
-
-		DLIST_REMOVE(pool->wrapper.list, wrap_tp);
-	}
-
 	/*
 	 * Delete all the registered
 	 * tevent_context/tevent_threaded_context
@@ -479,93 +336,12 @@ static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool)
 	return 0;
 }
 
-struct pthreadpool_tevent *_pthreadpool_tevent_wrapper_create(
-				struct pthreadpool_tevent *main_tp,
-				TALLOC_CTX *mem_ctx,
-				const struct pthreadpool_tevent_wrapper_ops *ops,
-				void *pstate,
-				size_t psize,
-				const char *type,
-				const char *location)
-{
-	void **ppstate = (void **)pstate;
-	struct pthreadpool_tevent *wrap_tp = NULL;
-	struct pthreadpool_tevent_wrapper *wrapper = NULL;
-
-	pthreadpool_tevent_cleanup_orphaned_jobs();
-
-	if (main_tp->wrapper.ctx != NULL) {
-		/*
-		 * stacking of wrappers is not supported
-		 */
-		errno = EINVAL;
-		return NULL;
-	}
-
-	if (main_tp->pool == NULL) {
-		/*
-		 * The pool is no longer valid,
-		 * most likely it was a wrapper context
-		 * where the main pool was destroyed.
-		 */
-		errno = EINVAL;
-		return NULL;
-	}
-
-	wrap_tp = talloc_zero(mem_ctx, struct pthreadpool_tevent);
-	if (wrap_tp == NULL) {
-		return NULL;
-	}
-
-	wrapper = talloc_zero(wrap_tp, struct pthreadpool_tevent_wrapper);
-	if (wrapper == NULL) {
-		TALLOC_FREE(wrap_tp);
-		return NULL;
-	}
-	wrapper->main_tp = main_tp;
-	wrapper->wrap_tp = wrap_tp;
-	wrapper->ops = ops;
-	wrapper->private_state = talloc_zero_size(wrapper, psize);
-	if (wrapper->private_state == NULL) {
-		TALLOC_FREE(wrap_tp);
-		return NULL;
-	}
-	talloc_set_name_const(wrapper->private_state, type);
-
-	wrap_tp->wrapper.ctx = wrapper;
-
-	DLIST_ADD_END(main_tp->wrapper.list, wrap_tp);
-
-	talloc_set_destructor(wrap_tp, pthreadpool_tevent_destructor);
-
-	*ppstate = wrapper->private_state;
-	return wrap_tp;
-}
-
-void pthreadpool_tevent_force_per_thread_cwd(struct pthreadpool_tevent *pool,
-					     const void *private_state)
-{
-	struct pthreadpool_tevent_wrapper *wrapper = pool->wrapper.ctx;
-
-	if (wrapper == NULL) {
-		abort();
-	}
-
-	if (wrapper->private_state != private_state) {
-		abort();
-	}
-
-	wrapper->force_per_thread_cwd = true;
-}
-
 static int pthreadpool_tevent_glue_destructor(
 	struct pthreadpool_tevent_glue *glue)
 {
 	struct pthreadpool_tevent_job_state *state = NULL;
 	struct pthreadpool_tevent_job_state *nstate = NULL;
 
-	TALLOC_FREE(glue->fde);
-
 	for (state = glue->states; state != NULL; state = nstate) {
 		nstate = state->next;
 
@@ -606,59 +382,6 @@ static int pthreadpool_tevent_glue_link_destructor(
 	return 0;
 }
 
-static void pthreadpool_tevent_glue_monitor(struct tevent_context *ev,
-					    struct tevent_fd *fde,
-					    uint16_t flags,
-					    void *private_data)
-{
-	struct pthreadpool_tevent_glue *glue =
-		talloc_get_type_abort(private_data,
-		struct pthreadpool_tevent_glue);
-	struct pthreadpool_tevent_job *job = NULL;
-	struct pthreadpool_tevent_job *njob = NULL;
-	int ret = -1;
-
-	ret = pthreadpool_restart_check_monitor_drain(glue->pool->pool);
-	if (ret != 0) {
-		TALLOC_FREE(glue->fde);
-	}
-
-	ret = pthreadpool_restart_check(glue->pool->pool);
-	if (ret == 0) {
-		/*
-		 * success...
-		 */
-		goto done;
-	}
-
-	/*
-	 * There's a problem and the pool
-	 * has not a single thread available
-	 * for pending jobs, so we can only
-	 * stop the jobs and return an error.
-	 * This is similar to a failure from
-	 * pthreadpool_add_job().
-	 */
-	for (job = glue->pool->jobs; job != NULL; job = njob) {
-		njob = job->next;
-
-		tevent_req_defer_callback(job->state->req,
-					  job->state->ev);
-		tevent_req_error(job->state->req, ret);
-	}
-
-done:
-	if (glue->states == NULL) {
-		/*
-		 * If the glue doesn't have any pending jobs
-		 * we remove the glue.
-		 *
-		 * In order to remove the fd event.
-		 */
-		TALLOC_FREE(glue);
-	}
-}
-
 static int pthreadpool_tevent_register_ev(
 				struct pthreadpool_tevent *pool,
 				struct pthreadpool_tevent_job_state *state)
@@ -666,7 +389,6 @@ static int pthreadpool_tevent_register_ev(
 	struct tevent_context *ev = state->ev;
 	struct pthreadpool_tevent_glue *glue = NULL;
 	struct pthreadpool_tevent_glue_ev_link *ev_link = NULL;
-	int monitor_fd = -1;
 
 	/*
 	 * See if this tevent_context was already registered by
@@ -699,28 +421,6 @@ static int pthreadpool_tevent_register_ev(
 	};
 	talloc_set_destructor(glue, pthreadpool_tevent_glue_destructor);
 
-	monitor_fd = pthreadpool_restart_check_monitor_fd(pool->pool);
-	if (monitor_fd == -1 && errno != ENOSYS) {
-		int saved_errno = errno;
-		TALLOC_FREE(glue);
-		return saved_errno;
-	}
-
-	if (monitor_fd != -1) {
-		glue->fde = tevent_add_fd(ev,
-					  glue,
-					  monitor_fd,
-					  TEVENT_FD_READ,
-					  pthreadpool_tevent_glue_monitor,
-					  glue);
-		if (glue->fde == NULL) {
-			close(monitor_fd);
-			TALLOC_FREE(glue);
-			return ENOMEM;
-		}
-		tevent_fd_set_auto_close(glue->fde);
-	}
-
 	/*
 	 * Now allocate the link object to the event context. Note this
 	 * is allocated OFF THE EVENT CONTEXT ITSELF, so if the event
@@ -860,24 +560,6 @@ static void pthreadpool_tevent_job_orphan(struct pthreadpool_tevent_job *job)
 		abort();
 	}
 
-	/*
-	 * Once we marked the request as 'orphaned'
-	 * we spin/loop if 'wrapper' is marked as active.
-	 *
-	 * We need to wait until the wrapper hook finished
-	 * before we can set job->wrapper = NULL.
-	 *
-	 * This is some kind of spinlock, but with
-	 * 1 millisecond sleeps in between, in order
-	 * to give the thread more cpu time to finish.
-	 */
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	while (job->needs_fence.wrapper) {
-		poll(NULL, 0, 1);
-		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	}
-	job->wrapper = NULL;
-
 	/*
 	 * Once we marked the request as 'orphaned'
 	 * we spin/loop if it's already marked
@@ -992,14 +674,9 @@ struct tevent_req *pthreadpool_tevent_job_send(
 	struct pthreadpool_tevent_job_state *state = NULL;
 	struct pthreadpool_tevent_job *job = NULL;
 	int ret;
-	struct pthreadpool_tevent_wrapper *wrapper = pool->wrapper.ctx;
 
 	pthreadpool_tevent_cleanup_orphaned_jobs();
 
-	if (wrapper != NULL) {
-		pool = wrapper->main_tp;
-	}
-
 	req = tevent_req_create(mem_ctx, &state,
 				struct pthreadpool_tevent_job_state);
 	if (req == NULL) {
@@ -1029,7 +706,6 @@ struct tevent_req *pthreadpool_tevent_job_send(
 		return tevent_req_post(req, ev);
 	}
 	job->pool = pool;
-	job->wrapper = wrapper;
 	job->fn = fn;
 	job->private_data = private_data;
 	job->im = tevent_create_immediate(state->job);
@@ -1128,73 +804,15 @@ static void pthreadpool_tevent_job_fn(void *private_data)
 	struct pthreadpool_tevent_job *job =
 		talloc_get_type_abort(private_data,
 		struct pthreadpool_tevent_job);
-	struct pthreadpool_tevent_wrapper *wrapper = NULL;
 
 	current_job = job;
 	job->needs_fence.started = true;
 	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	if (job->needs_fence.orphaned) {
-		current_job = NULL;
-		return;
-	}
-
-	wrapper = job->wrapper;
-	if (wrapper != NULL) {
-		bool ok;
-
-		job->needs_fence.wrapper = true;
-		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-		if (job->needs_fence.orphaned) {
-			job->needs_fence.wrapper = false;
-			PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-			current_job = NULL;
-			return;
-		}
-		ok = wrapper->ops->before_job(wrapper->wrap_tp,
-					      wrapper->private_state,
-					      wrapper->main_tp,
-					      __location__);
-		job->needs_fence.wrapper = false;
-		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-		if (!ok) {
-			job->needs_fence.exit_thread = true;
-			PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-			current_job = NULL;
-			return;
-		}
-	}
 
 	job->fn(job->private_data);
 
 	job->needs_fence.executed = true;
 	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-
-	if (wrapper != NULL) {
-		bool ok;
-
-		job->needs_fence.wrapper = true;
-		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-		if (job->needs_fence.orphaned) {
-			job->needs_fence.wrapper = false;
-			job->needs_fence.exit_thread = true;
-			PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-			current_job = NULL;
-			return;
-		}
-		ok = wrapper->ops->after_job(wrapper->wrap_tp,
-					     wrapper->private_state,
-					     wrapper->main_tp,
-					     __location__);
-		job->needs_fence.wrapper = false;
-		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-		if (!ok) {
-			job->needs_fence.exit_thread = true;
-			PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-			current_job = NULL;
-			return;
-		}
-	}
-
 	current_job = NULL;
 }
 
@@ -1213,15 +831,6 @@ static int pthreadpool_tevent_job_signal(int jobid,
 		/* Request already gone */
 		job->needs_fence.dropped = true;
 		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-		if (job->needs_fence.exit_thread) {
-			/*
-			 * A problem with the wrapper the current job/worker
-			 * thread needs to terminate.
-			 *
-			 * The pthreadpool_tevent is already gone.
-			 */
-			return -1;
-		}
 		return 0;
 	}
 
@@ -1247,15 +856,6 @@ static int pthreadpool_tevent_job_signal(int jobid,
 
 	job->needs_fence.signaled = true;
 	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	if (job->needs_fence.exit_thread) {
-		/*
-		 * A problem with the wrapper the current job/worker
-		 * thread needs to terminate.
-		 *
-		 * The pthreadpool_tevent is already gone.
-		 */
-		return -1;
-	}
 	return 0;
 }
 
diff --git a/lib/pthreadpool/pthreadpool_tevent.h b/lib/pthreadpool/pthreadpool_tevent.h
index 6c939fc1d2d..ff2ab7cfb73 100644
--- a/lib/pthreadpool/pthreadpool_tevent.h
+++ b/lib/pthreadpool/pthreadpool_tevent.h
@@ -29,38 +29,6 @@ struct pthreadpool_tevent;
 int pthreadpool_tevent_init(TALLOC_CTX *mem_ctx, unsigned max_threads,
 			    struct pthreadpool_tevent **presult);
 
-struct pthreadpool_tevent_wrapper_ops {
-	const char *name;
-
-	bool (*before_job)(struct pthreadpool_tevent *wrap_tp,
-			   void *private_state,
-			   struct pthreadpool_tevent *main_tp,
-			   const char *location);
-	bool (*after_job)(struct pthreadpool_tevent *wrap_tp,
-			  void *private_state,
-			  struct pthreadpool_tevent *main_tp,
-			  const char *location);
-};
-
-struct pthreadpool_tevent *_pthreadpool_tevent_wrapper_create(
-				struct pthreadpool_tevent *main_tp,
-				TALLOC_CTX *mem_ctx,
-				const struct pthreadpool_tevent_wrapper_ops *ops,
-				void *pstate,
-				size_t psize,
-				const char *type,
-				const char *location);
-#define pthreadpool_tevent_wrapper_create(main_tp, mem_ctx, ops, state, type) \
-	_pthreadpool_tevent_wrapper_create(main_tp, mem_ctx, ops, \
-				       state, sizeof(type), #type, __location__)
-
-/*
- * this can only be called directly after
- * pthreadpool_tevent_wrapper_create()
- */
-void pthreadpool_tevent_force_per_thread_cwd(struct pthreadpool_tevent *pool,
-					     const void *private_state);
-
 size_t pthreadpool_tevent_max_threads(struct pthreadpool_tevent *pool);
 size_t pthreadpool_tevent_queued_jobs(struct pthreadpool_tevent *pool);
 bool pthreadpool_tevent_per_thread_cwd(struct pthreadpool_tevent *pool);
-- 
2.17.2


From ec1c9647a49c032a88b9c3f5fd89145c4f654a54 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:43:07 +0100
Subject: [PATCH 18/56] Revert "pthreadpool: add
 pthreadpool_restart_check[_monitor_{fd,drain}]()"

This reverts commit 3c4cdb290723432b00ff9ff88b892cb4e66e76cd.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool.c      | 281 -----------------------------
 lib/pthreadpool/pthreadpool.h      |  64 -------
 lib/pthreadpool/pthreadpool_sync.c |  20 --
 3 files changed, 365 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool.c b/lib/pthreadpool/pthreadpool.c
index d482c159941..c2bafd52c08 100644
--- a/lib/pthreadpool/pthreadpool.c
+++ b/lib/pthreadpool/pthreadpool.c
@@ -24,7 +24,6 @@
 #include "system/filesys.h"
 #include "pthreadpool.h"
 #include "lib/util/dlinklist.h"
-#include "lib/util/blocking.h"
 
 #ifdef NDEBUG
 #undef NDEBUG
@@ -54,8 +53,6 @@ struct pthreadpool {
 	 */
 	pthread_cond_t condvar;
 
-	int check_pipefd[2];
-
 	/*
 	 * Array of jobs
 	 */
@@ -140,7 +137,6 @@ int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult,
 {
 	struct pthreadpool *pool;
 	int ret;
-	bool ok;
 
 	pool = (struct pthreadpool *)malloc(sizeof(struct pthreadpool));
 	if (pool == NULL) {
@@ -158,52 +154,10 @@ int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult,
 		return ENOMEM;
 	}
 
-	ret = pipe(pool->check_pipefd);
-	if (ret != 0) {
-		free(pool->jobs);
-		free(pool);
-		return ENOMEM;
-	}
-
-	ok = smb_set_close_on_exec(pool->check_pipefd[0]);
-	if (!ok) {
-		close(pool->check_pipefd[0]);
-		close(pool->check_pipefd[1]);
-		free(pool->jobs);
-		free(pool);
-		return EINVAL;
-	}
-	ok = smb_set_close_on_exec(pool->check_pipefd[1]);
-	if (!ok) {
-		close(pool->check_pipefd[0]);
-		close(pool->check_pipefd[1]);
-		free(pool->jobs);
-		free(pool);
-		return EINVAL;
-	}
-	ret = set_blocking(pool->check_pipefd[0], true);
-	if (ret == -1) {
-		close(pool->check_pipefd[0]);
-		close(pool->check_pipefd[1]);
-		free(pool->jobs);
-		free(pool);
-		return EINVAL;
-	}
-	ret = set_blocking(pool->check_pipefd[1], false);
-	if (ret == -1) {
-		close(pool->check_pipefd[0]);
-		close(pool->check_pipefd[1]);
-		free(pool->jobs);
-		free(pool);
-		return EINVAL;
-	}
-
 	pool->head = pool->num_jobs = 0;
 
 	ret = pthread_mutex_init(&pool->mutex, NULL);
 	if (ret != 0) {
-		close(pool->check_pipefd[0]);
-		close(pool->check_pipefd[1]);
 		free(pool->jobs);
 		free(pool);
 		return ret;
@@ -212,8 +166,6 @@ int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult,
 	ret = pthread_cond_init(&pool->condvar, NULL);
 	if (ret != 0) {
 		pthread_mutex_destroy(&pool->mutex);
-		close(pool->check_pipefd[0]);
-		close(pool->check_pipefd[1]);
 		free(pool->jobs);
 		free(pool);
 		return ret;
@@ -223,8 +175,6 @@ int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult,
 	if (ret != 0) {
 		pthread_cond_destroy(&pool->condvar);
 		pthread_mutex_destroy(&pool->mutex);
-		close(pool->check_pipefd[0]);
-		close(pool->check_pipefd[1]);
 		free(pool->jobs);
 		free(pool);
 		return ret;
@@ -247,8 +197,6 @@ int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult,
 		pthread_mutex_destroy(&pool->fork_mutex);
 		pthread_cond_destroy(&pool->condvar);
 		pthread_mutex_destroy(&pool->mutex);
-		close(pool->check_pipefd[0]);
-		close(pool->check_pipefd[1]);
 		free(pool->jobs);
 		free(pool);
 		return ret;
@@ -412,14 +360,6 @@ static void pthreadpool_child(void)
 		pool->head = 0;
 		pool->num_jobs = 0;
 		pool->stopped = true;
-		if (pool->check_pipefd[0] != -1) {
-			close(pool->check_pipefd[0]);
-			pool->check_pipefd[0] = -1;
-		}
-		if (pool->check_pipefd[1] != -1) {
-			close(pool->check_pipefd[1]);
-			pool->check_pipefd[1] = -1;
-		}
 
 		ret = pthread_cond_init(&pool->condvar, NULL);
 		assert(ret == 0);
@@ -482,14 +422,6 @@ static int pthreadpool_free(struct pthreadpool *pool)
 		return ret2;
 	}
 
-	if (pool->check_pipefd[0] != -1) {
-		close(pool->check_pipefd[0]);
-		pool->check_pipefd[0] = -1;
-	}
-	if (pool->check_pipefd[1] != -1) {
-		close(pool->check_pipefd[1]);
-		pool->check_pipefd[1] = -1;
-	}
 	free(pool->jobs);
 	free(pool);
 
@@ -506,15 +438,6 @@ static int pthreadpool_stop_locked(struct pthreadpool *pool)
 
 	pool->stopped = true;
 
-	if (pool->check_pipefd[0] != -1) {
-		close(pool->check_pipefd[0]);
-		pool->check_pipefd[0] = -1;
-	}
-	if (pool->check_pipefd[1] != -1) {
-		close(pool->check_pipefd[1]);
-		pool->check_pipefd[1] = -1;
-	}
-
 	if (pool->num_threads == 0) {
 		return 0;
 	}
@@ -599,33 +522,6 @@ static void pthreadpool_server_exit(struct pthreadpool *pool)
 
 	free_it = (pool->destroyed && (pool->num_threads == 0));
 
-	while (true) {
-		uint8_t c = 0;
-		ssize_t nwritten = 0;
-
-		if (pool->check_pipefd[1] == -1) {
-			break;
-		}
-
-		nwritten = write(pool->check_pipefd[1], &c, 1);
-		if (nwritten == -1) {
-			if (errno == EINTR) {
-				continue;
-			}
-			if (errno == EAGAIN) {
-				break;
-			}
-#ifdef EWOULDBLOCK
-			if (errno == EWOULDBLOCK) {
-				break;
-			}
-#endif
-			/* ignore ... */
-		}
-
-		break;
-	}
-
 	ret = pthread_mutex_unlock(&pool->mutex);
 	assert(ret == 0);
 
@@ -956,183 +852,6 @@ int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
 	return res;
 }
 
-int pthreadpool_restart_check(struct pthreadpool *pool)
-{
-	int res;
-	int unlock_res;
-	unsigned possible_threads = 0;
-	unsigned missing_threads = 0;
-
-	assert(!pool->destroyed);
-
-	res = pthread_mutex_lock(&pool->mutex);
-	if (res != 0) {
-		return res;
-	}
-
-	if (pool->stopped) {
-		/*
-		 * Protect against the pool being shut down while
-		 * trying to add a job
-		 */
-		unlock_res = pthread_mutex_unlock(&pool->mutex);
-		assert(unlock_res == 0);
-		return EINVAL;
-	}
-
-	if (pool->num_jobs == 0) {
-		/*
-		 * This also handles the pool->max_threads == 0 case as it never
-		 * calls pthreadpool_put_job()
-		 */
-		unlock_res = pthread_mutex_unlock(&pool->mutex);
-		assert(unlock_res == 0);
-		return 0;
-	}
-
-	if (pool->num_idle > 0) {
-		/*
-		 * We have idle threads and pending jobs,
-		 * this means we better let all threads
-		 * start and check for pending jobs.
-		 */
-		res = pthread_cond_broadcast(&pool->condvar);
-		assert(res == 0);
-	}
-
-	if (pool->num_threads < pool->max_threads) {
-		possible_threads = pool->max_threads - pool->num_threads;
-	}
-
-	if (pool->num_idle < pool->num_jobs) {
-		missing_threads = pool->num_jobs - pool->num_idle;
-	}
-
-	missing_threads = MIN(missing_threads, possible_threads);
-
-	while (missing_threads > 0) {
-
-		res = pthreadpool_create_thread(pool);
-		if (res != 0) {
-			break;
-		}
-
-		missing_threads--;
-	}
-
-	if (missing_threads == 0) {
-		/*
-		 * Ok, we recreated all thread we need.
-		 */
-		unlock_res = pthread_mutex_unlock(&pool->mutex);
-		assert(unlock_res == 0);
-		return 0;
-	}
-
-	if (pool->num_threads != 0) {
-		/*
-		 * At least one thread is still available, let
-		 * that one run the queued jobs.
-		 */
-		unlock_res = pthread_mutex_unlock(&pool->mutex);
-		assert(unlock_res == 0);
-		return 0;
-	}
-
-	/*
-	 * There's no thread available to run any pending jobs.
-	 * The caller may want to cancel the jobs and destroy the pool.
-	 * But that's up to the caller.
-	 */
-	unlock_res = pthread_mutex_unlock(&pool->mutex);
-	assert(unlock_res == 0);
-
-	return res;
-}
-
-int pthreadpool_restart_check_monitor_fd(struct pthreadpool *pool)
-{
-	int fd;
-	int ret;
-	bool ok;
-
-	if (pool->stopped) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (pool->check_pipefd[0] == -1) {
-		errno = ENOSYS;
-		return -1;
-	}
-
-	fd = dup(pool->check_pipefd[0]);
-	if (fd == -1) {
-		return -1;
-	}
-
-	ok = smb_set_close_on_exec(fd);
-	if (!ok) {
-		int saved_errno = errno;
-		close(fd);
-		errno = saved_errno;
-		return -1;
-	}
-
-	ret = set_blocking(fd, false);
-	if (ret == -1) {
-		int saved_errno = errno;
-		close(fd);
-		errno = saved_errno;
-		return -1;
-	}
-
-	return fd;
-}
-
-int pthreadpool_restart_check_monitor_drain(struct pthreadpool *pool)
-{
-	if (pool->stopped) {
-		return EINVAL;
-	}
-
-	if (pool->check_pipefd[0] == -1) {
-		return ENOSYS;
-	}
-
-	while (true) {
-		uint8_t buf[128];
-		ssize_t nread;
-
-		nread = read(pool->check_pipefd[0], buf, sizeof(buf));
-		if (nread == -1) {
-			if (errno == EINTR) {
-				continue;
-			}
-			if (errno == EAGAIN) {
-				return 0;
-			}
-#ifdef EWOULDBLOCK
-			if (errno == EWOULDBLOCK) {
-				return 0;
-			}
-#endif
-			if (errno == 0) {
-				errno = INT_MAX;
-			}
-
-			return errno;
-		}
-
-		if (nread < sizeof(buf)) {
-			return 0;
-		}
-	}
-
-	abort();
-	return INT_MAX;
-}
-
 size_t pthreadpool_cancel_job(struct pthreadpool *pool, int job_id,
 			      void (*fn)(void *private_data), void *private_data)
 {
diff --git a/lib/pthreadpool/pthreadpool.h b/lib/pthreadpool/pthreadpool.h
index 543567ceaf7..d8daf9e4519 100644
--- a/lib/pthreadpool/pthreadpool.h
+++ b/lib/pthreadpool/pthreadpool.h
@@ -144,70 +144,6 @@ int pthreadpool_destroy(struct pthreadpool *pool);
 int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
 			void (*fn)(void *private_data), void *private_data);
 
-/**
- * @brief Check if the pthreadpool needs a restart.
- *
- * This checks if there are enough threads to run the already
- * queued jobs. This should be called only the callers signal_fn
- * (passed to pthreadpool_init()) returned an error, so
- * that the job's worker thread exited.
- *
- * Typically this is called once the file destriptor
- * returned by pthreadpool_restart_check_monitor_fd()
- * became readable and pthreadpool_restart_check_monitor_drain()
- * returned success.
- *
- * This function tries to restart the missing threads.
- *
- * @param[in]	pool		The pool to run the job on
- * @return			success: 0, failure: errno
- *
- * @see pthreadpool_restart_check_monitor_fd
- * @see pthreadpool_restart_check_monitor_drain
- */
-int pthreadpool_restart_check(struct pthreadpool *pool);
-
-/**
- * @brief Return a file destriptor that monitors the pool.
- *
- * If the file destrictor becomes readable,
- * the event handler should call pthreadpool_restart_check_monitor_drain().
- *
- * pthreadpool_restart_check() should also be called once the
- * state is drained.
- *
- * This function returns a fresh fd using dup() each time.
- *
- * If the pool doesn't require restarts, this function
- * returns -1 and sets errno = ENOSYS. The caller
- * may ignore that situation.
- *
- * @param[in]	pool		The pool to run the job on
- * @return			success: 0, failure: -1 (set errno)
- *
- * @see pthreadpool_restart_check_monitor_fd
- * @see pthreadpool_restart_check_monitor_drain
- */
-int pthreadpool_restart_check_monitor_fd(struct pthreadpool *pool);
-
-/**
- * @brief Drain the monitor file destriptor of the pool.
- *
- * If the file destrictor returned by pthreadpool_restart_check_monitor_fd()
- * becomes readable, pthreadpool_restart_check_monitor_drain() should be
- * called before pthreadpool_restart_check().
- *
- * If this function returns an error the caller should close
- * the file destriptor it got from pthreadpool_restart_check_monitor_fd().
- *
- * @param[in]	pool		The pool to run the job on
- * @return			success: 0, failure: errno
- *
- * @see pthreadpool_restart_check_monitor_fd
- * @see pthreadpool_restart_check
- */
-int pthreadpool_restart_check_monitor_drain(struct pthreadpool *pool);
-
 /**
  * @brief Try to cancel a job in a pthreadpool
  *
diff --git a/lib/pthreadpool/pthreadpool_sync.c b/lib/pthreadpool/pthreadpool_sync.c
index a476ea712c3..2ed6f36dbbc 100644
--- a/lib/pthreadpool/pthreadpool_sync.c
+++ b/lib/pthreadpool/pthreadpool_sync.c
@@ -83,26 +83,6 @@ int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
 			       pool->signal_fn_private_data);
 }
 
-int pthreadpool_restart_check(struct pthreadpool *pool)
-{
-	if (pool->stopped) {
-		return EINVAL;
-	}
-
-	return 0;
-}
-
-int pthreadpool_restart_check_monitor_fd(struct pthreadpool *pool)
-{
-	errno = ENOSYS;
-	return -1;
-}
-
-int pthreadpool_restart_check_monitor_drain(struct pthreadpool *pool)
-{
-	return EINVAL;
-}
-
 size_t pthreadpool_cancel_job(struct pthreadpool *pool, int job_id,
 			      void (*fn)(void *private_data), void *private_data)
 {
-- 
2.17.2


From 5143d2a66f3bc9e5b2a5e88064e5d028ce1f9269 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:43:25 +0100
Subject: [PATCH 19/56] Revert "pthreadpool: add tests for
 pthreadpool_tevent_[current_job_]per_thread_cwd()"

This reverts commit fbafdc99ef2cef11a1a28e795ffe965cb53ef7fa.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/tests_cmocka.c | 144 ---------------------------------
 1 file changed, 144 deletions(-)

diff --git a/lib/pthreadpool/tests_cmocka.c b/lib/pthreadpool/tests_cmocka.c
index 5c7f6ab6904..dc7b1150b5c 100644
--- a/lib/pthreadpool/tests_cmocka.c
+++ b/lib/pthreadpool/tests_cmocka.c
@@ -244,147 +244,6 @@ static void test_create(void **state)
 	assert_false(in_main_thread);
 }
 
-static void test_per_thread_cwd_job(void *ptr)
-{
-	const bool *per_thread_cwd_ptr = ptr;
-	bool per_thread_cwd;
-	char cwdbuf[PATH_MAX] = {0,};
-	char *cwdstr = NULL;
-	int ret;
-
-	/*
-	 * This needs to be consistent.
-	 */
-	per_thread_cwd = pthreadpool_tevent_current_job_per_thread_cwd();
-	assert_int_equal(per_thread_cwd, *per_thread_cwd_ptr);
-
-	if (!per_thread_cwd) {
-		return;
-	}
-
-	/*
-	 * Check we're not already in "/".
-	 */
-	cwdstr = getcwd(cwdbuf, sizeof(cwdbuf));
-	assert_non_null(cwdstr);
-	assert_string_not_equal(cwdstr, "/");
-
-	ret = chdir("/");
-	assert_int_equal(ret, 0);
-
-	/*
-	 * Check we're in "/" now.
-	 */
-	cwdstr = getcwd(cwdbuf, sizeof(cwdbuf));
-	assert_non_null(cwdstr);
-	assert_string_equal(cwdstr, "/");
-}
-
-static int test_per_thread_cwd_do(struct tevent_context *ev,
-				  struct pthreadpool_tevent *pool)
-{
-	struct tevent_req *req;
-	bool per_thread_cwd;
-	bool ok;
-	int ret;
-	per_thread_cwd = pthreadpool_tevent_per_thread_cwd(pool);
-
-	req = pthreadpool_tevent_job_send(
-		ev, ev, pool, test_per_thread_cwd_job, &per_thread_cwd);
-	if (req == NULL) {
-		fprintf(stderr, "pthreadpool_tevent_job_send failed\n");
-		return ENOMEM;
-	}
-
-	ok = tevent_req_poll(req, ev);
-	if (!ok) {
-		ret = errno;
-		fprintf(stderr, "tevent_req_poll failed: %s\n",
-			strerror(ret));
-		return ret;
-	}
-
-	ret = pthreadpool_tevent_job_recv(req);
-	TALLOC_FREE(req);
-	if (ret != 0) {
-		fprintf(stderr, "tevent_req_recv failed: %s\n",
-			strerror(ret));
-		return ret;
-	}
-
-	return 0;
-}
-
-static void test_per_thread_cwd(void **state)
-{
-	struct pthreadpool_tevent_test *t = *state;
-	int ret;
-	bool per_thread_cwd_u;
-	bool per_thread_cwd_o;
-	bool per_thread_cwd_s;
-	char cwdbuf1[PATH_MAX] = {0,};
-	char *cwdstr1 = NULL;
-	char cwdbuf2[PATH_MAX] = {0,};
-	char *cwdstr2 = NULL;
-
-	/*
-	 * The unlimited and one pools
-	 * should be consistent.
-	 *
-	 * We can't enforce this as some constraint
-	 * container environments disable unshare()
-	 * completely, even just with CLONE_FS.
-	 */
-	per_thread_cwd_u = pthreadpool_tevent_per_thread_cwd(t->upool);
-	per_thread_cwd_o = pthreadpool_tevent_per_thread_cwd(t->opool);
-	assert_int_equal(per_thread_cwd_u, per_thread_cwd_o);
-
-	/*
-	 * The sync pool should never support this.
-	 */
-	per_thread_cwd_s = pthreadpool_tevent_per_thread_cwd(t->spool);
-	assert_false(per_thread_cwd_s);
-
-	/*
-	 * Check we're not already in "/".
-	 */
-	cwdstr1 = getcwd(cwdbuf1, sizeof(cwdbuf1));
-	assert_non_null(cwdstr1);
-	assert_string_not_equal(cwdstr1, "/");
-
-	will_return(__wrap_pthread_create, 0);
-	ret = test_per_thread_cwd_do(t->ev, t->upool);
-	assert_int_equal(ret, 0);
-
-	/*
-	 * Check we're still in the same directory.
-	 */
-	cwdstr2 = getcwd(cwdbuf2, sizeof(cwdbuf2));
-	assert_non_null(cwdstr2);
-	assert_string_equal(cwdstr2, cwdstr1);
-
-	will_return(__wrap_pthread_create, 0);
-	ret = test_per_thread_cwd_do(t->ev, t->opool);
-	assert_int_equal(ret, 0);
-
-	/*
-	 * Check we're still in the same directory.
-	 */
-	cwdstr2 = getcwd(cwdbuf2, sizeof(cwdbuf2));
-	assert_non_null(cwdstr2);
-	assert_string_equal(cwdstr2, cwdstr1);
-
-	ret = test_per_thread_cwd_do(t->ev, t->spool);
-	assert_int_equal(ret, 0);
-
-	/*
-	 * Check we're still in the same directory.
-	 */
-	cwdstr2 = getcwd(cwdbuf2, sizeof(cwdbuf2));
-	assert_non_null(cwdstr2);
-	assert_string_equal(cwdstr2, cwdstr1);
-}
-
 struct test_cancel_job {
 	int fdm; /* the main end of socketpair */
 	int fdj; /* the job end of socketpair */
@@ -811,9 +670,6 @@ int main(int argc, char **argv)
 		cmocka_unit_test_setup_teardown(test_create,
 						setup_pthreadpool_tevent,
 						teardown_pthreadpool_tevent),
-		cmocka_unit_test_setup_teardown(test_per_thread_cwd,
-						setup_pthreadpool_tevent,
-						teardown_pthreadpool_tevent),
 		cmocka_unit_test_setup_teardown(test_cancel_job,
 						setup_pthreadpool_tevent,
 						teardown_pthreadpool_tevent),
-- 
2.17.2


From 0c2b6ade92bae7560a0e30ce53473bb42057a555 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:43:42 +0100
Subject: [PATCH 20/56] pthreadpool: remove
 pthreadpool_tevent_current_job_per_thread_cwd()

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 21 ---------------------
 lib/pthreadpool/pthreadpool_tevent.h |  6 ------
 2 files changed, 27 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index b0a757aa1db..5c84807140c 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -211,8 +211,6 @@ struct pthreadpool_tevent_job {
 		 */
 		bool signaled;
 	} needs_fence;
-
-	bool per_thread_cwd;
 };
 
 static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool);
@@ -288,10 +286,6 @@ size_t pthreadpool_tevent_queued_jobs(struct pthreadpool_tevent *pool)
 
 bool pthreadpool_tevent_per_thread_cwd(struct pthreadpool_tevent *pool)
 {
-	if (pool->pool == NULL) {
-		return false;
-	}
-
 	return pthreadpool_per_thread_cwd(pool->pool);
 }
 
@@ -713,7 +707,6 @@ struct tevent_req *pthreadpool_tevent_job_send(
 		return tevent_req_post(req, ev);
 	}
 	PTHREAD_TEVENT_JOB_THREAD_FENCE_INIT(job);
-	job->per_thread_cwd = pthreadpool_tevent_per_thread_cwd(pool);
 	talloc_set_destructor(job, pthreadpool_tevent_job_destructor);
 	DLIST_ADD_END(job->pool->jobs, job);
 	job->state = state;
@@ -785,20 +778,6 @@ bool pthreadpool_tevent_current_job_continue(void)
 	return true;
 }
 
-bool pthreadpool_tevent_current_job_per_thread_cwd(void)
-{
-	if (current_job == NULL) {
-		/*
-		 * Should only be called from within
-		 * the job function.
-		 */
-		abort();
-		return false;
-	}
-
-	return current_job->per_thread_cwd;
-}
-
 static void pthreadpool_tevent_job_fn(void *private_data)
 {
 	struct pthreadpool_tevent_job *job =
diff --git a/lib/pthreadpool/pthreadpool_tevent.h b/lib/pthreadpool/pthreadpool_tevent.h
index ff2ab7cfb73..9724ba3ba7a 100644
--- a/lib/pthreadpool/pthreadpool_tevent.h
+++ b/lib/pthreadpool/pthreadpool_tevent.h
@@ -47,12 +47,6 @@ bool pthreadpool_tevent_current_job_orphaned(void);
  */
 bool pthreadpool_tevent_current_job_continue(void);
 
-/*
- * return true if the current job can rely on a per thread
- * current working directory.
- */
-bool pthreadpool_tevent_current_job_per_thread_cwd(void);
-
 struct tevent_req *pthreadpool_tevent_job_send(
 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 	struct pthreadpool_tevent *pool,
-- 
2.17.2


From 3facabcf7585bf1f1afd281d5e80bd9e49d38f84 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:44:07 +0100
Subject: [PATCH 21/56] Revert "pthreadpool: test cancelling and freeing
 pending pthreadpool_tevent jobs/pools"

This reverts commit 40d15260d24d0071732f47873f395fce29b8a6f4.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/tests_cmocka.c | 434 ---------------------------------
 1 file changed, 434 deletions(-)

diff --git a/lib/pthreadpool/tests_cmocka.c b/lib/pthreadpool/tests_cmocka.c
index dc7b1150b5c..e6af8849f01 100644
--- a/lib/pthreadpool/tests_cmocka.c
+++ b/lib/pthreadpool/tests_cmocka.c
@@ -17,16 +17,12 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "config.h"
 #include <errno.h>
 #include <pthread.h>
 #include <setjmp.h>
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
 
 #include <talloc.h>
 #include <tevent.h>
@@ -35,13 +31,6 @@
 #include <cmocka.h>
 #include <poll.h>
 
-#ifdef HAVE_VALGRIND_HELGRIND_H
-#include <valgrind/helgrind.h>
-#endif
-#ifndef ANNOTATE_BENIGN_RACE_SIZED
-#define ANNOTATE_BENIGN_RACE_SIZED(address, size, describtion)
-#endif
-
 struct pthreadpool_tevent_test {
 	struct tevent_context *ev;
 	struct pthreadpool_tevent *upool;
@@ -244,435 +233,12 @@ static void test_create(void **state)
 	assert_false(in_main_thread);
 }
 
-struct test_cancel_job {
-	int fdm; /* the main end of socketpair */
-	int fdj; /* the job end of socketpair */
-	bool started;
-	bool canceled;
-	bool orphaned;
-	bool finished;
-	size_t polls;
-	size_t timeouts;
-	int sleep_msec;
-	struct tevent_req *req;
-	bool completed;
-	int ret;
-};
-
-static void test_cancel_job_done(struct tevent_req *req);
-
-static int test_cancel_job_destructor(struct test_cancel_job *job)
-{
-	ANNOTATE_BENIGN_RACE_SIZED(&job->started,
-				   sizeof(job->started),
-				   "protected by pthreadpool_tevent code");
-	if (job->started) {
-		ANNOTATE_BENIGN_RACE_SIZED(&job->finished,
-					   sizeof(job->finished),
-					   "protected by pthreadpool_tevent code");
-		assert_true(job->finished);
-	}
-
-	ANNOTATE_BENIGN_RACE_SIZED(&job->fdj,
-				   sizeof(job->fdj),
-				   "protected by pthreadpool_tevent code");
-
-	if (job->fdm != -1) {
-		close(job->fdm);
-		job->fdm = -1;
-	}
-	if (job->fdj != -1) {
-		close(job->fdj);
-		job->fdj = -1;
-	}
-
-	return 0;
-}
-
-static struct test_cancel_job *test_cancel_job_create(TALLOC_CTX *mem_ctx)
-{
-	struct test_cancel_job *job = NULL;
-
-	job = talloc(mem_ctx, struct test_cancel_job);
-	if (job == NULL) {
-		return NULL;
-	}
-	*job = (struct test_cancel_job) {
-		.fdm = -1,
-		.fdj = -1,
-		.sleep_msec = 50,
-	};
-
-	talloc_set_destructor(job, test_cancel_job_destructor);
-	return job;
-}
-
-static void test_cancel_job_fn(void *ptr)
-{
-	struct test_cancel_job *job = (struct test_cancel_job *)ptr;
-	int fdj = -1;
-	char c = 0;
-	int ret;
-
-	assert_non_null(job); /* make sure we abort without a job pointer */
-
-	job->started = true;
-	fdj = job->fdj;
-	job->fdj = -1;
-
-	if (!pthreadpool_tevent_current_job_continue()) {
-		job->canceled = pthreadpool_tevent_current_job_canceled();
-		job->orphaned = pthreadpool_tevent_current_job_orphaned();
-		job->finished = true;
-		close(fdj);
-		return;
-	}
-
-	/*
-	 * Notify that we main thread
-	 *
-	 * write of 1 byte should always work!
-	 */
-	ret = write(fdj, &c, 1);
-	assert_int_equal(ret, 1);
-
-	/*
-	 * loop until the job was tried to
-	 * be canceled or becomes orphaned.
-	 *
-	 * If there's some activity on the fd
-	 * we directly finish.
-	 */
-	do {
-		struct pollfd pfd = {
-			.fd = fdj,
-			.events = POLLIN,
-		};
-
-		job->polls += 1;
-
-		ret = poll(&pfd, 1, job->sleep_msec);
-		if (ret == 1) {
-			job->finished = true;
-			close(fdj);
-			return;
-		}
-		assert_int_equal(ret, 0);
-
-		job->timeouts += 1;
-
-	} while (pthreadpool_tevent_current_job_continue());
-
-	job->canceled = pthreadpool_tevent_current_job_canceled();
-	job->orphaned = pthreadpool_tevent_current_job_orphaned();
-	job->finished = true;
-	close(fdj);
-}
-
-static void test_cancel_job_done(struct tevent_req *req)
-{
-	struct test_cancel_job *job =
-		tevent_req_callback_data(req,
-		struct test_cancel_job);
-
-	job->ret = pthreadpool_tevent_job_recv(job->req);
-	TALLOC_FREE(job->req);
-	job->completed = true;
-}
-
-static void test_cancel_job_wait(struct test_cancel_job *job,
-				 struct tevent_context *ev)
-{
-	/*
-	 * We have to keep looping until
-	 * test_cancel_job_done was triggered
-	 */
-	while (!job->completed) {
-		int ret;
-
-		ret = tevent_loop_once(ev);
-		assert_int_equal(ret, 0);
-	}
-}
-
-struct test_cancel_state {
-	struct test_cancel_job *job1;
-	struct test_cancel_job *job2;
-	struct test_cancel_job *job3;
-	struct test_cancel_job *job4;
-	struct test_cancel_job *job5;
-	struct test_cancel_job *job6;
-};
-
-static void test_cancel_job(void **private_data)
-{
-	struct pthreadpool_tevent_test *t = *private_data;
-	struct tevent_context *ev = t->ev;
-	struct pthreadpool_tevent *pool = t->opool;
-	struct test_cancel_state *state = NULL;
-	int ret;
-	bool ok;
-	int fdpair[2] = { -1, -1 };
-	char c = 0;
-
-	state = talloc_zero(t, struct test_cancel_state);
-	assert_non_null(state);
-	state->job1 = test_cancel_job_create(state);
-	assert_non_null(state->job1);
-	state->job2 = test_cancel_job_create(state);
-	assert_non_null(state->job2);
-	state->job3 = test_cancel_job_create(state);
-	assert_non_null(state->job3);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job1->fdm = fdpair[0];
-	state->job1->fdj = fdpair[1];
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(pool), 0);
-
-	will_return(__wrap_pthread_create, 0);
-	state->job1->req = pthreadpool_tevent_job_send(
-		state->job1, ev, pool, test_cancel_job_fn, state->job1);
-	assert_non_null(state->job1->req);
-	tevent_req_set_callback(state->job1->req,
-				test_cancel_job_done,
-				state->job1);
-
-	state->job2->req = pthreadpool_tevent_job_send(
-		state->job2, ev, pool, test_cancel_job_fn, NULL);
-	assert_non_null(state->job2->req);
-	tevent_req_set_callback(state->job2->req,
-				test_cancel_job_done,
-				state->job2);
-
-	state->job3->req = pthreadpool_tevent_job_send(
-		state->job3, ev, pool, test_cancel_job_fn, NULL);
-	assert_non_null(state->job3->req);
-	tevent_req_set_callback(state->job3->req,
-				test_cancel_job_done,
-				state->job3);
-
-	/*
-	 * Wait for the job 1 to start.
-	 */
-	ret = read(state->job1->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	/*
-	 * We cancel job 3 and destroy job2.
-	 * Both should never be executed.
-	 */
-	assert_int_equal(pthreadpool_tevent_queued_jobs(pool), 2);
-	TALLOC_FREE(state->job2->req);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(pool), 1);
-	ok = tevent_req_cancel(state->job3->req);
-	assert_true(ok);
-	assert_int_equal(pthreadpool_tevent_queued_jobs(pool), 0);
-
-	/*
-	 * Job 3 should complete as canceled, while
-	 * job 1 is still running.
-	 */
-	test_cancel_job_wait(state->job3, ev);
-	assert_int_equal(state->job3->ret, ECANCELED);
-	assert_null(state->job3->req);
-	assert_false(state->job3->started);
-
-	/*
-	 * Now job1 is canceled while it's running,
-	 * this should let it stop it's loop.
-	 */
-	ok = tevent_req_cancel(state->job1->req);
-	assert_false(ok);
-
-	/*
-	 * Job 1 completes, It got at least one sleep
-	 * timeout loop and has state->job1->canceled set.
-	 */
-	test_cancel_job_wait(state->job1, ev);
-	assert_int_equal(state->job1->ret, 0);
-	assert_null(state->job1->req);
-	assert_true(state->job1->started);
-	assert_true(state->job1->finished);
-	assert_true(state->job1->canceled);
-	assert_false(state->job1->orphaned);
-	assert_in_range(state->job1->polls, 1, 100);
-	assert_int_equal(state->job1->timeouts, state->job1->polls);
-
-	/*
-	 * Now we create jobs 4 and 5
-	 * Both should execute.
-	 * Job 4 is orphaned while running by a TALLOC_FREE()
-	 * This should stop job 4 and let job 5 start.
-	 * We do a "normal" exit in job 5 by creating some activity
-	 * on the socketpair.
-	 */
-
-	state->job4 = test_cancel_job_create(state);
-	assert_non_null(state->job4);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job4->fdm = fdpair[0];
-	state->job4->fdj = fdpair[1];
-
-	state->job4->req = pthreadpool_tevent_job_send(
-		state->job4, ev, pool, test_cancel_job_fn, state->job4);
-	assert_non_null(state->job4->req);
-	tevent_req_set_callback(state->job4->req,
-				test_cancel_job_done,
-				state->job4);
-
-	state->job5 = test_cancel_job_create(state);
-	assert_non_null(state->job5);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job5->fdm = fdpair[0];
-	state->job5->fdj = fdpair[1];
-
-	state->job5->req = pthreadpool_tevent_job_send(
-		state->job5, ev, pool, test_cancel_job_fn, state->job5);
-	assert_non_null(state->job5->req);
-	tevent_req_set_callback(state->job5->req,
-				test_cancel_job_done,
-				state->job5);
-
-	/*
-	 * Make sure job 5 can exit as soon as possible.
-	 * It will never get a sleep/poll timeout.
-	 */
-	ret = write(state->job5->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	/*
-	 * Wait for the job 4 to start
-	 */
-	ret = read(state->job4->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(pool), 1);
-
-	/*
-	 * destroy the request so that it's marked
-	 * as orphaned.
-	 */
-	TALLOC_FREE(state->job4->req);
-
-	/*
-	 * Job 5 completes, It got no sleep timeout loop.
-	 */
-	test_cancel_job_wait(state->job5, ev);
-	assert_int_equal(state->job5->ret, 0);
-	assert_null(state->job5->req);
-	assert_true(state->job5->started);
-	assert_true(state->job5->finished);
-	assert_false(state->job5->canceled);
-	assert_false(state->job5->orphaned);
-	assert_int_equal(state->job5->polls, 1);
-	assert_int_equal(state->job5->timeouts, 0);
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(pool), 0);
-
-	/*
-	 * Job 2 is still not executed as we did a TALLOC_FREE()
-	 * before is was scheduled.
-	 */
-	assert_false(state->job2->completed);
-	assert_false(state->job2->started);
-
-	/*
-	 * Job 4 is still wasn't completed as we did a TALLOC_FREE()
-	 * while it is was running. but it was started and has
-	 * orphaned set
-	 */
-	assert_false(state->job4->completed);
-	assert_true(state->job4->started);
-	assert_true(state->job4->finished);
-	assert_false(state->job4->canceled);
-	assert_true(state->job4->orphaned);
-	assert_in_range(state->job4->polls, 1, 100);
-	assert_int_equal(state->job4->timeouts, state->job4->polls);
-
-	/*
-	 * Now we create jobs 6
-	 * We destroy the pool while it's executing.
-	 */
-
-	state->job6 = test_cancel_job_create(state);
-	assert_non_null(state->job6);
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair);
-	assert_int_equal(ret, 0);
-
-	state->job6->fdm = fdpair[0];
-	state->job6->fdj = fdpair[1];
-
-	state->job6->req = pthreadpool_tevent_job_send(
-		state->job6, ev, pool, test_cancel_job_fn, state->job6);
-	assert_non_null(state->job6->req);
-	tevent_req_set_callback(state->job6->req,
-				test_cancel_job_done,
-				state->job6);
-
-	/*
-	 * Wait for the job 6 to start
-	 */
-	ret = read(state->job6->fdm, &c, 1);
-	assert_int_equal(ret, 1);
-
-	assert_int_equal(pthreadpool_tevent_queued_jobs(pool), 0);
-
-	/*
-	 * destroy the request so that it's marked
-	 * as orphaned.
-	 */
-	pool = NULL;
-	TALLOC_FREE(t->opool);
-
-	/*
-	 * Wait until the job finished.
-	 */
-	ret = read(state->job6->fdm, &c, 1);
-	assert_int_equal(ret, 0);
-
-	/*
-	 * Job 6 is still dangling arround.
-	 *
-	 * We need to convince valgrind --tool={drd,helgrind}
-	 * that the read above is good enough to be
-	 * sure the job is finished and closed the other end of
-	 * the socketpair.
-	 */
-	ANNOTATE_BENIGN_RACE_SIZED(state->job6,
-				   sizeof(*state->job6),
-				   "protected by thread fence");
-	assert_non_null(state->job6->req);
-	assert_true(tevent_req_is_in_progress(state->job6->req));
-	assert_false(state->job6->completed);
-	assert_true(state->job6->started);
-	assert_true(state->job6->finished);
-	assert_false(state->job6->canceled);
-	assert_true(state->job6->orphaned);
-	assert_in_range(state->job6->polls, 1, 100);
-	assert_int_equal(state->job6->timeouts, state->job4->polls);
-
-	TALLOC_FREE(state);
-}
-
 int main(int argc, char **argv)
 {
 	const struct CMUnitTest tests[] = {
 		cmocka_unit_test_setup_teardown(test_create,
 						setup_pthreadpool_tevent,
 						teardown_pthreadpool_tevent),
-		cmocka_unit_test_setup_teardown(test_cancel_job,
-						setup_pthreadpool_tevent,
-						teardown_pthreadpool_tevent),
 	};
 
 	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
-- 
2.17.2


From 1aeedb7423a77954a6d78a170208ee226e981824 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:44:22 +0100
Subject: [PATCH 22/56] Revert "pthreadpool: add a comment about a further
 optimization in pthreadpool_tevent_job_destructor()"

This reverts commit f23cac39b36b026650e0922c78fe0fd3fe567e35.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index 5c84807140c..9a482453abe 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -497,23 +497,6 @@ static int pthreadpool_tevent_job_destructor(struct pthreadpool_tevent_job *job)
 		TALLOC_FREE(job->im);
 	}
 
-	/*
-	 * TODO?: We could further improve this by adjusting
-	 * tevent_threaded_schedule_immediate_destructor()
-	 * and allow TALLOC_FREE() during its time
-	 * in the main_ev->scheduled_immediates list.
-	 *
-	 * PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	 * if (state->needs_fence.signaled) {
-	 *       *
-	 *       * The signal function is completed
-	 *       * in future we may be allowed
-	 *       * to call TALLOC_FREE(job->im).
-	 *       *
-	 *      TALLOC_FREE(job->im);
-	 * }
-	 */
-
 	/*
 	 * pthreadpool_tevent_job_orphan() already removed
 	 * it from pool->jobs. And we don't need try
-- 
2.17.2


From dc54c699cf7e0ece2b626d78679df2cc05260d3f Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:44:32 +0100
Subject: [PATCH 23/56] Revert "pthreadpool: maintain a list of job_states on
 each pthreadpool_tevent_glue"

This reverts commit aa9b64eccfd037941512bad108c4e3946714a502.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 102 +++++++--------------------
 1 file changed, 24 insertions(+), 78 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index 9a482453abe..fdcd494fc3e 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -18,7 +18,6 @@
  */
 
 #include "replace.h"
-#include "system/select.h"
 #include "system/threads.h"
 #include "system/filesys.h"
 #include "pthreadpool_tevent.h"
@@ -106,8 +105,6 @@ struct pthreadpool_tevent_glue {
 	struct tevent_threaded_context *tctx;
 	/* Pointer to link object owned by *ev. */
 	struct pthreadpool_tevent_glue_ev_link *ev_link;
-	/* active jobs */
-	struct pthreadpool_tevent_job_state *states;
 };
 
 /*
@@ -131,8 +128,6 @@ struct pthreadpool_tevent {
 };
 
 struct pthreadpool_tevent_job_state {
-	struct pthreadpool_tevent_job_state *prev, *next;
-	struct pthreadpool_tevent_glue *glue;
 	struct tevent_context *ev;
 	struct tevent_req *req;
 	struct pthreadpool_tevent_job *job;
@@ -333,16 +328,6 @@ static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool)
 static int pthreadpool_tevent_glue_destructor(
 	struct pthreadpool_tevent_glue *glue)
 {
-	struct pthreadpool_tevent_job_state *state = NULL;
-	struct pthreadpool_tevent_job_state *nstate = NULL;
-
-	for (state = glue->states; state != NULL; state = nstate) {
-		nstate = state->next;
-
-		/* The job this removes it from the list */
-		pthreadpool_tevent_job_orphan(state->job);
-	}
-
 	if (glue->pool->glue_list != NULL) {
 		DLIST_REMOVE(glue->pool->glue_list, glue);
 	}
@@ -376,11 +361,9 @@ static int pthreadpool_tevent_glue_link_destructor(
 	return 0;
 }
 
-static int pthreadpool_tevent_register_ev(
-				struct pthreadpool_tevent *pool,
-				struct pthreadpool_tevent_job_state *state)
+static int pthreadpool_tevent_register_ev(struct pthreadpool_tevent *pool,
+					  struct tevent_context *ev)
 {
-	struct tevent_context *ev = state->ev;
 	struct pthreadpool_tevent_glue *glue = NULL;
 	struct pthreadpool_tevent_glue_ev_link *ev_link = NULL;
 
@@ -391,9 +374,7 @@ static int pthreadpool_tevent_register_ev(
 	 * pair.
 	 */
 	for (glue = pool->glue_list; glue != NULL; glue = glue->next) {
-		if (glue->ev == state->ev) {
-			state->glue = glue;
-			DLIST_ADD_END(glue->states, state);
+		if (glue->ev == ev) {
 			return 0;
 		}
 	}
@@ -441,9 +422,6 @@ static int pthreadpool_tevent_register_ev(
 	}
 #endif
 
-	state->glue = glue;
-	DLIST_ADD_END(glue->states, state);
-
 	DLIST_ADD(pool->glue_list, glue);
 	return 0;
 }
@@ -459,7 +437,7 @@ static int pthreadpool_tevent_job_destructor(struct pthreadpool_tevent_job *job)
 	/*
 	 * We should never be called with needs_fence.orphaned == false.
 	 * Only pthreadpool_tevent_job_orphan() will call TALLOC_FREE(job)
-	 * after detaching from the request state, glue and pool list.
+	 * after detaching from the request state and pool list.
 	 */
 	if (!job->needs_fence.orphaned) {
 		abort();
@@ -537,42 +515,6 @@ static void pthreadpool_tevent_job_orphan(struct pthreadpool_tevent_job *job)
 		abort();
 	}
 
-	/*
-	 * Once we marked the request as 'orphaned'
-	 * we spin/loop if it's already marked
-	 * as 'finished' (which means that
-	 * pthreadpool_tevent_job_signal() was entered.
-	 * If it saw 'orphaned' it will exit after setting
-	 * 'dropped', otherwise it dereferences
-	 * job->state->glue->{tctx,ev} until it exited
-	 * after setting 'signaled'.
-	 *
-	 * We need to close this potential gab before
-	 * we can set job->state = NULL.
-	 *
-	 * This is some kind of spinlock, but with
-	 * 1 millisecond sleeps in between, in order
-	 * to give the thread more cpu time to finish.
-	 */
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	while (job->needs_fence.finished) {
-		if (job->needs_fence.dropped) {
-			break;
-		}
-		if (job->needs_fence.signaled) {
-			break;
-		}
-		poll(NULL, 0, 1);
-		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	}
-
-	/*
-	 * Once the gab is closed, we can remove
-	 * the glue link.
-	 */
-	DLIST_REMOVE(job->state->glue->states, job->state);
-	job->state->glue = NULL;
-
 	/*
 	 * We need to reparent to a long term context.
 	 * And detach from the request state.
@@ -625,10 +567,6 @@ static void pthreadpool_tevent_job_cleanup(struct tevent_req *req,
 		 * The job request is not scheduled in the pool
 		 * yet or anymore.
 		 */
-		if (state->glue != NULL) {
-			DLIST_REMOVE(state->glue->states, state);
-			state->glue = NULL;
-		}
 		return;
 	}
 
@@ -673,7 +611,7 @@ struct tevent_req *pthreadpool_tevent_job_send(
 		return tevent_req_post(req, ev);
 	}
 
-	ret = pthreadpool_tevent_register_ev(pool, state);
+	ret = pthreadpool_tevent_register_ev(pool, ev);
 	if (tevent_req_error(req, ret)) {
 		return tevent_req_post(req, ev);
 	}
@@ -786,6 +724,9 @@ static int pthreadpool_tevent_job_signal(int jobid,
 	struct pthreadpool_tevent_job *job =
 		talloc_get_type_abort(job_private_data,
 		struct pthreadpool_tevent_job);
+	struct pthreadpool_tevent_job_state *state = job->state;
+	struct tevent_threaded_context *tctx = NULL;
+	struct pthreadpool_tevent_glue *g = NULL;
 
 	job->needs_fence.finished = true;
 	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
@@ -796,22 +737,27 @@ static int pthreadpool_tevent_job_signal(int jobid,
 		return 0;
 	}
 
-	/*
-	 * state and state->glue are valid,
-	 * see the job->needs_fence.finished
-	 * "spinlock" loop in
-	 * pthreadpool_tevent_job_orphan()
-	 */
-	if (job->state->glue->tctx != NULL) {
+#ifdef HAVE_PTHREAD
+	for (g = job->pool->glue_list; g != NULL; g = g->next) {
+		if (g->ev == state->ev) {
+			tctx = g->tctx;
+			break;
+		}
+	}
+
+	if (tctx == NULL) {
+		abort();
+	}
+#endif
+
+	if (tctx != NULL) {
 		/* with HAVE_PTHREAD */
-		tevent_threaded_schedule_immediate(job->state->glue->tctx,
-						   job->im,
+		tevent_threaded_schedule_immediate(tctx, job->im,
 						   pthreadpool_tevent_job_done,
 						   job);
 	} else {
 		/* without HAVE_PTHREAD */
-		tevent_schedule_immediate(job->im,
-					  job->state->glue->ev,
+		tevent_schedule_immediate(job->im, state->ev,
 					  pthreadpool_tevent_job_done,
 					  job);
 	}
-- 
2.17.2


From a238ecacbdf1884a103d8a4aed3ee7cc353546a4 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:44:49 +0100
Subject: [PATCH 24/56] Revert "pthreadpool: add helgrind magic to
 PTHREAD_TEVENT_JOB_THREAD_FENCE_*()"

This reverts commit 9b73fda926eb8493e80012794483039be66d4e6c.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 34 ----------------------------
 1 file changed, 34 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index fdcd494fc3e..13972381670 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -26,39 +26,8 @@
 #include "lib/util/dlinklist.h"
 #include "lib/util/attr.h"
 
-/*
- * We try to give some hints to helgrind/drd
- *
- * Note ANNOTATE_BENIGN_RACE_SIZED(address, size, describtion)
- * takes an memory address range that ignored by helgrind/drd
- * 'description' is just ignored...
- *
- *
- * Note that ANNOTATE_HAPPENS_*(unique_uintptr)
- * just takes a DWORD/(void *) as unique key
- * for the barrier.
- */
-#ifdef HAVE_VALGRIND_HELGRIND_H
-#include <valgrind/helgrind.h>
-#endif
-#ifndef ANNOTATE_BENIGN_RACE_SIZED
-#define ANNOTATE_BENIGN_RACE_SIZED(address, size, describtion)
-#endif
-#ifndef ANNOTATE_HAPPENS_BEFORE
-#define ANNOTATE_HAPPENS_BEFORE(unique_uintptr)
-#endif
-#ifndef ANNOTATE_HAPPENS_AFTER
-#define ANNOTATE_HAPPENS_AFTER(unique_uintptr)
-#endif
-#ifndef ANNOTATE_HAPPENS_BEFORE_FORGET_ALL
-#define ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(unique_uintptr)
-#endif
-
 #define PTHREAD_TEVENT_JOB_THREAD_FENCE_INIT(__job) do { \
 	_UNUSED_ const struct pthreadpool_tevent_job *__j = __job; \
-	ANNOTATE_BENIGN_RACE_SIZED(&__j->needs_fence, \
-				   sizeof(__j->needs_fence), \
-				   "race by design, protected by fence"); \
 } while(0);
 
 #ifdef WITH_PTHREADPOOL
@@ -80,14 +49,11 @@
 
 #define PTHREAD_TEVENT_JOB_THREAD_FENCE(__job) do { \
 	_UNUSED_ const struct pthreadpool_tevent_job *__j = __job; \
-	ANNOTATE_HAPPENS_BEFORE(&__job->needs_fence); \
 	__PTHREAD_TEVENT_JOB_THREAD_FENCE(memory_order_seq_cst); \
-	ANNOTATE_HAPPENS_AFTER(&__job->needs_fence); \
 } while(0);
 
 #define PTHREAD_TEVENT_JOB_THREAD_FENCE_FINI(__job) do { \
 	_UNUSED_ const struct pthreadpool_tevent_job *__j = __job; \
-	ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&__job->needs_fence); \
 } while(0);
 
 struct pthreadpool_tevent_job_state;
-- 
2.17.2


From 595688259ba857b1901b7e25f619229793e106ac Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 23 Dec 2018 09:46:13 +0100
Subject: [PATCH 25/56] Revert "pthreadpool: add some lockless coordination
 between the main and job threads"

This reverts commit 9656b8d8ee11ee351870286f16ea8fbe49112292.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 212 +--------------------------
 lib/pthreadpool/pthreadpool_tevent.h |  14 --
 wscript                              |  12 +-
 3 files changed, 7 insertions(+), 231 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index 13972381670..4c1a4ceae9c 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -18,43 +18,11 @@
  */
 
 #include "replace.h"
-#include "system/threads.h"
 #include "system/filesys.h"
 #include "pthreadpool_tevent.h"
 #include "pthreadpool.h"
 #include "lib/util/tevent_unix.h"
 #include "lib/util/dlinklist.h"
-#include "lib/util/attr.h"
-
-#define PTHREAD_TEVENT_JOB_THREAD_FENCE_INIT(__job) do { \
-	_UNUSED_ const struct pthreadpool_tevent_job *__j = __job; \
-} while(0);
-
-#ifdef WITH_PTHREADPOOL
-/*
- * configure checked we have pthread and atomic_thread_fence() available
- */
-#define __PTHREAD_TEVENT_JOB_THREAD_FENCE(__order) do { \
-	atomic_thread_fence(__order); \
-} while(0)
-#else
-/*
- * we're using lib/pthreadpool/pthreadpool_sync.c ...
- */
-#define __PTHREAD_TEVENT_JOB_THREAD_FENCE(__order) do { } while(0)
-#ifndef HAVE___THREAD
-#define __thread
-#endif
-#endif
-
-#define PTHREAD_TEVENT_JOB_THREAD_FENCE(__job) do { \
-	_UNUSED_ const struct pthreadpool_tevent_job *__j = __job; \
-	__PTHREAD_TEVENT_JOB_THREAD_FENCE(memory_order_seq_cst); \
-} while(0);
-
-#define PTHREAD_TEVENT_JOB_THREAD_FENCE_FINI(__job) do { \
-	_UNUSED_ const struct pthreadpool_tevent_job *__j = __job; \
-} while(0);
 
 struct pthreadpool_tevent_job_state;
 
@@ -108,70 +76,6 @@ struct pthreadpool_tevent_job {
 
 	void (*fn)(void *private_data);
 	void *private_data;
-
-	/*
-	 * Coordination between threads
-	 *
-	 * There're only one side writing each element
-	 * either the main process or the job thread.
-	 *
-	 * The coordination is done by a full memory
-	 * barrier using atomic_thread_fence(memory_order_seq_cst)
-	 * wrapped in PTHREAD_TEVENT_JOB_THREAD_FENCE()
-	 */
-	struct {
-		/*
-		 * 'maycancel'
-		 * set when tevent_req_cancel() is called.
-		 * (only written by main thread!)
-		 */
-		bool maycancel;
-
-		/*
-		 * 'orphaned'
-		 * set when talloc_free is called on the job request,
-		 * tevent_context or pthreadpool_tevent.
-		 * (only written by main thread!)
-		 */
-		bool orphaned;
-
-		/*
-		 * 'started'
-		 * set when the job is picked up by a worker thread
-		 * (only written by job thread!)
-		 */
-		bool started;
-
-		/*
-		 * 'executed'
-		 * set once the job function returned.
-		 * (only written by job thread!)
-		 */
-		bool executed;
-
-		/*
-		 * 'finished'
-		 * set when pthreadpool_tevent_job_signal() is entered
-		 * (only written by job thread!)
-		 */
-		bool finished;
-
-		/*
-		 * 'dropped'
-		 * set when pthreadpool_tevent_job_signal() leaves with
-		 * orphaned already set.
-		 * (only written by job thread!)
-		 */
-		bool dropped;
-
-		/*
-		 * 'signaled'
-		 * set when pthreadpool_tevent_job_signal() leaves normal
-		 * and the immediate event was scheduled.
-		 * (only written by job thread!)
-		 */
-		bool signaled;
-	} needs_fence;
 };
 
 static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool);
@@ -401,11 +305,11 @@ static bool pthreadpool_tevent_job_cancel(struct tevent_req *req);
 static int pthreadpool_tevent_job_destructor(struct pthreadpool_tevent_job *job)
 {
 	/*
-	 * We should never be called with needs_fence.orphaned == false.
+	 * We should never be called with state->state != NULL.
 	 * Only pthreadpool_tevent_job_orphan() will call TALLOC_FREE(job)
 	 * after detaching from the request state and pool list.
 	 */
-	if (!job->needs_fence.orphaned) {
+	if (job->state != NULL) {
 		abort();
 	}
 
@@ -430,17 +334,6 @@ static int pthreadpool_tevent_job_destructor(struct pthreadpool_tevent_job *job)
 		}
 	}
 
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	if (job->needs_fence.dropped) {
-		/*
-		 * The signal function saw job->needs_fence.orphaned
-		 * before it started the signaling via the immediate
-		 * event. So we'll never geht triggered and can
-		 * remove job->im and let the whole job go...
-		 */
-		TALLOC_FREE(job->im);
-	}
-
 	/*
 	 * pthreadpool_tevent_job_orphan() already removed
 	 * it from pool->jobs. And we don't need try
@@ -464,15 +357,11 @@ static int pthreadpool_tevent_job_destructor(struct pthreadpool_tevent_job *job)
 	 */
 	DLIST_REMOVE(orphaned_jobs, job);
 
-	PTHREAD_TEVENT_JOB_THREAD_FENCE_FINI(job);
 	return 0;
 }
 
 static void pthreadpool_tevent_job_orphan(struct pthreadpool_tevent_job *job)
 {
-	job->needs_fence.orphaned = true;
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-
 	/*
 	 * We're the only function that sets
 	 * job->state = NULL;
@@ -593,7 +482,6 @@ struct tevent_req *pthreadpool_tevent_job_send(
 	if (tevent_req_nomem(job->im, req)) {
 		return tevent_req_post(req, ev);
 	}
-	PTHREAD_TEVENT_JOB_THREAD_FENCE_INIT(job);
 	talloc_set_destructor(job, pthreadpool_tevent_job_destructor);
 	DLIST_ADD_END(job->pool->jobs, job);
 	job->state = state;
@@ -610,76 +498,13 @@ struct tevent_req *pthreadpool_tevent_job_send(
 	return req;
 }
 
-static __thread struct pthreadpool_tevent_job *current_job;
-
-bool pthreadpool_tevent_current_job_canceled(void)
-{
-	if (current_job == NULL) {
-		/*
-		 * Should only be called from within
-		 * the job function.
-		 */
-		abort();
-		return false;
-	}
-
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(current_job);
-	return current_job->needs_fence.maycancel;
-}
-
-bool pthreadpool_tevent_current_job_orphaned(void)
-{
-	if (current_job == NULL) {
-		/*
-		 * Should only be called from within
-		 * the job function.
-		 */
-		abort();
-		return false;
-	}
-
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(current_job);
-	return current_job->needs_fence.orphaned;
-}
-
-bool pthreadpool_tevent_current_job_continue(void)
-{
-	if (current_job == NULL) {
-		/*
-		 * Should only be called from within
-		 * the job function.
-		 */
-		abort();
-		return false;
-	}
-
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(current_job);
-	if (current_job->needs_fence.maycancel) {
-		return false;
-	}
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(current_job);
-	if (current_job->needs_fence.orphaned) {
-		return false;
-	}
-
-	return true;
-}
-
 static void pthreadpool_tevent_job_fn(void *private_data)
 {
 	struct pthreadpool_tevent_job *job =
 		talloc_get_type_abort(private_data,
 		struct pthreadpool_tevent_job);
 
-	current_job = job;
-	job->needs_fence.started = true;
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-
 	job->fn(job->private_data);
-
-	job->needs_fence.executed = true;
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	current_job = NULL;
 }
 
 static int pthreadpool_tevent_job_signal(int jobid,
@@ -694,12 +519,8 @@ static int pthreadpool_tevent_job_signal(int jobid,
 	struct tevent_threaded_context *tctx = NULL;
 	struct pthreadpool_tevent_glue *g = NULL;
 
-	job->needs_fence.finished = true;
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	if (job->needs_fence.orphaned) {
+	if (state == NULL) {
 		/* Request already gone */
-		job->needs_fence.dropped = true;
-		PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
 		return 0;
 	}
 
@@ -728,8 +549,6 @@ static int pthreadpool_tevent_job_signal(int jobid,
 					  job);
 	}
 
-	job->needs_fence.signaled = true;
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
 	return 0;
 }
 
@@ -752,17 +571,9 @@ static void pthreadpool_tevent_job_done(struct tevent_context *ctx,
 
 	/*
 	 * pthreadpool_tevent_job_cleanup()
-	 * (called by tevent_req_done() or
-	 * tevent_req_error()) will destroy the job.
+	 * will destroy the job.
 	 */
-
-	if (job->needs_fence.executed) {
-		tevent_req_done(state->req);
-		return;
-	}
-
-	tevent_req_error(state->req, ENOEXEC);
-	return;
+	tevent_req_done(state->req);
 }
 
 static bool pthreadpool_tevent_job_cancel(struct tevent_req *req)
@@ -777,19 +588,6 @@ static bool pthreadpool_tevent_job_cancel(struct tevent_req *req)
 		return false;
 	}
 
-	job->needs_fence.maycancel = true;
-	PTHREAD_TEVENT_JOB_THREAD_FENCE(job);
-	if (job->needs_fence.started) {
-		/*
-		 * It was too late to cancel the request.
-		 *
-		 * The job still has the chance to look
-		 * at pthreadpool_tevent_current_job_canceled()
-		 * or pthreadpool_tevent_current_job_continue()
-		 */
-		return false;
-	}
-
 	num = pthreadpool_cancel_job(job->pool->pool, 0,
 				     pthreadpool_tevent_job_fn,
 				     job);
diff --git a/lib/pthreadpool/pthreadpool_tevent.h b/lib/pthreadpool/pthreadpool_tevent.h
index 9724ba3ba7a..d82abbaa22d 100644
--- a/lib/pthreadpool/pthreadpool_tevent.h
+++ b/lib/pthreadpool/pthreadpool_tevent.h
@@ -33,20 +33,6 @@ size_t pthreadpool_tevent_max_threads(struct pthreadpool_tevent *pool);
 size_t pthreadpool_tevent_queued_jobs(struct pthreadpool_tevent *pool);
 bool pthreadpool_tevent_per_thread_cwd(struct pthreadpool_tevent *pool);
 
-/*
- * return true - if tevent_req_cancel() was called.
- */
-bool pthreadpool_tevent_current_job_canceled(void);
-/*
- * return true - if talloc_free() was called on the job request,
- * tevent_context or pthreadpool_tevent.
- */
-bool pthreadpool_tevent_current_job_orphaned(void);
-/*
- * return true if canceled and orphaned are both false.
- */
-bool pthreadpool_tevent_current_job_continue(void);
-
 struct tevent_req *pthreadpool_tevent_job_send(
 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 	struct pthreadpool_tevent *pool,
diff --git a/wscript b/wscript
index da4254efde4..e38a8e9aecf 100644
--- a/wscript
+++ b/wscript
@@ -279,18 +279,10 @@ default_prefix = Options.default_prefix = '/usr/local/samba'
         conf.DEFINE('WITH_NTVFS_FILESERVER', 1)
 
     if Options.options.with_pthreadpool:
-        if conf.CONFIG_SET('HAVE_PTHREAD') and \
-           conf.CONFIG_SET('HAVE___THREAD') and \
-           conf.CONFIG_SET('HAVE_ATOMIC_THREAD_FENCE_SUPPORT'):
+        if conf.CONFIG_SET('HAVE_PTHREAD'):
             conf.DEFINE('WITH_PTHREADPOOL', '1')
         else:
-            if not conf.CONFIG_SET('HAVE_PTHREAD'):
-                Logs.warn("pthreadpool support cannot be enabled when pthread support was not found")
-            if not conf.CONFIG_SET('HAVE_ATOMIC_THREAD_FENCE_SUPPORT'):
-                Logs.warn("""pthreadpool support cannot be enabled when there is
-                          no support for atomic_thead_fence()""")
-            if not conf.CONFIG_SET('HAVE___THREAD'):
-                Logs.warn("pthreadpool support cannot be enabled when __thread support was not found")
+            Logs.warn("pthreadpool support cannot be enabled when pthread support was not found")
             conf.undefine('WITH_PTHREADPOOL')
 
     conf.SET_TARGET_TYPE('jansson', 'EMPTY')
-- 
2.17.2


From d1c9c8c02e15031261205efbd171c47be7745fdc Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 28 Dec 2018 09:02:54 +0100
Subject: [PATCH 26/56] Revert "pthreadpool: maintain a global list of orphaned
 pthreadpool_tevent_jobs"

This reverts commit 25756425aaf5465e56ea809cd415b6a387848919.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 41 ----------------------------
 lib/pthreadpool/pthreadpool_tevent.h |  2 --
 2 files changed, 43 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index 4c1a4ceae9c..9023f41129c 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -82,24 +82,6 @@ static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool);
 
 static void pthreadpool_tevent_job_orphan(struct pthreadpool_tevent_job *job);
 
-static struct pthreadpool_tevent_job *orphaned_jobs;
-
-void pthreadpool_tevent_cleanup_orphaned_jobs(void)
-{
-	struct pthreadpool_tevent_job *job = NULL;
-	struct pthreadpool_tevent_job *njob = NULL;
-
-	for (job = orphaned_jobs; job != NULL; job = njob) {
-		njob = job->next;
-
-		/*
-		 * The job destructor keeps the job alive
-		 * (and in the list) or removes it from the list.
-		 */
-		TALLOC_FREE(job);
-	}
-}
-
 static int pthreadpool_tevent_job_signal(int jobid,
 					 void (*job_fn)(void *private_data),
 					 void *job_private_data,
@@ -111,8 +93,6 @@ int pthreadpool_tevent_init(TALLOC_CTX *mem_ctx, unsigned max_threads,
 	struct pthreadpool_tevent *pool;
 	int ret;
 
-	pthreadpool_tevent_cleanup_orphaned_jobs();
-
 	pool = talloc_zero(mem_ctx, struct pthreadpool_tevent);
 	if (pool == NULL) {
 		return ENOMEM;
@@ -190,8 +170,6 @@ static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool)
 	}
 	pool->pool = NULL;
 
-	pthreadpool_tevent_cleanup_orphaned_jobs();
-
 	return 0;
 }
 
@@ -345,18 +323,10 @@ static int pthreadpool_tevent_job_destructor(struct pthreadpool_tevent_job *job)
 		/*
 		 * state->im still there means, we need to wait for the
 		 * immediate event to be triggered or just leak the memory.
-		 *
-		 * Move it to the orphaned list, if it's not already there.
 		 */
 		return -1;
 	}
 
-	/*
-	 * Finally remove from the orphaned_jobs list
-	 * and let talloc destroy us.
-	 */
-	DLIST_REMOVE(orphaned_jobs, job);
-
 	return 0;
 }
 
@@ -398,15 +368,6 @@ static void pthreadpool_tevent_job_orphan(struct pthreadpool_tevent_job *job)
 	 */
 	DLIST_REMOVE(job->pool->jobs, job);
 
-	/*
-	 * Add it to the list of orphaned jobs,
-	 * which may be cleaned up later.
-	 *
-	 * The destructor removes it from the list
-	 * when possible or it denies the free
-	 * and keep it in the list.
-	 */
-	DLIST_ADD_END(orphaned_jobs, job);
 	TALLOC_FREE(job);
 }
 
@@ -445,8 +406,6 @@ struct tevent_req *pthreadpool_tevent_job_send(
 	struct pthreadpool_tevent_job *job = NULL;
 	int ret;
 
-	pthreadpool_tevent_cleanup_orphaned_jobs();
-
 	req = tevent_req_create(mem_ctx, &state,
 				struct pthreadpool_tevent_job_state);
 	if (req == NULL) {
diff --git a/lib/pthreadpool/pthreadpool_tevent.h b/lib/pthreadpool/pthreadpool_tevent.h
index d82abbaa22d..81b586143c2 100644
--- a/lib/pthreadpool/pthreadpool_tevent.h
+++ b/lib/pthreadpool/pthreadpool_tevent.h
@@ -22,8 +22,6 @@
 
 #include <tevent.h>
 
-void pthreadpool_tevent_cleanup_orphaned_jobs(void);
-
 struct pthreadpool_tevent;
 
 int pthreadpool_tevent_init(TALLOC_CTX *mem_ctx, unsigned max_threads,
-- 
2.17.2


From 9a6f7466fe277d4470266aa2c47a6f9741816768 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 28 Dec 2018 09:03:34 +0100
Subject: [PATCH 27/56] Revert "pthreadpool: add
 pthreadpool_tevent_job_cancel()"

This reverts commit 791c05144ee9296024cc0fdebe4afeaaf67e26bc.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 40 ----------------------------
 1 file changed, 40 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index 9023f41129c..83937044359 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -278,7 +278,6 @@ static void pthreadpool_tevent_job_fn(void *private_data);
 static void pthreadpool_tevent_job_done(struct tevent_context *ctx,
 					struct tevent_immediate *im,
 					void *private_data);
-static bool pthreadpool_tevent_job_cancel(struct tevent_req *req);
 
 static int pthreadpool_tevent_job_destructor(struct pthreadpool_tevent_job *job)
 {
@@ -453,7 +452,6 @@ struct tevent_req *pthreadpool_tevent_job_send(
 		return tevent_req_post(req, ev);
 	}
 
-	tevent_req_set_cancel_fn(req, pthreadpool_tevent_job_cancel);
 	return req;
 }
 
@@ -535,44 +533,6 @@ static void pthreadpool_tevent_job_done(struct tevent_context *ctx,
 	tevent_req_done(state->req);
 }
 
-static bool pthreadpool_tevent_job_cancel(struct tevent_req *req)
-{
-	struct pthreadpool_tevent_job_state *state =
-		tevent_req_data(req,
-		struct pthreadpool_tevent_job_state);
-	struct pthreadpool_tevent_job *job = state->job;
-	size_t num;
-
-	if (job == NULL) {
-		return false;
-	}
-
-	num = pthreadpool_cancel_job(job->pool->pool, 0,
-				     pthreadpool_tevent_job_fn,
-				     job);
-	if (num == 0) {
-		/*
-		 * It was too late to cancel the request.
-		 */
-		return false;
-	}
-
-	/*
-	 * It was not too late to cancel the request.
-	 *
-	 * We can remove job->im, as it will never be used.
-	 */
-	TALLOC_FREE(job->im);
-
-	/*
-	 * pthreadpool_tevent_job_cleanup()
-	 * will destroy the job.
-	 */
-	tevent_req_defer_callback(req, state->ev);
-	tevent_req_error(req, ECANCELED);
-	return true;
-}
-
 int pthreadpool_tevent_job_recv(struct tevent_req *req)
 {
 	return tevent_req_simple_recv_unix(req);
-- 
2.17.2


From d33513869a3e7d175c334adf78a592962043ddce Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 28 Dec 2018 09:03:45 +0100
Subject: [PATCH 28/56] Revert "pthreadpool: split out pthreadpool_tevent_job
 from pthreadpool_tevent_job_state"

This reverts commit 245d684d28dab630f3d47ff61006a1fe3e5eeefa.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/pthreadpool/pthreadpool_tevent.c | 238 ++++++++-------------------
 1 file changed, 66 insertions(+), 172 deletions(-)

diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index 83937044359..643849a6aea 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -58,21 +58,15 @@ struct pthreadpool_tevent {
 	struct pthreadpool *pool;
 	struct pthreadpool_tevent_glue *glue_list;
 
-	struct pthreadpool_tevent_job *jobs;
+	struct pthreadpool_tevent_job_state *jobs;
 };
 
 struct pthreadpool_tevent_job_state {
-	struct tevent_context *ev;
-	struct tevent_req *req;
-	struct pthreadpool_tevent_job *job;
-};
-
-struct pthreadpool_tevent_job {
-	struct pthreadpool_tevent_job *prev, *next;
-
+	struct pthreadpool_tevent_job_state *prev, *next;
 	struct pthreadpool_tevent *pool;
-	struct pthreadpool_tevent_job_state *state;
+	struct tevent_context *ev;
 	struct tevent_immediate *im;
+	struct tevent_req *req;
 
 	void (*fn)(void *private_data);
 	void *private_data;
@@ -80,8 +74,6 @@ struct pthreadpool_tevent_job {
 
 static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool);
 
-static void pthreadpool_tevent_job_orphan(struct pthreadpool_tevent_job *job);
-
 static int pthreadpool_tevent_job_signal(int jobid,
 					 void (*job_fn)(void *private_data),
 					 void *job_private_data,
@@ -136,8 +128,7 @@ bool pthreadpool_tevent_per_thread_cwd(struct pthreadpool_tevent *pool)
 
 static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool)
 {
-	struct pthreadpool_tevent_job *job = NULL;
-	struct pthreadpool_tevent_job *njob = NULL;
+	struct pthreadpool_tevent_job_state *state, *next;
 	struct pthreadpool_tevent_glue *glue = NULL;
 	int ret;
 
@@ -146,11 +137,10 @@ static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool)
 		return ret;
 	}
 
-	for (job = pool->jobs; job != NULL; job = njob) {
-		njob = job->next;
-
-		/* The job this removes it from the list */
-		pthreadpool_tevent_job_orphan(job);
+	for (state = pool->jobs; state != NULL; state = next) {
+		next = state->next;
+		DLIST_REMOVE(pool->jobs, state);
+		state->pool = NULL;
 	}
 
 	/*
@@ -279,120 +269,27 @@ static void pthreadpool_tevent_job_done(struct tevent_context *ctx,
 					struct tevent_immediate *im,
 					void *private_data);
 
-static int pthreadpool_tevent_job_destructor(struct pthreadpool_tevent_job *job)
+static int pthreadpool_tevent_job_state_destructor(
+	struct pthreadpool_tevent_job_state *state)
 {
-	/*
-	 * We should never be called with state->state != NULL.
-	 * Only pthreadpool_tevent_job_orphan() will call TALLOC_FREE(job)
-	 * after detaching from the request state and pool list.
-	 */
-	if (job->state != NULL) {
-		abort();
-	}
-
-	/*
-	 * If the job is not finished (job->im still there)
-	 * and it's still attached to the pool,
-	 * we try to cancel it (before it was starts)
-	 */
-	if (job->im != NULL && job->pool != NULL) {
-		size_t num;
-
-		num = pthreadpool_cancel_job(job->pool->pool, 0,
-					     pthreadpool_tevent_job_fn,
-					     job);
-		if (num != 0) {
-			/*
-			 * It was not too late to cancel the request.
-			 *
-			 * We can remove job->im, as it will never be used.
-			 */
-			TALLOC_FREE(job->im);
-		}
-	}
-
-	/*
-	 * pthreadpool_tevent_job_orphan() already removed
-	 * it from pool->jobs. And we don't need try
-	 * pthreadpool_cancel_job() again.
-	 */
-	job->pool = NULL;
-
-	if (job->im != NULL) {
-		/*
-		 * state->im still there means, we need to wait for the
-		 * immediate event to be triggered or just leak the memory.
-		 */
-		return -1;
-	}
-
-	return 0;
-}
-
-static void pthreadpool_tevent_job_orphan(struct pthreadpool_tevent_job *job)
-{
-	/*
-	 * We're the only function that sets
-	 * job->state = NULL;
-	 */
-	if (job->state == NULL) {
-		abort();
+	if (state->pool == NULL) {
+		return 0;
 	}
 
 	/*
-	 * We need to reparent to a long term context.
-	 * And detach from the request state.
-	 * Maybe the destructor will keep the memory
-	 * and leak it for now.
+	 * We should never be called with state->req == NULL,
+	 * state->pool must be cleared before the 2nd talloc_free().
 	 */
-	(void)talloc_reparent(job->state, NULL, job);
-	job->state->job = NULL;
-	job->state = NULL;
-
-	/*
-	 * job->pool will only be set to NULL
-	 * in the first destructur run.
-	 */
-	if (job->pool == NULL) {
+	if (state->req == NULL) {
 		abort();
 	}
 
-	/*
-	 * Dettach it from the pool.
-	 *
-	 * The job might still be running,
-	 * so we keep job->pool.
-	 * The destructor will set it to NULL
-	 * after trying pthreadpool_cancel_job()
-	 */
-	DLIST_REMOVE(job->pool->jobs, job);
-
-	TALLOC_FREE(job);
-}
-
-static void pthreadpool_tevent_job_cleanup(struct tevent_req *req,
-					   enum tevent_req_state req_state)
-{
-	struct pthreadpool_tevent_job_state *state =
-		tevent_req_data(req,
-		struct pthreadpool_tevent_job_state);
-
-	if (state->job == NULL) {
-		/*
-		 * The job request is not scheduled in the pool
-		 * yet or anymore.
-		 */
-		return;
-	}
-
 	/*
 	 * We need to reparent to a long term context.
-	 * Maybe the destructor will keep the memory
-	 * and leak it for now.
 	 */
-	pthreadpool_tevent_job_orphan(state->job);
-	state->job = NULL; /* not needed but looks better */
-	return;
+	(void)talloc_reparent(state->req, NULL, state);
+	state->req = NULL;
+	return -1;
 }
 
 struct tevent_req *pthreadpool_tevent_job_send(
@@ -400,9 +297,8 @@ struct tevent_req *pthreadpool_tevent_job_send(
 	struct pthreadpool_tevent *pool,
 	void (*fn)(void *private_data), void *private_data)
 {
-	struct tevent_req *req = NULL;
-	struct pthreadpool_tevent_job_state *state = NULL;
-	struct pthreadpool_tevent_job *job = NULL;
+	struct tevent_req *req;
+	struct pthreadpool_tevent_job_state *state;
 	int ret;
 
 	req = tevent_req_create(mem_ctx, &state,
@@ -410,10 +306,11 @@ struct tevent_req *pthreadpool_tevent_job_send(
 	if (req == NULL) {
 		return NULL;
 	}
+	state->pool = pool;
 	state->ev = ev;
 	state->req = req;
-
-	tevent_req_set_cleanup_fn(req, pthreadpool_tevent_job_cleanup);
+	state->fn = fn;
+	state->private_data = private_data;
 
 	if (pool == NULL) {
 		tevent_req_error(req, EINVAL);
@@ -424,44 +321,39 @@ struct tevent_req *pthreadpool_tevent_job_send(
 		return tevent_req_post(req, ev);
 	}
 
-	ret = pthreadpool_tevent_register_ev(pool, ev);
-	if (tevent_req_error(req, ret)) {
+	state->im = tevent_create_immediate(state);
+	if (tevent_req_nomem(state->im, req)) {
 		return tevent_req_post(req, ev);
 	}
 
-	job = talloc_zero(state, struct pthreadpool_tevent_job);
-	if (tevent_req_nomem(job, req)) {
-		return tevent_req_post(req, ev);
-	}
-	job->pool = pool;
-	job->fn = fn;
-	job->private_data = private_data;
-	job->im = tevent_create_immediate(state->job);
-	if (tevent_req_nomem(job->im, req)) {
+	ret = pthreadpool_tevent_register_ev(pool, ev);
+	if (tevent_req_error(req, ret)) {
 		return tevent_req_post(req, ev);
 	}
-	talloc_set_destructor(job, pthreadpool_tevent_job_destructor);
-	DLIST_ADD_END(job->pool->jobs, job);
-	job->state = state;
-	state->job = job;
 
-	ret = pthreadpool_add_job(job->pool->pool, 0,
+	ret = pthreadpool_add_job(pool->pool, 0,
 				  pthreadpool_tevent_job_fn,
-				  job);
+				  state);
 	if (tevent_req_error(req, ret)) {
 		return tevent_req_post(req, ev);
 	}
 
+	/*
+	 * Once the job is scheduled, we need to protect
+	 * our memory.
+	 */
+	talloc_set_destructor(state, pthreadpool_tevent_job_state_destructor);
+
+	DLIST_ADD_END(pool->jobs, state);
+
 	return req;
 }
 
 static void pthreadpool_tevent_job_fn(void *private_data)
 {
-	struct pthreadpool_tevent_job *job =
-		talloc_get_type_abort(private_data,
-		struct pthreadpool_tevent_job);
-
-	job->fn(job->private_data);
+	struct pthreadpool_tevent_job_state *state = talloc_get_type_abort(
+		private_data, struct pthreadpool_tevent_job_state);
+	state->fn(state->private_data);
 }
 
 static int pthreadpool_tevent_job_signal(int jobid,
@@ -469,20 +361,18 @@ static int pthreadpool_tevent_job_signal(int jobid,
 					 void *job_private_data,
 					 void *private_data)
 {
-	struct pthreadpool_tevent_job *job =
-		talloc_get_type_abort(job_private_data,
-		struct pthreadpool_tevent_job);
-	struct pthreadpool_tevent_job_state *state = job->state;
+	struct pthreadpool_tevent_job_state *state = talloc_get_type_abort(
+		job_private_data, struct pthreadpool_tevent_job_state);
 	struct tevent_threaded_context *tctx = NULL;
 	struct pthreadpool_tevent_glue *g = NULL;
 
-	if (state == NULL) {
-		/* Request already gone */
+	if (state->pool == NULL) {
+		/* The pthreadpool_tevent is already gone */
 		return 0;
 	}
 
 #ifdef HAVE_PTHREAD
-	for (g = job->pool->glue_list; g != NULL; g = g->next) {
+	for (g = state->pool->glue_list; g != NULL; g = g->next) {
 		if (g->ev == state->ev) {
 			tctx = g->tctx;
 			break;
@@ -496,14 +386,14 @@ static int pthreadpool_tevent_job_signal(int jobid,
 
 	if (tctx != NULL) {
 		/* with HAVE_PTHREAD */
-		tevent_threaded_schedule_immediate(tctx, job->im,
+		tevent_threaded_schedule_immediate(tctx, state->im,
 						   pthreadpool_tevent_job_done,
-						   job);
+						   state);
 	} else {
 		/* without HAVE_PTHREAD */
-		tevent_schedule_immediate(job->im, state->ev,
+		tevent_schedule_immediate(state->im, state->ev,
 					  pthreadpool_tevent_job_done,
-					  job);
+					  state);
 	}
 
 	return 0;
@@ -513,23 +403,27 @@ static void pthreadpool_tevent_job_done(struct tevent_context *ctx,
 					struct tevent_immediate *im,
 					void *private_data)
 {
-	struct pthreadpool_tevent_job *job =
-		talloc_get_type_abort(private_data,
-		struct pthreadpool_tevent_job);
-	struct pthreadpool_tevent_job_state *state = job->state;
+	struct pthreadpool_tevent_job_state *state = talloc_get_type_abort(
+		private_data, struct pthreadpool_tevent_job_state);
 
-	TALLOC_FREE(job->im);
+	if (state->pool != NULL) {
+		DLIST_REMOVE(state->pool->jobs, state);
+		state->pool = NULL;
+	}
 
-	if (state == NULL) {
-		/* Request already gone */
-		TALLOC_FREE(job);
+	if (state->req == NULL) {
+		/*
+		 * There was a talloc_free() state->req
+		 * while the job was pending,
+		 * which mean we're reparented on a longterm
+		 * talloc context.
+		 *
+		 * We just cleanup here...
+		 */
+		talloc_free(state);
 		return;
 	}
 
-	/*
-	 * pthreadpool_tevent_job_cleanup()
-	 * will destroy the job.
-	 */
 	tevent_req_done(state->req);
 }
 
-- 
2.17.2


From fcde5e4e018c030f2c4cd44ee87ebcf7a00d677c Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:36:43 +0100
Subject: [PATCH 29/56] Revert "smbd: remove unused change_to_root_user() from
 brl_timeout_fn()"

This reverts commit c310647e560abc2343ef2ff0ab15daab0fba2650.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/blocking.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 095c9edeacc..c281aae619d 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -47,6 +47,9 @@ void brl_timeout_fn(struct tevent_context *event_ctx,
 		TALLOC_FREE(sconn->smb1.locks.brl_timeout);
 	}
 
+	change_to_root_user();	/* TODO: Possibly run all timed events as
+				 * root */
+
 	process_blocking_lock_queue(sconn);
 }
 
-- 
2.17.2


From 567fd09fbd6bdcc1c2ea1f0b7351949665c1c250 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:37:03 +0100
Subject: [PATCH 30/56] Revert "smbd: remove unused change_to_root_user() from
 smbd_sig_hup_handler()"

This reverts commit d0b1f96f086bdd613644f64b3f75ee8c4388f674.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/process.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 4f9e5d1d71b..a7c302c362a 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -998,6 +998,7 @@ static void smbd_sig_hup_handler(struct tevent_context *ev,
 		talloc_get_type_abort(private_data,
 		struct smbd_server_connection);
 
+	change_to_root_user();
 	DEBUG(1,("Reloading services after SIGHUP\n"));
 	reload_services(sconn, conn_snum_used, false);
 }
-- 
2.17.2


From 5faf02ddd307c07292dd4644b9b68c34fdfcdc7d Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:37:16 +0100
Subject: [PATCH 31/56] Revert "smbd: avoid explicit change_to_user() in
 defer_rename_done() already done by impersonation"

This reverts commit e37e41b3cac52e3623f0c79f83733a51edb35c10.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smb2_setinfo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index 11b126aa794..7c1f84bd79d 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -284,6 +284,7 @@ static void defer_rename_done(struct tevent_req *subreq)
 	NTSTATUS status;
 	struct share_mode_lock *lck;
 	int ret_size = 0;
+	bool ok;
 
 	status = dbwrap_watched_watch_recv(subreq, NULL, NULL);
 	TALLOC_FREE(subreq);
@@ -294,6 +295,16 @@ static void defer_rename_done(struct tevent_req *subreq)
 		return;
 	}
 
+	/*
+	 * Make sure we run as the user again
+	 */
+	ok = change_to_user(state->smb2req->tcon->compat,
+			    state->smb2req->session->compat->vuid);
+	if (!ok) {
+		tevent_req_nterror(state->req, NT_STATUS_ACCESS_DENIED);
+		return;
+	}
+
 	/* Do we still need to wait ? */
 	lck = get_existing_share_mode_lock(state->req, state->fsp->file_id);
 	if (lck == NULL) {
-- 
2.17.2


From a19e71cf45df6304f911f88853926c6a112a1296 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:38:27 +0100
Subject: [PATCH 32/56] Revert "smbd: implement
 smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers"

This reverts commit 1b804f7ae23f54a6c1004e5ff17b9df1376b5adb.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/uid.c | 951 +--------------------------------------------
 1 file changed, 21 insertions(+), 930 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 0518e5254a8..e7f0a8f620b 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -975,961 +975,52 @@ uint64_t get_current_vuid(connection_struct *conn)
 	return current_user.vuid;
 }
 
-struct smbd_impersonate_conn_vuid_state {
-	struct connection_struct *conn;
-	uint64_t vuid;
-};
-
-static bool smbd_impersonate_conn_vuid_before_use(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		const char *location)
-{
-	struct smbd_impersonate_conn_vuid_state *state =
-		talloc_get_type_abort(private_data,
-		struct smbd_impersonate_conn_vuid_state);
-	bool ok;
-
-	DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]"
-		  "old uid[%ju] old gid[%ju] vuid[%ju] cwd[%s]\n",
-		  __func__, wrap_ev, main_ev, location,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  (uintmax_t)state->vuid, state->conn->cwd_fname->base_name));
-
-	ok = become_user(state->conn, state->vuid);
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
-		return false;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-
-	return true;
-}
-
-static void smbd_impersonate_conn_vuid_after_use(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		const char *location)
-{
-	struct smbd_impersonate_conn_vuid_state *state =
-		talloc_get_type_abort(private_data,
-		struct smbd_impersonate_conn_vuid_state);
-	bool ok;
-
-	DEBUG(11,("%s: deimpersonating[%s] uid[%ju] gid[%ju] cwd[%s] "
-		  "location[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name, location));
-
-	ok = unbecome_user();
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_vuid_after_use() - failed");
-		return;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
-
-static void smbd_impersonate_conn_vuid_before_fd_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_fd *fde,
-		uint16_t flags,
-		const char *handler_name,
-		const char *location)
-{
-	struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_vuid_state);
-	bool ok;
-
-	DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
-		  __func__, fde, (uintmax_t)flags, handler_name, location));
-
-	ok = change_to_user(state->conn, state->vuid);
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
-		return;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
-
-static void smbd_impersonate_conn_vuid_after_fd_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_fd *fde,
-		uint16_t flags,
-		const char *handler_name,
-		const char *location)
-{
-	DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
-		  __func__, fde, handler_name, location));
-
-	/* be lazy and defer change_to_root_user() */
-}
-
-static void smbd_impersonate_conn_vuid_before_timer_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_timer *te,
-		struct timeval requested_time,
-		struct timeval trigger_time,
-		const char *handler_name,
-		const char *location)
-{
-	struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_vuid_state);
-	struct timeval_buf requested_buf;
-	struct timeval_buf trigger_buf;
-	bool ok;
-
-	DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
-		  "handler_name[%s] location[%s]\n",
-		  __func__, te,
-		  timeval_str_buf(&requested_time, true, true, &requested_buf),
-		  timeval_str_buf(&trigger_time, true, true, &trigger_buf),
-		  handler_name, location));
-
-	ok = change_to_user(state->conn, state->vuid);
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
-		return;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
-
-static void smbd_impersonate_conn_vuid_after_timer_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_timer *te,
-		struct timeval requested_time,
-		struct timeval trigger_time,
-		const char *handler_name,
-		const char *location)
-{
-	DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
-		  __func__, te, handler_name, location));
-
-	/* be lazy and defer change_to_root_user() */
-}
-
-static void smbd_impersonate_conn_vuid_before_immediate_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_immediate *im,
-		const char *handler_name,
-		const char *location)
-{
-	struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_vuid_state);
-	bool ok;
-
-	DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
-		  __func__, im, handler_name, location));
-
-	ok = change_to_user(state->conn, state->vuid);
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
-		return;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
-
-static void smbd_impersonate_conn_vuid_after_immediate_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_immediate *im,
-		const char *handler_name,
-		const char *location)
-{
-	DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
-		  __func__, im, handler_name, location));
-
-	/* be lazy and defer unbecome_user() */
-}
-
-static void smbd_impersonate_conn_vuid_before_signal_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_signal *se,
-		int signum,
-		int count,
-		void *siginfo,
-		const char *handler_name,
-		const char *location)
-{
-	struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_vuid_state);
-	bool ok;
-
-	DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
-		  "handler_name[%s] location[%s]\n",
-		  __func__, se, signum, count, siginfo, handler_name, location));
-
-	ok = change_to_user(state->conn, state->vuid);
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
-		return;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
-
-static void smbd_impersonate_conn_vuid_after_signal_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_signal *se,
-		int signum,
-		int count,
-		void *siginfo,
-		const char *handler_name,
-		const char *location)
-{
-	DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
-		  __func__, se, handler_name, location));
-
-	/* be lazy and defer change_to_root_user() */
-}
-
-static const struct tevent_wrapper_ops smbd_impersonate_conn_vuid_ops = {
-	.name				= "smbd_impersonate_conn_vuid",
-	.before_use			= smbd_impersonate_conn_vuid_before_use,
-	.after_use			= smbd_impersonate_conn_vuid_after_use,
-	.before_fd_handler		= smbd_impersonate_conn_vuid_before_fd_handler,
-	.after_fd_handler		= smbd_impersonate_conn_vuid_after_fd_handler,
-	.before_timer_handler		= smbd_impersonate_conn_vuid_before_timer_handler,
-	.after_timer_handler		= smbd_impersonate_conn_vuid_after_timer_handler,
-	.before_immediate_handler	= smbd_impersonate_conn_vuid_before_immediate_handler,
-	.after_immediate_handler	= smbd_impersonate_conn_vuid_after_immediate_handler,
-	.before_signal_handler		= smbd_impersonate_conn_vuid_before_signal_handler,
-	.after_signal_handler		= smbd_impersonate_conn_vuid_after_signal_handler,
-};
-
 struct tevent_context *smbd_impersonate_conn_vuid_create(
 				struct tevent_context *main_ev,
 				struct connection_struct *conn,
 				uint64_t vuid)
 {
-	struct tevent_context *ev = NULL;
-	struct smbd_impersonate_conn_vuid_state *state = NULL;
-
-	ev = tevent_context_wrapper_create(main_ev,
-					   conn,
-					   &smbd_impersonate_conn_vuid_ops,
-					   &state,
-					   struct smbd_impersonate_conn_vuid_state);
-	if (ev == NULL) {
-		return NULL;
-	}
-	state->conn = conn;
-	state->vuid = vuid;
-
-	return ev;
-}
-
-struct smbd_impersonate_conn_sess_state {
-	struct connection_struct *conn;
-	struct auth_session_info *session_info;
-};
-
-static bool smbd_impersonate_conn_sess_before_use(struct tevent_context *wrap_ev,
-						  void *private_data,
-						  struct tevent_context *main_ev,
-						  const char *location)
-{
-	struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_sess_state);
-	bool ok;
-
-	DEBUG(11,("%s: impersonating user[%s] wrap_ev[%p] main_ev[%p] "
-		  "location[%s] old uid[%ju] old gid[%ju] cwd[%s]\n",
-		  __func__, state->session_info->unix_info->unix_name,
-		  wrap_ev, main_ev, location,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-
-	ok = become_user_by_session(state->conn, state->session_info);
-	if (!ok) {
-		return false;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-
-	return true;
-}
-
-static void smbd_impersonate_conn_sess_after_use(struct tevent_context *wrap_ev,
-						 void *private_data,
-						 struct tevent_context *main_ev,
-						 const char *location)
-{
-	struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_sess_state);
-	bool ok;
-
-	DEBUG(11,("%s: deimpersonating[%s] uid[%ju] gid[%ju] cwd[%s] "
-		  "location[%s]\n",
-		  __func__, state->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name, location));
-
-	ok = unbecome_user();
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_sess_after_use() - failed");
-		return;
-	}
-
-	DEBUG(11,("%s: deimpersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
-
-static void smbd_impersonate_conn_sess_before_fd_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_fd *fde,
-		uint16_t flags,
-		const char *handler_name,
-		const char *location)
-{
-	struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_sess_state);
-	bool ok;
-
-	DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
-		  __func__, fde, (uintmax_t)flags, handler_name, location));
-
-	ok = change_to_user_by_session(state->conn, state->session_info);
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_sess_before_fd_handler failed");
-		return;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
-
-static void smbd_impersonate_conn_sess_after_fd_handler(struct tevent_context *wrap_ev,
-							void *private_data,
-							struct tevent_context *main_ev,
-							struct tevent_fd *fde,
-							uint16_t flags,
-							const char *handler_name,
-							const char *location)
-{
-	DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
-		  __func__, fde, handler_name, location));
-
-	/* be lazy and defer change_to_root_user() */
-}
-
-static void smbd_impersonate_conn_sess_before_timer_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_timer *te,
-		struct timeval requested_time,
-		struct timeval trigger_time,
-		const char *handler_name,
-		const char *location)
-{
-	struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_sess_state);
-	struct timeval_buf requested_buf;
-	struct timeval_buf trigger_buf;
-	bool ok;
-
-	DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
-		  "handler_name[%s] location[%s]\n",
-		  __func__, te,
-		  timeval_str_buf(&requested_time, true, true, &requested_buf),
-		  timeval_str_buf(&trigger_time, true, true, &trigger_buf),
-		  handler_name, location));
-
-	ok = change_to_user_by_session(state->conn, state->session_info);
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_sess_before_tm_handler failed");
-		return;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
-
-static void smbd_impersonate_conn_sess_after_timer_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_timer *te,
-		struct timeval requested_time,
-		struct timeval trigger_time,
-		const char *handler_name,
-		const char *location)
-{
-	DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
-		  __func__, te, handler_name, location));
-
-	/* be lazy and defer change_to_root_user() */
-}
-
-static void smbd_impersonate_conn_sess_before_immediate_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_immediate *im,
-		const char *handler_name,
-		const char *location)
-{
-	struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_sess_state);
-	bool ok;
-
-	DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
-		  __func__, im, handler_name, location));
-
-	ok = change_to_user_by_session(state->conn, state->session_info);
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_sess_before_im_handler failed");
-		return;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
-
-static void smbd_impersonate_conn_sess_after_immediate_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_immediate *im,
-		const char *handler_name,
-		const char *location)
-{
-	DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
-		  __func__, im, handler_name, location));
-
-	/* be lazy and defer unbecome_user() */
-}
-
-static void smbd_impersonate_conn_sess_before_signal_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_signal *se,
-		int signum,
-		int count,
-		void *siginfo,
-		const char *handler_name,
-		const char *location)
-{
-	struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
-		private_data, struct smbd_impersonate_conn_sess_state);
-	bool ok;
-
-	DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
-		  "handler_name[%s] location[%s]\n",
-		  __func__, se, signum, count, siginfo, handler_name, location));
-
-	ok = change_to_user_by_session(state->conn, state->session_info);
-	if (!ok) {
-		smb_panic("smbd_impersonate_conn_sess_before_si_handler failed");
-		return;
-	}
-
-	DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
-		  __func__, state->conn->session_info->unix_info->unix_name,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  state->conn->cwd_fname->base_name));
-}
+	struct tevent_context *wrap_ev = NULL;
 
-static void smbd_impersonate_conn_sess_after_signal_handler(
-		struct tevent_context *wrap_ev,
-		void *private_data,
-		struct tevent_context *main_ev,
-		struct tevent_signal *se,
-		int signum,
-		int count,
-		void *siginfo,
-		const char *handler_name,
-		const char *location)
-{
-	DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
-		  __func__, se, handler_name, location));
+	wrap_ev = smbd_impersonate_debug_create(main_ev,
+						"conn_vuid",
+						DBGLVL_DEBUG);
 
-	/* be lazy and defer change_to_root_user() */
+	return wrap_ev;
 }
 
-static const struct tevent_wrapper_ops smbd_impersonate_conn_sess_ops = {
-	.name				= "smbd_impersonate_conn_sess",
-	.before_use			= smbd_impersonate_conn_sess_before_use,
-	.after_use			= smbd_impersonate_conn_sess_after_use,
-	.before_fd_handler		= smbd_impersonate_conn_sess_before_fd_handler,
-	.after_fd_handler		= smbd_impersonate_conn_sess_after_fd_handler,
-	.before_timer_handler		= smbd_impersonate_conn_sess_before_timer_handler,
-	.after_timer_handler		= smbd_impersonate_conn_sess_after_timer_handler,
-	.before_immediate_handler	= smbd_impersonate_conn_sess_before_immediate_handler,
-	.after_immediate_handler	= smbd_impersonate_conn_sess_after_immediate_handler,
-	.before_signal_handler		= smbd_impersonate_conn_sess_before_signal_handler,
-	.after_signal_handler		= smbd_impersonate_conn_sess_after_signal_handler,
-};
-
 struct tevent_context *smbd_impersonate_conn_sess_create(
 				struct tevent_context *main_ev,
 				struct connection_struct *conn,
 				struct auth_session_info *session_info)
 {
-	struct tevent_context *ev = NULL;
-	struct smbd_impersonate_conn_sess_state *state = NULL;
-
-	ev = tevent_context_wrapper_create(main_ev,
-					   conn,
-					   &smbd_impersonate_conn_sess_ops,
-					   &state,
-					   struct smbd_impersonate_conn_sess_state);
-	if (ev == NULL) {
-		return NULL;
-	}
-	state->conn = conn;
-	state->session_info = session_info;
-
-	return ev;
-}
-
-struct smbd_impersonate_root_state {
-	uint8_t _dummy;
-};
-
-static bool smbd_impersonate_root_before_use(struct tevent_context *wrap_ev,
-					     void *private_data,
-					     struct tevent_context *main_ev,
-					     const char *location)
-{
-	DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]"
-		  "uid[%ju] gid[%ju]\n",
-		  __func__, wrap_ev, main_ev, location,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid()));
-
-	become_root();
-	return true;
-}
-
-static void smbd_impersonate_root_after_use(struct tevent_context *wrap_ev,
-					    void *private_data,
-					    struct tevent_context *main_ev,
-					    const char *location)
-{
-	unbecome_root();
-
-	DEBUG(11,("%s: uid[%ju] gid[%ju] location[%s]\n",
-		  __func__, (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  location));
-}
-
-static void smbd_impersonate_root_before_fd_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_fd *fde,
-						uint16_t flags,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
-		  __func__, fde, (uintmax_t)flags, handler_name, location));
-
-	smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
-}
-
-static void smbd_impersonate_root_after_fd_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_fd *fde,
-						uint16_t flags,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
-		  __func__, fde, handler_name, location));
-
-	smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
-}
-
-static void smbd_impersonate_root_before_timer_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_timer *te,
-						struct timeval requested_time,
-						struct timeval trigger_time,
-						const char *handler_name,
-						const char *location)
-{
-	struct timeval_buf requested_buf;
-	struct timeval_buf trigger_buf;
-
-	DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
-		  "handler_name[%s] location[%s]\n",
-		  __func__, te,
-		  timeval_str_buf(&requested_time, true, true, &requested_buf),
-		  timeval_str_buf(&trigger_time, true, true, &trigger_buf),
-		  handler_name, location));
-
-	smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
-}
-
-static void smbd_impersonate_root_after_timer_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_timer *te,
-						struct timeval requested_time,
-						struct timeval trigger_time,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
-		  __func__, te, handler_name, location));
-
-	smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
-}
-
-static void smbd_impersonate_root_before_immediate_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_immediate *im,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
-		  __func__, im, handler_name, location));
-
-	smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
-}
-
-static void smbd_impersonate_root_after_immediate_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_immediate *im,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
-		  __func__, im, handler_name, location));
-
-	smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
-}
-
-static void smbd_impersonate_root_before_signal_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_signal *se,
-						int signum,
-						int count,
-						void *siginfo,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
-		  "handler_name[%s] location[%s]\n",
-		  __func__, se, signum, count, siginfo, handler_name, location));
+	struct tevent_context *wrap_ev = NULL;
 
-	smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
-}
+	wrap_ev = smbd_impersonate_debug_create(main_ev,
+						"conn_sess",
+						DBGLVL_DEBUG);
 
-static void smbd_impersonate_root_after_signal_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_signal *se,
-						int signum,
-						int count,
-						void *siginfo,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
-		  __func__, se, handler_name, location));
-
-	smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
+	return wrap_ev;
 }
 
-static const struct tevent_wrapper_ops smbd_impersonate_root_ops = {
-	.name				= "smbd_impersonate_root",
-	.before_use			= smbd_impersonate_root_before_use,
-	.after_use			= smbd_impersonate_root_after_use,
-	.before_fd_handler		= smbd_impersonate_root_before_fd_handler,
-	.after_fd_handler		= smbd_impersonate_root_after_fd_handler,
-	.before_timer_handler		= smbd_impersonate_root_before_timer_handler,
-	.after_timer_handler		= smbd_impersonate_root_after_timer_handler,
-	.before_immediate_handler	= smbd_impersonate_root_before_immediate_handler,
-	.after_immediate_handler	= smbd_impersonate_root_after_immediate_handler,
-	.before_signal_handler		= smbd_impersonate_root_before_signal_handler,
-	.after_signal_handler		= smbd_impersonate_root_after_signal_handler,
-};
-
 struct tevent_context *smbd_impersonate_root_create(struct tevent_context *main_ev)
 {
-	struct tevent_context *ev = NULL;
-	struct smbd_impersonate_root_state *state = NULL;
-
-	ev = tevent_context_wrapper_create(main_ev,
-					   main_ev,
-					   &smbd_impersonate_root_ops,
-					   &state,
-					   struct smbd_impersonate_root_state);
-	if (ev == NULL) {
-		return NULL;
-	}
-
-	return ev;
-}
-
-struct smbd_impersonate_guest_state {
-	uint8_t _dummy;
-};
-
-static bool smbd_impersonate_guest_before_use(struct tevent_context *wrap_ev,
-					      void *private_data,
-					      struct tevent_context *main_ev,
-					      const char *location)
-{
-	DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]"
-		  "uid[%ju] gid[%ju]\n",
-		  __func__, wrap_ev, main_ev, location,
-		  (uintmax_t)geteuid(), (uintmax_t)getegid()));
-
-	return become_guest();
-}
-
-static void smbd_impersonate_guest_after_use(struct tevent_context *wrap_ev,
-					     void *private_data,
-					     struct tevent_context *main_ev,
-					     const char *location)
-{
-	unbecome_guest();
-
-	DEBUG(11,("%s: uid[%ju] gid[%ju] location[%s]\n",
-		  __func__, (uintmax_t)geteuid(), (uintmax_t)getegid(),
-		  location));
-}
-
-static void smbd_impersonate_guest_before_fd_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_fd *fde,
-						uint16_t flags,
-						const char *handler_name,
-						const char *location)
-{
-	bool ok;
-
-	DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
-		  __func__, fde, (uintmax_t)flags, handler_name, location));
-
-	ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
-					        main_ev, location);
-	if (!ok) {
-		smb_panic("smbd_impersonate_guest_before_use() - failed");
-		return;
-	}
-}
-
-static void smbd_impersonate_guest_after_fd_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_fd *fde,
-						uint16_t flags,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
-		  __func__, fde, handler_name, location));
-
-	smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
-}
-
-static void smbd_impersonate_guest_before_timer_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_timer *te,
-						struct timeval requested_time,
-						struct timeval trigger_time,
-						const char *handler_name,
-						const char *location)
-{
-	bool ok;
-	struct timeval_buf requested_buf;
-	struct timeval_buf trigger_buf;
-
-	DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
-		  "handler_name[%s] location[%s]\n",
-		  __func__, te,
-		  timeval_str_buf(&requested_time, true, true, &requested_buf),
-		  timeval_str_buf(&trigger_time, true, true, &trigger_buf),
-		  handler_name, location));
-
-	ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
-					       main_ev, location);
-	if (!ok) {
-		smb_panic("smbd_impersonate_guest_before_use() - failed");
-		return;
-	}
-}
-
-static void smbd_impersonate_guest_after_timer_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_timer *te,
-						struct timeval requested_time,
-						struct timeval trigger_time,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
-		  __func__, te, handler_name, location));
-
-	smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
-}
-
-static void smbd_impersonate_guest_before_immediate_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_immediate *im,
-						const char *handler_name,
-						const char *location)
-{
-	bool ok;
-
-	DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
-		  __func__, im, handler_name, location));
-
-	ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
-					       main_ev, location);
-	if (!ok) {
-		smb_panic("smbd_impersonate_guest_before_use() - failed");
-		return;
-	}
-}
-
-static void smbd_impersonate_guest_after_immediate_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_immediate *im,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
-		  __func__, im, handler_name, location));
-
-	smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
-}
-
-static void smbd_impersonate_guest_before_signal_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_signal *se,
-						int signum,
-						int count,
-						void *siginfo,
-						const char *handler_name,
-						const char *location)
-{
-	bool ok;
-
-	DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
-		  "handler_name[%s] location[%s]\n",
-		  __func__, se, signum, count, siginfo, handler_name, location));
-
-	ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
-					       main_ev, location);
-	if (!ok) {
-		smb_panic("smbd_impersonate_guest_before_use() - failed");
-		return;
-	}
-}
+	struct tevent_context *wrap_ev = NULL;
 
-static void smbd_impersonate_guest_after_signal_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_signal *se,
-						int signum,
-						int count,
-						void *siginfo,
-						const char *handler_name,
-						const char *location)
-{
-	DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
-		  __func__, se, handler_name, location));
+	wrap_ev = smbd_impersonate_debug_create(main_ev,
+						"root",
+						DBGLVL_DEBUG);
 
-	smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
+	return wrap_ev;
 }
 
-static const struct tevent_wrapper_ops smbd_impersonate_guest_ops = {
-	.name				= "smbd_impersonate_guest",
-	.before_use			= smbd_impersonate_guest_before_use,
-	.after_use			= smbd_impersonate_guest_after_use,
-	.before_fd_handler		= smbd_impersonate_guest_before_fd_handler,
-	.after_fd_handler		= smbd_impersonate_guest_after_fd_handler,
-	.before_timer_handler		= smbd_impersonate_guest_before_timer_handler,
-	.after_timer_handler		= smbd_impersonate_guest_after_timer_handler,
-	.before_immediate_handler	= smbd_impersonate_guest_before_immediate_handler,
-	.after_immediate_handler	= smbd_impersonate_guest_after_immediate_handler,
-	.before_signal_handler		= smbd_impersonate_guest_before_signal_handler,
-	.after_signal_handler		= smbd_impersonate_guest_after_signal_handler,
-};
-
 struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev)
 {
-	struct tevent_context *ev = NULL;
-	struct smbd_impersonate_guest_state *state = NULL;
-
-	ev = tevent_context_wrapper_create(main_ev,
-					   main_ev,
-					   &smbd_impersonate_guest_ops,
-					   &state,
-					   struct smbd_impersonate_guest_state);
-	if (ev == NULL) {
-		return NULL;
-	}
+	struct tevent_context *wrap_ev = NULL;
+
+	wrap_ev = smbd_impersonate_debug_create(main_ev,
+						"guest",
+						DBGLVL_DEBUG);
 
-	return ev;
+	return wrap_ev;
 }
-- 
2.17.2


From 917f3f6bccfabd25e7031b98b8fdf512a8254e07 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:38:34 +0100
Subject: [PATCH 33/56] Revert "smbd: make use of
 smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers"

This reverts commit 0dcaa0707bad67f7bfaa10ccaf167bfefbe87a0c.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_readonly.c |  2 +-
 source3/smbd/conn.c            |  2 +-
 source3/smbd/msdfs.c           | 34 +++-------------------------------
 source3/smbd/process.c         | 18 ++----------------
 source3/smbd/uid.c             | 20 ++------------------
 5 files changed, 9 insertions(+), 67 deletions(-)

diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c
index e7e12747a22..570eb7c4d15 100644
--- a/source3/modules/vfs_readonly.c
+++ b/source3/modules/vfs_readonly.c
@@ -84,7 +84,7 @@ static int readonly_connect(vfs_handle_struct *handle,
       for (i=0; i< VUID_CACHE_SIZE; i++) {
         struct vuid_cache_entry *ent = &conn->vuid_cache->array[i];
         ent->vuid = UID_FIELD_INVALID;
-        TALLOC_FREE(ent->user_ev_ctx);
+        ent->user_ev_ctx = NULL;
         TALLOC_FREE(ent->session_info);
         ent->read_only = false;
         ent->share_access = 0;
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index cfff6404608..3b9aaac7834 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -98,7 +98,7 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid)
 			if (conn->user_ev_ctx == ent->user_ev_ctx) {
 				conn->user_ev_ctx = NULL;
 			}
-			TALLOC_FREE(ent->user_ev_ctx);
+			ent->user_ev_ctx = NULL;
 
 			/*
 			 * We need to keep conn->session_info around
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 5283edbecfc..a5771646971 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -264,17 +264,8 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	sconn->root_ev_ctx = smbd_impersonate_root_create(sconn->raw_ev_ctx);
-	if (sconn->root_ev_ctx == NULL) {
-		TALLOC_FREE(sconn);
-		return NT_STATUS_NO_MEMORY;
-	}
-	sconn->guest_ev_ctx = smbd_impersonate_guest_create(sconn->raw_ev_ctx);
-	if (sconn->guest_ev_ctx == NULL) {
-		TALLOC_FREE(sconn);
-		return NT_STATUS_NO_MEMORY;
-	}
-
+	sconn->root_ev_ctx = sconn->raw_ev_ctx;
+	sconn->guest_ev_ctx = sconn->raw_ev_ctx;
 	sconn->msg_ctx = msg;
 
 	conn = conn_new(sconn);
@@ -328,26 +319,7 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		vfs_user = get_current_username();
 	}
 
-	/*
-	 * The impersonation has to be done by the caller
-	 * of create_conn_struct_tos[_cwd]().
-	 *
-	 * Note: the context can't be changed anyway
-	 * as we're using our own tevent_context
-	 * and not a global one were other requests
-	 * could change the current unix token.
-	 *
-	 * We just use a wrapper tevent_context in order
-	 * to avoid crashes because TALLOC_FREE(conn->user_ev_ctx)
-	 * would also remove sconn->raw_ev_ctx.
-	 */
-	conn->user_ev_ctx = smbd_impersonate_debug_create(sconn->raw_ev_ctx,
-							  "FAKE impersonation",
-							  DBGLVL_DEBUG);
-	if (conn->user_ev_ctx == NULL) {
-		TALLOC_FREE(conn);
-		return NT_STATUS_NO_MEMORY;
-	}
+	conn->user_ev_ctx = sconn->raw_ev_ctx;
 
 	set_conn_connectpath(conn, connpath);
 
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index a7c302c362a..72e1f3feaee 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3900,8 +3900,6 @@ void smbd_process(struct tevent_context *ev_ctx,
 		.ev = ev_ctx,
 		.frame = talloc_stackframe(),
 	};
-	struct tevent_context *root_ev_ctx = NULL;
-	struct tevent_context *guest_ev_ctx = NULL;
 	struct smbXsrv_client *client = NULL;
 	struct smbd_server_connection *sconn = NULL;
 	struct smbXsrv_connection *xconn = NULL;
@@ -3914,18 +3912,6 @@ void smbd_process(struct tevent_context *ev_ctx,
 	char *chroot_dir = NULL;
 	int rc;
 
-	root_ev_ctx = smbd_impersonate_root_create(ev_ctx);
-	if (root_ev_ctx == NULL) {
-		DEBUG(0,("smbd_impersonate_root_create() failed\n"));
-		exit_server_cleanly("smbd_impersonate_root_create().\n");
-	}
-
-	guest_ev_ctx = smbd_impersonate_guest_create(ev_ctx);
-	if (guest_ev_ctx == NULL) {
-		DEBUG(0,("smbd_impersonate_guest_create() failed\n"));
-		exit_server_cleanly("smbd_impersonate_guest_create().\n");
-	}
-
 	status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
 	if (!NT_STATUS_IS_OK(status)) {
 		DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
@@ -3946,8 +3932,8 @@ void smbd_process(struct tevent_context *ev_ctx,
 	sconn->client = client;
 
 	sconn->raw_ev_ctx = ev_ctx;
-	sconn->root_ev_ctx = root_ev_ctx;
-	sconn->guest_ev_ctx = guest_ev_ctx;
+	sconn->root_ev_ctx = ev_ctx;
+	sconn->guest_ev_ctx = ev_ctx;
 	sconn->msg_ctx = msg_ctx;
 
 	ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index e7f0a8f620b..2ce5366b775 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -307,7 +307,7 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
 		}
 	}
 	/* Not used, safe to free. */
-	TALLOC_FREE(conn->user_ev_ctx);
+	conn->user_ev_ctx = NULL;
 	TALLOC_FREE(conn->session_info);
 }
 
@@ -482,23 +482,7 @@ static bool check_user_ok(connection_struct *conn,
 		ent->session_info->unix_token->uid = sec_initial_uid();
 	}
 
-	if (vuid == UID_FIELD_INVALID) {
-		ent->user_ev_ctx = smbd_impersonate_conn_sess_create(
-			conn->sconn->raw_ev_ctx, conn, ent->session_info);
-		if (ent->user_ev_ctx == NULL) {
-			TALLOC_FREE(ent->session_info);
-			ent->vuid = UID_FIELD_INVALID;
-			return false;
-		}
-	} else {
-		ent->user_ev_ctx = smbd_impersonate_conn_vuid_create(
-			conn->sconn->raw_ev_ctx, conn, vuid);
-		if (ent->user_ev_ctx == NULL) {
-			TALLOC_FREE(ent->session_info);
-			ent->vuid = UID_FIELD_INVALID;
-			return false;
-		}
-	}
+	ent->user_ev_ctx = conn->sconn->raw_ev_ctx;
 
 	/*
 	 * It's actually OK to call check_user_ok() with
-- 
2.17.2


From 12128d4f18250971e72db6f97580f69f243e9eae Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:38:36 +0100
Subject: [PATCH 34/56] Revert "smbd: add simple noop
 smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers"

This reverts commit 5285966e67cbee8519015df12a15e938e85e6ee7.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/proto.h | 11 ----------
 source3/smbd/uid.c   | 50 --------------------------------------------
 2 files changed, 61 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index eb35a94862a..8d088785164 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1244,17 +1244,6 @@ const struct security_unix_token *get_current_utok(connection_struct *conn);
 const struct security_token *get_current_nttok(connection_struct *conn);
 uint64_t get_current_vuid(connection_struct *conn);
 
-struct tevent_context *smbd_impersonate_conn_vuid_create(
-				struct tevent_context *main_ev,
-				struct connection_struct *conn,
-				uint64_t vuid);
-struct tevent_context *smbd_impersonate_conn_sess_create(
-				struct tevent_context *main_ev,
-				struct connection_struct *conn,
-				struct auth_session_info *session_info);
-struct tevent_context *smbd_impersonate_root_create(struct tevent_context *main_ev);
-struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev);
-
 /* The following definitions come from smbd/utmp.c  */
 
 void sys_utmp_claim(const char *username, const char *hostname,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 2ce5366b775..c850708bbe8 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -958,53 +958,3 @@ uint64_t get_current_vuid(connection_struct *conn)
 {
 	return current_user.vuid;
 }
-
-struct tevent_context *smbd_impersonate_conn_vuid_create(
-				struct tevent_context *main_ev,
-				struct connection_struct *conn,
-				uint64_t vuid)
-{
-	struct tevent_context *wrap_ev = NULL;
-
-	wrap_ev = smbd_impersonate_debug_create(main_ev,
-						"conn_vuid",
-						DBGLVL_DEBUG);
-
-	return wrap_ev;
-}
-
-struct tevent_context *smbd_impersonate_conn_sess_create(
-				struct tevent_context *main_ev,
-				struct connection_struct *conn,
-				struct auth_session_info *session_info)
-{
-	struct tevent_context *wrap_ev = NULL;
-
-	wrap_ev = smbd_impersonate_debug_create(main_ev,
-						"conn_sess",
-						DBGLVL_DEBUG);
-
-	return wrap_ev;
-}
-
-struct tevent_context *smbd_impersonate_root_create(struct tevent_context *main_ev)
-{
-	struct tevent_context *wrap_ev = NULL;
-
-	wrap_ev = smbd_impersonate_debug_create(main_ev,
-						"root",
-						DBGLVL_DEBUG);
-
-	return wrap_ev;
-}
-
-struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev)
-{
-	struct tevent_context *wrap_ev = NULL;
-
-	wrap_ev = smbd_impersonate_debug_create(main_ev,
-						"guest",
-						DBGLVL_DEBUG);
-
-	return wrap_ev;
-}
-- 
2.17.2


From 7080d57e0b787b2637d30878a1da037e16fa92f5 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:41:57 +0100
Subject: [PATCH 35/56] Revert "smbd: add smbd_impersonate_debug_create()
 helper"

This reverts commit 23319ef5a2eff4811b685d4ab54179efc49bac99.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/proto.h |   6 --
 source3/smbd/uid.c   | 229 -------------------------------------------
 2 files changed, 235 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 8d088785164..ba9ab501adb 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1211,12 +1211,6 @@ void reply_transs2(struct smb_request *req);
 
 /* The following definitions come from smbd/uid.c  */
 
-#define smbd_impersonate_debug_create(main_ev, name, dbg_lvl) \
-	_smbd_impersonate_debug_create(main_ev, name, dbg_lvl, __location__)
-struct tevent_context *_smbd_impersonate_debug_create(struct tevent_context *main_ev,
-						      const char *name,
-						      int dbg_lvl,
-						      const char *location);
 bool change_to_guest(void);
 NTSTATUS check_user_share_access(connection_struct *conn,
 				const struct auth_session_info *session_info,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index c850708bbe8..adf9e8c1c51 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -26,235 +26,6 @@
 #include "passdb/lookup_sid.h"
 #include "auth.h"
 #include "../auth/auth_util.h"
-#include "lib/util/time_basic.h"
-
-struct smbd_impersonate_debug_state {
-	int dbg_lvl;
-	const char *name;
-};
-
-static bool smbd_impersonate_debug_before_use(struct tevent_context *wrap_ev,
-					      void *private_data,
-					      struct tevent_context *main_ev,
-					      const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev, location));
-
-	return true;
-}
-
-static void smbd_impersonate_debug_after_use(struct tevent_context *wrap_ev,
-					     void *private_data,
-					     struct tevent_context *main_ev,
-					     const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev, location));
-}
-
-static void smbd_impersonate_debug_before_fd_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_fd *fde,
-						uint16_t flags,
-						const char *handler_name,
-						const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
-	      "fde[%p] flags[0x%X] handler_name[%s] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev,
-	      fde, flags, handler_name, location));
-}
-
-static void smbd_impersonate_debug_after_fd_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_fd *fde,
-						uint16_t flags,
-						const char *handler_name,
-						const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
-	      "fde[%p] flags[0x%X] handler_name[%s] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev,
-	      fde, flags, handler_name, location));
-}
-
-static void smbd_impersonate_debug_before_timer_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_timer *te,
-						struct timeval requested_time,
-						struct timeval trigger_time,
-						const char *handler_name,
-						const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-	struct timeval_buf requested_buf;
-	struct timeval_buf trigger_buf;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
-	      "te[%p] requested_time[%s] trigger_time[%s] handler_name[%s] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev, te,
-	      timeval_str_buf(&requested_time, true, true, &requested_buf),
-	      timeval_str_buf(&trigger_time, true, true, &trigger_buf),
-	      handler_name, location));
-}
-
-static void smbd_impersonate_debug_after_timer_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_timer *te,
-						struct timeval requested_time,
-						struct timeval trigger_time,
-						const char *handler_name,
-						const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-	struct timeval_buf requested_buf;
-	struct timeval_buf trigger_buf;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
-	      "te[%p] requested_time[%s] trigger_time[%s] handler_name[%s] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev, te,
-	      timeval_str_buf(&requested_time, true, true, &requested_buf),
-	      timeval_str_buf(&trigger_time, true, true, &trigger_buf),
-	      handler_name, location));
-}
-
-static void smbd_impersonate_debug_before_immediate_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_immediate *im,
-						const char *handler_name,
-						const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
-	      "im[%p] handler_name[%s] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev,
-	      im, handler_name, location));
-}
-
-static void smbd_impersonate_debug_after_immediate_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_immediate *im,
-						const char *handler_name,
-						const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
-	      "im[%p] handler_name[%s] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev,
-	      im, handler_name, location));
-}
-
-static void smbd_impersonate_debug_before_signal_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_signal *se,
-						int signum,
-						int count,
-						void *siginfo,
-						const char *handler_name,
-						const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
-	      "se[%p] signum[%d] count[%d] siginfo[%p] handler_name[%s] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev,
-	      se, signum, count, siginfo, handler_name, location));
-}
-
-static void smbd_impersonate_debug_after_signal_handler(struct tevent_context *wrap_ev,
-						void *private_data,
-						struct tevent_context *main_ev,
-						struct tevent_signal *se,
-						int signum,
-						int count,
-						void *siginfo,
-						const char *handler_name,
-						const char *location)
-{
-	struct smbd_impersonate_debug_state *state =
-		(struct smbd_impersonate_debug_state *)private_data;
-
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
-	      "se[%p] signum[%d] count[%d] siginfo[%p] handler_name[%s] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev,
-	      se, signum, count, siginfo, handler_name, location));
-}
-
-static const struct tevent_wrapper_ops smbd_impersonate_debug_ops = {
-	.name				= "smbd_impersonate_debug",
-	.before_use			= smbd_impersonate_debug_before_use,
-	.after_use			= smbd_impersonate_debug_after_use,
-	.before_fd_handler		= smbd_impersonate_debug_before_fd_handler,
-	.after_fd_handler		= smbd_impersonate_debug_after_fd_handler,
-	.before_timer_handler		= smbd_impersonate_debug_before_timer_handler,
-	.after_timer_handler		= smbd_impersonate_debug_after_timer_handler,
-	.before_immediate_handler	= smbd_impersonate_debug_before_immediate_handler,
-	.after_immediate_handler	= smbd_impersonate_debug_after_immediate_handler,
-	.before_signal_handler		= smbd_impersonate_debug_before_signal_handler,
-	.after_signal_handler		= smbd_impersonate_debug_after_signal_handler,
-};
-
-struct tevent_context *_smbd_impersonate_debug_create(struct tevent_context *main_ev,
-						      const char *name,
-						      int dbg_lvl,
-						      const char *location)
-{
-	struct tevent_context *wrap_ev = NULL;
-	struct smbd_impersonate_debug_state *state = NULL;
-
-	wrap_ev = tevent_context_wrapper_create(main_ev,
-					main_ev,
-					&smbd_impersonate_debug_ops,
-					&state,
-					struct smbd_impersonate_debug_state);
-	if (wrap_ev == NULL) {
-		return NULL;
-	}
-	state->name = name;
-	state->dbg_lvl = dbg_lvl;
-	DEBUG(state->dbg_lvl, (
-	      "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] location[%s]\n",
-	      __func__, state->name, wrap_ev, state, main_ev, location));
-
-	return wrap_ev;
-}
 
 /* what user is current? */
 extern struct current_user current_user;
-- 
2.17.2


From 0ff8b82e4aec9721de1c6287fa365102724fb042 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:42:45 +0100
Subject: [PATCH 36/56] Revert "smbd: add [un]become_guest() helper functions"

This reverts commit 7b5a47b84696e8e5c26207bd398742b883e598c2.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/proto.h |  2 --
 source3/smbd/uid.c   | 28 ----------------------------
 2 files changed, 30 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index ba9ab501adb..3662a925dd6 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1225,8 +1225,6 @@ void become_root(void);
 void unbecome_root(void);
 void smbd_become_root(void);
 void smbd_unbecome_root(void);
-bool become_guest(void);
-void unbecome_guest(void);
 bool become_user(connection_struct *conn, uint64_t vuid);
 bool become_user_by_fsp(struct files_struct *fsp);
 bool become_user_by_session(connection_struct *conn,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index adf9e8c1c51..f902f2aeae3 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -599,34 +599,6 @@ void smbd_unbecome_root(void)
 	pop_conn_ctx();
 }
 
-bool become_guest(void)
-{
-	bool ok;
-
-	ok = push_sec_ctx();
-	if (!ok) {
-		return false;
-	}
-
-	push_conn_ctx();
-
-	ok = change_to_guest();
-	if (!ok) {
-		pop_sec_ctx();
-		pop_conn_ctx();
-		return false;
-	}
-
-	return true;
-}
-
-void unbecome_guest(void)
-{
-	pop_sec_ctx();
-	pop_conn_ctx();
-	return;
-}
-
 /****************************************************************************
  Push the current security context then force a change via change_to_user().
  Saves and restores the connection context.
-- 
2.17.2


From c6302cb81429eae2278085eb955c39b0f85057b7 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 12:41:25 +0100
Subject: [PATCH 37/56] Revert "s4:messaging: make sure only
 imessaging_client_init() can be used with a wrapper tevent_context wrapper"

This reverts commit e186d6a06b1b300256a2cb4138f0532d518d0597.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source4/lib/messaging/messaging.c | 28 ++--------------------------
 1 file changed, 2 insertions(+), 26 deletions(-)

diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index 59c48cd44cb..6c10289515f 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -361,7 +361,7 @@ NTSTATUS imessaging_reinit_all(void)
 /*
   create the listening socket and setup the dispatcher
 */
-static struct imessaging_context *imessaging_init_internal(TALLOC_CTX *mem_ctx,
+struct imessaging_context *imessaging_init(TALLOC_CTX *mem_ctx,
 					   struct loadparm_context *lp_ctx,
 					   struct server_id server_id,
 					   struct tevent_context *ev)
@@ -625,30 +625,6 @@ static void imessaging_dgm_recv(struct tevent_context *ev,
 	}
 }
 
-struct imessaging_context *imessaging_init(TALLOC_CTX *mem_ctx,
-					   struct loadparm_context *lp_ctx,
-					   struct server_id server_id,
-					   struct tevent_context *ev)
-{
-	if (ev == NULL) {
-		return NULL;
-	}
-
-	if (tevent_context_is_wrapper(ev)) {
-		/*
-		 * This is really a programmer error!
-		 *
-		 * The main/raw tevent context should
-		 * have been registered first!
-		 */
-		DBG_ERR("Should not be used with a wrapper tevent context\n");
-		errno = EINVAL;
-		return NULL;
-	}
-
-	return imessaging_init_internal(mem_ctx, lp_ctx, server_id, ev);
-}
-
 /*
    A hack, for the short term until we get 'client only' messaging in place
 */
@@ -665,7 +641,7 @@ struct imessaging_context *imessaging_client_init(TALLOC_CTX *mem_ctx,
 	/* This is because we are not in the s3 serverid database */
 	id.unique_id = SERVERID_UNIQUE_ID_NOT_TO_VERIFY;
 
-	return imessaging_init_internal(mem_ctx, lp_ctx, id, ev);
+	return imessaging_init(mem_ctx, lp_ctx, id, ev);
 }
 /*
   a list of registered irpc server functions
-- 
2.17.2


From 1c1eee1f28a3ffefd8430e83b6782bb1332bedd1 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 12:45:15 +0100
Subject: [PATCH 38/56] Revert "s3:messages: allow
 messaging_filtered_read_send() to use wrapper tevent_context"

This reverts commit 2b05f1098187e00166649c8ea7c63e6901b9d242.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/lib/messages.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index aa899142333..864d758fb13 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -206,7 +206,7 @@ static bool messaging_register_event_context(struct messaging_context *ctx,
 			continue;
 		}
 
-		if (tevent_context_same_loop(reg->ev, ev)) {
+		if (reg->ev == ev) {
 			reg->refcount += 1;
 			return true;
 		}
@@ -255,7 +255,7 @@ static bool messaging_deregister_event_context(struct messaging_context *ctx,
 			continue;
 		}
 
-		if (tevent_context_same_loop(reg->ev, ev)) {
+		if (reg->ev == ev) {
 			reg->refcount -= 1;
 
 			if (reg->refcount == 0) {
@@ -1025,9 +1025,7 @@ struct tevent_req *messaging_filtered_read_send(
 	state->filter = filter;
 	state->private_data = private_data;
 
-	if (tevent_context_is_wrapper(ev) &&
-	    !tevent_context_same_loop(ev, msg_ctx->event_ctx))
-	{
+	if (tevent_context_is_wrapper(ev)) {
 		/* This is really a programmer error! */
 		DBG_ERR("Wrapper tevent context doesn't use main context.\n");
 		tevent_req_error(req, EINVAL);
@@ -1036,11 +1034,7 @@ struct tevent_req *messaging_filtered_read_send(
 
 	/*
 	 * We have to defer the callback here, as we might be called from
-	 * within a different tevent_context than state->ev.
-	 *
-	 * This is important for two cases:
-	 * 1. nested event contexts, used by blocking ctdb calls
-	 * 2. possible impersonation using wrapper tevent contexts.
+	 * within a different tevent_context than state->ev
 	 */
 	tevent_req_defer_callback(req, state->ev);
 
@@ -1336,7 +1330,7 @@ static bool messaging_dispatch_waiters(struct messaging_context *msg_ctx,
 
 		state = tevent_req_data(
 			req, struct messaging_filtered_read_state);
-		if (tevent_context_same_loop(ev, state->ev) &&
+		if ((ev == state->ev) &&
 		    state->filter(rec, state->private_data)) {
 			messaging_filtered_read_done(req, rec);
 			return true;
-- 
2.17.2


From 19761438f4272b6baed8db290b90540ee1f43d09 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 12:45:28 +0100
Subject: [PATCH 39/56] Revert "s3:messages: allow messaging_dgm_ref() to use
 wrapper tevent_context"

This reverts commit 9dc332060cf5f249ea887dbc60ec7a39b6f91120.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/lib/messages_dgm_ref.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/source3/lib/messages_dgm_ref.c b/source3/lib/messages_dgm_ref.c
index 12ff21ca628..fd170961746 100644
--- a/source3/lib/messages_dgm_ref.c
+++ b/source3/lib/messages_dgm_ref.c
@@ -55,6 +55,18 @@ void *messaging_dgm_ref(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 {
 	struct msg_dgm_ref *result, *tmp_refs;
 
+	if (tevent_context_is_wrapper(ev)) {
+		/*
+		 * This is really a programmer error!
+		 *
+		 * The main/raw tevent context should
+		 * have been registered first!
+		 */
+		DBG_ERR("Should not be used with a wrapper tevent context\n");
+		*err = EINVAL;
+		return NULL;
+	}
+
 	result = talloc(mem_ctx, struct msg_dgm_ref);
 	if (result == NULL) {
 		*err = ENOMEM;
@@ -75,18 +87,6 @@ void *messaging_dgm_ref(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 	if (refs == NULL) {
 		int ret;
 
-		if (tevent_context_is_wrapper(ev)) {
-			/*
-			 * This is really a programmer error!
-			 *
-			 * The main/raw tevent context should
-			 * have been registered first!
-			 */
-			DBG_ERR("Should not be used with a wrapper tevent context\n");
-			*err = EINVAL;
-			return NULL;
-		}
-
 		ret = messaging_dgm_init(ev, unique, socket_dir, lockfile_dir,
 					 msg_dgm_ref_recv, NULL);
 		DBG_DEBUG("messaging_dgm_init returned %s\n", strerror(ret));
-- 
2.17.2


From 9c34e7734b7e8f8b543abbfae703ad4aefe27ab9 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 12:45:42 +0100
Subject: [PATCH 40/56] Revert "s3:messages: allow
 messaging_{dgm,ctdb}_register_tevent_context() to use wrapper tevent_context"

This reverts commit 660cf86639753edaa7a7a21a5b5ae207ae7d4260.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/lib/messages_ctdb.c | 38 +++++++++----------------------------
 source3/lib/messages_dgm.c  | 38 +++++++++----------------------------
 2 files changed, 18 insertions(+), 58 deletions(-)

diff --git a/source3/lib/messages_ctdb.c b/source3/lib/messages_ctdb.c
index 11fe72661cc..a1aeb37af19 100644
--- a/source3/lib/messages_ctdb.c
+++ b/source3/lib/messages_ctdb.c
@@ -209,6 +209,14 @@ struct messaging_ctdb_fde *messaging_ctdb_register_tevent_context(
 		return NULL;
 	}
 
+	if (tevent_context_is_wrapper(ev)) {
+		/*
+		 * This is really a programmer error!
+		 */
+		DBG_ERR("Should not be used with a wrapper tevent context\n");
+		return NULL;
+	}
+
 	fde = talloc(mem_ctx, struct messaging_ctdb_fde);
 	if (fde == NULL) {
 		return NULL;
@@ -226,24 +234,7 @@ struct messaging_ctdb_fde *messaging_ctdb_register_tevent_context(
 			 */
 			continue;
 		}
-
-		/*
-		 * We can only have one tevent_fd
-		 * per low level tevent_context.
-		 *
-		 * This means any wrapper tevent_context
-		 * needs to share the structure with
-		 * the main tevent_context and/or
-		 * any sibling wrapper tevent_context.
-		 *
-		 * This means we need to use tevent_context_same_loop()
-		 * instead of just (fde_ev->ev == ev).
-		 *
-		 * Note: the tevent_context_is_wrapper() check below
-		 * makes sure that fde_ev->ev is always a raw
-		 * tevent context.
-		 */
-		if (tevent_context_same_loop(fde_ev->ev, ev)) {
+		if (fde_ev->ev == ev) {
 			break;
 		}
 	}
@@ -251,17 +242,6 @@ struct messaging_ctdb_fde *messaging_ctdb_register_tevent_context(
 	if (fde_ev == NULL) {
 		int sock = ctdbd_conn_get_fd(ctx->conn);
 
-		if (tevent_context_is_wrapper(ev)) {
-			/*
-			 * This is really a programmer error!
-			 *
-			 * The main/raw tevent context should
-			 * have been registered first!
-			 */
-			DBG_ERR("Should not be used with a wrapper tevent context\n");
-			return NULL;
-		}
-
 		fde_ev = talloc(fde, struct messaging_ctdb_fde_ev);
 		if (fde_ev == NULL) {
 			return NULL;
diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c
index af12be8d82e..a661a16c99a 100644
--- a/source3/lib/messages_dgm.c
+++ b/source3/lib/messages_dgm.c
@@ -1683,6 +1683,14 @@ struct messaging_dgm_fde *messaging_dgm_register_tevent_context(
 		return NULL;
 	}
 
+	if (tevent_context_is_wrapper(ev)) {
+		/*
+		 * This is really a programmer error!
+		 */
+		DBG_ERR("Should not be used with a wrapper tevent context\n");
+		return NULL;
+	}
+
 	fde = talloc(mem_ctx, struct messaging_dgm_fde);
 	if (fde == NULL) {
 		return NULL;
@@ -1700,40 +1708,12 @@ struct messaging_dgm_fde *messaging_dgm_register_tevent_context(
 			 */
 			continue;
 		}
-
-		/*
-		 * We can only have one tevent_fd
-		 * per low level tevent_context.
-		 *
-		 * This means any wrapper tevent_context
-		 * needs to share the structure with
-		 * the main tevent_context and/or
-		 * any sibling wrapper tevent_context.
-		 *
-		 * This means we need to use tevent_context_same_loop()
-		 * instead of just (fde_ev->ev == ev).
-		 *
-		 * Note: the tevent_context_is_wrapper() check below
-		 * makes sure that fde_ev->ev is always a raw
-		 * tevent context.
-		 */
-		if (tevent_context_same_loop(fde_ev->ev, ev)) {
+		if (fde_ev->ev == ev) {
 			break;
 		}
 	}
 
 	if (fde_ev == NULL) {
-		if (tevent_context_is_wrapper(ev)) {
-			/*
-			 * This is really a programmer error!
-			 *
-			 * The main/raw tevent context should
-			 * have been registered first!
-			 */
-			DBG_ERR("Should not be used with a wrapper tevent context\n");
-			return NULL;
-		}
-
 		fde_ev = talloc(fde, struct messaging_dgm_fde_ev);
 		if (fde_ev == NULL) {
 			return NULL;
-- 
2.17.2


From 3dea9645097bc3e2d457dc500a582cdc20276918 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 12:48:30 +0100
Subject: [PATCH 41/56] Revert "s3:messages: protect against usage of wrapper
 tevent_context objects for messaging"

This reverts commit 7f2afc20e1b6397c364a98d1be006377c95e4665.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/lib/messages.c          | 23 -----------------------
 source3/lib/messages_ctdb.c     |  8 --------
 source3/lib/messages_ctdb_ref.c | 12 ------------
 source3/lib/messages_dgm.c      | 14 --------------
 source3/lib/messages_dgm_ref.c  | 12 ------------
 5 files changed, 69 deletions(-)

diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 864d758fb13..dd19173b973 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -365,11 +365,6 @@ static bool messaging_alert_event_contexts(struct messaging_context *ctx)
 		 * alternatively would be to track whether the
 		 * immediate has already been scheduled. For
 		 * now, avoid that complexity here.
-		 *
-		 * reg->ev and ctx->event_ctx can't
-		 * be wrapper tevent_context pointers
-		 * so we don't need to use
-		 * tevent_context_same_loop().
 		 */
 
 		if (reg->ev == ctx->event_ctx) {
@@ -498,12 +493,6 @@ static NTSTATUS messaging_init_internal(TALLOC_CTX *mem_ctx,
 
 	sec_init();
 
-	if (tevent_context_is_wrapper(ev)) {
-		/* This is really a programmer error! */
-		DBG_ERR("Should not be used with a wrapper tevent context\n");
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
 	lck_path = lock_path(talloc_tos(), "msg.lock");
 	if (lck_path == NULL) {
 		return NT_STATUS_NO_MEMORY;
@@ -1025,13 +1014,6 @@ struct tevent_req *messaging_filtered_read_send(
 	state->filter = filter;
 	state->private_data = private_data;
 
-	if (tevent_context_is_wrapper(ev)) {
-		/* This is really a programmer error! */
-		DBG_ERR("Wrapper tevent context doesn't use main context.\n");
-		tevent_req_error(req, EINVAL);
-		return tevent_req_post(req, ev);
-	}
-
 	/*
 	 * We have to defer the callback here, as we might be called from
 	 * within a different tevent_context than state->ev
@@ -1352,11 +1334,6 @@ static void messaging_dispatch_rec(struct messaging_context *msg_ctx,
 	bool consumed;
 	size_t i;
 
-	/*
-	 * ev and msg_ctx->event_ctx can't be wrapper tevent_context pointers
-	 * so we don't need to use tevent_context_same_loop().
-	 */
-
 	if (ev == msg_ctx->event_ctx) {
 		consumed = messaging_dispatch_classic(msg_ctx, rec);
 		if (consumed) {
diff --git a/source3/lib/messages_ctdb.c b/source3/lib/messages_ctdb.c
index a1aeb37af19..d3e2e3f8589 100644
--- a/source3/lib/messages_ctdb.c
+++ b/source3/lib/messages_ctdb.c
@@ -209,14 +209,6 @@ struct messaging_ctdb_fde *messaging_ctdb_register_tevent_context(
 		return NULL;
 	}
 
-	if (tevent_context_is_wrapper(ev)) {
-		/*
-		 * This is really a programmer error!
-		 */
-		DBG_ERR("Should not be used with a wrapper tevent context\n");
-		return NULL;
-	}
-
 	fde = talloc(mem_ctx, struct messaging_ctdb_fde);
 	if (fde == NULL) {
 		return NULL;
diff --git a/source3/lib/messages_ctdb_ref.c b/source3/lib/messages_ctdb_ref.c
index 47b4b758dac..3570ed8ae4c 100644
--- a/source3/lib/messages_ctdb_ref.c
+++ b/source3/lib/messages_ctdb_ref.c
@@ -52,18 +52,6 @@ void *messaging_ctdb_ref(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 {
 	struct msg_ctdb_ref *result, *tmp_refs;
 
-	if (tevent_context_is_wrapper(ev)) {
-		/*
-		 * This is really a programmer error!
-		 *
-		 * The main/raw tevent context should
-		 * have been registered first!
-		 */
-		DBG_ERR("Should not be used with a wrapper tevent context\n");
-		*err = EINVAL;
-		return NULL;
-	}
-
 	result = talloc(mem_ctx, struct msg_ctdb_ref);
 	if (result == NULL) {
 		*err = ENOMEM;
diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c
index a661a16c99a..37eefeb0a4a 100644
--- a/source3/lib/messages_dgm.c
+++ b/source3/lib/messages_dgm.c
@@ -993,12 +993,6 @@ int messaging_dgm_init(struct tevent_context *ev,
 		return EEXIST;
 	}
 
-	if (tevent_context_is_wrapper(ev)) {
-		/* This is really a programmer error! */
-		DBG_ERR("Should not be used with a wrapper tevent context\n");
-		return EINVAL;
-	}
-
 	ctx = talloc_zero(NULL, struct messaging_dgm_context);
 	if (ctx == NULL) {
 		goto fail_nomem;
@@ -1683,14 +1677,6 @@ struct messaging_dgm_fde *messaging_dgm_register_tevent_context(
 		return NULL;
 	}
 
-	if (tevent_context_is_wrapper(ev)) {
-		/*
-		 * This is really a programmer error!
-		 */
-		DBG_ERR("Should not be used with a wrapper tevent context\n");
-		return NULL;
-	}
-
 	fde = talloc(mem_ctx, struct messaging_dgm_fde);
 	if (fde == NULL) {
 		return NULL;
diff --git a/source3/lib/messages_dgm_ref.c b/source3/lib/messages_dgm_ref.c
index fd170961746..470dfbeabc7 100644
--- a/source3/lib/messages_dgm_ref.c
+++ b/source3/lib/messages_dgm_ref.c
@@ -55,18 +55,6 @@ void *messaging_dgm_ref(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 {
 	struct msg_dgm_ref *result, *tmp_refs;
 
-	if (tevent_context_is_wrapper(ev)) {
-		/*
-		 * This is really a programmer error!
-		 *
-		 * The main/raw tevent context should
-		 * have been registered first!
-		 */
-		DBG_ERR("Should not be used with a wrapper tevent context\n");
-		*err = EINVAL;
-		return NULL;
-	}
-
 	result = talloc(mem_ctx, struct msg_dgm_ref);
 	if (result == NULL) {
 		*err = ENOMEM;
-- 
2.17.2


From e83379fbf78c147c44d5b053240e4970313e8e02 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:17:22 +0100
Subject: [PATCH 42/56] Revert "smbd: remove unused
 smbd_server_connection->ev_ctx"

This reverts commit 721fbbfa7001b2788602106101f0407483894322.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h | 1 +
 source3/smbd/msdfs.c   | 1 +
 source3/smbd/process.c | 1 +
 3 files changed, 3 insertions(+)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 9b01ddda5ec..a9c3a07290c 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -879,6 +879,7 @@ struct smbd_server_connection {
 	const struct tsocket_address *local_address;
 	const struct tsocket_address *remote_address;
 	const char *remote_hostname;
+	struct tevent_context *ev_ctx;
 	struct tevent_context *raw_ev_ctx;
 	struct tevent_context *root_ev_ctx;
 	struct tevent_context *guest_ev_ctx;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index a5771646971..c523abb3158 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -264,6 +264,7 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	sconn->ev_ctx = sconn->raw_ev_ctx;
 	sconn->root_ev_ctx = sconn->raw_ev_ctx;
 	sconn->guest_ev_ctx = sconn->raw_ev_ctx;
 	sconn->msg_ctx = msg;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 72e1f3feaee..ae7f6de76d3 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3931,6 +3931,7 @@ void smbd_process(struct tevent_context *ev_ctx,
 	client->sconn = sconn;
 	sconn->client = client;
 
+	sconn->ev_ctx = ev_ctx;
 	sconn->raw_ev_ctx = ev_ctx;
 	sconn->root_ev_ctx = ev_ctx;
 	sconn->guest_ev_ctx = ev_ctx;
-- 
2.17.2


From 20478d1cfb8a6504a6db7e8b0497b0e8c5398c86 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:18:55 +0100
Subject: [PATCH 43/56] Revert "smbd: add an effective
 {smb,smbd_smb2}_request->ev_ctx that holds the event context used for the
 request processing"

This reverts commit 894e5001c747ce765dad5517778dda55d7d1f4d9.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/include/vfs.h                | 2 --
 source3/smbd/aio.c                   | 8 ++++----
 source3/smbd/globals.h               | 3 ---
 source3/smbd/ipc.c                   | 4 ++--
 source3/smbd/open.c                  | 8 ++++----
 source3/smbd/pipes.c                 | 8 ++++----
 source3/smbd/process.c               | 8 --------
 source3/smbd/reply.c                 | 2 +-
 source3/smbd/smb2_break.c            | 4 ++--
 source3/smbd/smb2_close.c            | 2 +-
 source3/smbd/smb2_create.c           | 6 +++---
 source3/smbd/smb2_flush.c            | 2 +-
 source3/smbd/smb2_getinfo.c          | 2 +-
 source3/smbd/smb2_glue.c             | 1 -
 source3/smbd/smb2_ioctl.c            | 2 +-
 source3/smbd/smb2_ioctl_named_pipe.c | 2 +-
 source3/smbd/smb2_lock.c             | 4 ++--
 source3/smbd/smb2_notify.c           | 4 ++--
 source3/smbd/smb2_query_directory.c  | 2 +-
 source3/smbd/smb2_read.c             | 2 +-
 source3/smbd/smb2_server.c           | 2 --
 source3/smbd/smb2_sesssetup.c        | 4 ++--
 source3/smbd/smb2_setinfo.c          | 2 +-
 source3/smbd/smb2_tcon.c             | 4 ++--
 source3/smbd/smb2_write.c            | 2 +-
 25 files changed, 37 insertions(+), 53 deletions(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 959dd405915..1a05283fe6c 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -518,8 +518,6 @@ struct smb_request {
 
 	size_t unread_bytes;
 	bool encrypted;
-	/* the tevent_context (wrapper) the request operates on */
-	struct tevent_context *ev_ctx;
 	connection_struct *conn;
 	struct smbd_server_connection *sconn;
 	struct smbXsrv_connection *xconn;
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index 29723d23fa5..8ac3ef7278e 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -206,7 +206,7 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
 	aio_ex->nbyte = smb_maxcnt;
 	aio_ex->offset = startpos;
 
-	req = SMB_VFS_PREAD_SEND(aio_ex, smbreq->ev_ctx,
+	req = SMB_VFS_PREAD_SEND(aio_ex, fsp->conn->sconn->ev_ctx,
 				 fsp,
 				 smb_buf(aio_ex->outbuf.data) + 1 /* pad */,
 				 smb_maxcnt, startpos);
@@ -459,7 +459,7 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
 	aio_ex->nbyte = numtowrite;
 	aio_ex->offset = startpos;
 
-	req = pwrite_fsync_send(aio_ex, smbreq->ev_ctx, fsp,
+	req = pwrite_fsync_send(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
 				data, numtowrite, startpos,
 				aio_ex->write_through);
 	if (req == NULL) {
@@ -705,7 +705,7 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
 	aio_ex->nbyte = smb_maxcnt;
 	aio_ex->offset = startpos;
 
-	req = SMB_VFS_PREAD_SEND(aio_ex, smbreq->ev_ctx, fsp,
+	req = SMB_VFS_PREAD_SEND(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
 				 preadbuf->data, smb_maxcnt, startpos);
 	if (req == NULL) {
 		DEBUG(0, ("smb2: SMB_VFS_PREAD_SEND failed. "
@@ -846,7 +846,7 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
 	aio_ex->nbyte = in_data.length;
 	aio_ex->offset = in_offset;
 
-	req = pwrite_fsync_send(aio_ex, smbreq->ev_ctx, fsp,
+	req = pwrite_fsync_send(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
 				in_data.data, in_data.length, in_offset,
 				write_through);
 	if (req == NULL) {
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index a9c3a07290c..3bc2afb2063 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -705,9 +705,6 @@ struct smbd_smb2_request {
 	struct smbXsrv_tcon *tcon;
 	uint32_t last_tid;
 
-	/* the tevent_context (wrapper) the request operates on */
-	struct tevent_context *ev_ctx;
-
 	int current_idx;
 	bool do_signing;
 	/* Was the request encrypted? */
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 85236e0102f..f1c8ea0c2ed 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -281,7 +281,7 @@ static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
 	state->num_data = length;
 	state->max_read = max_read;
 
-	subreq = np_write_send(state, req->ev_ctx, state->handle,
+	subreq = np_write_send(state, req->sconn->ev_ctx, state->handle,
 			       state->data, length);
 	if (subreq == NULL) {
 		TALLOC_FREE(state);
@@ -330,7 +330,7 @@ static void api_dcerpc_cmd_write_done(struct tevent_req *subreq)
 		goto send;
 	}
 
-	subreq = np_read_send(state, req->ev_ctx,
+	subreq = np_read_send(state, req->sconn->ev_ctx,
 			      state->handle, state->data, state->max_read);
 	if (subreq == NULL) {
 		reply_nterror(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index a3df8a1b736..bab9286751f 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2408,7 +2408,7 @@ static void defer_open(struct share_mode_lock *lck,
 	DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
 
 	watch_req = dbwrap_watched_watch_send(watch_state,
-					      req->ev_ctx,
+					      req->sconn->ev_ctx,
 					      lck->data->record,
 					      (struct server_id){0});
 	if (watch_req == NULL) {
@@ -2416,7 +2416,7 @@ static void defer_open(struct share_mode_lock *lck,
 	}
 	tevent_req_set_callback(watch_req, defer_open_done, watch_state);
 
-	ok = tevent_req_set_endtime(watch_req, req->ev_ctx, abs_timeout);
+	ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
 	if (!ok) {
 		exit_server("tevent_req_set_endtime failed");
 	}
@@ -2508,7 +2508,7 @@ static void setup_kernel_oplock_poll_open(struct timeval request_time,
 	 * As this timer event is owned by req, it will
 	 * disappear if req it talloc_freed.
 	 */
-	open_rec->te = tevent_add_timer(req->ev_ctx,
+	open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
 					req,
 					timeval_current_ofs(1, 0),
 					kernel_oplock_poll_open_timer,
@@ -2695,7 +2695,7 @@ static void schedule_async_open(struct timeval request_time,
 		exit_server("push_deferred_open_message_smb failed");
 	}
 
-	open_rec->te = tevent_add_timer(req->ev_ctx,
+	open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
 					req,
 					timeval_current_ofs(20, 0),
 					schedule_async_open_timer,
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index c945f0f6177..4be57bc2a5f 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -67,7 +67,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
 			 conn->sconn->remote_address,
 			 conn->sconn->local_address,
 			 conn->session_info,
-			 smb_req->ev_ctx,
+			 conn->sconn->ev_ctx,
 			 conn->sconn->msg_ctx,
 			 &fsp->fake_file_handle);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -206,7 +206,7 @@ void reply_pipe_write(struct smb_request *req)
 	DEBUG(6, ("reply_pipe_write: %s, name: %s len: %d\n", fsp_fnum_dbg(fsp),
 		  fsp_str_dbg(fsp), (int)state->numtowrite));
 
-	subreq = np_write_send(state, req->ev_ctx,
+	subreq = np_write_send(state, req->sconn->ev_ctx,
 			       fsp->fake_file_handle, data, state->numtowrite);
 	if (subreq == NULL) {
 		TALLOC_FREE(state);
@@ -322,7 +322,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
 		state->numtowrite -= 2;
 	}
 
-	subreq = np_write_send(state, req->ev_ctx,
+	subreq = np_write_send(state, req->sconn->ev_ctx,
 			       fsp->fake_file_handle, data, state->numtowrite);
 	if (subreq == NULL) {
 		TALLOC_FREE(state);
@@ -435,7 +435,7 @@ void reply_pipe_read_and_X(struct smb_request *req)
 	state->outbuf = req->outbuf;
 	req->outbuf = NULL;
 
-	subreq = np_read_send(state, req->ev_ctx,
+	subreq = np_read_send(state, req->sconn->ev_ctx,
 			      fsp->fake_file_handle, data,
 			      state->smb_maxcnt);
 	if (subreq == NULL) {
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index ae7f6de76d3..82fcadb909f 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1506,8 +1506,6 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 
 	errno = 0;
 
-	req->ev_ctx = NULL;
-
 	if (!xconn->smb1.negprot.done) {
 		switch (type) {
 			/*
@@ -1642,8 +1640,6 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
 			return conn;
 		}
-
-		req->ev_ctx = conn->user_ev_ctx;
 	} else if (flags & AS_GUEST) {
 		/*
 		 * Does this protocol need to be run as guest? (Only archane
@@ -1653,13 +1649,9 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
 			return conn;
 		}
-
-		req->ev_ctx = req->sconn->guest_ev_ctx;
 	} else {
 		/* This call needs to be run as root */
 		change_to_root_user();
-
-		req->ev_ctx = req->sconn->root_ev_ctx;
 	}
 
 	/* load service specific parameters */
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index f2617fab3b3..405bd6ce004 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -5417,7 +5417,7 @@ void reply_close(struct smb_request *req)
 		 */
 
 		fsp->deferred_close = tevent_wait_send(
-			fsp, req->ev_ctx);
+			fsp, fsp->conn->sconn->ev_ctx);
 		if (fsp->deferred_close == NULL) {
 			status = NT_STATUS_NO_MEMORY;
 			goto done;
diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c
index ec9c0f1376b..ae6b9214b22 100644
--- a/source3/smbd/smb2_break.c
+++ b/source3/smbd/smb2_break.c
@@ -86,7 +86,7 @@ NTSTATUS smbd_smb2_request_process_break(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
 	}
 
-	subreq = smbd_smb2_oplock_break_send(req, req->ev_ctx,
+	subreq = smbd_smb2_oplock_break_send(req, req->sconn->ev_ctx,
 					     req, in_fsp, in_oplock_level);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
@@ -265,7 +265,7 @@ static NTSTATUS smbd_smb2_request_process_lease_break(
 	in_lease_key.data[1] = BVAL(inbody, 16);
 	in_lease_state = IVAL(inbody, 24);
 
-	subreq = smbd_smb2_lease_break_send(req, req->ev_ctx, req,
+	subreq = smbd_smb2_lease_break_send(req, req->sconn->ev_ctx, req,
 					    in_lease_key, in_lease_state);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c
index 1888736e4ae..dea9512dfc6 100644
--- a/source3/smbd/smb2_close.c
+++ b/source3/smbd/smb2_close.c
@@ -70,7 +70,7 @@ NTSTATUS smbd_smb2_request_process_close(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_close_send(req, req->ev_ctx,
+	subreq = smbd_smb2_close_send(req, req->sconn->ev_ctx,
 				      req, in_fsp, in_flags);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index fdd04ac0331..9de7cef6f10 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -228,7 +228,7 @@ NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *smb2req)
 	}
 
 	tsubreq = smbd_smb2_create_send(smb2req,
-				       smb2req->ev_ctx,
+				       smb2req->sconn->ev_ctx,
 				       smb2req,
 				       in_oplock_level,
 				       in_impersonation_level,
@@ -1759,7 +1759,7 @@ bool schedule_deferred_open_message_smb2(
 		(unsigned long long)mid ));
 
 	tevent_schedule_immediate(state->im,
-			smb2req->ev_ctx,
+			smb2req->sconn->ev_ctx,
 			smbd_smb2_create_request_dispatch_immediate,
 			smb2req);
 
@@ -1791,7 +1791,7 @@ static bool smbd_smb2_create_cancel(struct tevent_req *req)
 
 	remove_deferred_open_message_smb2_internal(smb2req, mid);
 
-	tevent_req_defer_callback(req, smb2req->ev_ctx);
+	tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
 	tevent_req_nterror(req, NT_STATUS_CANCELLED);
 	return true;
 }
diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c
index 4f815a6f5b0..470a8df4944 100644
--- a/source3/smbd/smb2_flush.c
+++ b/source3/smbd/smb2_flush.c
@@ -58,7 +58,7 @@ NTSTATUS smbd_smb2_request_process_flush(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_flush_send(req, req->ev_ctx,
+	subreq = smbd_smb2_flush_send(req, req->sconn->ev_ctx,
 				      req, in_fsp);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 314f44e858c..29625fc1ba7 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -122,7 +122,7 @@ NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_getinfo_send(req, req->ev_ctx,
+	subreq = smbd_smb2_getinfo_send(req, req->sconn->ev_ctx,
 					req, in_fsp,
 					in_info_type,
 					in_file_info_class,
diff --git a/source3/smbd/smb2_glue.c b/source3/smbd/smb2_glue.c
index cccc763c342..6a73ec050e2 100644
--- a/source3/smbd/smb2_glue.c
+++ b/source3/smbd/smb2_glue.c
@@ -46,7 +46,6 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req)
 	smbreq->conn = req->tcon->compat;
 	smbreq->sconn = req->sconn;
 	smbreq->xconn = req->xconn;
-	smbreq->ev_ctx = req->ev_ctx;
 	smbreq->smbpid = (uint16_t)IVAL(inhdr, SMB2_HDR_PID);
 	smbreq->flags2 = FLAGS2_UNICODE_STRINGS |
 			 FLAGS2_32_BIT_ERROR_CODES |
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index 451733c1a65..be70e3a0912 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -217,7 +217,7 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
 		break;
 	}
 
-	subreq = smbd_smb2_ioctl_send(req, req->ev_ctx,
+	subreq = smbd_smb2_ioctl_send(req, req->sconn->ev_ctx,
 				      req, in_fsp,
 				      in_ctl_code,
 				      in_input_buffer,
diff --git a/source3/smbd/smb2_ioctl_named_pipe.c b/source3/smbd/smb2_ioctl_named_pipe.c
index f8012ae1920..f9e3dec049c 100644
--- a/source3/smbd/smb2_ioctl_named_pipe.c
+++ b/source3/smbd/smb2_ioctl_named_pipe.c
@@ -143,7 +143,7 @@ static void smbd_smb2_ioctl_pipe_write_done(struct tevent_req *subreq)
 		(unsigned int)state->out_output.length ));
 
 	subreq = np_read_send(state->smbreq->conn,
-			      state->smb2req->ev_ctx,
+			      state->smb2req->sconn->ev_ctx,
 			      state->fsp->fake_file_handle,
 			      state->out_output.data,
 			      state->out_output.length);
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index da5a54df623..3cc591089a4 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -134,7 +134,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_lock_send(req, req->ev_ctx,
+	subreq = smbd_smb2_lock_send(req, req->sconn->ev_ctx,
 				     req, in_fsp,
 				     in_lock_count,
 				     in_locks);
@@ -368,7 +368,7 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
 	}
 
 	if (async) {
-		tevent_req_defer_callback(req, smb2req->ev_ctx);
+		tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
 		SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
 		return req;
 	}
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index e49e76d9641..24241562556 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -94,7 +94,7 @@ NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_notify_send(req, req->ev_ctx,
+	subreq = smbd_smb2_notify_send(req, req->sconn->ev_ctx,
 				       req, in_fsp,
 				       in_flags,
 				       in_output_buffer_length,
@@ -355,7 +355,7 @@ static void smbd_smb2_notify_reply(struct smb_request *smbreq,
 		}
 	}
 
-	tevent_req_defer_callback(req, state->smb2req->ev_ctx);
+	tevent_req_defer_callback(req, state->smb2req->sconn->ev_ctx);
 
 	if (!NT_STATUS_IS_OK(state->status)) {
 		tevent_req_nterror(req, state->status);
diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c
index 65824ca4677..51406f5e57b 100644
--- a/source3/smbd/smb2_query_directory.c
+++ b/source3/smbd/smb2_query_directory.c
@@ -125,7 +125,7 @@ NTSTATUS smbd_smb2_request_process_query_directory(struct smbd_smb2_request *req
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_query_directory_send(req, req->ev_ctx,
+	subreq = smbd_smb2_query_directory_send(req, req->sconn->ev_ctx,
 				     req, in_fsp,
 				     in_file_info_class,
 				     in_flags,
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 065a5cd5fc6..a7d2496bc6f 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -97,7 +97,7 @@ NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_read_send(req, req->ev_ctx,
+	subreq = smbd_smb2_read_send(req, req->sconn->ev_ctx,
 				     req, in_fsp,
 				     in_flags,
 				     in_length,
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index e36db1e55f5..1e9ed331aa6 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2620,10 +2620,8 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		SMB_ASSERT(call->fileid_ofs == 0);
 		/* This call needs to be run as root */
 		change_to_root_user();
-		req->ev_ctx = req->sconn->root_ev_ctx;
 	} else {
 		SMB_ASSERT(call->need_tcon);
-		req->ev_ctx = req->tcon->compat->user_ev_ctx;
 	}
 
 #define _INBYTES(_r) \
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 5420d4f09bb..2c24e7a1abc 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -95,7 +95,7 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
 	in_security_buffer.length = in_security_length;
 
 	subreq = smbd_smb2_session_setup_wrap_send(smb2req,
-						   smb2req->ev_ctx,
+						   smb2req->sconn->ev_ctx,
 						   smb2req,
 						   in_session_id,
 						   in_flags,
@@ -1218,7 +1218,7 @@ NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, status);
 	}
 
-	subreq = smbd_smb2_logoff_send(req, req->ev_ctx, req);
+	subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
 	}
diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index 7c1f84bd79d..b19cbb150a7 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -108,7 +108,7 @@ NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_setinfo_send(req, req->ev_ctx,
+	subreq = smbd_smb2_setinfo_send(req, req->sconn->ev_ctx,
 					req, in_fsp,
 					in_info_type,
 					in_file_info_class,
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index 3a4a15d3059..ebd31602efc 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -94,7 +94,7 @@ NTSTATUS smbd_smb2_request_process_tcon(struct smbd_smb2_request *req)
 	}
 
 	subreq = smbd_smb2_tree_connect_send(req,
-					     req->ev_ctx,
+					     req->sconn->ev_ctx,
 					     req,
 					     in_path_string);
 	if (subreq == NULL) {
@@ -491,7 +491,7 @@ NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, status);
 	}
 
-	subreq = smbd_smb2_tdis_send(req, req->ev_ctx, req);
+	subreq = smbd_smb2_tdis_send(req, req->sconn->ev_ctx, req);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
 	}
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index d5ab12ecc21..ee95bd317ae 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -109,7 +109,7 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_write_send(req, req->ev_ctx,
+	subreq = smbd_smb2_write_send(req, req->sconn->ev_ctx,
 				      req, in_fsp,
 				      in_data_buffer,
 				      in_offset,
-- 
2.17.2


From 88f2db8535047f3aec45bd6221dad414424effc0 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:19:20 +0100
Subject: [PATCH 44/56] Revert "smbd: add an effective
 connection_struct->user_ev_ctx that holds the event context used for the
 current user"

This reverts commit f2df8be16be9dccd3d10ec060f1efbe5007a28c6.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/include/vfs.h             | 2 --
 source3/modules/vfs_aio_pthread.c | 2 +-
 source3/modules/vfs_default.c     | 2 +-
 source3/modules/vfs_readonly.c    | 1 -
 source3/smbd/conn.c               | 7 -------
 source3/smbd/msdfs.c              | 2 --
 source3/smbd/uid.c                | 6 ------
 7 files changed, 2 insertions(+), 20 deletions(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 1a05283fe6c..8c35fa5ecc7 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -402,7 +402,6 @@ typedef struct files_struct {
 
 struct vuid_cache_entry {
 	struct auth_session_info *session_info;
-	struct tevent_context *user_ev_ctx;
 	uint64_t vuid; /* SMB2 compat */
 	bool read_only;
 	uint32_t share_access;
@@ -450,7 +449,6 @@ typedef struct connection_struct {
 	 * on the vuid using this tid, this might change per SMB request.
 	 */
 	struct auth_session_info *session_info;
-	struct tevent_context *user_ev_ctx;
 
 	/*
 	 * If the "force group" parameter is set, this is the primary gid that
diff --git a/source3/modules/vfs_aio_pthread.c b/source3/modules/vfs_aio_pthread.c
index c1d1a7d518a..cb90b12d4b2 100644
--- a/source3/modules/vfs_aio_pthread.c
+++ b/source3/modules/vfs_aio_pthread.c
@@ -276,7 +276,7 @@ static int open_async(const files_struct *fsp,
 	}
 
 	subreq = pthreadpool_tevent_job_send(opd,
-					     fsp->conn->user_ev_ctx,
+					     fsp->conn->sconn->ev_ctx,
 					     fsp->conn->sconn->pool,
 					     aio_open_worker, opd);
 	if (subreq == NULL) {
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 09a6eaf5477..fe244fb67ff 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1844,7 +1844,7 @@ static struct tevent_req *vfswrap_offload_write_send(
 		return tevent_req_post(req, ev);
 	}
 
-	state->src_ev = src_fsp->conn->user_ev_ctx;
+	state->src_ev = src_fsp->conn->sconn->ev_ctx;
 	state->src_fsp = src_fsp;
 
 	state->buf = talloc_array(state, uint8_t, num);
diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c
index 570eb7c4d15..cde8ef973ca 100644
--- a/source3/modules/vfs_readonly.c
+++ b/source3/modules/vfs_readonly.c
@@ -84,7 +84,6 @@ static int readonly_connect(vfs_handle_struct *handle,
       for (i=0; i< VUID_CACHE_SIZE; i++) {
         struct vuid_cache_entry *ent = &conn->vuid_cache->array[i];
         ent->vuid = UID_FIELD_INVALID;
-        ent->user_ev_ctx = NULL;
         TALLOC_FREE(ent->session_info);
         ent->read_only = false;
         ent->share_access = 0;
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 3b9aaac7834..8f472c0d245 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -94,12 +94,6 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid)
 
 		if (ent->vuid == vuid) {
 			ent->vuid = UID_FIELD_INVALID;
-
-			if (conn->user_ev_ctx == ent->user_ev_ctx) {
-				conn->user_ev_ctx = NULL;
-			}
-			ent->user_ev_ctx = NULL;
-
 			/*
 			 * We need to keep conn->session_info around
 			 * if it's equal to ent->session_info as a SMBulogoff
@@ -123,7 +117,6 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid)
 			} else {
 				TALLOC_FREE(ent->session_info);
 			}
-
 			ent->read_only = False;
 			ent->share_access = 0;
 		}
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index c523abb3158..65e95128aa2 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -320,8 +320,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		vfs_user = get_current_username();
 	}
 
-	conn->user_ev_ctx = sconn->raw_ev_ctx;
-
 	set_conn_connectpath(conn, connpath);
 
 	/*
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index f902f2aeae3..7aecea5f857 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -78,7 +78,6 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
 		}
 	}
 	/* Not used, safe to free. */
-	conn->user_ev_ctx = NULL;
 	TALLOC_FREE(conn->session_info);
 }
 
@@ -204,7 +203,6 @@ static bool check_user_ok(connection_struct *conn,
 			}
 			free_conn_session_info_if_unused(conn);
 			conn->session_info = ent->session_info;
-			conn->user_ev_ctx = ent->user_ev_ctx;
 			conn->read_only = ent->read_only;
 			conn->share_access = ent->share_access;
 			conn->vuid = ent->vuid;
@@ -253,8 +251,6 @@ static bool check_user_ok(connection_struct *conn,
 		ent->session_info->unix_token->uid = sec_initial_uid();
 	}
 
-	ent->user_ev_ctx = conn->sconn->raw_ev_ctx;
-
 	/*
 	 * It's actually OK to call check_user_ok() with
 	 * vuid == UID_FIELD_INVALID as called from change_to_user_by_session().
@@ -267,7 +263,6 @@ static bool check_user_ok(connection_struct *conn,
 	free_conn_session_info_if_unused(conn);
 	conn->session_info = ent->session_info;
 	conn->vuid = ent->vuid;
-	conn->user_ev_ctx = ent->user_ev_ctx;
 	if (vuid == UID_FIELD_INVALID) {
 		/*
 		 * Not strictly needed, just make it really
@@ -276,7 +271,6 @@ static bool check_user_ok(connection_struct *conn,
 		ent->read_only = false;
 		ent->share_access = 0;
 		ent->session_info = NULL;
-		ent->user_ev_ctx = NULL;
 	}
 
 	conn->read_only = readonly_share;
-- 
2.17.2


From e4dbb91e9d10b1183da86ce3c18d6d24ab70c27c Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:20:54 +0100
Subject: [PATCH 45/56] Revert "smbd: use sconn->root_ev_ctx for
 smbd_sig_{term,hup}_handler()"

This reverts commit c835ffa72ddfd2431d22909148913b50f0d829d1.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/process.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 82fcadb909f..525e28a1ec5 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -977,7 +977,7 @@ static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
 {
 	struct tevent_signal *se;
 
-	se = tevent_add_signal(sconn->root_ev_ctx,
+	se = tevent_add_signal(sconn->ev_ctx,
 			       sconn,
 			       SIGTERM, 0,
 			       smbd_sig_term_handler,
@@ -1007,7 +1007,7 @@ static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
 {
 	struct tevent_signal *se;
 
-	se = tevent_add_signal(sconn->root_ev_ctx,
+	se = tevent_add_signal(sconn->ev_ctx,
 			       sconn,
 			       SIGHUP, 0,
 			       smbd_sig_hup_handler,
-- 
2.17.2


From 5073882c3341d555214e146b4f2630f509ad745d Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:20:58 +0100
Subject: [PATCH 46/56] Revert "smbd: use sconn->root_ev_ctx for
 brl_timeout_fn()"

This reverts commit 182991c26c8149c79b13a277b9822efc49fd1df0.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/blocking.c  | 6 +-----
 source3/smbd/smb2_lock.c | 6 +-----
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index c281aae619d..6cbf5c03e93 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -135,11 +135,7 @@ static bool recalc_brl_timeout(struct smbd_server_connection *sconn)
 		    (int)from_now.tv_sec, (int)from_now.tv_usec));
 	}
 
-	/*
-	 * brl_timeout_fn() calls change_to_root_user()
-	 * so we can use sconn->root_ev_ctx.
-	 */
-	sconn->smb1.locks.brl_timeout = tevent_add_timer(sconn->root_ev_ctx,
+	sconn->smb1.locks.brl_timeout = tevent_add_timer(sconn->ev_ctx,
 							 NULL, next_timeout,
 							 brl_timeout_fn, sconn);
 	if (sconn->smb1.locks.brl_timeout == NULL) {
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index 3cc591089a4..a05470e52e4 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -568,12 +568,8 @@ static bool recalc_smb2_brl_timeout(struct smbd_server_connection *sconn)
 			(int)from_now.tv_sec, (int)from_now.tv_usec));
 	}
 
-	/*
-	 * brl_timeout_fn() calls change_to_root_user()
-	 * so we can use sconn->root_ev_ctx.
-	 */
 	sconn->smb2.locks.brl_timeout = tevent_add_timer(
-				sconn->root_ev_ctx,
+				sconn->ev_ctx,
 				NULL,
 				next_timeout,
 				brl_timeout_fn,
-- 
2.17.2


From e658760e008cfb5d8857c928d16473eb2cc4d775 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:21:01 +0100
Subject: [PATCH 47/56] Revert "smbd: add
 smbd_server_connection->{root,guest}_ev_ctx pointer"

This reverts commit 146938217ed1ab9a7a9f38c055fec5513cbd5c4d.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h | 2 --
 source3/smbd/msdfs.c   | 2 --
 source3/smbd/process.c | 2 --
 3 files changed, 6 deletions(-)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 3bc2afb2063..f6a519cec69 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -878,8 +878,6 @@ struct smbd_server_connection {
 	const char *remote_hostname;
 	struct tevent_context *ev_ctx;
 	struct tevent_context *raw_ev_ctx;
-	struct tevent_context *root_ev_ctx;
-	struct tevent_context *guest_ev_ctx;
 	struct messaging_context *msg_ctx;
 	struct notify_context *notify_ctx;
 	struct security_unix_token *root_ut;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 65e95128aa2..af5888c8a24 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -265,8 +265,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 	}
 
 	sconn->ev_ctx = sconn->raw_ev_ctx;
-	sconn->root_ev_ctx = sconn->raw_ev_ctx;
-	sconn->guest_ev_ctx = sconn->raw_ev_ctx;
 	sconn->msg_ctx = msg;
 
 	conn = conn_new(sconn);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 525e28a1ec5..6f532b5b5c9 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3925,8 +3925,6 @@ void smbd_process(struct tevent_context *ev_ctx,
 
 	sconn->ev_ctx = ev_ctx;
 	sconn->raw_ev_ctx = ev_ctx;
-	sconn->root_ev_ctx = ev_ctx;
-	sconn->guest_ev_ctx = ev_ctx;
 	sconn->msg_ctx = msg_ctx;
 
 	ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
-- 
2.17.2


From 576b804ee69786630fce0e7603f8c9b6a40cb073 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:21:04 +0100
Subject: [PATCH 48/56] Revert "smbd: use raw_ev_ctx to clear the
 MSG_SMB_CONF_UPDATED registration"

This reverts commit f5f9b719741465c7be3de20a6a69ec106ecc4568.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/process.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 6f532b5b5c9..5996bb9cc0c 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -4068,7 +4068,7 @@ void smbd_process(struct tevent_context *ev_ctx,
 			   ID_CACHE_KILL, smbd_id_cache_kill);
 
 	messaging_deregister(sconn->msg_ctx,
-			     MSG_SMB_CONF_UPDATED, sconn->raw_ev_ctx);
+			     MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
 	messaging_register(sconn->msg_ctx, sconn,
 			   MSG_SMB_CONF_UPDATED, smbd_conf_updated);
 
-- 
2.17.2


From 009dd2228d13051b5ca35662012a4921b3994616 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:21:06 +0100
Subject: [PATCH 49/56] Revert "smbd: explain that/why we use the raw
 tevent_context for linux_oplock_signal_handler()"

This reverts commit dc517b20f60a156d73fdd551557eb1d4366dfdeb.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/oplock_linux.c | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c
index 76760ff0346..9292a3370e5 100644
--- a/source3/smbd/oplock_linux.c
+++ b/source3/smbd/oplock_linux.c
@@ -125,12 +125,6 @@ static void linux_oplock_signal_handler(struct tevent_context *ev_ctx,
 	int fd = info->si_fd;
 	files_struct *fsp;
 
-	/*
-	 * This function doesn't expect any specific impersonation, as it only
-	 * sends messages to other smbd processes. And messaging_send_iov_from()
-	 * already handles EACCES.
-	 */
-
 	fsp = file_find_fd(sconn, fd);
 	if (fsp == NULL) {
 		DEBUG(0,("linux_oplock_signal_handler: failed to find fsp for file fd=%d (file was closed ?)\n", fd ));
@@ -241,13 +235,7 @@ struct kernel_oplocks *linux_init_kernel_oplocks(struct smbd_server_connection *
 	ctx->ops = &linux_koplocks;
 	ctx->private_data = sconn;
 
-	/*
-	 * linux_oplock_signal_handler() only
-	 * sends messages to other smbd processes
-	 * and doesn't require any impersonation.
-	 * So we can just use the raw tevent_context.
-	 */
-	se = tevent_add_signal(sconn->raw_ev_ctx,
+	se = tevent_add_signal(sconn->ev_ctx,
 			       ctx,
 			       RT_SIGNAL_LEASE, SA_SIGINFO,
 			       linux_oplock_signal_handler,
-- 
2.17.2


From 205f99f47336abb72f4a09855528e2ef28972f91 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:23:43 +0100
Subject: [PATCH 50/56] Revert "smbd: explain that/why we use the raw
 tevent_context for do_break_to_none()"

This reverts commit 1d5210b615035e46b90758ac7aa4ceec9174bee5.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/oplock.c | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index d733bec2d26..3feddaa90b8 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -1236,15 +1236,7 @@ static void contend_level2_oplocks_begin_default(files_struct *fsp,
 		TALLOC_FREE(state);
 		return;
 	}
-
-	/*
-	 * do_break_to_none() only operates on the
-	 * locking.tdb and sends network packets to
-	 * the client. That doesn't require any
-	 * impersonation, so we just use the
-	 * raw tevent context here.
-	 */
-	tevent_schedule_immediate(im, sconn->raw_ev_ctx, do_break_to_none, state);
+	tevent_schedule_immediate(im, sconn->ev_ctx, do_break_to_none, state);
 }
 
 static void send_break_to_none(struct messaging_context *msg_ctx,
@@ -1271,11 +1263,6 @@ static void do_break_to_none(struct tevent_context *ctx,
 	struct share_mode_lock *lck;
 	struct share_mode_data *d;
 
-	/*
-	 * Note this function doesn't run under any specific impersonation and
-	 * is not expected to call any SMB_VFS operation!
-	 */
-
 	lck = get_existing_share_mode_lock(talloc_tos(), state->id);
 	if (lck == NULL) {
 		DEBUG(1, ("%s: failed to lock share mode entry for file %s.\n",
-- 
2.17.2


From 34b9fc85c74bed61b049d2b5925b845e42a6b0ab Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:23:52 +0100
Subject: [PATCH 51/56] Revert "smbd: explain that/why we use the raw
 tevent_context for oplock_timeout_handler()"

This reverts commit e73eaa3c8004d3d8aff316cdb26b0bef85eceaca.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/oplock.c | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 3feddaa90b8..64ca0d17585 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -817,11 +817,6 @@ static void oplock_timeout_handler(struct tevent_context *ctx,
 {
 	files_struct *fsp = (files_struct *)private_data;
 
-	/*
-	 * Note this function doesn't run under any specific impersonation and
-	 * is not expected to call any SMB_VFS operation!
-	 */
-
 	SMB_ASSERT(fsp->sent_oplock_break != NO_BREAK_SENT);
 
 	/* Remove the timed event handler. */
@@ -842,15 +837,8 @@ static void add_oplock_timeout_handler(files_struct *fsp)
 			  "around\n"));
 	}
 
-	/*
-	 * For now we keep the logic and use the
-	 * raw event context. We're called from
-	 * the messaging system from a raw event context.
-	 * Also oplock_timeout_handler doesn't invoke
-	 * SMB_VFS calls.
-	 */
 	fsp->oplock_timeout =
-		tevent_add_timer(fsp->conn->sconn->raw_ev_ctx, fsp,
+		tevent_add_timer(fsp->conn->sconn->ev_ctx, fsp,
 				 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
 				 oplock_timeout_handler, fsp);
 
-- 
2.17.2


From b36fe797dba406fd48680488d80624056ab10c00 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:24:37 +0100
Subject: [PATCH 52/56] Revert "smbd: explain that/why we use the raw
 tevent_context for lease_timeout_handler()"

This reverts commit 52f098d38da72d6eff3c4cac61487da897a8651c.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/oplock.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 64ca0d17585..31a36304310 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -354,11 +354,6 @@ static void lease_timeout_handler(struct tevent_context *ctx,
 	struct share_mode_lock *lck;
 	uint16_t old_epoch = lease->lease.lease_epoch;
 
-	/*
-	 * This function runs without any specific impersonation
-	 * and must not call any SMB_VFS operations!
-	 */
-
 	fsp = file_find_one_fsp_from_lease_key(lease->sconn,
 					       &lease->lease.lease_key);
 	if (fsp == NULL) {
@@ -454,12 +449,7 @@ bool fsp_lease_update(struct share_mode_lock *lck,
 
 			DEBUG(10,("%s: setup timeout handler\n", __func__));
 
-			/*
-			 * lease_timeout_handler() only accesses locking.tdb
-			 * so we don't use any impersonation and use
-			 * the raw tevent context.
-			 */
-			lease->timeout = tevent_add_timer(lease->sconn->raw_ev_ctx,
+			lease->timeout = tevent_add_timer(lease->sconn->ev_ctx,
 							  lease, t,
 							  lease_timeout_handler,
 							  lease);
-- 
2.17.2


From 0e8fb12a21f011e0f9557a986ad78a14cc217f50 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:26:03 +0100
Subject: [PATCH 53/56] Revert "smbd: explain that/why we use the raw
 tevent_context for update_write_time_handler()"

This reverts commit 7cfafaf190643eb28fc95d21a02a4e5e529e16d1.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/fileio.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index 1fe806e058d..cde6a057ccd 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -232,17 +232,9 @@ void trigger_write_time_update(struct files_struct *fsp)
 	DEBUG(5, ("Update write time %d usec later on %s\n",
 		  delay, fsp_str_dbg(fsp)));
 
-	/*
-	 * trigger the update 2 seconds later
-	 *
-	 * Note that update_write_time_handler()
-	 * => fsp_flush_write_time_update()
-	 * won't do any SMB_VFS calls and don't
-	 * need impersonation. So we use the
-	 * raw event context for this.
-	 */
+	/* trigger the update 2 seconds later */
 	fsp->update_write_time_event =
-		tevent_add_timer(fsp->conn->sconn->raw_ev_ctx, NULL,
+		tevent_add_timer(fsp->conn->sconn->ev_ctx, NULL,
 				 timeval_current_ofs_usec(delay),
 				 update_write_time_handler, fsp);
 }
-- 
2.17.2


From 1161cbfee88a4609f6a7c7fcf62647efc8dd06bd Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:26:08 +0100
Subject: [PATCH 54/56] Revert "vfs_glusterfs: explain that/why we use the raw
 tevent_context in init_gluster_aio()"

This reverts commit b0af5715b0a7592a9728e0b76f653b9ab6228708.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_glusterfs.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index 9b623a4658b..c9d57b4b646 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -766,16 +766,7 @@ static bool init_gluster_aio(struct vfs_handle_struct *handle)
 	read_fd = fds[0];
 	write_fd = fds[1];
 
-	/*
-	 * We use the raw tevent context here,
-	 * as this is a global event handler.
-	 *
-	 * The tevent_req_defer_callback()
-	 * calls will make sure the results
-	 * of async calls are propagated
-	 * to the correct tevent_context.
-	 */
-	aio_read_event = tevent_add_fd(handle->conn->sconn->raw_ev_ctx,
+	aio_read_event = tevent_add_fd(handle->conn->sconn->ev_ctx,
 					NULL,
 					read_fd,
 					TEVENT_FD_READ,
-- 
2.17.2


From 1f3987e2f68801ef6d6caf87d9514fe5dd099950 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Fri, 28 Dec 2018 13:25:57 +0100
Subject: [PATCH 55/56] s3:smbd: use passed in ev in
 smbd_smb2_query_directory_send()

The ev argument is also a raw ev.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smb2_query_directory.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c
index 51406f5e57b..e7914947637 100644
--- a/source3/smbd/smb2_query_directory.c
+++ b/source3/smbd/smb2_query_directory.c
@@ -275,7 +275,7 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
 	if (req == NULL) {
 		return NULL;
 	}
-	state->ev = fsp->conn->sconn->raw_ev_ctx;
+	state->ev = ev;
 	state->fsp = fsp;
 	state->smb2req = smb2req;
 	state->in_output_buffer_length = in_output_buffer_length;
-- 
2.17.2


From 4e7feebec009440e8a22af4b230fbf9628228126 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 15:26:15 +0100
Subject: [PATCH 56/56] Revert "smbd: add smbd_server_connection->raw_ev_ctx
 pointer"

This reverts commit 6114f9545fa856717220658e87f2a60f6767b7f4.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h | 1 -
 source3/smbd/msdfs.c   | 5 ++---
 source3/smbd/process.c | 1 -
 3 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index f6a519cec69..be6d434d5fa 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -877,7 +877,6 @@ struct smbd_server_connection {
 	const struct tsocket_address *remote_address;
 	const char *remote_hostname;
 	struct tevent_context *ev_ctx;
-	struct tevent_context *raw_ev_ctx;
 	struct messaging_context *msg_ctx;
 	struct notify_context *notify_ctx;
 	struct security_unix_token *root_ut;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index af5888c8a24..19cb301f56b 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -258,13 +258,12 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	sconn->raw_ev_ctx = samba_tevent_context_init(sconn);
-	if (sconn->raw_ev_ctx == NULL) {
+	sconn->ev_ctx = samba_tevent_context_init(sconn);
+	if (sconn->ev_ctx == NULL) {
 		TALLOC_FREE(sconn);
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	sconn->ev_ctx = sconn->raw_ev_ctx;
 	sconn->msg_ctx = msg;
 
 	conn = conn_new(sconn);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 5996bb9cc0c..1a8080b54df 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3924,7 +3924,6 @@ void smbd_process(struct tevent_context *ev_ctx,
 	sconn->client = client;
 
 	sconn->ev_ctx = ev_ctx;
-	sconn->raw_ev_ctx = ev_ctx;
 	sconn->msg_ctx = msg_ctx;
 
 	ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
-- 
2.17.2

-------------- next part --------------
From f26abf629107bcbfe3165c920e3fdc0576bb8576 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:10:01 +0100
Subject: [PATCH 1/7] Revert "tevent: use talloc_zero_size() for the private
 state in tevent_context_wrapper_create()"

This reverts commit 9d31bbf9793ca9d2041eb8769511aca6c9684e94.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/tevent/tevent_wrapper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/tevent/tevent_wrapper.c b/lib/tevent/tevent_wrapper.c
index ce07af98358..a07696af0a4 100644
--- a/lib/tevent/tevent_wrapper.c
+++ b/lib/tevent/tevent_wrapper.c
@@ -371,7 +371,7 @@ struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *mai
 	ev->wrapper.glue->wrap_ev = ev;
 	ev->wrapper.glue->main_ev = main_ev;
 	ev->wrapper.glue->ops = ops;
-	ev->wrapper.glue->private_state = talloc_zero_size(ev->wrapper.glue, psize);
+	ev->wrapper.glue->private_state = talloc_size(ev->wrapper.glue, psize);
 	if (ev->wrapper.glue->private_state == NULL) {
 		talloc_free(ev);
 		return NULL;
-- 
2.17.2


From f21b27ffe98bf5d2d7f140f60f9ebaba9e7fc478 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:16:37 +0100
Subject: [PATCH 2/7] Revert "tevent: fix CID 1437974 dereference after null
 check"

This reverts commit ba991da43469a1844b67fcec19a15ceda409fc3f.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/tevent/tevent_wrapper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/tevent/tevent_wrapper.c b/lib/tevent/tevent_wrapper.c
index a07696af0a4..05c4c06968a 100644
--- a/lib/tevent/tevent_wrapper.c
+++ b/lib/tevent/tevent_wrapper.c
@@ -347,7 +347,7 @@ struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *mai
 		/*
 		 * wrappers conflict with nesting
 		 */
-		tevent_debug(main_ev, TEVENT_DEBUG_FATAL,
+		tevent_debug(main_ev->wrapper.glue->main_ev, TEVENT_DEBUG_FATAL,
 			     "%s: %s() conflicts with nesting\n",
 			     __func__, location);
 		errno = EINVAL;
-- 
2.17.2


From d2cb3d077659235a81df3ab561c32f9bbf2c1989 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 11:16:47 +0100
Subject: [PATCH 3/7] Revert "tevent: fix CID 1437976 dereference before null
 check"

This reverts commit 3761d42e4fe563ad893f14468e98bd1f5a807604.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/tevent/tevent_threads.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c
index a89990f231a..21a9b686ba9 100644
--- a/lib/tevent/tevent_threads.c
+++ b/lib/tevent/tevent_threads.c
@@ -473,7 +473,7 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
 #ifdef HAVE_PTHREAD
 	const char *create_location = im->create_location;
 	struct tevent_context *main_ev = NULL;
-	struct tevent_wrapper_glue *glue = NULL;
+	struct tevent_wrapper_glue *glue = tctx->event_ctx->wrapper.glue;
 	int ret, wakeup_fd;
 
 	ret = pthread_mutex_lock(&tctx->event_ctx_mutex);
@@ -492,8 +492,6 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
 		return;
 	}
 
-	glue = tctx->event_ctx->wrapper.glue;
-
 	if ((im->event_ctx != NULL) || (handler == NULL)) {
 		abort();
 	}
-- 
2.17.2


From 48c3bc9f7f4264058d016feacea334681a641f8d Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 12:53:57 +0100
Subject: [PATCH 4/7] Revert "tevent: add a test that frees wrapper_ev with
 pending events"

This reverts commit 6189446abe27acda82afb6d9eb43b0b01c5ce4bc.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/tevent/testsuite.c | 157 -----------------------------------------
 1 file changed, 157 deletions(-)

diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index 62a8da3c1a1..c0ec9f32d09 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -1048,159 +1048,6 @@ static bool test_wrapper(struct torture_context *tctx,
 	goto done;
 }
 
-static void test_free_wrapper_signal_handler(struct tevent_context *ev,
-					struct tevent_signal *se,
-					int signum,
-					int count,
-					void *siginfo,
-					void *private_data)
-{
-	struct torture_context *tctx =
-		talloc_get_type_abort(private_data,
-		struct torture_context);
-
-	torture_comment(tctx, "signal handler\n");
-
-	talloc_free(se);
-
-	/*
-	 * signal handlers have highest priority in tevent, so this signal
-	 * handler will always be started before the other handlers
-	 * below. Freeing the (wrapper) event context here tests that the
-	 * wrapper implementation correclty handles the wrapper ev going away
-	 * with pending events.
-	 */
-	talloc_free(ev);
-	return;
-}
-
-static void test_free_wrapper_fd_handler(struct tevent_context *ev,
-					 struct tevent_fd *fde,
-					 unsigned short fd_flags,
-					 void *private_data)
-{
-	/*
-	 * This should never be called as
-	 * test_free_wrapper_signal_handler()
-	 * already destroyed the wrapper tevent_context.
-	 */
-	abort();
-}
-
-static void test_free_wrapper_immediate_handler(struct tevent_context *ev,
-					   struct tevent_immediate *im,
-					   void *private_data)
-{
-	/*
-	 * This should never be called as
-	 * test_free_wrapper_signal_handler()
-	 * already destroyed the wrapper tevent_context.
-	 */
-	abort();
-}
-
-static void test_free_wrapper_timer_handler(struct tevent_context *ev,
-				       struct tevent_timer *te,
-				       struct timeval tv,
-				       void *private_data)
-{
-	/*
-	 * This should never be called as
-	 * test_free_wrapper_signal_handler()
-	 * already destroyed the wrapper tevent_context.
-	 */
-	abort();
-}
-
-static bool test_free_wrapper(struct torture_context *tctx,
-			      const void *test_data)
-{
-	struct test_wrapper_state *state = NULL;
-	int sock[2] = { -1, -1};
-	uint8_t c = 0;
-	const char *backend = (const char *)test_data;
-	TALLOC_CTX *frame = talloc_stackframe();
-	struct tevent_context *ev = NULL;
-	struct tevent_context *wrap_ev = NULL;
-	struct tevent_fd *fde = NULL;
-	struct tevent_timer *te = NULL;
-	struct tevent_signal *se = NULL;
-	struct tevent_immediate *im = NULL;
-	int ret;
-	bool ok = false;
-
-	ev = tevent_context_init_byname(frame, backend);
-	if (ev == NULL) {
-		torture_skip(tctx, talloc_asprintf(tctx,
-			     "event backend '%s' not supported\n",
-			     backend));
-		return true;
-	}
-
-	tevent_set_debug_stderr(ev);
-	torture_comment(tctx, "tevent backend '%s'\n", backend);
-
-	wrap_ev = tevent_context_wrapper_create(
-		ev, ev,	&test_wrapper_ops, &state, struct test_wrapper_state);
-	torture_assert_not_null_goto(tctx, wrap_ev, ok, done,
-				     "tevent_context_wrapper_create failed\n");
-	*state = (struct test_wrapper_state) {
-		.tctx = tctx,
-	};
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
-	torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n");
-
-	fde = tevent_add_fd(wrap_ev, frame,
-			    sock[1],
-			    TEVENT_FD_READ,
-			    test_free_wrapper_fd_handler,
-			    NULL);
-	torture_assert_not_null_goto(tctx, fde, ok, done,
-				     "tevent_add_fd failed\n");
-
-	te = tevent_add_timer(wrap_ev, frame,
-			      timeval_current_ofs(0, 0),
-			      test_free_wrapper_timer_handler, NULL);
-	torture_assert_not_null_goto(tctx, te, ok, done,
-				     "tevent_add_timer failed\n");
-
-	im = tevent_create_immediate(frame);
-	torture_assert_not_null_goto(tctx, im, ok, done,
-				     "tevent_create_immediate failed\n");
-
-	se = tevent_add_signal(wrap_ev, frame,
-			       SIGUSR1,
-			       0,
-			       test_free_wrapper_signal_handler,
-			       tctx);
-	torture_assert_not_null_goto(tctx, se, ok, done,
-				     "tevent_add_signal failed\n");
-
-	do_write(sock[0], &c, 1);
-	kill(getpid(), SIGUSR1);
-	tevent_schedule_immediate(im,
-				  wrap_ev,
-				  test_free_wrapper_immediate_handler,
-				  NULL);
-
-	ret = tevent_loop_wait(ev);
-	torture_assert_goto(tctx, ret == 0, ok, done, "tevent_loop_wait failed\n");
-
-	ok = true;
-
-done:
-	TALLOC_FREE(frame);
-
-	if (sock[0] != -1) {
-		close(sock[0]);
-	}
-	if (sock[1] != -1) {
-		close(sock[1]);
-	}
-	return ok;
-}
-
 #ifdef HAVE_PTHREAD
 
 static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1789,10 +1636,6 @@ struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
 					       "wrapper",
 					       test_wrapper,
 					       (const void *)list[i]);
-		torture_suite_add_simple_tcase_const(backend_suite,
-					       "free_wrapper",
-					       test_free_wrapper,
-					       (const void *)list[i]);
 
 		torture_suite_add_suite(suite, backend_suite);
 	}
-- 
2.17.2


From 09f66c393c9a0e636c654023690627f4d405b958 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 12:54:03 +0100
Subject: [PATCH 5/7] Revert "tevent: add a simple wrapper test"

This reverts commit 4991c935c03236f60183d37b4a24c68713ee4962.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/tevent/testsuite.c | 356 -----------------------------------------
 1 file changed, 356 deletions(-)

diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index c0ec9f32d09..50f9b4d4ddd 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -696,358 +696,6 @@ static bool test_event_fd2(struct torture_context *tctx,
 	return true;
 }
 
-struct test_wrapper_state {
-	struct torture_context *tctx;
-	int num_events;
-	int num_wrap_handlers;
-};
-
-static bool test_wrapper_before_use(struct tevent_context *wrap_ev,
-				    void *private_data,
-				    struct tevent_context *main_ev,
-				    const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-	return true;
-}
-
-static void test_wrapper_after_use(struct tevent_context *wrap_ev,
-				   void *private_data,
-				   struct tevent_context *main_ev,
-				   const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-}
-
-static void test_wrapper_before_fd_handler(struct tevent_context *wrap_ev,
-					   void *private_data,
-					   struct tevent_context *main_ev,
-					   struct tevent_fd *fde,
-					   uint16_t flags,
-					   const char *handler_name,
-					   const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-}
-
-static void test_wrapper_after_fd_handler(struct tevent_context *wrap_ev,
-					  void *private_data,
-					  struct tevent_context *main_ev,
-					  struct tevent_fd *fde,
-					  uint16_t flags,
-					  const char *handler_name,
-					  const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-}
-
-static void test_wrapper_before_timer_handler(struct tevent_context *wrap_ev,
-					      void *private_data,
-					      struct tevent_context *main_ev,
-					      struct tevent_timer *te,
-					      struct timeval requested_time,
-					      struct timeval trigger_time,
-					      const char *handler_name,
-					      const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-}
-
-static void test_wrapper_after_timer_handler(struct tevent_context *wrap_ev,
-					     void *private_data,
-					     struct tevent_context *main_ev,
-					     struct tevent_timer *te,
-					     struct timeval requested_time,
-					     struct timeval trigger_time,
-					     const char *handler_name,
-					     const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-}
-
-static void test_wrapper_before_immediate_handler(struct tevent_context *wrap_ev,
-						  void *private_data,
-						  struct tevent_context *main_ev,
-						  struct tevent_immediate *im,
-						  const char *handler_name,
-						  const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-}
-
-static void test_wrapper_after_immediate_handler(struct tevent_context *wrap_ev,
-						 void *private_data,
-						 struct tevent_context *main_ev,
-						 struct tevent_immediate *im,
-						 const char *handler_name,
-						 const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-}
-
-static void test_wrapper_before_signal_handler(struct tevent_context *wrap_ev,
-					       void *private_data,
-					       struct tevent_context *main_ev,
-					       struct tevent_signal *se,
-					       int signum,
-					       int count,
-					       void *siginfo,
-					       const char *handler_name,
-					       const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-}
-
-static void test_wrapper_after_signal_handler(struct tevent_context *wrap_ev,
-					      void *private_data,
-					      struct tevent_context *main_ev,
-					      struct tevent_signal *se,
-					      int signum,
-					      int count,
-					      void *siginfo,
-					      const char *handler_name,
-					      const char *location)
-{
-	struct test_wrapper_state *state =
-		talloc_get_type_abort(private_data,
-		struct test_wrapper_state);
-
-	torture_comment(state->tctx, "%s\n", __func__);
-	state->num_wrap_handlers++;
-}
-
-static const struct tevent_wrapper_ops test_wrapper_ops = {
-	.name				= "test_wrapper",
-	.before_use			= test_wrapper_before_use,
-	.after_use			= test_wrapper_after_use,
-	.before_fd_handler		= test_wrapper_before_fd_handler,
-	.after_fd_handler		= test_wrapper_after_fd_handler,
-	.before_timer_handler		= test_wrapper_before_timer_handler,
-	.after_timer_handler		= test_wrapper_after_timer_handler,
-	.before_immediate_handler	= test_wrapper_before_immediate_handler,
-	.after_immediate_handler	= test_wrapper_after_immediate_handler,
-	.before_signal_handler		= test_wrapper_before_signal_handler,
-	.after_signal_handler		= test_wrapper_after_signal_handler,
-};
-
-static void test_wrapper_timer_handler(struct tevent_context *ev,
-				       struct tevent_timer *te,
-				       struct timeval tv,
-				       void *private_data)
-{
-	struct test_wrapper_state *state =
-		(struct test_wrapper_state *)private_data;
-
-
-	torture_comment(state->tctx, "timer handler\n");
-
-	state->num_events++;
-	talloc_free(te);
-	return;
-}
-
-static void test_wrapper_fd_handler(struct tevent_context *ev,
-				    struct tevent_fd *fde,
-				    unsigned short fd_flags,
-				    void *private_data)
-{
-	struct test_wrapper_state *state =
-		(struct test_wrapper_state *)private_data;
-
-	torture_comment(state->tctx, "fd handler\n");
-
-	state->num_events++;
-	talloc_free(fde);
-	return;
-}
-
-static void test_wrapper_immediate_handler(struct tevent_context *ev,
-					   struct tevent_immediate *im,
-					   void *private_data)
-{
-	struct test_wrapper_state *state =
-		(struct test_wrapper_state *)private_data;
-
-	state->num_events++;
-	talloc_free(im);
-
-	torture_comment(state->tctx, "immediate handler\n");
-	return;
-}
-
-static void test_wrapper_signal_handler(struct tevent_context *ev,
-					struct tevent_signal *se,
-					int signum,
-					int count,
-					void *siginfo,
-					void *private_data)
-{
-	struct test_wrapper_state *state =
-		(struct test_wrapper_state *)private_data;
-
-	torture_comment(state->tctx, "signal handler\n");
-
-	state->num_events++;
-	talloc_free(se);
-	return;
-}
-
-static bool test_wrapper(struct torture_context *tctx,
-			 const void *test_data)
-{
-	struct test_wrapper_state *state = NULL;
-	int sock[2] = { -1, -1};
-	uint8_t c = 0;
-	const int num_events = 4;
-	const char *backend = (const char *)test_data;
-	struct tevent_context *ev = NULL;
-	struct tevent_context *wrap_ev = NULL;
-	struct tevent_fd *fde = NULL;
-	struct tevent_timer *te = NULL;
-	struct tevent_signal *se = NULL;
-	struct tevent_immediate *im = NULL;
-	int ret;
-	bool ok = false;
-	bool ret2;
-
-	ev = tevent_context_init_byname(tctx, backend);
-	if (ev == NULL) {
-		torture_skip(tctx, talloc_asprintf(tctx,
-			     "event backend '%s' not supported\n",
-			     backend));
-		return true;
-	}
-
-	tevent_set_debug_stderr(ev);
-	torture_comment(tctx, "tevent backend '%s'\n", backend);
-
-	wrap_ev = tevent_context_wrapper_create(
-		ev, ev,	&test_wrapper_ops, &state, struct test_wrapper_state);
-	torture_assert_not_null_goto(tctx, wrap_ev, ok, done,
-				     "tevent_context_wrapper_create failed\n");
-	*state = (struct test_wrapper_state) {
-		.tctx = tctx,
-	};
-
-	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
-	torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n");
-
-	te = tevent_add_timer(wrap_ev, wrap_ev,
-			      timeval_current_ofs(0, 0),
-			      test_wrapper_timer_handler, state);
-	torture_assert_not_null_goto(tctx, te, ok, done,
-				     "tevent_add_timer failed\n");
-
-	fde = tevent_add_fd(wrap_ev, wrap_ev,
-			    sock[1],
-			    TEVENT_FD_READ,
-			    test_wrapper_fd_handler,
-			    state);
-	torture_assert_not_null_goto(tctx, fde, ok, done,
-				     "tevent_add_fd failed\n");
-
-	im = tevent_create_immediate(wrap_ev);
-	torture_assert_not_null_goto(tctx, im, ok, done,
-				     "tevent_create_immediate failed\n");
-
-	se = tevent_add_signal(wrap_ev, wrap_ev,
-			       SIGUSR1,
-			       0,
-			       test_wrapper_signal_handler,
-			       state);
-	torture_assert_not_null_goto(tctx, se, ok, done,
-				     "tevent_add_signal failed\n");
-
-	do_write(sock[0], &c, 1);
-	kill(getpid(), SIGUSR1);
-	tevent_schedule_immediate(im,
-				  wrap_ev,
-				  test_wrapper_immediate_handler,
-				  state);
-
-	ret2 = tevent_context_push_use(wrap_ev);
-	torture_assert_goto(tctx, ret2, ok, done, "tevent_context_push_use(wrap_ev) failed\n");
-	ret2 = tevent_context_push_use(ev);
-	torture_assert_goto(tctx, ret2, ok, pop_use, "tevent_context_push_use(ev) failed\n");
-	tevent_context_pop_use(ev);
-	tevent_context_pop_use(wrap_ev);
-
-	ret = tevent_loop_wait(ev);
-	torture_assert_int_equal_goto(tctx, ret, 0, ok, done, "tevent_loop_wait failed\n");
-
-	torture_comment(tctx, "Num events: %d\n", state->num_events);
-	torture_comment(tctx, "Num wrap handlers: %d\n",
-			state->num_wrap_handlers);
-
-	torture_assert_int_equal_goto(tctx, state->num_events, num_events, ok, done,
-				      "Wrong event count\n");
-	torture_assert_int_equal_goto(tctx, state->num_wrap_handlers,
-				      num_events*2+2,
-				      ok, done, "Wrong wrapper count\n");
-
-	ok = true;
-
-done:
-	TALLOC_FREE(wrap_ev);
-	TALLOC_FREE(ev);
-
-	if (sock[0] != -1) {
-		close(sock[0]);
-	}
-	if (sock[1] != -1) {
-		close(sock[1]);
-	}
-	return ok;
-pop_use:
-	tevent_context_pop_use(wrap_ev);
-	goto done;
-}
-
 #ifdef HAVE_PTHREAD
 
 static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1632,10 +1280,6 @@ struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
 					       "fd2",
 					       test_event_fd2,
 					       (const void *)list[i]);
-		torture_suite_add_simple_tcase_const(backend_suite,
-					       "wrapper",
-					       test_wrapper,
-					       (const void *)list[i]);
 
 		torture_suite_add_suite(suite, backend_suite);
 	}
-- 
2.17.2


From 4f34a68739cad29da9a742bb83ac604ae26a25cf Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 12:54:06 +0100
Subject: [PATCH 6/7] Revert "tevent: add tevent_context_wrapper_create()
 infrastructure"

This reverts commit ac9569b1a61319166e497d51917db7f04a2746ce.

The ABI change will be reverted when the tevent ABI version is bumped to
1.0.0.

See the discussion in

https://lists.samba.org/archive/samba-technical/2018-December/131731.html

for the reasoning behind this revert.

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 lib/tevent/ABI/tevent-0.9.37.sigs |   5 -
 lib/tevent/tevent.c               |  30 +-
 lib/tevent/tevent.h               | 260 --------------
 lib/tevent/tevent_debug.c         |  16 -
 lib/tevent/tevent_epoll.c         |   8 -
 lib/tevent/tevent_fd.c            |  29 +-
 lib/tevent/tevent_immediate.c     |  27 +-
 lib/tevent/tevent_internal.h      |  35 --
 lib/tevent/tevent_poll.c          |   2 -
 lib/tevent/tevent_signal.c        |  32 +-
 lib/tevent/tevent_threads.c       |  42 +--
 lib/tevent/tevent_timed.c         |  32 +-
 lib/tevent/tevent_wrapper.c       | 568 ------------------------------
 lib/tevent/wscript                |   2 +-
 14 files changed, 19 insertions(+), 1069 deletions(-)
 delete mode 100644 lib/tevent/tevent_wrapper.c

diff --git a/lib/tevent/ABI/tevent-0.9.37.sigs b/lib/tevent/ABI/tevent-0.9.37.sigs
index f6227db5c93..5929dcc3e8c 100644
--- a/lib/tevent/ABI/tevent-0.9.37.sigs
+++ b/lib/tevent/ABI/tevent-0.9.37.sigs
@@ -1,9 +1,6 @@
 _tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *)
 _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
 _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
-_tevent_context_pop_use: void (struct tevent_context *, const char *)
-_tevent_context_push_use: bool (struct tevent_context *, const char *)
-_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *)
 _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *)
 _tevent_loop_once: int (struct tevent_context *, const char *)
 _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *)
@@ -50,8 +47,6 @@ tevent_common_wakeup_init: int (struct tevent_context *)
 tevent_context_init: struct tevent_context *(TALLOC_CTX *)
 tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *)
 tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *)
-tevent_context_is_wrapper: bool (struct tevent_context *)
-tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *)
 tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...)
 tevent_fd_get_flags: uint16_t (struct tevent_fd *)
 tevent_fd_set_auto_close: void (struct tevent_fd *)
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index dbec1821e41..de0436df373 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -298,17 +298,10 @@ int tevent_common_context_destructor(struct tevent_context *ev)
 	struct tevent_timer *te, *tn;
 	struct tevent_immediate *ie, *in;
 	struct tevent_signal *se, *sn;
-	struct tevent_wrapper_glue *gl, *gn;
+
 #ifdef HAVE_PTHREAD
 	int ret;
-#endif
-
-	if (ev->wrapper.glue != NULL) {
-		tevent_abort(ev,
-			"tevent_common_context_destructor() active on wrapper");
-	}
 
-#ifdef HAVE_PTHREAD
 	ret = pthread_mutex_lock(&tevent_contexts_mutex);
 	if (ret != 0) {
 		abort();
@@ -352,18 +345,10 @@ int tevent_common_context_destructor(struct tevent_context *ev)
 	}
 #endif
 
-	for (gl = ev->wrapper.list; gl; gl = gn) {
-		gn = gl->next;
-
-		gl->main_ev = NULL;
-		DLIST_REMOVE(ev->wrapper.list, gl);
-	}
-
 	tevent_common_wakeup_fini(ev);
 
 	for (fd = ev->fd_events; fd; fd = fn) {
 		fn = fd->next;
-		fd->wrapper = NULL;
 		fd->event_ctx = NULL;
 		DLIST_REMOVE(ev->fd_events, fd);
 	}
@@ -371,14 +356,12 @@ int tevent_common_context_destructor(struct tevent_context *ev)
 	ev->last_zero_timer = NULL;
 	for (te = ev->timer_events; te; te = tn) {
 		tn = te->next;
-		te->wrapper = NULL;
 		te->event_ctx = NULL;
 		DLIST_REMOVE(ev->timer_events, te);
 	}
 
 	for (ie = ev->immediate_events; ie; ie = in) {
 		in = ie->next;
-		ie->wrapper = NULL;
 		ie->event_ctx = NULL;
 		ie->cancel_fn = NULL;
 		DLIST_REMOVE(ev->immediate_events, ie);
@@ -386,7 +369,6 @@ int tevent_common_context_destructor(struct tevent_context *ev)
 
 	for (se = ev->signal_events; se; se = sn) {
 		sn = se->next;
-		se->wrapper = NULL;
 		se->event_ctx = NULL;
 		DLIST_REMOVE(ev->signal_events, se);
 		/*
@@ -693,16 +675,6 @@ struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
 
 void tevent_loop_allow_nesting(struct tevent_context *ev)
 {
-	if (ev->wrapper.glue != NULL) {
-		tevent_abort(ev, "tevent_loop_allow_nesting() on wrapper");
-		return;
-	}
-
-	if (ev->wrapper.list != NULL) {
-		tevent_abort(ev, "tevent_loop_allow_nesting() with wrapper");
-		return;
-	}
-
 	ev->nesting.allowed = true;
 }
 
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 664604a06bd..4529d5ffe13 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -429,12 +429,6 @@ int _tevent_loop_wait(struct tevent_context *ev, const char *location);
  *
  * @param[in] fde       File descriptor event on which to set the destructor
  * @param[in] close_fn  Destructor to execute when fde is freed
- *
- * @note That the close_fn() on tevent_fd is *NOT* wrapped on contexts
- * created by tevent_context_wrapper_create()!
- *
- * @see tevent_fd_set_close_fn
- * @see tevent_context_wrapper_create
  */
 void tevent_fd_set_close_fn(struct tevent_fd *fde,
 			    tevent_fd_close_fn_t close_fn);
@@ -445,8 +439,6 @@ void tevent_fd_set_close_fn(struct tevent_fd *fde,
  * This function calls close(fd) internally.
  *
  * @param[in] fde  File descriptor event to auto-close
- *
- * @see tevent_fd_set_close_fn
  */
 void tevent_fd_set_auto_close(struct tevent_fd *fde);
 
@@ -2160,258 +2152,6 @@ bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
 
 /* @} */
 
-/**
- * @defgroup tevent_wrapper_ops The tevent wrapper operation functions
- * @ingroup tevent
- *
- * The following structure and registration functions are exclusively
- * needed for people writing wrapper functions for event handlers
- * e.g. wrappers can be used for debugging/profiling or impersonation.
- *
- * There is nothing useful for normal tevent user in here.
- *
- * @note That the close_fn() on tevent_fd is *NOT* wrapped!
- *
- * @see tevent_context_wrapper_create
- * @see tevent_fd_set_auto_close
- * @{
- */
-
-struct tevent_wrapper_ops {
-	const char *name;
-
-	bool (*before_use)(struct tevent_context *wrap_ev,
-			   void *private_state,
-			   struct tevent_context *main_ev,
-			   const char *location);
-	void (*after_use)(struct tevent_context *wrap_ev,
-			  void *private_state,
-			  struct tevent_context *main_ev,
-			  const char *location);
-
-	void (*before_fd_handler)(struct tevent_context *wrap_ev,
-				  void *private_state,
-				  struct tevent_context *main_ev,
-				  struct tevent_fd *fde,
-				  uint16_t flags,
-				  const char *handler_name,
-				  const char *location);
-	void (*after_fd_handler)(struct tevent_context *wrap_ev,
-				 void *private_state,
-				 struct tevent_context *main_ev,
-				 struct tevent_fd *fde,
-				 uint16_t flags,
-				 const char *handler_name,
-				 const char *location);
-
-	void (*before_timer_handler)(struct tevent_context *wrap_ev,
-				     void *private_state,
-				     struct tevent_context *main_ev,
-				     struct tevent_timer *te,
-				     struct timeval requested_time,
-				     struct timeval trigger_time,
-				     const char *handler_name,
-				     const char *location);
-	void (*after_timer_handler)(struct tevent_context *wrap_ev,
-				    void *private_state,
-				    struct tevent_context *main_ev,
-				    struct tevent_timer *te,
-				    struct timeval requested_time,
-				    struct timeval trigger_time,
-				    const char *handler_name,
-				    const char *location);
-
-	void (*before_immediate_handler)(struct tevent_context *wrap_ev,
-					 void *private_state,
-					 struct tevent_context *main_ev,
-					 struct tevent_immediate *im,
-					 const char *handler_name,
-					 const char *location);
-	void (*after_immediate_handler)(struct tevent_context *wrap_ev,
-					void *private_state,
-					struct tevent_context *main_ev,
-					struct tevent_immediate *im,
-					const char *handler_name,
-					const char *location);
-
-	void (*before_signal_handler)(struct tevent_context *wrap_ev,
-				      void *private_state,
-				      struct tevent_context *main_ev,
-				      struct tevent_signal *se,
-				      int signum,
-				      int count,
-				      void *siginfo,
-				      const char *handler_name,
-				      const char *location);
-	void (*after_signal_handler)(struct tevent_context *wrap_ev,
-				     void *private_state,
-				     struct tevent_context *main_ev,
-				     struct tevent_signal *se,
-				     int signum,
-				     int count,
-				     void *siginfo,
-				     const char *handler_name,
-				     const char *location);
-};
-
-#ifdef DOXYGEN
-/**
- * @brief Create a wrapper tevent_context.
- *
- * @param[in]  main_ev        The main event context to work on.
- *
- * @param[in]  mem_ctx        The talloc memory context to use.
- *
- * @param[in]  ops            The tevent_wrapper_ops function table.
- *
- * @param[out] private_state  The private state use by the wrapper functions.
- *
- * @param[in]  private_type   The talloc type of the private_state.
- *
- * @return                    The wrapper event context, NULL on error.
- *
- * @note Available as of tevent 0.9.37
- */
-struct tevent_context *tevent_context_wrapper_create(struct tevent_context *main_ev,
-						TALLOC_CTX *mem_ctx,
-						const struct tevent_wrapper_ops *ops,
-						void **private_state,
-						const char *private_type);
-#else
-struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev,
-						TALLOC_CTX *mem_ctx,
-						const struct tevent_wrapper_ops *ops,
-						void *pstate,
-						size_t psize,
-						const char *type,
-						const char *location);
-#define tevent_context_wrapper_create(main_ev, mem_ctx, ops, state, type) \
-	_tevent_context_wrapper_create(main_ev, mem_ctx, ops, \
-				       state, sizeof(type), #type, __location__)
-#endif
-
-/**
- * @brief Check if the event context is a wrapper event context.
- *
- * @param[in]  ev       The event context to work on.
- *
- * @return              Is a wrapper (true), otherwise (false).
- *
- * @see tevent_context_wrapper_create()
- *
- * @note Available as of tevent 0.9.37
- */
-bool tevent_context_is_wrapper(struct tevent_context *ev);
-
-#ifdef DOXYGEN
-/**
- * @brief Prepare the environment of a (wrapper) event context.
- *
- * A caller might call this before passing a wrapper event context
- * to a tevent_req based *_send() function.
- *
- * The wrapper event context might do something like impersonation.
- *
- * tevent_context_push_use() must always be used in combination
- * with tevent_context_pop_use().
- *
- * There is a global stack of currently active/busy wrapper event contexts.
- * Each wrapper can only appear once on that global stack!
- * The stack size is limited to 32 elements, which should be enough
- * for all useful scenarios.
- *
- * In addition to an explicit tevent_context_push_use() also
- * the invocation of an immediate, timer or fd handler implicitly
- * pushes the wrapper on the stack.
- *
- * Therefore there are some strict constraints for the usage of
- * tevent_context_push_use():
- * - It must not be called from within an event handler
- *   that already acts on the wrapper.
- * - tevent_context_pop_use() must be called before
- *   leaving the code block that called tevent_context_push_use().
- * - The caller is responsible ensure the correct stack ordering
- * - Any violation of these constraints results in calling
- *   the abort handler of the given tevent context.
- *
- * Calling tevent_context_push_use() on a raw event context
- * still consumes an element on the stack, but it's otherwise
- * a no-op.
- *
- * If tevent_context_push_use() returns false, it means
- * that the wrapper's before_use() hook returned this failure,
- * in that case you must not call tevent_context_pop_use() as
- * the wrapper is not pushed onto the stack.
- *
- * @param[in]  ev       The event context to work on.
- *
- * @return              Success (true) or failure (false).
- *
- * @note This is only needed if wrapper event contexts are in use.
- *
- * @see tevent_context_pop_use
- *
- * @note Available as of tevent 0.9.37
- */
-bool tevent_context_push_use(struct tevent_context *ev);
-#else
-bool _tevent_context_push_use(struct tevent_context *ev,
-				const char *location);
-#define tevent_context_push_use(ev) \
-	_tevent_context_push_use(ev, __location__)
-#endif
-
-#ifdef DOXYGEN
-/**
- * @brief Release the environment of a (wrapper) event context.
- *
- * The wrapper event context might undo something like impersonation.
- *
- * This must be called after a succesful tevent_context_push_use().
- * Any ordering violation results in calling
- * the abort handler of the given tevent context.
- *
- * This basically calls the wrapper's after_use() hook.
- *
- * @param[in]  ev       The event context to work on.
- *
- * @note This is only needed if wrapper event contexts are in use.
- *
- * @see tevent_context_push_use
- *
- * @note Available as of tevent 0.9.37
- */
-void tevent_context_pop_use(struct tevent_context *ev);
-#else
-void _tevent_context_pop_use(struct tevent_context *ev,
-			       const char *location);
-#define tevent_context_pop_use(ev) \
-	_tevent_context_pop_use(ev, __location__)
-#endif
-
-/**
- * @brief Check is the two context pointers belong to the same low level loop
- *
- * With the introduction of wrapper contexts it's not trivial
- * to check if two context pointers belong to the same low level
- * event loop. Some code may need to know this in order
- * to make some caching decisions.
- *
- * @param[in]  ev1       The first event context.
- * @param[in]  ev2       The second event context.
- *
- * @return true if both contexts belong to the same (still existing) context
- * loop, false otherwise.
- *
- * @see tevent_context_wrapper_create
- *
- * @note Available as of tevent 0.9.37
- */
-bool tevent_context_same_loop(struct tevent_context *ev1,
-			      struct tevent_context *ev2);
-
-/* @} */
-
 /**
  * @defgroup tevent_compat The tevent compatibility functions
  * @ingroup tevent
diff --git a/lib/tevent/tevent_debug.c b/lib/tevent/tevent_debug.c
index 0a57639076e..31da7b96836 100644
--- a/lib/tevent/tevent_debug.c
+++ b/lib/tevent/tevent_debug.c
@@ -41,13 +41,6 @@ int tevent_set_debug(struct tevent_context *ev,
 				   va_list ap) PRINTF_ATTRIBUTE(3,0),
 		     void *context)
 {
-	if (ev->wrapper.glue != NULL) {
-		ev = tevent_wrapper_main_ev(ev);
-		tevent_abort(ev, "tevent_set_debug() on wrapper");
-		errno = EINVAL;
-		return -1;
-	}
-
 	ev->debug_ops.debug = debug;
 	ev->debug_ops.context = context;
 	return 0;
@@ -93,9 +86,6 @@ void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
 	if (!ev) {
 		return;
 	}
-	if (ev->wrapper.glue != NULL) {
-		ev = tevent_wrapper_main_ev(ev);
-	}
 	if (ev->debug_ops.debug == NULL) {
 		return;
 	}
@@ -108,12 +98,6 @@ void tevent_set_trace_callback(struct tevent_context *ev,
 			       tevent_trace_callback_t cb,
 			       void *private_data)
 {
-	if (ev->wrapper.glue != NULL) {
-		ev = tevent_wrapper_main_ev(ev);
-		tevent_abort(ev, "tevent_set_trace_callback() on wrapper");
-		return;
-	}
-
 	ev->tracing.callback = cb;
 	ev->tracing.private_data = private_data;
 }
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index 9cbe505c98a..5f7ef5d83d1 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -323,10 +323,8 @@ static int epoll_add_multiplex_fd(struct epoll_event_context *epoll_ev,
 			     "add_fde[%p] mpx_fde[%p] fd[%d] - disabling\n",
 			     add_fde, mpx_fde, add_fde->fd);
 		DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde);
-		mpx_fde->wrapper = NULL;
 		mpx_fde->event_ctx = NULL;
 		DLIST_REMOVE(epoll_ev->ev->fd_events, add_fde);
-		add_fde->wrapper = NULL;
 		add_fde->event_ctx = NULL;
 		return 0;
 	} else if (ret != 0) {
@@ -389,11 +387,9 @@ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct tevent_
 			     "fde[%p] mpx_fde[%p] fd[%d] - disabling\n",
 			     fde, mpx_fde, fde->fd);
 		DLIST_REMOVE(epoll_ev->ev->fd_events, fde);
-		fde->wrapper = NULL;
 		fde->event_ctx = NULL;
 		if (mpx_fde != NULL) {
 			DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde);
-			mpx_fde->wrapper = NULL;
 			mpx_fde->event_ctx = NULL;
 		}
 		return;
@@ -466,11 +462,9 @@ static void epoll_del_event(struct epoll_event_context *epoll_ev, struct tevent_
 			     "fde[%p] mpx_fde[%p] fd[%d] - disabling\n",
 			     fde, mpx_fde, fde->fd);
 		DLIST_REMOVE(epoll_ev->ev->fd_events, fde);
-		fde->wrapper = NULL;
 		fde->event_ctx = NULL;
 		if (mpx_fde != NULL) {
 			DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde);
-			mpx_fde->wrapper = NULL;
 			mpx_fde->event_ctx = NULL;
 		}
 		return;
@@ -517,11 +511,9 @@ static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_
 			     "fde[%p] mpx_fde[%p] fd[%d] - disabling\n",
 			     fde, mpx_fde, fde->fd);
 		DLIST_REMOVE(epoll_ev->ev->fd_events, fde);
-		fde->wrapper = NULL;
 		fde->event_ctx = NULL;
 		if (mpx_fde != NULL) {
 			DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde);
-			mpx_fde->wrapper = NULL;
 			mpx_fde->event_ctx = NULL;
 		}
 		return;
diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c
index b92c45f1ddd..7859cbb00ef 100644
--- a/lib/tevent/tevent_fd.c
+++ b/lib/tevent/tevent_fd.c
@@ -51,7 +51,6 @@ int tevent_common_fd_destructor(struct tevent_fd *fde)
 	if (fde->busy) {
 		return -1;
 	}
-	fde->wrapper = NULL;
 
 	return 0;
 }
@@ -110,8 +109,6 @@ void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
 int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
 				    bool *removed)
 {
-	struct tevent_context *handler_ev = fde->event_ctx;
-
 	if (removed != NULL) {
 		*removed = false;
 	}
@@ -121,31 +118,7 @@ int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
 	}
 
 	fde->busy = true;
-	if (fde->wrapper != NULL) {
-		handler_ev = fde->wrapper->wrap_ev;
-
-		tevent_wrapper_push_use_internal(handler_ev, fde->wrapper);
-		fde->wrapper->ops->before_fd_handler(
-					fde->wrapper->wrap_ev,
-					fde->wrapper->private_state,
-					fde->wrapper->main_ev,
-					fde,
-					flags,
-					fde->handler_name,
-					fde->location);
-	}
-	fde->handler(handler_ev, fde, flags, fde->private_data);
-	if (fde->wrapper != NULL) {
-		fde->wrapper->ops->after_fd_handler(
-					fde->wrapper->wrap_ev,
-					fde->wrapper->private_state,
-					fde->wrapper->main_ev,
-					fde,
-					flags,
-					fde->handler_name,
-					fde->location);
-		tevent_wrapper_pop_use_internal(handler_ev, fde->wrapper);
-	}
+	fde->handler(fde->event_ctx, fde, flags, fde->private_data);
 	fde->busy = false;
 
 	if (fde->destroyed) {
diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c
index ef7d8a566c0..0649d1eacf2 100644
--- a/lib/tevent/tevent_immediate.c
+++ b/lib/tevent/tevent_immediate.c
@@ -100,7 +100,6 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
 {
 	const char *create_location = im->create_location;
 	bool busy = im->busy;
-	struct tevent_wrapper_glue *glue = im->wrapper;
 
 	tevent_common_immediate_cancel(im);
 
@@ -110,7 +109,6 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
 
 	*im = (struct tevent_immediate) {
 		.event_ctx		= ev,
-		.wrapper		= glue,
 		.handler		= handler,
 		.private_data		= private_data,
 		.handler_name		= handler_name,
@@ -130,7 +128,6 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
 int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
 					   bool *removed)
 {
-	struct tevent_context *handler_ev = im->event_ctx;
 	struct tevent_context *ev = im->event_ctx;
 	struct tevent_immediate cur = *im;
 
@@ -150,29 +147,7 @@ int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
 	im->busy = true;
 	im->handler_name = NULL;
 	tevent_common_immediate_cancel(im);
-	if (cur.wrapper != NULL) {
-		handler_ev = cur.wrapper->wrap_ev;
-
-		tevent_wrapper_push_use_internal(handler_ev, cur.wrapper);
-		cur.wrapper->ops->before_immediate_handler(
-					cur.wrapper->wrap_ev,
-					cur.wrapper->private_state,
-					cur.wrapper->main_ev,
-					im,
-					cur.handler_name,
-					cur.schedule_location);
-	}
-	cur.handler(handler_ev, im, cur.private_data);
-	if (cur.wrapper != NULL) {
-		cur.wrapper->ops->after_immediate_handler(
-					cur.wrapper->wrap_ev,
-					cur.wrapper->private_state,
-					cur.wrapper->main_ev,
-					im,
-					cur.handler_name,
-					cur.schedule_location);
-		tevent_wrapper_pop_use_internal(handler_ev, cur.wrapper);
-	}
+	cur.handler(ev, im, cur.private_data);
 	im->busy = false;
 
 	if (im->destroyed) {
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index 5365fce3533..6f0c719cdc1 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -189,7 +189,6 @@ struct tevent_req_profile {
 struct tevent_fd {
 	struct tevent_fd *prev, *next;
 	struct tevent_context *event_ctx;
-	struct tevent_wrapper_glue *wrapper;
 	bool busy;
 	bool destroyed;
 	int fd;
@@ -209,7 +208,6 @@ struct tevent_fd {
 struct tevent_timer {
 	struct tevent_timer *prev, *next;
 	struct tevent_context *event_ctx;
-	struct tevent_wrapper_glue *wrapper;
 	bool busy;
 	bool destroyed;
 	struct timeval next_event;
@@ -226,7 +224,6 @@ struct tevent_timer {
 struct tevent_immediate {
 	struct tevent_immediate *prev, *next;
 	struct tevent_context *event_ctx;
-	struct tevent_wrapper_glue *wrapper;
 	bool busy;
 	bool destroyed;
 	tevent_immediate_handler_t handler;
@@ -244,7 +241,6 @@ struct tevent_immediate {
 struct tevent_signal {
 	struct tevent_signal *prev, *next;
 	struct tevent_context *event_ctx;
-	struct tevent_wrapper_glue *wrapper;
 	bool busy;
 	bool destroyed;
 	int signum;
@@ -337,18 +333,6 @@ struct tevent_context {
 		void *private_data;
 	} tracing;
 
-	struct {
-		/*
-		 * This is used on the main event context
-		 */
-		struct tevent_wrapper_glue *list;
-
-		/*
-		 * This is used on the wrapper event context
-		 */
-		struct tevent_wrapper_glue *glue;
-	} wrapper;
-
 	/*
 	 * an optimization pointer into timer_events
 	 * used by used by common code via
@@ -432,25 +416,6 @@ int tevent_common_invoke_signal_handler(struct tevent_signal *se,
 					int signum, int count, void *siginfo,
 					bool *removed);
 
-struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev);
-
-struct tevent_wrapper_ops;
-
-struct tevent_wrapper_glue {
-	struct tevent_wrapper_glue *prev, *next;
-	struct tevent_context *wrap_ev;
-	struct tevent_context *main_ev;
-	bool busy;
-	bool destroyed;
-	const struct tevent_wrapper_ops *ops;
-	void *private_state;
-};
-
-void tevent_wrapper_push_use_internal(struct tevent_context *ev,
-				      struct tevent_wrapper_glue *wrapper);
-void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr,
-				     struct tevent_wrapper_glue *wrapper);
-
 bool tevent_standard_init(void);
 bool tevent_poll_init(void);
 bool tevent_poll_event_add_fd_internal(struct tevent_context *ev,
diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c
index f4c6c2dbe80..74c418ca421 100644
--- a/lib/tevent/tevent_poll.c
+++ b/lib/tevent/tevent_poll.c
@@ -535,7 +535,6 @@ static int poll_event_loop_poll(struct tevent_context *ev,
 			poll_ev->fdes[idx] = NULL;
 			poll_ev->deleted = true;
 			DLIST_REMOVE(ev->fd_events, fde);
-			fde->wrapper = NULL;
 			fde->event_ctx = NULL;
 			continue;
 		}
@@ -587,7 +586,6 @@ static int poll_event_loop_poll(struct tevent_context *ev,
 			poll_ev->deleted = true;
 			if (fde != NULL) {
 				DLIST_REMOVE(ev->fd_events, fde);
-				fde->wrapper = NULL;
 				fde->event_ctx = NULL;
 			}
 		}
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index 5ca0b8d2ab1..a787f97b964 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -216,7 +216,6 @@ static int tevent_signal_destructor(struct tevent_signal *se)
 	if (se->busy) {
 		return -1;
 	}
-	se->wrapper = NULL;
 
 	return 0;
 }
@@ -339,7 +338,6 @@ int tevent_common_invoke_signal_handler(struct tevent_signal *se,
 					int signum, int count, void *siginfo,
 					bool *removed)
 {
-	struct tevent_context *handler_ev = se->event_ctx;
 	bool remove = false;
 
 	if (removed != NULL) {
@@ -351,35 +349,7 @@ int tevent_common_invoke_signal_handler(struct tevent_signal *se,
 	}
 
 	se->busy = true;
-	if (se->wrapper != NULL) {
-		handler_ev = se->wrapper->wrap_ev;
-
-		tevent_wrapper_push_use_internal(handler_ev, se->wrapper);
-		se->wrapper->ops->before_signal_handler(
-						se->wrapper->wrap_ev,
-						se->wrapper->private_state,
-						se->wrapper->main_ev,
-						se,
-						signum,
-						count,
-						siginfo,
-						se->handler_name,
-						se->location);
-	}
-	se->handler(handler_ev, se, signum, count, siginfo, se->private_data);
-	if (se->wrapper != NULL) {
-		se->wrapper->ops->after_signal_handler(
-						se->wrapper->wrap_ev,
-						se->wrapper->private_state,
-						se->wrapper->main_ev,
-						se,
-						signum,
-						count,
-						siginfo,
-						se->handler_name,
-						se->location);
-		tevent_wrapper_pop_use_internal(handler_ev, se->wrapper);
-	}
+	se->handler(se->event_ctx, se, signum, count, siginfo, se->private_data);
 	se->busy = false;
 
 #ifdef SA_RESETHAND
diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c
index 21a9b686ba9..5d4e0c42676 100644
--- a/lib/tevent/tevent_threads.c
+++ b/lib/tevent/tevent_threads.c
@@ -217,18 +217,6 @@ struct tevent_thread_proxy *tevent_thread_proxy_create(
 	int pipefds[2];
 	struct tevent_thread_proxy *tp;
 
-	if (dest_ev_ctx->wrapper.glue != NULL) {
-		/*
-		 * stacking of wrappers is not supported
-		 */
-		tevent_debug(dest_ev_ctx->wrapper.glue->main_ev,
-			     TEVENT_DEBUG_FATAL,
-			     "%s() not allowed on a wrapper context\n",
-			     __func__);
-		errno = EINVAL;
-		return NULL;
-	}
-
 	tp = talloc_zero(dest_ev_ctx, struct tevent_thread_proxy);
 	if (tp == NULL) {
 		return NULL;
@@ -387,11 +375,10 @@ void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp,
 static int tevent_threaded_context_destructor(
 	struct tevent_threaded_context *tctx)
 {
-	struct tevent_context *main_ev = tevent_wrapper_main_ev(tctx->event_ctx);
 	int ret;
 
-	if (main_ev != NULL) {
-		DLIST_REMOVE(main_ev->threaded_contexts, tctx);
+	if (tctx->event_ctx != NULL) {
+		DLIST_REMOVE(tctx->event_ctx->threaded_contexts, tctx);
 	}
 
 	/*
@@ -423,11 +410,10 @@ struct tevent_threaded_context *tevent_threaded_context_create(
 	TALLOC_CTX *mem_ctx, struct tevent_context *ev)
 {
 #ifdef HAVE_PTHREAD
-	struct tevent_context *main_ev = tevent_wrapper_main_ev(ev);
 	struct tevent_threaded_context *tctx;
 	int ret;
 
-	ret = tevent_common_wakeup_init(main_ev);
+	ret = tevent_common_wakeup_init(ev);
 	if (ret != 0) {
 		errno = ret;
 		return NULL;
@@ -445,7 +431,7 @@ struct tevent_threaded_context *tevent_threaded_context_create(
 		return NULL;
 	}
 
-	DLIST_ADD(main_ev->threaded_contexts, tctx);
+	DLIST_ADD(ev->threaded_contexts, tctx);
 	talloc_set_destructor(tctx, tevent_threaded_context_destructor);
 
 	return tctx;
@@ -472,8 +458,7 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
 {
 #ifdef HAVE_PTHREAD
 	const char *create_location = im->create_location;
-	struct tevent_context *main_ev = NULL;
-	struct tevent_wrapper_glue *glue = tctx->event_ctx->wrapper.glue;
+	struct tevent_context *ev;
 	int ret, wakeup_fd;
 
 	ret = pthread_mutex_lock(&tctx->event_ctx_mutex);
@@ -481,7 +466,9 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
 		abort();
 	}
 
-	if (tctx->event_ctx == NULL) {
+	ev = tctx->event_ctx;
+
+	if (ev == NULL) {
 		/*
 		 * Our event context is already gone.
 		 */
@@ -502,11 +489,8 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
 		abort();
 	}
 
-	main_ev = tevent_wrapper_main_ev(tctx->event_ctx);
-
 	*im = (struct tevent_immediate) {
-		.event_ctx		= tctx->event_ctx,
-		.wrapper		= glue,
+		.event_ctx		= ev,
 		.handler		= handler,
 		.private_data		= private_data,
 		.handler_name		= handler_name,
@@ -522,15 +506,15 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
 	 */
 	talloc_set_destructor(im, tevent_threaded_schedule_immediate_destructor);
 
-	ret = pthread_mutex_lock(&main_ev->scheduled_mutex);
+	ret = pthread_mutex_lock(&ev->scheduled_mutex);
 	if (ret != 0) {
 		abort();
 	}
 
-	DLIST_ADD_END(main_ev->scheduled_immediates, im);
-	wakeup_fd = main_ev->wakeup_fd;
+	DLIST_ADD_END(ev->scheduled_immediates, im);
+	wakeup_fd = ev->wakeup_fd;
 
-	ret = pthread_mutex_unlock(&main_ev->scheduled_mutex);
+	ret = pthread_mutex_unlock(&ev->scheduled_mutex);
 	if (ret != 0) {
 		abort();
 	}
diff --git a/lib/tevent/tevent_timed.c b/lib/tevent/tevent_timed.c
index b521f096c48..cb948d4ba29 100644
--- a/lib/tevent/tevent_timed.c
+++ b/lib/tevent/tevent_timed.c
@@ -157,7 +157,6 @@ static int tevent_common_timed_destructor(struct tevent_timer *te)
 	if (te->busy) {
 		return -1;
 	}
-	te->wrapper = NULL;
 
 	return 0;
 }
@@ -320,8 +319,6 @@ int tevent_common_invoke_timer_handler(struct tevent_timer *te,
 				       struct timeval current_time,
 				       bool *removed)
 {
-	struct tevent_context *handler_ev = te->event_ctx;
-
 	if (removed != NULL) {
 		*removed = false;
 	}
@@ -352,40 +349,13 @@ int tevent_common_invoke_timer_handler(struct tevent_timer *te,
 	 * otherwise we pass the current time
 	 */
 	te->busy = true;
-	if (te->wrapper != NULL) {
-		handler_ev = te->wrapper->wrap_ev;
-
-		tevent_wrapper_push_use_internal(handler_ev, te->wrapper);
-		te->wrapper->ops->before_timer_handler(
-					te->wrapper->wrap_ev,
-					te->wrapper->private_state,
-					te->wrapper->main_ev,
-					te,
-					te->next_event,
-					current_time,
-					te->handler_name,
-					te->location);
-	}
-	te->handler(handler_ev, te, current_time, te->private_data);
-	if (te->wrapper != NULL) {
-		te->wrapper->ops->after_timer_handler(
-					te->wrapper->wrap_ev,
-					te->wrapper->private_state,
-					te->wrapper->main_ev,
-					te,
-					te->next_event,
-					current_time,
-					te->handler_name,
-					te->location);
-		tevent_wrapper_pop_use_internal(handler_ev, te->wrapper);
-	}
+	te->handler(te->event_ctx, te, current_time, te->private_data);
 	te->busy = false;
 
 	tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE,
 		     "Ending timer event %p \"%s\"\n",
 		     te, te->handler_name);
 
-	te->wrapper = NULL;
 	te->event_ctx = NULL;
 	talloc_set_destructor(te, NULL);
 	TALLOC_FREE(te);
diff --git a/lib/tevent/tevent_wrapper.c b/lib/tevent/tevent_wrapper.c
deleted file mode 100644
index 05c4c06968a..00000000000
--- a/lib/tevent/tevent_wrapper.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
-   Infrastructure for event context wrappers
-
-   Copyright (C) Stefan Metzmacher 2014
-
-     ** NOTE! The following LGPL license applies to the tevent
-     ** library. This does NOT imply that all of Samba is released
-     ** under the LGPL
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 3 of the License, or (at your option) any later version.
-
-   This library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "replace.h"
-#ifdef HAVE_PTHREAD
-#include "system/threads.h"
-#endif
-#include "tevent.h"
-#include "tevent_internal.h"
-#include "tevent_util.h"
-
-static int tevent_wrapper_glue_context_init(struct tevent_context *ev)
-{
-	tevent_abort(ev, "tevent_wrapper_glue_context_init() called");
-	errno = ENOSYS;
-	return -1;
-}
-
-static struct tevent_fd *tevent_wrapper_glue_add_fd(struct tevent_context *ev,
-						    TALLOC_CTX *mem_ctx,
-						    int fd, uint16_t flags,
-						    tevent_fd_handler_t handler,
-						    void *private_data,
-						    const char *handler_name,
-						    const char *location)
-{
-	struct tevent_wrapper_glue *glue = ev->wrapper.glue;
-	struct tevent_fd *fde = NULL;
-
-	if (glue->destroyed) {
-		tevent_abort(ev, "add_fd wrapper use after free");
-		return NULL;
-	}
-
-	if (glue->main_ev == NULL) {
-		errno = EINVAL;
-		return NULL;
-	}
-
-	fde = _tevent_add_fd(glue->main_ev, mem_ctx, fd, flags,
-			     handler, private_data,
-			     handler_name, location);
-	if (fde == NULL) {
-		return NULL;
-	}
-
-	fde->wrapper = glue;
-
-	return fde;
-}
-
-static struct tevent_timer *tevent_wrapper_glue_add_timer(struct tevent_context *ev,
-							  TALLOC_CTX *mem_ctx,
-							  struct timeval next_event,
-							  tevent_timer_handler_t handler,
-							  void *private_data,
-							  const char *handler_name,
-							  const char *location)
-{
-	struct tevent_wrapper_glue *glue = ev->wrapper.glue;
-	struct tevent_timer *te = NULL;
-
-	if (glue->destroyed) {
-		tevent_abort(ev, "add_timer wrapper use after free");
-		return NULL;
-	}
-
-	if (glue->main_ev == NULL) {
-		errno = EINVAL;
-		return NULL;
-	}
-
-	te = _tevent_add_timer(glue->main_ev, mem_ctx, next_event,
-			       handler, private_data,
-			       handler_name, location);
-	if (te == NULL) {
-		return NULL;
-	}
-
-	te->wrapper = glue;
-
-	return te;
-}
-
-static void tevent_wrapper_glue_schedule_immediate(struct tevent_immediate *im,
-						   struct tevent_context *ev,
-						   tevent_immediate_handler_t handler,
-						   void *private_data,
-						   const char *handler_name,
-						   const char *location)
-{
-	struct tevent_wrapper_glue *glue = ev->wrapper.glue;
-
-	if (glue->destroyed) {
-		tevent_abort(ev, "scheduke_immediate wrapper use after free");
-		return;
-	}
-
-	if (glue->main_ev == NULL) {
-		tevent_abort(ev, location);
-		errno = EINVAL;
-		return;
-	}
-
-	_tevent_schedule_immediate(im, glue->main_ev,
-				   handler, private_data,
-				   handler_name, location);
-
-	im->wrapper = glue;
-
-	return;
-}
-
-static struct tevent_signal *tevent_wrapper_glue_add_signal(struct tevent_context *ev,
-							    TALLOC_CTX *mem_ctx,
-							    int signum, int sa_flags,
-							    tevent_signal_handler_t handler,
-							    void *private_data,
-							    const char *handler_name,
-							    const char *location)
-{
-	struct tevent_wrapper_glue *glue = ev->wrapper.glue;
-	struct tevent_signal *se = NULL;
-
-	if (glue->destroyed) {
-		tevent_abort(ev, "add_signal wrapper use after free");
-		return NULL;
-	}
-
-	if (glue->main_ev == NULL) {
-		errno = EINVAL;
-		return NULL;
-	}
-
-	se = _tevent_add_signal(glue->main_ev, mem_ctx,
-				signum, sa_flags,
-				handler, private_data,
-				handler_name, location);
-	if (se == NULL) {
-		return NULL;
-	}
-
-	se->wrapper = glue;
-
-	return se;
-}
-
-static int tevent_wrapper_glue_loop_once(struct tevent_context *ev, const char *location)
-{
-	tevent_abort(ev, "tevent_wrapper_glue_loop_once() called");
-	errno = ENOSYS;
-	return -1;
-}
-
-static int tevent_wrapper_glue_loop_wait(struct tevent_context *ev, const char *location)
-{
-	tevent_abort(ev, "tevent_wrapper_glue_loop_wait() called");
-	errno = ENOSYS;
-	return -1;
-}
-
-static const struct tevent_ops tevent_wrapper_glue_ops = {
-	.context_init		= tevent_wrapper_glue_context_init,
-	.add_fd			= tevent_wrapper_glue_add_fd,
-	.set_fd_close_fn	= tevent_common_fd_set_close_fn,
-	.get_fd_flags		= tevent_common_fd_get_flags,
-	.set_fd_flags		= tevent_common_fd_set_flags,
-	.add_timer		= tevent_wrapper_glue_add_timer,
-	.schedule_immediate	= tevent_wrapper_glue_schedule_immediate,
-	.add_signal		= tevent_wrapper_glue_add_signal,
-	.loop_once		= tevent_wrapper_glue_loop_once,
-	.loop_wait		= tevent_wrapper_glue_loop_wait,
-};
-
-static int tevent_wrapper_context_destructor(struct tevent_context *wrap_ev)
-{
-	struct tevent_wrapper_glue *glue = wrap_ev->wrapper.glue;
-	struct tevent_context *main_ev = NULL;
-	struct tevent_fd *fd = NULL, *fn = NULL;
-	struct tevent_timer *te = NULL, *tn = NULL;
-	struct tevent_immediate *ie = NULL, *in = NULL;
-	struct tevent_signal *se = NULL, *sn = NULL;
-#ifdef HAVE_PTHREAD
-	struct tevent_threaded_context *tctx = NULL, *tctxn = NULL;
-#endif
-
-	if (glue == NULL) {
-		tevent_abort(wrap_ev,
-			"tevent_wrapper_context_destructor() active on main");
-	}
-
-	if (glue->destroyed && glue->busy) {
-		tevent_common_check_double_free(wrap_ev,
-			"tevent_context wrapper double free");
-	}
-	glue->destroyed = true;
-
-	if (glue->busy) {
-		return -1;
-	}
-
-	main_ev = glue->main_ev;
-	if (main_ev == NULL) {
-		return 0;
-	}
-
-	tevent_debug(wrap_ev, TEVENT_DEBUG_TRACE,
-		     "Destroying wrapper context %p \"%s\"\n",
-		     wrap_ev, talloc_get_name(glue->private_state));
-
-	glue->main_ev = NULL;
-	DLIST_REMOVE(main_ev->wrapper.list, glue);
-
-#ifdef HAVE_PTHREAD
-	for (tctx = main_ev->threaded_contexts; tctx != NULL; tctx = tctxn) {
-		int ret;
-
-		tctxn = tctx->next;
-
-		if (tctx->event_ctx != glue->wrap_ev) {
-			continue;
-		}
-
-		ret = pthread_mutex_lock(&tctx->event_ctx_mutex);
-		if (ret != 0) {
-			abort();
-		}
-
-		/*
-		 * Indicate to the thread that the tevent_context is
-		 * gone. The counterpart of this is in
-		 * _tevent_threaded_schedule_immediate, there we read
-		 * this under the threaded_context's mutex.
-		 */
-
-		tctx->event_ctx = NULL;
-
-		ret = pthread_mutex_unlock(&tctx->event_ctx_mutex);
-		if (ret != 0) {
-			abort();
-		}
-
-		DLIST_REMOVE(main_ev->threaded_contexts, tctx);
-	}
-#endif
-
-	for (fd = main_ev->fd_events; fd; fd = fn) {
-		fn = fd->next;
-
-		if (fd->wrapper != glue) {
-			continue;
-		}
-
-		tevent_fd_set_flags(fd, 0);
-
-		fd->wrapper = NULL;
-		fd->event_ctx = NULL;
-		DLIST_REMOVE(main_ev->fd_events, fd);
-	}
-
-	for (te = main_ev->timer_events; te; te = tn) {
-		tn = te->next;
-
-		if (te->wrapper != glue) {
-			continue;
-		}
-
-		te->wrapper = NULL;
-		te->event_ctx = NULL;
-
-		if (main_ev->last_zero_timer == te) {
-			main_ev->last_zero_timer = DLIST_PREV(te);
-		}
-		DLIST_REMOVE(main_ev->timer_events, te);
-	}
-
-	for (ie = main_ev->immediate_events; ie; ie = in) {
-		in = ie->next;
-
-		if (ie->wrapper != glue) {
-			continue;
-		}
-
-		ie->wrapper = NULL;
-		ie->event_ctx = NULL;
-		ie->cancel_fn = NULL;
-		DLIST_REMOVE(main_ev->immediate_events, ie);
-	}
-
-	for (se = main_ev->signal_events; se; se = sn) {
-		sn = se->next;
-
-		if (se->wrapper != glue) {
-			continue;
-		}
-
-		se->wrapper = NULL;
-		tevent_cleanup_pending_signal_handlers(se);
-	}
-
-	return 0;
-}
-
-struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev,
-						TALLOC_CTX *mem_ctx,
-						const struct tevent_wrapper_ops *ops,
-						void *pstate,
-						size_t psize,
-						const char *type,
-						const char *location)
-{
-	void **ppstate = (void **)pstate;
-	struct tevent_context *ev = NULL;
-
-	if (main_ev->wrapper.glue != NULL) {
-		/*
-		 * stacking of wrappers is not supported
-		 */
-		tevent_debug(main_ev->wrapper.glue->main_ev, TEVENT_DEBUG_FATAL,
-			     "%s: %s() stacking not allowed\n",
-			     __func__, location);
-		errno = EINVAL;
-		return NULL;
-	}
-
-	if (main_ev->nesting.allowed) {
-		/*
-		 * wrappers conflict with nesting
-		 */
-		tevent_debug(main_ev->wrapper.glue->main_ev, TEVENT_DEBUG_FATAL,
-			     "%s: %s() conflicts with nesting\n",
-			     __func__, location);
-		errno = EINVAL;
-		return NULL;
-	}
-
-	ev = talloc_zero(mem_ctx, struct tevent_context);
-	if (ev == NULL) {
-		return NULL;
-	}
-	ev->ops = &tevent_wrapper_glue_ops;
-
-	ev->wrapper.glue = talloc_zero(ev, struct tevent_wrapper_glue);
-	if (ev->wrapper.glue == NULL) {
-		talloc_free(ev);
-		return NULL;
-	}
-
-	talloc_set_destructor(ev, tevent_wrapper_context_destructor);
-
-	ev->wrapper.glue->wrap_ev = ev;
-	ev->wrapper.glue->main_ev = main_ev;
-	ev->wrapper.glue->ops = ops;
-	ev->wrapper.glue->private_state = talloc_size(ev->wrapper.glue, psize);
-	if (ev->wrapper.glue->private_state == NULL) {
-		talloc_free(ev);
-		return NULL;
-	}
-	talloc_set_name_const(ev->wrapper.glue->private_state, type);
-
-	DLIST_ADD_END(main_ev->wrapper.list, ev->wrapper.glue);
-
-	*ppstate = ev->wrapper.glue->private_state;
-	return ev;
-}
-
-bool tevent_context_is_wrapper(struct tevent_context *ev)
-{
-	if (ev->wrapper.glue != NULL) {
-		return true;
-	}
-
-	return false;
-}
-
-_PRIVATE_
-struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev)
-{
-	if (ev == NULL) {
-		return NULL;
-	}
-
-	if (ev->wrapper.glue == NULL) {
-		return ev;
-	}
-
-	return ev->wrapper.glue->main_ev;
-}
-
-/*
- * 32 stack elements should be more than enough
- *
- * e.g. Samba uses just 8 elements for [un]become_{root,user}()
- */
-#define TEVENT_WRAPPER_STACK_SIZE 32
-
-static struct tevent_wrapper_stack {
-	const void *ev_ptr;
-	const struct tevent_wrapper_glue *wrapper;
-} wrapper_stack[TEVENT_WRAPPER_STACK_SIZE];
-
-static size_t wrapper_stack_idx;
-
-_PRIVATE_
-void tevent_wrapper_push_use_internal(struct tevent_context *ev,
-				      struct tevent_wrapper_glue *wrapper)
-{
-	/*
-	 * ev and wrapper need to belong together!
-	 * It's also fine to only have a raw ev
-	 * without a wrapper.
-	 */
-	if (unlikely(ev->wrapper.glue != wrapper)) {
-		tevent_abort(ev, "tevent_wrapper_push_use_internal() invalid arguments");
-		return;
-	}
-
-	if (wrapper != NULL) {
-		if (unlikely(wrapper->busy)) {
-			tevent_abort(ev, "wrapper already busy!");
-			return;
-		}
-		wrapper->busy = true;
-	}
-
-	if (unlikely(wrapper_stack_idx >= TEVENT_WRAPPER_STACK_SIZE)) {
-		tevent_abort(ev, "TEVENT_WRAPPER_STACK_SIZE overflow");
-		return;
-	}
-
-	wrapper_stack[wrapper_stack_idx] = (struct tevent_wrapper_stack) {
-		.ev_ptr = ev,
-		.wrapper = wrapper,
-	};
-	wrapper_stack_idx++;
-}
-
-_PRIVATE_
-void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr,
-				     struct tevent_wrapper_glue *wrapper)
-{
-	struct tevent_context *main_ev = NULL;
-
-	/*
-	 * Note that __ev_ptr might a a stale pointer and should not
-	 * be touched, we just compare the pointer value in order
-	 * to enforce the stack order.
-	 */
-
-	if (wrapper != NULL) {
-		main_ev = wrapper->main_ev;
-	}
-
-	if (unlikely(wrapper_stack_idx == 0)) {
-		tevent_abort(main_ev, "tevent_wrapper stack already empty");
-		return;
-	}
-	wrapper_stack_idx--;
-
-	if (wrapper != NULL) {
-		wrapper->busy = false;
-	}
-
-	if (wrapper_stack[wrapper_stack_idx].ev_ptr != __ev_ptr) {
-		tevent_abort(main_ev, "tevent_wrapper_pop_use mismatch ev!");
-		return;
-	}
-	if (wrapper_stack[wrapper_stack_idx].wrapper != wrapper) {
-		tevent_abort(main_ev, "tevent_wrapper_pop_use mismatch wrap!");
-		return;
-	}
-
-	if (wrapper == NULL) {
-		return;
-	}
-
-	if (wrapper->destroyed) {
-		/*
-		 * Notice that we can't use TALLOC_FREE()
-		 * here because wrapper is a talloc child
-		 * of wrapper->wrap_ev.
-		 */
-		talloc_free(wrapper->wrap_ev);
-	}
-}
-
-bool _tevent_context_push_use(struct tevent_context *ev,
-			      const char *location)
-{
-	bool ok;
-
-	if (ev->wrapper.glue == NULL) {
-		tevent_wrapper_push_use_internal(ev, NULL);
-		return true;
-	}
-
-	if (ev->wrapper.glue->main_ev == NULL) {
-		return false;
-	}
-
-	tevent_wrapper_push_use_internal(ev, ev->wrapper.glue);
-	ok = ev->wrapper.glue->ops->before_use(ev->wrapper.glue->wrap_ev,
-					       ev->wrapper.glue->private_state,
-					       ev->wrapper.glue->main_ev,
-					       location);
-	if (!ok) {
-		tevent_wrapper_pop_use_internal(ev, ev->wrapper.glue);
-		return false;
-	}
-
-	return true;
-}
-
-void _tevent_context_pop_use(struct tevent_context *ev,
-			     const char *location)
-{
-	tevent_wrapper_pop_use_internal(ev, ev->wrapper.glue);
-
-	if (ev->wrapper.glue == NULL) {
-		return;
-	}
-
-	if (ev->wrapper.glue->main_ev == NULL) {
-		return;
-	}
-
-	ev->wrapper.glue->ops->after_use(ev->wrapper.glue->wrap_ev,
-					 ev->wrapper.glue->private_state,
-					 ev->wrapper.glue->main_ev,
-					 location);
-}
-
-bool tevent_context_same_loop(struct tevent_context *ev1,
-			      struct tevent_context *ev2)
-{
-	struct tevent_context *main_ev1 = tevent_wrapper_main_ev(ev1);
-	struct tevent_context *main_ev2 = tevent_wrapper_main_ev(ev2);
-
-	if (main_ev1 == NULL) {
-		return false;
-	}
-
-	if (main_ev1 == main_ev2) {
-		return true;
-	}
-
-	return false;
-}
diff --git a/lib/tevent/wscript b/lib/tevent/wscript
index 9d6b671437e..b51c4640c7d 100644
--- a/lib/tevent/wscript
+++ b/lib/tevent/wscript
@@ -79,7 +79,7 @@ samba_dist.DIST_DIRS('lib/tevent:. lib/replace:lib/replace lib/talloc:lib/talloc
     bld.RECURSE('lib/talloc')
 
     SRC = '''tevent.c tevent_debug.c tevent_fd.c tevent_immediate.c
-             tevent_queue.c tevent_req.c tevent_wrapper.c
+             tevent_queue.c tevent_req.c
              tevent_poll.c tevent_threads.c
              tevent_signal.c tevent_standard.c tevent_timed.c tevent_util.c tevent_wakeup.c'''
 
-- 
2.17.2


From 2953c10e4291e518ac6e6617339affadf9eb4322 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 27 Dec 2018 14:44:26 +0100
Subject: [PATCH 7/7] tevent: version 1.0.0

* remove tevent_context_same_loop() function
* remove tevent_context_wrapper_create() infrastructure
---
 lib/tevent/ABI/tevent-0.9.37.sigs |   5 ++
 lib/tevent/ABI/tevent-1.0.0.sigs  | 121 ++++++++++++++++++++++++++++++
 lib/tevent/wscript                |   2 +-
 3 files changed, 127 insertions(+), 1 deletion(-)
 create mode 100644 lib/tevent/ABI/tevent-1.0.0.sigs

diff --git a/lib/tevent/ABI/tevent-0.9.37.sigs b/lib/tevent/ABI/tevent-0.9.37.sigs
index 5929dcc3e8c..f6227db5c93 100644
--- a/lib/tevent/ABI/tevent-0.9.37.sigs
+++ b/lib/tevent/ABI/tevent-0.9.37.sigs
@@ -1,6 +1,9 @@
 _tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *)
 _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
 _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+_tevent_context_pop_use: void (struct tevent_context *, const char *)
+_tevent_context_push_use: bool (struct tevent_context *, const char *)
+_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *)
 _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *)
 _tevent_loop_once: int (struct tevent_context *, const char *)
 _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *)
@@ -47,6 +50,8 @@ tevent_common_wakeup_init: int (struct tevent_context *)
 tevent_context_init: struct tevent_context *(TALLOC_CTX *)
 tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *)
 tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *)
+tevent_context_is_wrapper: bool (struct tevent_context *)
+tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *)
 tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...)
 tevent_fd_get_flags: uint16_t (struct tevent_fd *)
 tevent_fd_set_auto_close: void (struct tevent_fd *)
diff --git a/lib/tevent/ABI/tevent-1.0.0.sigs b/lib/tevent/ABI/tevent-1.0.0.sigs
new file mode 100644
index 00000000000..5929dcc3e8c
--- /dev/null
+++ b/lib/tevent/ABI/tevent-1.0.0.sigs
@@ -0,0 +1,121 @@
+_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *)
+_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
+_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *)
+_tevent_loop_once: int (struct tevent_context *, const char *)
+_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *)
+_tevent_loop_wait: int (struct tevent_context *, const char *)
+_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *)
+_tevent_req_callback_data: void *(struct tevent_req *)
+_tevent_req_cancel: bool (struct tevent_req *, const char *)
+_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *)
+_tevent_req_data: void *(struct tevent_req *)
+_tevent_req_done: void (struct tevent_req *, const char *)
+_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *)
+_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *)
+_tevent_req_notify_callback: void (struct tevent_req *, const char *)
+_tevent_req_oom: void (struct tevent_req *, const char *)
+_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *)
+_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *)
+tevent_abort: void (struct tevent_context *, const char *)
+tevent_backend_list: const char **(TALLOC_CTX *)
+tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *)
+tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *)
+tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
+tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+tevent_common_check_double_free: void (TALLOC_CTX *, const char *)
+tevent_common_check_signal: int (struct tevent_context *)
+tevent_common_context_destructor: int (struct tevent_context *)
+tevent_common_fd_destructor: int (struct tevent_fd *)
+tevent_common_fd_get_flags: uint16_t (struct tevent_fd *)
+tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t)
+tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t)
+tevent_common_have_events: bool (struct tevent_context *)
+tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *)
+tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *)
+tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *)
+tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *)
+tevent_common_loop_immediate: bool (struct tevent_context *)
+tevent_common_loop_timer_delay: struct timeval (struct tevent_context *)
+tevent_common_loop_wait: int (struct tevent_context *, const char *)
+tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *)
+tevent_common_threaded_activate_immediate: void (struct tevent_context *)
+tevent_common_wakeup: int (struct tevent_context *)
+tevent_common_wakeup_fd: int (int)
+tevent_common_wakeup_init: int (struct tevent_context *)
+tevent_context_init: struct tevent_context *(TALLOC_CTX *)
+tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *)
+tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *)
+tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...)
+tevent_fd_get_flags: uint16_t (struct tevent_fd *)
+tevent_fd_set_auto_close: void (struct tevent_fd *)
+tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t)
+tevent_fd_set_flags: void (struct tevent_fd *, uint16_t)
+tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *)
+tevent_loop_allow_nesting: void (struct tevent_context *)
+tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *)
+tevent_num_signals: size_t (void)
+tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *)
+tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *)
+tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *)
+tevent_queue_entry_untrigger: void (struct tevent_queue_entry *)
+tevent_queue_length: size_t (struct tevent_queue *)
+tevent_queue_running: bool (struct tevent_queue *)
+tevent_queue_start: void (struct tevent_queue *)
+tevent_queue_stop: void (struct tevent_queue *)
+tevent_queue_wait_recv: bool (struct tevent_req *)
+tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *)
+tevent_re_initialise: int (struct tevent_context *)
+tevent_register_backend: bool (const char *, const struct tevent_ops *)
+tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *)
+tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *)
+tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *)
+tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *)
+tevent_req_is_in_progress: bool (struct tevent_req *)
+tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *)
+tevent_req_poll: bool (struct tevent_req *, struct tevent_context *)
+tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *)
+tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *)
+tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **)
+tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *)
+tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **)
+tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *)
+tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *)
+tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *)
+tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *)
+tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *)
+tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *)
+tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval)
+tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t)
+tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval)
+tevent_req_received: void (struct tevent_req *)
+tevent_req_reset_endtime: void (struct tevent_req *)
+tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *)
+tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn)
+tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn)
+tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval)
+tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn)
+tevent_req_set_profile: bool (struct tevent_req *)
+tevent_sa_info_queue_count: size_t (void)
+tevent_set_abort_fn: void (void (*)(const char *))
+tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *)
+tevent_set_debug_stderr: int (struct tevent_context *)
+tevent_set_default_backend: void (const char *)
+tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *)
+tevent_signal_support: bool (struct tevent_context *)
+tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *)
+tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *)
+tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *)
+tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t)
+tevent_timeval_compare: int (const struct timeval *, const struct timeval *)
+tevent_timeval_current: struct timeval (void)
+tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t)
+tevent_timeval_is_zero: bool (const struct timeval *)
+tevent_timeval_set: struct timeval (uint32_t, uint32_t)
+tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *)
+tevent_timeval_zero: struct timeval (void)
+tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point)
+tevent_update_timer: void (struct tevent_timer *, struct timeval)
+tevent_wakeup_recv: bool (struct tevent_req *)
+tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval)
diff --git a/lib/tevent/wscript b/lib/tevent/wscript
index b51c4640c7d..4d5fc572d41 100644
--- a/lib/tevent/wscript
+++ b/lib/tevent/wscript
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 APPNAME = 'tevent'
-VERSION = '0.9.37'
+VERSION = '1.0.0'
 
 import sys, os
 
-- 
2.17.2



More information about the samba-technical mailing list