|
|
dc8c34 |
From 899662a8fc635997586e9891f3d93629b479dc96 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Rich Megginson <rmeggins@redhat.com>
|
|
|
dc8c34 |
Date: Wed, 24 Apr 2013 20:36:37 -0600
|
|
|
dc8c34 |
Subject: [PATCH 57/99] Ticket #47349 - DS instance crashes under a high load
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47349
|
|
|
dc8c34 |
Reviewed by: nkinder (Thanks!)
|
|
|
dc8c34 |
Branch: 389-ds-base-1.2.11
|
|
|
dc8c34 |
Fix Description: handle_new_connection initializes the connection object,
|
|
|
dc8c34 |
then calls connection_table_move_connection_on_to_active_list to put it
|
|
|
dc8c34 |
on the list of active connections, then unlocks the c_mutex, then calls
|
|
|
dc8c34 |
connection_new_private to allocate c_private. If another thread
|
|
|
dc8c34 |
interrupts after the conn has been moved to the active list, but before
|
|
|
dc8c34 |
c_private has been allocated, the new conn will be available via
|
|
|
dc8c34 |
connection_table_iterate_active_connections where table_iterate_function
|
|
|
dc8c34 |
will attempt to dereference the NULL c_private.
|
|
|
dc8c34 |
The fix is to move connection_new_private inside the c_mutex lock, and to
|
|
|
dc8c34 |
move connection_table_move_connection_on_to_active_list to be the very last
|
|
|
dc8c34 |
thing before releasing the c_mutex lock. Once the conn is on the active
|
|
|
dc8c34 |
list it is live and we cannot do anything else to it.
|
|
|
dc8c34 |
Note: I have still not been able to reproduce the problem in a non-debug
|
|
|
dc8c34 |
optimized build.
|
|
|
dc8c34 |
Platforms tested: RHEL6 x86_64
|
|
|
dc8c34 |
Note: Before patch, server would crash within 5 minutes. After patch, server
|
|
|
dc8c34 |
has been running for several days in customer environment.
|
|
|
dc8c34 |
Flag Day: no
|
|
|
dc8c34 |
Doc impact: no
|
|
|
dc8c34 |
(cherry picked from commit 05d209432571dc64b242ae47113ae4cbb43607d2)
|
|
|
dc8c34 |
(cherry picked from commit 11c0f99aaa2deead80bde7e35dd9f9aabac5cc20)
|
|
|
dc8c34 |
(cherry picked from commit d1754414bffca63ceec42812387e233c717fe14e)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/daemon.c | 25 +++++++++++++------------
|
|
|
dc8c34 |
1 file changed, 13 insertions(+), 12 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
|
|
dc8c34 |
index 0304e4a..0a87293 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/daemon.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/daemon.c
|
|
|
dc8c34 |
@@ -2685,16 +2685,6 @@ handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, i
|
|
|
dc8c34 |
/* Call the plugin extension constructors */
|
|
|
dc8c34 |
conn->c_extension = factory_create_extension(connection_type,conn,NULL /* Parent */);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- /* Add this connection slot to the doubly linked list of active connections. This
|
|
|
dc8c34 |
- * list is used to find the connections that should be used in the poll call. This
|
|
|
dc8c34 |
- * connection will be added directly after slot 0 which serves as the head of the list */
|
|
|
dc8c34 |
- if ( conn != NULL && conn->c_next == NULL && conn->c_prev == NULL )
|
|
|
dc8c34 |
- {
|
|
|
dc8c34 |
- /* Now give the new connection to the connection code */
|
|
|
dc8c34 |
- connection_table_move_connection_on_to_active_list(the_connection_table,conn);
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
#if defined(ENABLE_LDAPI)
|
|
|
dc8c34 |
#if !defined( XP_WIN32 )
|
|
|
dc8c34 |
/* ldapi */
|
|
|
dc8c34 |
@@ -2707,10 +2697,21 @@ handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, i
|
|
|
dc8c34 |
#endif
|
|
|
dc8c34 |
#endif /* ENABLE_LDAPI */
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- PR_Unlock( conn->c_mutex );
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
connection_new_private(conn);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+ /* Add this connection slot to the doubly linked list of active connections. This
|
|
|
dc8c34 |
+ * list is used to find the connections that should be used in the poll call. This
|
|
|
dc8c34 |
+ * connection will be added directly after slot 0 which serves as the head of the list.
|
|
|
dc8c34 |
+ * This must be done as the very last thing before we unlock the mutex, because once it
|
|
|
dc8c34 |
+ * is added to the active list, it is live. */
|
|
|
dc8c34 |
+ if ( conn != NULL && conn->c_next == NULL && conn->c_prev == NULL )
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
+ /* Now give the new connection to the connection code */
|
|
|
dc8c34 |
+ connection_table_move_connection_on_to_active_list(the_connection_table,conn);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ PR_Unlock( conn->c_mutex );
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
g_increment_current_conn_count();
|
|
|
dc8c34 |
|
|
|
dc8c34 |
return 0;
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.8.1.4
|
|
|
dc8c34 |
|