andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 209da318fec805ca0430f50337e829133ac444a0 Mon Sep 17 00:00:00 2001
dc8c34
From: Noriko Hosoi <nhosoi@totoro.usersys.redhat.com>
dc8c34
Date: Fri, 8 Feb 2013 12:13:14 -0800
dc8c34
Subject: [PATCH 32/33] Ticket #576 - DNA: use event queue for config update
dc8c34
 only at the start up
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/576
dc8c34
dc8c34
Bug description: DNA config updates were always put into the
dc8c34
event queue and executed in 30 seconds, which increased a chance
dc8c34
to conflict with the ordinary modify operations and cause db
dc8c34
deadlocks.
dc8c34
dc8c34
Fix description: The 30 seconds delay is necessary at the start-
dc8c34
up time when MMR is configured to guarantee the shared config is
dc8c34
logged in the changelog.  This patch leaves the behaviour of the
dc8c34
config update at the start-up as it is; the rest won't be queued
dc8c34
but updated immediately.
dc8c34
dc8c34
Reviewed by Rich (Thank you!!)
dc8c34
(cherry picked from commit 7c11ed17796ba8b17afa5758fcfdf1c937b54ef4)
dc8c34
---
dc8c34
 ldap/servers/plugins/dna/dna.c |   78 +++++++++++++++++++++++++++------------
dc8c34
 1 files changed, 54 insertions(+), 24 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
dc8c34
index 36dd936..6babe23 100644
dc8c34
--- a/ldap/servers/plugins/dna/dna.c
dc8c34
+++ b/ldap/servers/plugins/dna/dna.c
dc8c34
@@ -93,6 +93,7 @@
dc8c34
 #define DNA_SHARED_CFG_DN   "dnaSharedCfgDN"
dc8c34
 
dc8c34
 /* Shared Config */
dc8c34
+#define DNA_SHAREDCONFIG    "dnaSharedConfig"
dc8c34
 #define DNA_REMAINING       "dnaRemainingValues"
dc8c34
 #define DNA_THRESHOLD       "dnaThreshold"
dc8c34
 #define DNA_HOSTNAME        "dnaHostname"
dc8c34
@@ -219,7 +220,7 @@ static int dna_be_txn_preop_init(Slapi_PBlock *pb);
dc8c34
  * Local operation functions
dc8c34
  *
dc8c34
  */
dc8c34
-static int dna_load_plugin_config();
dc8c34
+static int dna_load_plugin_config(int use_eventq);
dc8c34
 static int dna_parse_config_entry(Slapi_Entry * e, int apply);
dc8c34
 static void dna_delete_config();
dc8c34
 static void dna_free_config_entry(struct configEntry ** entry);
dc8c34
@@ -571,7 +572,7 @@ dna_start(Slapi_PBlock * pb)
dc8c34
         slapi_ch_calloc(1, sizeof(struct configEntry));
dc8c34
     PR_INIT_CLIST(dna_global_config);
dc8c34
 
dc8c34
-    if (dna_load_plugin_config() != DNA_SUCCESS) {
dc8c34
+    if (dna_load_plugin_config(1/* use eventq */) != DNA_SUCCESS) {
dc8c34
         slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
dc8c34
                         "dna_start: unable to load plug-in configuration\n");
dc8c34
         return DNA_FAILURE;
dc8c34
@@ -639,7 +640,7 @@ done:
dc8c34
  * ------ cn=etc etc
dc8c34
  */
dc8c34
 static int
dc8c34
-dna_load_plugin_config()
dc8c34
+dna_load_plugin_config(int use_eventq)
dc8c34
 {
dc8c34
     int status = DNA_SUCCESS;
dc8c34
     int result;
dc8c34
@@ -649,7 +650,8 @@ dna_load_plugin_config()
dc8c34
     Slapi_Entry **entries = NULL;
dc8c34
 
dc8c34
     slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
dc8c34
-                    "--> dna_load_plugin_config\n");
dc8c34
+                    "--> dna_load_plugin_config %s\n",
dc8c34
+                    use_eventq?"using event queue":"");
dc8c34
 
dc8c34
     dna_write_lock();
dc8c34
     dna_delete_config();
dc8c34
@@ -681,13 +683,18 @@ dna_load_plugin_config()
dc8c34
         dna_parse_config_entry(entries[i], 1);
