Blame SOURCES/0097-Ticket-49768-Under-network-intensive-load-persistent.patch

6e8815
From 2136ba8dd18e72bfbe037517c10187bfe695628f Mon Sep 17 00:00:00 2001
6e8815
From: Thierry Bordaz <tbordaz@redhat.com>
6e8815
Date: Thu, 24 May 2018 15:36:34 +0200
6e8815
Subject: [PATCH] Ticket 49768 - Under network intensive load persistent search
6e8815
 can erronously decrease connection refcnt
6e8815
6e8815
Bug Description:
6e8815
	If a connection enters in turbo mode (because of high traffic) or
6e8815
	a worker reads several requests in the read buffer (more_data), the thread
6e8815
	keeps processing connection.
6e8815
	In that condition it should not decrease the refcnt.
6e8815
	In case the operation is a persistent search, it decreases systematically
6e8815
	the refcnt.
6e8815
	So refcnt can become lower than the actual number of threads active on the connection.
6e8815
6e8815
	Most of the time it can create messages like
6e8815
		Attempt to release connection that is not acquired
6e8815
	In some rare case, if the a connection is out of the active list but a remaining thread
6e8815
	tries to remove it again it can lead to a crash
6e8815
6e8815
Fix Description:
6e8815
	The fix consist, when processing a PS, to decrease the refcnt at the condition
6e8815
	the connection is not in turbo mode or in more_data.
6e8815
6e8815
https://pagure.io/389-ds-base/issue/49768
6e8815
6e8815
Reviewed by: Mark Reynolds
6e8815
6e8815
Platforms tested: F26
6e8815
6e8815
Flag Day: no
6e8815
6e8815
Doc impact: no
6e8815
---
6e8815
 ldap/servers/slapd/connection.c | 14 +++++++++++---
6e8815
 1 file changed, 11 insertions(+), 3 deletions(-)
6e8815
6e8815
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
6e8815
index c54e7c26c..1dbb49f06 100644
6e8815
--- a/ldap/servers/slapd/connection.c
6e8815
+++ b/ldap/servers/slapd/connection.c
6e8815
@@ -1811,9 +1811,17 @@ connection_threadmain()
6e8815
         slapi_counter_increment(ops_completed);
6e8815
         /* If this op isn't a persistent search, remove it */
6e8815
         if (op->o_flags & OP_FLAG_PS) {
6e8815
-            PR_EnterMonitor(conn->c_mutex);
6e8815
-            connection_release_nolock(conn); /* psearch acquires ref to conn - release this one now */
6e8815
-            PR_ExitMonitor(conn->c_mutex);
6e8815
+            /* Release the connection (i.e. decrease refcnt) at the condition
6e8815
+             * this thread will not loop on it.
6e8815
+             * If we are in turbo mode (dedicated to that connection) or
6e8815
+             * more_data (continue reading buffered req) this thread
6e8815
+             * continues to hold the connection
6e8815
+             */
6e8815
+            if (!thread_turbo_flag && !more_data) {
6e8815
+                PR_EnterMonitor(conn->c_mutex);
6e8815
+                connection_release_nolock(conn); /* psearch acquires ref to conn - release this one now */
6e8815
+                PR_ExitMonitor(conn->c_mutex);
6e8815
+            }
6e8815
             /* ps_add makes a shallow copy of the pb - so we
6e8815
                  * can't free it or init it here - just set operation to NULL.
6e8815
                  * ps_send_results will call connection_remove_operation_ext to free it
6e8815
-- 
6e8815
2.17.1
6e8815