The branch, master has been updated via 73c3932 s4-ldapserver: serialise ldap server operations via a8bac4a s4-packet: make packet_recv_disable() a lot more efficient via cad0219 s4-process: fixed the thread process model so it compiles from e5e5a11 Add unique IP address binding for client connections (EPM and ncacn_ip_tcp levels)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 73c3932b2d0dac784a0605abf6e532dba5514a01 Author: Andrew Tridgell <tri...@samba.org> Date: Tue Sep 7 11:57:44 2010 +1000 s4-ldapserver: serialise ldap server operations This ensures that two ldap server operations cannot happen in parallel by using packet_recv_disable() and packet_recv_enable() to disable other interfaces during ldap calls. This prevents problems caused by parallel ldap operations where transactions could overlap. commit a8bac4a09a4a81c280c62fb4dcdbd0e61c782479 Author: Andrew Tridgell <tri...@samba.org> Date: Tue Sep 7 11:55:47 2010 +1000 s4-packet: make packet_recv_disable() a lot more efficient this avoids doing an epoll system call when we want to prevent receipt of packets on a socket, unless there actually is a packet to receive. commit cad0219e69d2acc766583083c0738c2b9ea3901f Author: Andrew Tridgell <tri...@samba.org> Date: Tue Sep 7 11:25:42 2010 +1000 s4-process: fixed the thread process model so it compiles it doesn't actually work, but at least it now compiles ----------------------------------------------------------------------- Summary of changes: source4/ldap_server/ldap_server.c | 53 +++++++++++++++++++++++++++++++++++++ source4/ldap_server/ldap_server.h | 7 +++++ source4/lib/stream/packet.c | 8 ++++- source4/smbd/process_thread.c | 3 +- 4 files changed, 68 insertions(+), 3 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index 946e1bf..e975590 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -132,6 +132,32 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn, } /* + disable packets on other sockets while processing this one + */ +static void ldapsrv_disable_recv(struct ldapsrv_connection *conn) +{ + struct ldapsrv_packet_interfaces *p; + for (p=conn->service->packet_interfaces; p; p=p->next) { + if (p->packet != conn->packet) { + packet_recv_disable(p->packet); + } + } +} + +/* + disable packets on other sockets while processing this one + */ +static void ldapsrv_enable_recv(struct ldapsrv_connection *conn) +{ + struct ldapsrv_packet_interfaces *p; + for (p=conn->service->packet_interfaces; p; p=p->next) { + if (p->packet != conn->packet) { + packet_recv_enable(p->packet); + } + } +} + +/* decode/process data */ static NTSTATUS ldapsrv_decode(void *private_data, DATA_BLOB blob) @@ -162,7 +188,13 @@ static NTSTATUS ldapsrv_decode(void *private_data, DATA_BLOB blob) talloc_steal(conn, msg); asn1_free(asn1); + /* disable messages on other sockets while processing this one */ + ldapsrv_disable_recv(conn); + ldapsrv_process_message(conn, msg); + + ldapsrv_enable_recv(conn); + return NT_STATUS_OK; } @@ -325,6 +357,15 @@ failed: } /* + remove a packet interface from the service level list + */ +static int packet_interface_destructor(struct ldapsrv_packet_interfaces *packet_interface) +{ + DLIST_REMOVE(packet_interface->service->packet_interfaces, packet_interface); + return 0; +} + +/* initialise a server_context from a open socket and register a event handler for reading from that socket */ @@ -397,6 +438,18 @@ static void ldapsrv_accept(struct stream_connection *c, /* Ensure we don't get packets until the database is ready below */ packet_recv_disable(conn->packet); + /* add to the service level list of packet interfaces, to + * allow us to serialise between connections + */ + conn->packet_interface = talloc(conn, struct ldapsrv_packet_interfaces); + if (conn->packet_interface == NULL) { + ldapsrv_terminate_connection(conn, "out of memory"); + } + conn->packet_interface->service = ldapsrv_service; + conn->packet_interface->packet = conn->packet; + DLIST_ADD(conn->service->packet_interfaces, conn->packet_interface); + talloc_set_destructor(conn->packet_interface, packet_interface_destructor); + server_credentials = cli_credentials_init(conn); if (!server_credentials) { stream_terminate_connection(c, "Failed to init server credentials\n"); diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h index 8b45285..0fb8d2f 100644 --- a/source4/ldap_server/ldap_server.h +++ b/source4/ldap_server/ldap_server.h @@ -50,6 +50,8 @@ struct ldapsrv_connection { struct tevent_timer *ite; struct tevent_timer *te; } limits; + + struct ldapsrv_packet_interfaces *packet_interface; }; struct ldapsrv_call { @@ -66,6 +68,11 @@ struct ldapsrv_call { struct ldapsrv_service { struct tls_params *tls_params; struct task_server *task; + struct ldapsrv_packet_interfaces { + struct ldapsrv_packet_interfaces *next, *prev; + struct packet_context *packet; + struct ldapsrv_service *service; + } *packet_interfaces; }; #include "ldap_server/proto.h" diff --git a/source4/lib/stream/packet.c b/source4/lib/stream/packet.c index 251d951..9834370 100644 --- a/source4/lib/stream/packet.c +++ b/source4/lib/stream/packet.c @@ -42,6 +42,7 @@ struct packet_context { bool serialise; int processing; bool recv_disable; + bool recv_need_enable; bool nofree; bool busy; @@ -256,6 +257,7 @@ _PUBLIC_ void packet_recv(struct packet_context *pc) } if (pc->recv_disable) { + pc->recv_need_enable = true; EVENT_FD_NOT_READABLE(pc->fde); return; } @@ -464,7 +466,6 @@ next_partial: */ _PUBLIC_ void packet_recv_disable(struct packet_context *pc) { - EVENT_FD_NOT_READABLE(pc->fde); pc->recv_disable = true; } @@ -473,7 +474,10 @@ _PUBLIC_ void packet_recv_disable(struct packet_context *pc) */ _PUBLIC_ void packet_recv_enable(struct packet_context *pc) { - EVENT_FD_READABLE(pc->fde); + if (pc->recv_need_enable) { + pc->recv_need_enable = false; + EVENT_FD_READABLE(pc->fde); + } pc->recv_disable = false; if (pc->num_read != 0 && pc->packet_size >= pc->num_read) { event_add_timed(pc->ev, pc, timeval_zero(), packet_next_event, pc); diff --git a/source4/smbd/process_thread.c b/source4/smbd/process_thread.c index c047d23..b169a79 100644 --- a/source4/smbd/process_thread.c +++ b/source4/smbd/process_thread.c @@ -29,6 +29,7 @@ #endif #include "system/wait.h" #include "system/filesys.h" +#include "system/time.h" #include "lib/events/events.h" #include "lib/util/dlinklist.h" #include "lib/util/mutex.h" @@ -317,7 +318,7 @@ static int thread_rwlock_lock_read(smb_rwlock_t *rwlockP, const char *name) pthread_rwlock_t *rwlock = (pthread_rwlock_t *)rwlockP->rwlock; int rc; double t; - struct time tp1; + struct timespec tp1; /* Test below is ONLY for debugging */ if ((rc = pthread_rwlock_tryrdlock(rwlock))) { if (rc == EBUSY) { -- Samba Shared Repository