dc8c34
     }
dc8c34
 
dc8c34
-    /* Setup an event to update the shared config 30
dc8c34
-     * seconds from now.  We need to do this since
dc8c34
-     * performing the operation at this point when
dc8c34
-     * starting up  would cause the change to not
dc8c34
-     * get changelogged. */
dc8c34
-    time(&now;;
dc8c34
-    slapi_eq_once(dna_update_config_event, NULL, now + 30);
dc8c34
+    if (use_eventq) {
dc8c34
+        /* Setup an event to update the shared config 30
dc8c34
+         * seconds from now.  We need to do this since
dc8c34
+         * performing the operation at this point when
dc8c34
+         * starting up  would cause the change to not
dc8c34
+         * get changelogged. */
dc8c34
+        time(&now;;
dc8c34
+        slapi_eq_once(dna_update_config_event, NULL, now + 30);
dc8c34
+    } else {
dc8c34
+        int nolock = 1; /* no need to lock since dna write lock is held. */
dc8c34
+        dna_update_config_event(0, &nolock);
dc8c34
+    }
dc8c34
 
dc8c34
 cleanup:
dc8c34
     slapi_free_search_results_internal(search_pb);
dc8c34
@@ -1240,9 +1247,15 @@ dna_update_config_event(time_t event_time, void *arg)
dc8c34
     Slapi_PBlock *pb = NULL;
dc8c34
     struct configEntry *config_entry = NULL;
dc8c34
     PRCList *list = NULL;
dc8c34
+    int nolock = 0;
dc8c34
 
dc8c34
-    /* Get read lock to prevent config changes */
dc8c34
-    dna_read_lock();
dc8c34
+    if (arg) {
dc8c34
+        nolock = *(int *)arg;
dc8c34
+    }
dc8c34
+    if (!nolock) {
dc8c34
+        /* Get read lock to prevent config changes */
dc8c34
+        dna_read_lock();
dc8c34
+    }
dc8c34
 
dc8c34
     /* Bail out if the plug-in close function was just called. */
dc8c34
     if (!g_plugin_started) {
dc8c34
@@ -1287,7 +1300,9 @@ dna_update_config_event(time_t event_time, void *arg)
dc8c34
     }
dc8c34
 
dc8c34
 bail:
dc8c34
-    dna_unlock();
dc8c34
+    if (!nolock) {
dc8c34
+        dna_unlock();
dc8c34
+    }
dc8c34
     slapi_pblock_destroy(pb);
dc8c34
 }
dc8c34
 
dc8c34
@@ -2161,7 +2176,7 @@ dna_update_shared_config(struct configEntry * config_entry)
dc8c34
                 slapi_entry_init_ext(e, sdn, NULL); /* sdn is copied into e */
dc8c34
                 slapi_sdn_free(&sdn;;
dc8c34
 
dc8c34
-                slapi_entry_add_string(e, SLAPI_ATTR_OBJECTCLASS, "dnaSharedConfig");
dc8c34
+                slapi_entry_add_string(e, SLAPI_ATTR_OBJECTCLASS, DNA_SHAREDCONFIG);
dc8c34
                 slapi_entry_add_string(e, DNA_HOSTNAME, hostname);
dc8c34
                 slapi_entry_add_string(e, DNA_PORTNUM, portnum);
dc8c34
                 if (secureportnum) {
dc8c34
@@ -2770,6 +2785,7 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e, char **errstr)
dc8c34
     char **generated_types = NULL;
dc8c34
     PRUint64 setval = 0;
dc8c34
     int i;
dc8c34
+    int issharedconfig = 0;
dc8c34
 
dc8c34
     /* Bail out if the plug-in close function was just called. */
dc8c34
     if (!g_plugin_started) {
dc8c34
@@ -2787,7 +2803,12 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e, char **errstr)
dc8c34
      *  We also check if we need to get the next range of values, and grab them.
dc8c34
      *  We do this here so we don't have to do it in the be_txn_preop.
dc8c34
      */
dc8c34
-    dna_read_lock();
dc8c34
+    /* Has write lock for config entries. */
dc8c34
+    issharedconfig = slapi_entry_attr_hasvalue(e, SLAPI_ATTR_OBJECTCLASS,
dc8c34
+                                               DNA_SHAREDCONFIG);
dc8c34
+    if (!issharedconfig) {
dc8c34
+        dna_read_lock();
dc8c34
+    }
dc8c34
 
dc8c34
     if (!PR_CLIST_IS_EMPTY(dna_global_config)) {
dc8c34
         list = PR_LIST_HEAD(dna_global_config);
dc8c34
@@ -2945,7 +2966,9 @@ next:
dc8c34
         }
dc8c34
     }
dc8c34
 
dc8c34
-    dna_unlock();
dc8c34
+    if (!issharedconfig) {
dc8c34
+        dna_unlock();
dc8c34
+    }
dc8c34
 
dc8c34
     slapi_ch_array_free(generated_types);
dc8c34
 bail:
dc8c34
@@ -3314,7 +3337,7 @@ dna_pre_op(Slapi_PBlock * pb, int modtype)
dc8c34
             ret = _dna_pre_op_add(pb, test_e, &errstr);
dc8c34
         } else {
dc8c34
             if((ret = _dna_pre_op_modify(pb, test_e, smods, &errstr))){
dc8c34
-            	slapi_mods_free(&smods);
dc8c34
+                slapi_mods_free(&smods);
dc8c34
             }
dc8c34
         }
