[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1763-ge744b0a

Volker Lendecke vlendec at samba.org
Sun May 24 13:00:36 GMT 2009


The branch, master has been updated
       via  e744b0af683b459d5eeaf65f4f8d95b0e10c8ec6 (commit)
       via  7043ef2a794e5bbd9ea8e738fb3dcb390b237351 (commit)
       via  f528dbcf2e28ab9f5fd1e0a56b64a31514105cf3 (commit)
       via  9de2efaa5b197c46508c36f50bbe6c5026f2953a (commit)
       via  4906d7fc679210555871bcb080e504fcc11734c6 (commit)
       via  e337124c555aee32f0d075b8008c77da3065c1e1 (commit)
       via  6492ffd8df0d8bd847c977396edd070b8be65f54 (commit)
       via  a8e02b591b0c82c1f75f4f51bc683d9775f13d54 (commit)
       via  1a69ba894514dd4eaba9fa015bdf930a5b620fea (commit)
      from  8c39931eb3edfd685fb9f9a9b28bd89bc2deede5 (commit)

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


- Log -----------------------------------------------------------------
commit e744b0af683b459d5eeaf65f4f8d95b0e10c8ec6
Author: Volker Lendecke <vl at samba.org>
Date:   Wed May 20 14:18:23 2009 +0200

    use epoll for local-wbclient test

commit 7043ef2a794e5bbd9ea8e738fb3dcb390b237351
Author: Volker Lendecke <vl at samba.org>
Date:   Sun May 24 13:22:26 2009 +0200

    Don't limit the number of retries in wb_trans.
    
    This is better done with a tevent_req_set_endtime the caller should issue.

commit f528dbcf2e28ab9f5fd1e0a56b64a31514105cf3
Author: Volker Lendecke <vl at samba.org>
Date:   Sun May 24 13:18:34 2009 +0200

    Don't set a timeout deep inside wb_connect

commit 9de2efaa5b197c46508c36f50bbe6c5026f2953a
Author: Volker Lendecke <vl at samba.org>
Date:   Sun May 24 13:14:12 2009 +0200

    Change async_connect to use connect instead of getsockopt to get the error
    
    On my Linux box, this is definitely the more reliable strategy with unix domain
    sockets, and according to my tests it also works correctly with TCP sockets.

commit 4906d7fc679210555871bcb080e504fcc11734c6
Author: Volker Lendecke <vl at samba.org>
Date:   Fri May 22 22:30:09 2009 +0200

    Do queueing in wbclient.c
    
    The _trigger fn must know about wbc_context, while we were waiting in the
    queue the fd might have changed

commit e337124c555aee32f0d075b8008c77da3065c1e1
Author: Volker Lendecke <vl at samba.org>
Date:   Fri May 22 19:29:46 2009 +0200

    Fix closed_fd(): select returning 0 means no fd listening

commit 6492ffd8df0d8bd847c977396edd070b8be65f54
Author: Volker Lendecke <vl at samba.org>
Date:   Sun May 10 10:49:39 2009 +0200

    Fix wb_simple_trans queueing

commit a8e02b591b0c82c1f75f4f51bc683d9775f13d54
Author: Volker Lendecke <vl at samba.org>
Date:   Sat May 23 16:10:54 2009 +0200

    Add "err_on_readability" to writev_send
    
    A socket where the other side has closed only becomes readable. To catch
    errors early when sitting in a pure writev, we need to also test for
    readability.

commit 1a69ba894514dd4eaba9fa015bdf930a5b620fea
Author: Volker Lendecke <vl at samba.org>
Date:   Sun May 10 10:49:18 2009 +0200

    Allow NULL queue to writev_send

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

Summary of changes:
 lib/async_req/async_sock.c        |   73 +++++++++++++++++++++---------
 lib/async_req/async_sock.h        |    1 +
 source3/lib/wb_reqtrans.c         |   49 ++------------------
 source3/lib/wbclient.c            |   89 ++++++++++++++++++++++++------------
 source3/libsmb/async_smb.c        |    4 +-
 source3/rpc_server/srv_pipe_hnd.c |    2 +-
 source3/torture/torture.c         |    2 +-
 7 files changed, 121 insertions(+), 99 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index 5439728..fe71b29 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -167,6 +167,8 @@ struct async_connect_state {
 	int result;
 	int sys_errno;
 	long old_sockflags;
+	socklen_t address_len;
+	struct sockaddr_storage address;
 };
 
 static void async_connect_connected(struct tevent_context *ev,
@@ -209,6 +211,13 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
 	state->fd = fd;
 	state->sys_errno = 0;
 
+	state->address_len = address_len;
+	if (address_len > sizeof(state->address)) {
+		errno = EINVAL;
+		goto post_errno;
+	}
+	memcpy(&state->address, address, address_len);
+
 	state->old_sockflags = fcntl(fd, F_GETFL, 0);
 	if (state->old_sockflags == -1) {
 		goto post_errno;
@@ -270,8 +279,6 @@ static void async_connect_connected(struct tevent_context *ev,
 	struct async_connect_state *state =
 		tevent_req_data(req, struct async_connect_state);
 
-	TALLOC_FREE(fde);
-
 	/*
 	 * Stevens, Network Programming says that if there's a
 	 * successful connect, the socket is only writable. Upon an
@@ -279,20 +286,23 @@ static void async_connect_connected(struct tevent_context *ev,
 	 */
 	if ((flags & (TEVENT_FD_READ|TEVENT_FD_WRITE))
 	    == (TEVENT_FD_READ|TEVENT_FD_WRITE)) {
-		int sockerr;
-		socklen_t err_len = sizeof(sockerr);
-
-		if (getsockopt(state->fd, SOL_SOCKET, SO_ERROR,
-			       (void *)&sockerr, &err_len) == 0) {
-			errno = sockerr;
+		int ret;
+
+		ret = connect(state->fd,
+			      (struct sockaddr *)(void *)&state->address,
+			      state->address_len);
+		if (ret == 0) {
+			TALLOC_FREE(fde);
+			tevent_req_done(req);
+			return;
 		}
 
-		state->sys_errno = errno;
-
-		DEBUG(10, ("connect returned %s\n", strerror(errno)));
-
-		fcntl(state->fd, F_SETFL, state->old_sockflags);
-		tevent_req_error(req, state->sys_errno);
+		if (errno == EINPROGRESS) {
+			/* Try again later, leave the fde around */
+			return;
+		}
+		TALLOC_FREE(fde);
+		tevent_req_error(req, errno);
 		return;
 	}
 
@@ -327,6 +337,7 @@ struct writev_state {
 	struct iovec *iov;
 	int count;
 	size_t total_size;
+	uint16_t flags;
 };
 
 static void writev_trigger(struct tevent_req *req, void *private_data);
@@ -335,13 +346,14 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
 
 struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 			       struct tevent_queue *queue, int fd,
+			       bool err_on_readability,
 			       struct iovec *iov, int count)
 {
-	struct tevent_req *result;
+	struct tevent_req *req;
 	struct writev_state *state;
 
-	result = tevent_req_create(mem_ctx, &state, struct writev_state);
-	if (result == NULL) {
+	req = tevent_req_create(mem_ctx, &state, struct writev_state);
+	if (req == NULL) {
 		return NULL;
 	}
 	state->ev = ev;
@@ -353,13 +365,27 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 	if (state->iov == NULL) {
 		goto fail;
 	}
+	state->flags = TEVENT_FD_WRITE;
+	if (err_on_readability) {
+		state->flags |= TEVENT_FD_READ;
+	}
+
+	if (queue == NULL) {
+		struct tevent_fd *fde;
+		fde = tevent_add_fd(state->ev, state, state->fd,
+				    state->flags, writev_handler, req);
+		if (tevent_req_nomem(fde, req)) {
+			return tevent_req_post(req, ev);
+		}
+		return req;
+	}
 
-	if (!tevent_queue_add(queue, ev, result, writev_trigger, NULL)) {
+	if (!tevent_queue_add(queue, ev, req, writev_trigger, NULL)) {
 		goto fail;
 	}
-	return result;
+	return req;
  fail:
-	TALLOC_FREE(result);
+	TALLOC_FREE(req);
 	return NULL;
 }
 
@@ -368,7 +394,7 @@ static void writev_trigger(struct tevent_req *req, void *private_data)
 	struct writev_state *state = tevent_req_data(req, struct writev_state);
 	struct tevent_fd *fde;
 
-	fde = tevent_add_fd(state->ev, state, state->fd, TEVENT_FD_WRITE,
+	fde = tevent_add_fd(state->ev, state, state->fd, state->flags,
 			    writev_handler, req);
 	if (fde == NULL) {
 		tevent_req_error(req, ENOMEM);
@@ -387,6 +413,11 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
 
 	to_write = 0;
 
+	if (flags & TEVENT_FD_READ) {
+		tevent_req_error(req, EPIPE);
+		return;
+	}
+
 	for (i=0; i<state->count; i++) {
 		to_write += state->iov[i].iov_len;
 	}
diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h
index ec859dc..a50e932 100644
--- a/lib/async_req/async_sock.h
+++ b/lib/async_req/async_sock.h
@@ -41,6 +41,7 @@ int async_connect_recv(struct tevent_req *req, int *perrno);
 
 struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 			       struct tevent_queue *queue, int fd,
+			       bool err_on_readability,
 			       struct iovec *iov, int count);
 ssize_t writev_recv(struct tevent_req *req, int *perrno);
 
diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c
index df92ecf..55883ba 100644
--- a/source3/lib/wb_reqtrans.c
+++ b/source3/lib/wb_reqtrans.c
@@ -152,7 +152,7 @@ struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
 		count = 2;
 	}
 
-	subreq = writev_send(state, ev, queue, fd, state->iov, count);
+	subreq = writev_send(state, ev, queue, fd, true, state->iov, count);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -169,14 +169,7 @@ static void wb_req_write_done(struct tevent_req *subreq)
 	int err;
 
 	state->ret = writev_recv(subreq, &err);
-	/*
-	 * We do not TALLOC_FREE(subreq) here, as this would trigger the next
-	 * write of a client. The winbind protocol is purely request/response
-	 * without multiplex ID's, so having multiple requeusts on the fly
-	 * would confuse sequencing.
-	 *
-	 * Eventually the writev_req will be freed, "subreq" a child of "req"
-	 */
+	TALLOC_FREE(subreq);
 	if (state->ret < 0) {
 		tevent_req_error(req, err);
 		return;
@@ -309,7 +302,7 @@ struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
 		count = 2;
 	}
 
-	subreq = writev_send(state, ev, queue, fd, state->iov, count);
+	subreq = writev_send(state, ev, queue, fd, true, state->iov, count);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -345,27 +338,6 @@ ssize_t wb_resp_write_recv(struct tevent_req *req, int *err)
 	return state->ret;
 }
 
-static bool closed_fd(int fd)
-{
-	struct timeval tv;
-	fd_set r_fds;
-
-	if (fd == -1) {
-		return true;
-	}
-
-	FD_ZERO(&r_fds);
-	FD_SET(fd, &r_fds);
-	ZERO_STRUCT(tv);
-
-	if ((select(fd+1, &r_fds, NULL, NULL, &tv) == -1)
-	    || FD_ISSET(fd, &r_fds)) {
-		return true;
-	}
-
-	return false;
-}
-
 struct wb_simple_trans_state {
 	struct tevent_context *ev;
 	int fd;
@@ -388,11 +360,6 @@ struct tevent_req *wb_simple_trans_send(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
-	if (closed_fd(fd)) {
-		tevent_req_error(req, EPIPE);
-		return tevent_req_post(req, ev);
-	}
-
 	wb_req->length = sizeof(struct winbindd_request);
 
 	state->ev = ev;
@@ -417,14 +384,7 @@ static void wb_simple_trans_write_done(struct tevent_req *subreq)
 	int err;
 
 	ret = wb_req_write_recv(subreq, &err);
-	/*
-	 * We do not TALLOC_FREE(subreq) here, as this would trigger the next
-	 * write of a client. The winbind protocol is purely request/response
-	 * without multiplex ID's, so having multiple requeusts on the fly
-	 * would confuse sequencing.
-	 *
-	 * Eventually the "subreq" will be freed, it is a child of "req"
-	 */
+	TALLOC_FREE(subreq);
 	if (ret == -1) {
 		tevent_req_error(req, err);
 		return;
@@ -446,6 +406,7 @@ static void wb_simple_trans_read_done(struct tevent_req *subreq)
 	int err;
 
 	ret = wb_resp_read_recv(subreq, state, &state->wb_resp, &err);
+	TALLOC_FREE(subreq);
 	if (ret == -1) {
 		tevent_req_error(req, err);
 		return;
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
index 63401fa..164cfc9 100644
--- a/source3/lib/wbclient.c
+++ b/source3/lib/wbclient.c
@@ -261,11 +261,6 @@ static struct tevent_req *wb_connect_send(TALLOC_CTX *mem_ctx,
 		goto nomem;
 	}
 	tevent_req_set_callback(subreq, wbc_connect_connected, result);
-
-	if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) {
-		goto nomem;
-	}
-
 	return result;
 
  post_status:
@@ -376,7 +371,7 @@ static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq)
 	state->wb_req.cmd = WINBINDD_INTERFACE_VERSION;
 	state->wb_req.pid = getpid();
 
-	subreq = wb_simple_trans_send(state, state->ev, state->wb_ctx->queue,
+	subreq = wb_simple_trans_send(state, state->ev, NULL,
 				      state->wb_ctx->fd, &state->wb_req);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
@@ -408,7 +403,7 @@ static void wb_open_pipe_ping_done(struct tevent_req *subreq)
 	state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR;
 	state->wb_req.pid = getpid();
 
-	subreq = wb_simple_trans_send(state, state->ev, state->wb_ctx->queue,
+	subreq = wb_simple_trans_send(state, state->ev, NULL,
 				      state->wb_ctx->fd, &state->wb_req);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
@@ -473,10 +468,34 @@ struct wb_trans_state {
 	struct tevent_context *ev;
 	struct winbindd_request *wb_req;
 	struct winbindd_response *wb_resp;
-	int num_retries;
 	bool need_priv;
 };
 
+static bool closed_fd(int fd)
+{
+	struct timeval tv;
+	fd_set r_fds;
+	int selret;
+
+	if (fd == -1) {
+		return true;
+	}
+
+	FD_ZERO(&r_fds);
+	FD_SET(fd, &r_fds);
+	ZERO_STRUCT(tv);
+
+	selret = select(fd+1, &r_fds, NULL, NULL, &tv);
+	if (selret == -1) {
+		return true;
+	}
+	if (selret == 0) {
+		return false;
+	}
+	return (FD_ISSET(fd, &r_fds));
+}
+
+static void wb_trans_trigger(struct tevent_req *req, void *private_data);
 static void wb_trans_connect_done(struct tevent_req *subreq);
 static void wb_trans_done(struct tevent_req *subreq);
 static void wb_trans_retry_wait_done(struct tevent_req *subreq);
@@ -486,7 +505,7 @@ struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
 				 struct wb_context *wb_ctx, bool need_priv,
 				 struct winbindd_request *wb_req)
 {
-	struct tevent_req *req, *subreq;
+	struct tevent_req *req;
 	struct wb_trans_state *state;
 
 	req = tevent_req_create(mem_ctx, &state, struct wb_trans_state);
@@ -496,30 +515,46 @@ struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
 	state->wb_ctx = wb_ctx;
 	state->ev = ev;
 	state->wb_req = wb_req;
-	state->num_retries = 10;
 	state->need_priv = need_priv;
 
-	if ((wb_ctx->fd == -1) || (need_priv && !wb_ctx->is_priv)) {
-		subreq = wb_open_pipe_send(state, ev, wb_ctx, need_priv);
-		if (subreq == NULL) {
-			goto fail;
+	if (!tevent_queue_add(wb_ctx->queue, ev, req, wb_trans_trigger,
+			      NULL)) {
+		tevent_req_nomem(NULL, req);
+		return tevent_req_post(req, ev);
+	}
+	return req;
+}
+
+static void wb_trans_trigger(struct tevent_req *req, void *private_data)
+{
+	struct wb_trans_state *state = tevent_req_data(
+		req, struct wb_trans_state);
+	struct tevent_req *subreq;
+
+	if ((state->wb_ctx->fd != -1) && closed_fd(state->wb_ctx->fd)) {
+		close(state->wb_ctx->fd);
+		state->wb_ctx->fd = -1;
+	}
+
+	if ((state->wb_ctx->fd == -1)
+	    || (state->need_priv && !state->wb_ctx->is_priv)) {
+		subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
+					   state->need_priv);
+		if (tevent_req_nomem(subreq, req)) {
+			return;
 		}
 		tevent_req_set_callback(subreq, wb_trans_connect_done, req);
-		return req;
+		return;
 	}
 
 	state->wb_req->pid = getpid();
 
-	subreq = wb_simple_trans_send(state, ev, wb_ctx->queue, wb_ctx->fd,
-				      wb_req);
-	if (subreq == NULL) {
-		goto fail;
+	subreq = wb_simple_trans_send(state, state->ev, NULL,
+				      state->wb_ctx->fd, state->wb_req);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
 	}
 	tevent_req_set_callback(subreq, wb_trans_done, req);
-	return req;
- fail:
-	TALLOC_FREE(req);
-	return NULL;
 }
 
 static bool wb_trans_retry(struct tevent_req *req,
@@ -541,12 +576,6 @@ static bool wb_trans_retry(struct tevent_req *req,
 		return true;
 	}
 
-	state->num_retries -= 1;
-	if (state->num_retries == 0) {
-		tevent_req_error(req, wbc_err);
-		return true;
-	}
-
 	/*
 	 * The transfer as such failed, retry after one second
 	 */
@@ -603,7 +632,7 @@ static void wb_trans_connect_done(struct tevent_req *subreq)
 		return;
 	}
 
-	subreq = wb_simple_trans_send(state, state->ev, state->wb_ctx->queue,
+	subreq = wb_simple_trans_send(state, state->ev, NULL,
 				      state->wb_ctx->fd, state->wb_req);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index 12bc0a6..6edfe51 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -680,10 +680,10 @@ static NTSTATUS cli_smb_req_iov_send(struct tevent_req *req,
 		iov[0].iov_base = (void *)buf;
 		iov[0].iov_len = talloc_get_size(buf);
 		subreq = writev_send(state, state->ev, state->cli->outgoing,
-				     state->cli->fd, iov, 1);
+				     state->cli->fd, false, iov, 1);
 	} else {
 		subreq = writev_send(state, state->ev, state->cli->outgoing,
-				     state->cli->fd, iov, iov_count);
+				     state->cli->fd, false, iov, iov_count);
 	}
 	if (subreq == NULL) {
 		return NT_STATUS_NO_MEMORY;
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index f244161..a17adfb 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -1221,7 +1221,7 @@ struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
 		state->iov.iov_len = len;
 
 		subreq = writev_send(state, ev, p->write_queue, p->fd,
-				     &state->iov, 1);
+				     false, &state->iov, 1);
 		if (subreq == NULL) {
 			goto fail;
 		}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 20561a7..41343ca 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -5886,7 +5886,7 @@ static bool run_local_wbclient(int dummy)
 
 	BlockSignals(True, SIGPIPE);
 
-	ev = event_context_init(talloc_tos());
+	ev = tevent_context_init_byname(talloc_tos(), "epoll");
 	if (ev == NULL) {
 		goto fail;
 	}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list