The branch, master has been updated via be394406ee0 lib: Try nonblocking writes in writev_send() via 79f55ba3271 lib: Use optimize_empty in writev_send() via 8946531f1f7 winbind: Set the parent->child sock nonblocking via 0e50ed19360 libsmb: Make sure that the TCP socket is non-blocking via f52f531771d lib: Remove unused SOCKET_FLAG_BLOCK via 051b7c135c9 lib: Simplify writev_cancel() from e2d260c7b42 third_party: Update resolv_wrapper to version 1.1.6
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit be394406ee016c6bab75fcd96417554468cf495d Author: Volker Lendecke <v...@samba.org> Date: Thu Mar 19 17:00:59 2020 +0100 lib: Try nonblocking writes in writev_send() All callers now use nonblocking sockets, so that we can optimize by doing early writes Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Wed Mar 25 10:41:29 UTC 2020 on sn-devel-184 commit 79f55ba3271b54068535e97695f5d6065a7048a5 Author: Volker Lendecke <v...@samba.org> Date: Thu Mar 12 16:20:25 2020 +0100 lib: Use optimize_empty in writev_send() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 8946531f1f70c87b17ded5a9b42cf0329fe83fe7 Author: Volker Lendecke <v...@samba.org> Date: Fri Mar 20 12:17:08 2020 +0100 winbind: Set the parent->child sock nonblocking The parent goes through wb_simple_trans_send(), which deals with short writes fine. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 0e50ed193606c3716bcd3955e6305f6891f34cff Author: Volker Lendecke <v...@samba.org> Date: Fri Mar 20 11:46:43 2020 +0100 libsmb: Make sure that the TCP socket is non-blocking All traffic goes through smbXcli_base.c, and that is prepared to deal with short writes via the conn->outgoing queue. Instead of making sure that all callers properly set the socket nonblocking, do it here, so that we can later optimize sending out data to the server. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit f52f531771d6a25b2e363384bf94a9fa14334e1b Author: Volker Lendecke <v...@samba.org> Date: Fri Mar 20 11:31:15 2020 +0100 lib: Remove unused SOCKET_FLAG_BLOCK Nobody in the code set this flag, so remove it Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 051b7c135c959dad8b19c69aa372c7060e39ff19 Author: Volker Lendecke <v...@samba.org> Date: Thu Mar 12 11:42:41 2020 +0100 lib: Simplify writev_cancel() We can only reasonably cancel a writev request that is still queued. Once writing has started, cancel is pointless. Simplify the if-conditions. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/async_req/async_sock.c | 91 ++++++++++++++++++++++------------------ libcli/smb/smbXcli_base.c | 1 + source3/winbindd/winbindd_dual.c | 1 + source4/lib/socket/socket.c | 5 +-- source4/lib/socket/socket.h | 1 - source4/lib/socket/socket_ip.c | 49 +++++++++------------- source4/lib/socket/socket_unix.c | 28 +++++-------- 7 files changed, 85 insertions(+), 91 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index e436d00ac79..8f04a7bcbae 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -291,11 +291,14 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return req; } - state->queue_entry = tevent_queue_add_entry(queue, ev, req, - writev_trigger, NULL); + state->queue_entry = tevent_queue_add_optimize_empty( + queue, ev, req, writev_trigger, NULL); if (tevent_req_nomem(state->queue_entry, req)) { return tevent_req_post(req, ev); } + if (!tevent_req_is_in_progress(req)) { + return tevent_req_post(req, ev); + } return req; } @@ -312,35 +315,67 @@ static bool writev_cancel(struct tevent_req *req) { struct writev_state *state = tevent_req_data(req, struct writev_state); - TALLOC_FREE(state->queue_entry); - TALLOC_FREE(state->fde); - - if (state->count == 0) { - /* - * already completed. - */ - return false; - } - - tevent_req_defer_callback(req, state->ev); if (state->total_size > 0) { /* * We've already started to write :-( */ - tevent_req_error(req, EIO); return false; } + TALLOC_FREE(state->queue_entry); + TALLOC_FREE(state->fde); + + tevent_req_defer_callback(req, state->ev); tevent_req_error(req, ECANCELED); return true; } +static void writev_do(struct tevent_req *req, struct writev_state *state) +{ + ssize_t written; + bool ok; + + written = writev(state->fd, state->iov, state->count); + if ((written == -1) && + ((errno == EINTR) || + (errno == EAGAIN) || + (errno == EWOULDBLOCK))) { + /* retry after going through the tevent loop */ + return; + } + if (written == -1) { + tevent_req_error(req, errno); + return; + } + if (written == 0) { + tevent_req_error(req, EPIPE); + return; + } + state->total_size += written; + + ok = iov_advance(&state->iov, &state->count, written); + if (!ok) { + tevent_req_error(req, EIO); + return; + } + + if (state->count == 0) { + tevent_req_done(req); + return; + } +} + static void writev_trigger(struct tevent_req *req, void *private_data) { struct writev_state *state = tevent_req_data(req, struct writev_state); state->queue_entry = NULL; + writev_do(req, state); + if (!tevent_req_is_in_progress(req)) { + return; + } + state->fde = tevent_add_fd(state->ev, state, state->fd, state->flags, writev_handler, req); if (tevent_req_nomem(state->fde, req)) { @@ -355,8 +390,6 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, private_data, struct tevent_req); struct writev_state *state = tevent_req_data(req, struct writev_state); - ssize_t written; - bool ok; if ((state->flags & TEVENT_FD_READ) && (flags & TEVENT_FD_READ)) { int ret, value; @@ -390,31 +423,7 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, } } - written = writev(state->fd, state->iov, state->count); - if ((written == -1) && (errno == EINTR)) { - /* retry */ - return; - } - if (written == -1) { - tevent_req_error(req, errno); - return; - } - if (written == 0) { - tevent_req_error(req, EPIPE); - return; - } - state->total_size += written; - - ok = iov_advance(&state->iov, &state->count, written); - if (!ok) { - tevent_req_error(req, EIO); - return; - } - - if (state->count == 0) { - tevent_req_done(req); - return; - } + writev_do(req, state); } ssize_t writev_recv(struct tevent_req *req, int *perrno) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 0115cbbec18..895fa64fcf5 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -338,6 +338,7 @@ struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx, return NULL; } + set_blocking(fd, false); conn->sock_fd = fd; conn->remote_name = talloc_strdup(conn, remote_name); diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 8188ed097df..8ad2485324e 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -1688,6 +1688,7 @@ static bool fork_domain_child(struct winbindd_child *child) } child->sock = fdpair[1]; + set_blocking(child->sock, false); return True; } diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index d7535bf357a..26f23f56653 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -79,15 +79,14 @@ _PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socke send calls on non-blocking sockets will randomly recv/send less data than requested */ - if (!(flags & SOCKET_FLAG_BLOCK) && - type == SOCKET_TYPE_STREAM && + if (type == SOCKET_TYPE_STREAM && getenv("SOCKET_TESTNONBLOCK") != NULL) { (*new_sock)->flags |= SOCKET_FLAG_TESTNONBLOCK; } /* we don't do a connect() on dgram sockets, so need to set non-blocking at socket create time */ - if (!(flags & SOCKET_FLAG_BLOCK) && type == SOCKET_TYPE_DGRAM) { + if (type == SOCKET_TYPE_DGRAM) { set_blocking(socket_get_fd(*new_sock), false); } diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h index a492bc10367..d0fb5e0bfca 100644 --- a/source4/lib/socket/socket.h +++ b/source4/lib/socket/socket.h @@ -98,7 +98,6 @@ enum socket_state { SOCKET_STATE_SERVER_ERROR }; -#define SOCKET_FLAG_BLOCK 0x00000001 #define SOCKET_FLAG_PEEK 0x00000002 #define SOCKET_FLAG_TESTNONBLOCK 0x00000004 #define SOCKET_FLAG_ENCRYPT 0x00000008 /* This socket diff --git a/source4/lib/socket/socket_ip.c b/source4/lib/socket/socket_ip.c index 2aba491e06c..762ec3d48c4 100644 --- a/source4/lib/socket/socket_ip.c +++ b/source4/lib/socket/socket_ip.c @@ -81,11 +81,9 @@ static NTSTATUS ip_connect_complete(struct socket_context *sock, uint32_t flags) return map_nt_error_from_unix_common(error); } - if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, false); - if (ret == -1) { - return map_nt_error_from_unix_common(errno); - } + ret = set_blocking(sock->fd, false); + if (ret == -1) { + return map_nt_error_from_unix_common(errno); } sock->state = SOCKET_STATE_CLIENT_CONNECTED; @@ -201,11 +199,9 @@ static NTSTATUS ipv4_listen(struct socket_context *sock, } } - if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, false); - if (ret == -1) { - return map_nt_error_from_unix_common(errno); - } + ret = set_blocking(sock->fd, false); + if (ret == -1) { + return map_nt_error_from_unix_common(errno); } sock->state= SOCKET_STATE_SERVER_LISTEN; @@ -217,7 +213,7 @@ static NTSTATUS ipv4_accept(struct socket_context *sock, struct socket_context * { struct sockaddr_in cli_addr; socklen_t cli_addr_len = sizeof(cli_addr); - int new_fd; + int new_fd, ret; if (sock->type != SOCKET_TYPE_STREAM) { return NT_STATUS_INVALID_PARAMETER; @@ -228,13 +224,12 @@ static NTSTATUS ipv4_accept(struct socket_context *sock, struct socket_context * return map_nt_error_from_unix_common(errno); } - if (!(sock->flags & SOCKET_FLAG_BLOCK)) { - int ret = set_blocking(new_fd, false); - if (ret == -1) { - close(new_fd); - return map_nt_error_from_unix_common(errno); - } + ret = set_blocking(new_fd, false); + if (ret == -1) { + close(new_fd); + return map_nt_error_from_unix_common(errno); } + smb_set_close_on_exec(new_fd); @@ -731,11 +726,9 @@ static NTSTATUS ipv6_listen(struct socket_context *sock, } } - if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, false); - if (ret == -1) { - return map_nt_error_from_unix_common(errno); - } + ret = set_blocking(sock->fd, false); + if (ret == -1) { + return map_nt_error_from_unix_common(errno); } sock->state= SOCKET_STATE_SERVER_LISTEN; @@ -747,7 +740,7 @@ static NTSTATUS ipv6_tcp_accept(struct socket_context *sock, struct socket_conte { struct sockaddr_in6 cli_addr; socklen_t cli_addr_len = sizeof(cli_addr); - int new_fd; + int new_fd, ret; if (sock->type != SOCKET_TYPE_STREAM) { return NT_STATUS_INVALID_PARAMETER; @@ -758,12 +751,10 @@ static NTSTATUS ipv6_tcp_accept(struct socket_context *sock, struct socket_conte return map_nt_error_from_unix_common(errno); } - if (!(sock->flags & SOCKET_FLAG_BLOCK)) { - int ret = set_blocking(new_fd, false); - if (ret == -1) { - close(new_fd); - return map_nt_error_from_unix_common(errno); - } + ret = set_blocking(new_fd, false); + if (ret == -1) { + close(new_fd); + return map_nt_error_from_unix_common(errno); } smb_set_close_on_exec(new_fd); diff --git a/source4/lib/socket/socket_unix.c b/source4/lib/socket/socket_unix.c index 6876e395ed6..d4946d88eeb 100644 --- a/source4/lib/socket/socket_unix.c +++ b/source4/lib/socket/socket_unix.c @@ -84,11 +84,9 @@ static NTSTATUS unixdom_connect_complete(struct socket_context *sock, uint32_t f return map_nt_error_from_unix_common(error); } - if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, false); - if (ret == -1) { - return map_nt_error_from_unix_common(errno); - } + ret = set_blocking(sock->fd, false); + if (ret == -1) { + return map_nt_error_from_unix_common(errno); } sock->state = SOCKET_STATE_CLIENT_CONNECTED; @@ -163,11 +161,9 @@ static NTSTATUS unixdom_listen(struct socket_context *sock, } } - if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, false); - if (ret == -1) { - return unixdom_error(errno); - } + ret = set_blocking(sock->fd, false); + if (ret == -1) { + return unixdom_error(errno); } sock->state = SOCKET_STATE_SERVER_LISTEN; @@ -181,7 +177,7 @@ static NTSTATUS unixdom_accept(struct socket_context *sock, { struct sockaddr_un cli_addr; socklen_t cli_addr_len = sizeof(cli_addr); - int new_fd; + int new_fd, ret; if (sock->type != SOCKET_TYPE_STREAM) { return NT_STATUS_INVALID_PARAMETER; @@ -192,12 +188,10 @@ static NTSTATUS unixdom_accept(struct socket_context *sock, return unixdom_error(errno); } - if (!(sock->flags & SOCKET_FLAG_BLOCK)) { - int ret = set_blocking(new_fd, false); - if (ret == -1) { - close(new_fd); - return map_nt_error_from_unix_common(errno); - } + ret = set_blocking(new_fd, false); + if (ret == -1) { + close(new_fd); + return map_nt_error_from_unix_common(errno); } smb_set_close_on_exec(new_fd); -- Samba Shared Repository