dc8c34
         if (ret) {
dc8c34
@@ -3404,6 +3427,7 @@ static int dna_be_txn_pre_op(Slapi_PBlock *pb, int modtype)
dc8c34
     char *type = NULL;
dc8c34
     int numvals, e_numvals = 0;
dc8c34
     int i, len, ret = 0;
dc8c34
+    int issharedconfig = 0;
dc8c34
 
dc8c34
     slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
dc8c34
                     "--> dna_be_txn_pre_op\n");
dc8c34
@@ -3439,7 +3463,12 @@ static int dna_be_txn_pre_op(Slapi_PBlock *pb, int modtype)
dc8c34
         slapi_mods_init_passin(smods, mods);
dc8c34
     }
dc8c34
 
dc8c34
-    dna_read_lock();
dc8c34
+    /* Has write lock for config entries. */
dc8c34
+    issharedconfig = slapi_entry_attr_hasvalue(e, SLAPI_ATTR_OBJECTCLASS,
dc8c34
+                                               DNA_SHAREDCONFIG);
dc8c34
+    if (!issharedconfig) {
dc8c34
+        dna_read_lock();
dc8c34
+    }
dc8c34
 
dc8c34
     if (!PR_CLIST_IS_EMPTY(dna_global_config)) {
dc8c34
         list = PR_LIST_HEAD(dna_global_config);
dc8c34
@@ -3449,7 +3478,7 @@ static int dna_be_txn_pre_op(Slapi_PBlock *pb, int modtype)
dc8c34
 
dc8c34
             /* Did we already service all of these configured types? */
dc8c34
             if (dna_list_contains_types(generated_types, config_entry->types)) {
dc8c34
-                    goto next;
dc8c34
+                goto next;
dc8c34
             }
dc8c34
 
dc8c34
             /* is the entry in scope? */
dc8c34
@@ -3626,12 +3655,13 @@ static int dna_be_txn_pre_op(Slapi_PBlock *pb, int modtype)
dc8c34
             } else if (types_to_generate) {
dc8c34
                 slapi_ch_free((void **)&types_to_generate);
dc8c34
             }
dc8c34
-          next:
dc8c34
+next:
dc8c34
             list = PR_NEXT_LINK(list);
dc8c34
         }
dc8c34
     }
dc8c34
-    dna_unlock();
dc8c34
-
dc8c34
+    if (!issharedconfig) {
dc8c34
+        dna_unlock();
dc8c34
+    }
dc8c34
 bail:
dc8c34
 
dc8c34
     if (LDAP_CHANGETYPE_MODIFY == modtype) {
dc8c34
@@ -3669,7 +3699,7 @@ static int dna_config_check_post_op(Slapi_PBlock * pb)
dc8c34
     if (!slapi_op_internal(pb)) { /* If internal, no need to check. */
dc8c34
         if ((dn = dna_get_dn(pb))) {
dc8c34
             if (dna_dn_is_config(dn)) {
dc8c34
-                dna_load_plugin_config();
dc8c34
+                dna_load_plugin_config(0);
dc8c34
             }
dc8c34
         }
dc8c34
     }
dc8c34
-- 
dc8c34
1.7.7.6
dc8c34