The branch, master has been updated via 332eeb8 ctdbd_conn: Only poll if there's a timeout via c71b0c4 ctdbd_conn: Remove ctdb_packet via a2a6872 ctdbd_conn: Remove ctdb_packet dependency from e185ff2 ctdb-locking: Simplify ctdb_find_lock_context()
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 332eeb8bc152a7ba10c81c92cd8aec21733692c3 Author: Volker Lendecke <v...@samba.org> Date: Mon Jul 21 12:35:39 2014 +0000 ctdbd_conn: Only poll if there's a timeout At this point the ctdb socket is blocking, so we can save a syscall when we wait indefinitely anyway. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> Autobuild-User(master): Michael Adam <ob...@samba.org> Autobuild-Date(master): Wed Aug 6 18:01:54 CEST 2014 on sn-devel-104 commit c71b0c413c34b2a98557a1baebaebe665b4d8a8c Author: Volker Lendecke <v...@samba.org> Date: Tue May 27 07:50:01 2014 +0000 ctdbd_conn: Remove ctdb_packet Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit a2a687205bdab22c2e97bc04c7f41f1071707961 Author: Volker Lendecke <v...@samba.org> Date: Tue May 6 12:21:42 2014 +0200 ctdbd_conn: Remove ctdb_packet dependency This was an early, failed attempt at async socket handling. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/include/ctdb_packet.h | 85 ------- source3/lib/ctdb_packet.c | 273 -------------------- source3/lib/ctdbd_conn.c | 555 ++++++++++++++++------------------------- source3/wscript_build | 1 - 4 files changed, 221 insertions(+), 693 deletions(-) delete mode 100644 source3/include/ctdb_packet.h delete mode 100644 source3/lib/ctdb_packet.c Changeset truncated at 500 lines: diff --git a/source3/include/ctdb_packet.h b/source3/include/ctdb_packet.h deleted file mode 100644 index 026b23f..0000000 --- a/source3/include/ctdb_packet.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - Unix SMB/CIFS implementation. - CTDB Packet handling - Copyright (C) Volker Lendecke 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * A ctdb_packet context is a wrapper around a bidirectional file descriptor, - * hiding the handling of individual requests. - */ - -struct ctdb_packet_context; - -/* - * Initialize a ctdb_packet context. The fd is given to the ctdb_packet context, meaning - * that it is automatically closed when the ctdb_packet context is freed. - */ -struct ctdb_packet_context *ctdb_packet_init(TALLOC_CTX *mem_ctx, int fd); - -/* - * Pull data from the fd - */ -NTSTATUS ctdb_packet_fd_read(struct ctdb_packet_context *ctx); - -/* - * Sync read, wait for the next chunk - */ -NTSTATUS ctdb_packet_fd_read_sync_timeout(struct ctdb_packet_context *ctx, int timeout); - -/* - * Handle an incoming ctdb_packet: - * Return False if none is available - * Otherwise return True and store the callback result in *status - * Callback must either talloc_move or talloc_free buf - */ -bool ctdb_packet_handler(struct ctdb_packet_context *ctx, - bool (*full_req)(const uint8_t *buf, - size_t available, - size_t *length, - void *private_data), - NTSTATUS (*callback)(uint8_t *buf, size_t length, - void *private_data), - void *private_data, - NTSTATUS *status); - -/* - * How many bytes of outgoing data do we have pending? - */ -size_t ctdb_packet_outgoing_bytes(struct ctdb_packet_context *ctx); - -/* - * Push data to the fd - */ -NTSTATUS ctdb_packet_fd_write(struct ctdb_packet_context *ctx); - -/* - * Sync flush all outgoing bytes - */ -NTSTATUS ctdb_packet_flush(struct ctdb_packet_context *ctx); - -/* - * Send a list of DATA_BLOBs - * - * Example: ctdb_packet_send(ctx, 2, data_blob_const(&size, sizeof(size)), - * data_blob_const(buf, size)); - */ -NTSTATUS ctdb_packet_send(struct ctdb_packet_context *ctx, int num_blobs, ...); - -/* - * Get the ctdb_packet context's file descriptor - */ -int ctdb_packet_get_fd(struct ctdb_packet_context *ctx); diff --git a/source3/lib/ctdb_packet.c b/source3/lib/ctdb_packet.c deleted file mode 100644 index 5ea1c25..0000000 --- a/source3/lib/ctdb_packet.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - Unix SMB/CIFS implementation. - CTDB Packet handling - Copyright (C) Volker Lendecke 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "../lib/util/select.h" -#include "system/filesys.h" -#include "ctdb_packet.h" - -struct ctdb_packet_context { - int fd; - DATA_BLOB in, out; -}; - -/* - * Close the underlying fd - */ -static int ctdb_packet_context_destructor(struct ctdb_packet_context *ctx) -{ - return close(ctx->fd); -} - -/* - * Initialize a ctdb_packet context. The fd is given to the ctdb_packet context, meaning - * that it is automatically closed when the ctdb_packet context is freed. - */ -struct ctdb_packet_context *ctdb_packet_init(TALLOC_CTX *mem_ctx, int fd) -{ - struct ctdb_packet_context *result; - - if (!(result = talloc_zero(mem_ctx, struct ctdb_packet_context))) { - return NULL; - } - - result->fd = fd; - talloc_set_destructor(result, ctdb_packet_context_destructor); - return result; -} - -/* - * Pull data from the fd - */ -NTSTATUS ctdb_packet_fd_read(struct ctdb_packet_context *ctx) -{ - int res, available; - size_t new_size; - uint8 *in; - - res = ioctl(ctx->fd, FIONREAD, &available); - - if (res == -1) { - DEBUG(10, ("ioctl(FIONREAD) failed: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - SMB_ASSERT(available >= 0); - - if (available == 0) { - return NT_STATUS_END_OF_FILE; - } - - new_size = ctx->in.length + available; - - if (new_size < ctx->in.length) { - DEBUG(0, ("integer wrap\n")); - return NT_STATUS_NO_MEMORY; - } - - if (!(in = talloc_realloc(ctx, ctx->in.data, uint8, new_size))) { - DEBUG(10, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; - } - - ctx->in.data = in; - - res = recv(ctx->fd, in + ctx->in.length, available, 0); - - if (res < 0) { - DEBUG(10, ("recv failed: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - if (res == 0) { - return NT_STATUS_END_OF_FILE; - } - - ctx->in.length += res; - - return NT_STATUS_OK; -} - -NTSTATUS ctdb_packet_fd_read_sync_timeout(struct ctdb_packet_context *ctx, int timeout) -{ - int res, revents; - - res = poll_one_fd(ctx->fd, POLLIN|POLLHUP, timeout, &revents); - if (res == 0) { - DEBUG(10, ("poll timed out\n")); - return NT_STATUS_IO_TIMEOUT; - } - - if (res == -1) { - DEBUG(10, ("poll returned %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - if ((revents & (POLLIN|POLLHUP|POLLERR)) == 0) { - DEBUG(10, ("socket not readable\n")); - return NT_STATUS_IO_TIMEOUT; - } - - return ctdb_packet_fd_read(ctx); -} - -bool ctdb_packet_handler(struct ctdb_packet_context *ctx, - bool (*full_req)(const uint8_t *buf, - size_t available, - size_t *length, - void *priv), - NTSTATUS (*callback)(uint8_t *buf, size_t length, - void *priv), - void *priv, NTSTATUS *status) -{ - size_t length; - uint8_t *buf; - - if (!full_req(ctx->in.data, ctx->in.length, &length, priv)) { - return False; - } - - if (length > ctx->in.length) { - *status = NT_STATUS_INTERNAL_ERROR; - return true; - } - - if (length == ctx->in.length) { - buf = ctx->in.data; - ctx->in.data = NULL; - ctx->in.length = 0; - } else { - buf = (uint8_t *)talloc_memdup(ctx, ctx->in.data, length); - if (buf == NULL) { - *status = NT_STATUS_NO_MEMORY; - return true; - } - - memmove(ctx->in.data, ctx->in.data + length, - ctx->in.length - length); - ctx->in.length -= length; - } - - *status = callback(buf, length, priv); - return True; -} - -/* - * How many bytes of outgoing data do we have pending? - */ -size_t ctdb_packet_outgoing_bytes(struct ctdb_packet_context *ctx) -{ - return ctx->out.length; -} - -/* - * Push data to the fd - */ -NTSTATUS ctdb_packet_fd_write(struct ctdb_packet_context *ctx) -{ - ssize_t sent; - - sent = sys_send(ctx->fd, ctx->out.data, ctx->out.length, 0); - - if (sent == -1) { - DEBUG(0, ("send failed: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - memmove(ctx->out.data, ctx->out.data + sent, - ctx->out.length - sent); - ctx->out.length -= sent; - - return NT_STATUS_OK; -} - -/* - * Sync flush all outgoing bytes - */ -NTSTATUS ctdb_packet_flush(struct ctdb_packet_context *ctx) -{ - while (ctx->out.length != 0) { - NTSTATUS status = ctdb_packet_fd_write(ctx); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - } - return NT_STATUS_OK; -} - -/* - * Send a list of DATA_BLOBs - * - * Example: ctdb_packet_send(ctx, 2, data_blob_const(&size, sizeof(size)), - * data_blob_const(buf, size)); - */ -NTSTATUS ctdb_packet_send(struct ctdb_packet_context *ctx, int num_blobs, ...) -{ - va_list ap; - int i; - size_t len; - uint8 *out; - - len = ctx->out.length; - - va_start(ap, num_blobs); - for (i=0; i<num_blobs; i++) { - size_t tmp; - DATA_BLOB blob = va_arg(ap, DATA_BLOB); - - tmp = len + blob.length; - if (tmp < len) { - DEBUG(0, ("integer overflow\n")); - va_end(ap); - return NT_STATUS_NO_MEMORY; - } - len = tmp; - } - va_end(ap); - - if (len == 0) { - return NT_STATUS_OK; - } - - if (!(out = talloc_realloc(ctx, ctx->out.data, uint8, len))) { - DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; - } - - ctx->out.data = out; - - va_start(ap, num_blobs); - for (i=0; i<num_blobs; i++) { - DATA_BLOB blob = va_arg(ap, DATA_BLOB); - - memcpy(ctx->out.data+ctx->out.length, blob.data, blob.length); - ctx->out.length += blob.length; - } - va_end(ap); - - SMB_ASSERT(ctx->out.length == len); - return NT_STATUS_OK; -} - -/* - * Get the ctdb_packet context's file descriptor - */ -int ctdb_packet_get_fd(struct ctdb_packet_context *ctx) -{ - return ctx->fd; -} diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index 201c700..3e5e838 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -22,8 +22,8 @@ #include "util_tdb.h" #include "serverid.h" #include "ctdbd_conn.h" +#include "system/select.h" -#include "ctdb_packet.h" #include "messages.h" /* @@ -54,7 +54,7 @@ struct ctdbd_connection { uint32_t reqid; uint32_t our_vnn; uint64_t rand_srvid; - struct ctdb_packet_context *pkt; + int fd; struct tevent_fd *fde; bool (*release_ip_handler)(const char *ip_addr, void *private_data); @@ -208,10 +208,8 @@ const char *lp_ctdbd_socket(void) * Get us a ctdb connection */ -static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx, - struct ctdb_packet_context **presult) +static int ctdbd_connect(int *pfd) { - struct ctdb_packet_context *result; const char *sockname = lp_ctdbd_socket(); struct sockaddr_un addr = { 0, }; int fd; @@ -219,61 +217,26 @@ static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx, fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { - DEBUG(3, ("Could not create socket: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); + int err = errno; + DEBUG(3, ("Could not create socket: %s\n", strerror(err))); + return err; } addr.sun_family = AF_UNIX; snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", sockname); salen = sizeof(struct sockaddr_un); + if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) { + int err = errno; DEBUG(1, ("connect(%s) failed: %s\n", sockname, - strerror(errno))); + strerror(err))); close(fd); - return map_nt_error_from_unix(errno); + return err; } - if (!(result = ctdb_packet_init(mem_ctx, fd))) { - close(fd); - return NT_STATUS_NO_MEMORY; - } - - *presult = result; - return NT_STATUS_OK; -} - -/* - * Do we have a complete ctdb packet in the queue? - */ - -static bool ctdb_req_complete(const uint8_t *buf, size_t available, - size_t *length, - void *private_data) -{ - uint32_t msglen; - - if (available < sizeof(msglen)) { - return False; - } - - msglen = *((const uint32_t *)buf); - - DEBUG(11, ("msglen = %d\n", msglen)); - - if (msglen < sizeof(struct ctdb_req_header)) { - DEBUG(0, ("Got invalid msglen: %d, expected at least %d for " - "the req_header\n", (int)msglen, - (int)sizeof(struct ctdb_req_header))); - cluster_fatal("ctdbd protocol error\n"); - } - - if (available < msglen) { - return false; - } - - *length = msglen; - return true; + *pfd = fd; + return 0; } /* @@ -303,25 +266,6 @@ static void deferred_message_dispatch(struct tevent_context *event_ctx, TALLOC_FREE(te); } -struct req_pull_state { - TALLOC_CTX *mem_ctx; - DATA_BLOB req; -}; - -/* - * Pull a ctdb request out of the incoming ctdb_packet queue - */ - -static NTSTATUS ctdb_req_pull(uint8_t *buf, size_t length, - void *private_data) -{ - struct req_pull_state *state = (struct req_pull_state *)private_data; - - state->req.data = talloc_move(state->mem_ctx, &buf); - state->req.length = length; - return NT_STATUS_OK; -} - /* -- Samba Shared Repository