Blame SOURCES/0012-Ticket-47512-backend-txn-plugin-fixup-tasks-should-b.patch

ba46c7
From 9817459cec5df74f9270adc80cd2af5d80567068 Mon Sep 17 00:00:00 2001
ba46c7
From: Mark Reynolds <mreynolds@redhat.com>
ba46c7
Date: Fri, 13 Sep 2013 15:16:31 -0400
ba46c7
Subject: [PATCH 12/28] Ticket 47512 - backend txn plugin fixup tasks should be done in a txn
ba46c7
ba46c7
Description:  If a plugin is a backend txn plugin, then its fixup tasks should
ba46c7
              also be done in a transaction.
ba46c7
ba46c7
https://fedorahosted.org/389/ticket/47512
ba46c7
ba46c7
Reviewed by: richm(Thanks!)
ba46c7
(cherry picked from commit e439c4679b6e422103ec39a08c2013a37c0a7dd0)
ba46c7
(cherry picked from commit 76bad9a5751f1ecb2f792faf1f0687acf6661112)
ba46c7
---
ba46c7
 ldap/servers/plugins/automember/automember.c    |   32 +++++++++-
ba46c7
 ldap/servers/plugins/linkedattrs/fixup_task.c   |   80 ++++++++++++++++++++--
ba46c7
 ldap/servers/plugins/linkedattrs/linked_attrs.c |    3 +-
ba46c7
 ldap/servers/plugins/linkedattrs/linked_attrs.h |    2 +
ba46c7
 4 files changed, 106 insertions(+), 11 deletions(-)
ba46c7
ba46c7
diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c
ba46c7
index 02dcc0d..c7168cb 100644
ba46c7
--- a/ldap/servers/plugins/automember/automember.c
ba46c7
+++ b/ldap/servers/plugins/automember/automember.c
ba46c7
@@ -2135,7 +2135,7 @@ out:
ba46c7
 void automember_rebuild_task_thread(void *arg){
ba46c7
     Slapi_Task *task = (Slapi_Task *)arg;
ba46c7
     struct configEntry *config = NULL;
ba46c7
-    Slapi_PBlock *search_pb = NULL;
ba46c7
+    Slapi_PBlock *search_pb = NULL, *fixup_pb = NULL;
ba46c7
     Slapi_Entry **entries = NULL;
ba46c7
     task_data *td = NULL;
ba46c7
     PRCList *list = NULL;
ba46c7
@@ -2176,6 +2176,27 @@ void automember_rebuild_task_thread(void *arg){
ba46c7
         goto out;
ba46c7
     }
ba46c7
     slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
ba46c7
+
ba46c7
+    /*
ba46c7
+     * If this is a backend txn plugin, start the transaction
ba46c7
+     */
ba46c7
+    if (plugin_is_betxn) {
ba46c7
+        Slapi_Backend *be = slapi_be_select(td->base_dn);
ba46c7
+
ba46c7
+        if (be) {
ba46c7
+            fixup_pb = slapi_pblock_new();
ba46c7
+            slapi_pblock_set(fixup_pb, SLAPI_BACKEND, be);
ba46c7
+            if(slapi_back_transaction_begin(fixup_pb) != LDAP_SUCCESS){
ba46c7
+                slapi_log_error(SLAPI_LOG_FATAL, AUTOMEMBER_PLUGIN_SUBSYSTEM,
ba46c7
+                        "automember_rebuild_task_thread: failed to start transaction\n");
ba46c7
+            }
ba46c7
+        } else {
ba46c7
+            slapi_log_error(SLAPI_LOG_FATAL, AUTOMEMBER_PLUGIN_SUBSYSTEM,
ba46c7
+                    "automember_rebuild_task_thread: failed to get be backend from %s\n",
ba46c7
+                    slapi_sdn_get_dn(td->base_dn));
ba46c7
+        }
ba46c7
+    }
ba46c7
+
ba46c7
     /*
ba46c7
      *  Grab the config read lock, and loop over the entries
ba46c7
      */
ba46c7
@@ -2205,6 +2226,15 @@ void automember_rebuild_task_thread(void *arg){
ba46c7
     slapi_free_search_results_internal(search_pb);
ba46c7
 
ba46c7
 out:
ba46c7
+    if (plugin_is_betxn && fixup_pb) {
ba46c7
+        if (i == 0 || result != 0) { /* no updates performed */
ba46c7
+            slapi_back_transaction_abort(fixup_pb);
ba46c7
+        } else {
ba46c7
+            slapi_back_transaction_commit(fixup_pb);
ba46c7
+        }
ba46c7
+        slapi_pblock_destroy(fixup_pb);
ba46c7
+    }
ba46c7
+
ba46c7
     if(result){
ba46c7
         /* error */
ba46c7
         slapi_task_log_notice(task, "Automember rebuild task aborted.  Error (%d)", result);
ba46c7
diff --git a/ldap/servers/plugins/linkedattrs/fixup_task.c b/ldap/servers/plugins/linkedattrs/fixup_task.c
ba46c7
index 9fa7f6f..537544d 100644
ba46c7
--- a/ldap/servers/plugins/linkedattrs/fixup_task.c
ba46c7
+++ b/ldap/servers/plugins/linkedattrs/fixup_task.c
ba46c7
@@ -139,11 +139,11 @@ linked_attrs_fixup_task_destructor(Slapi_Task *task)
ba46c7
 static void
ba46c7
 linked_attrs_fixup_task_thread(void *arg)
ba46c7
 {
ba46c7
-	int rc = 0;
ba46c7
 	Slapi_Task *task = (Slapi_Task *)arg;
ba46c7
 	task_data *td = NULL;
ba46c7
 	PRCList *main_config = NULL;
ba46c7
 	int found_config = 0;
ba46c7
+	int rc = 0;
ba46c7
 
ba46c7
 	/* Fetch our task data from the task */
ba46c7
 	td = (task_data *)slapi_task_get_data(task);
ba46c7
@@ -218,8 +218,10 @@ static void
ba46c7
 linked_attrs_fixup_links(struct configEntry *config)
ba46c7
 {
ba46c7
     Slapi_PBlock *pb = slapi_pblock_new();
ba46c7
+    Slapi_PBlock *fixup_pb = NULL;
ba46c7
     char *del_filter = NULL;
ba46c7
     char *add_filter = NULL;
ba46c7
+    int rc = 0;
ba46c7
 
ba46c7
     del_filter = slapi_ch_smprintf("%s=*", config->managedtype);
ba46c7
     add_filter = slapi_ch_smprintf("%s=*", config->linktype);
ba46c7
@@ -228,12 +230,33 @@ linked_attrs_fixup_links(struct configEntry *config)
ba46c7
     slapi_lock_mutex(config->lock);
ba46c7
 
ba46c7
     if (config->scope) {
ba46c7
+        /*
ba46c7
+         * If this is a backend txn plugin, start the transaction
ba46c7
+         */
ba46c7
+        if (plugin_is_betxn) {
ba46c7
+            Slapi_DN *fixup_dn = slapi_sdn_new_dn_byref(config->scope);
ba46c7
+            Slapi_Backend *be = slapi_be_select(fixup_dn);
ba46c7
+
ba46c7
+            if (be) {
ba46c7
+                fixup_pb = slapi_pblock_new();
ba46c7
+                slapi_pblock_set(fixup_pb, SLAPI_BACKEND, be);
ba46c7
+                if(slapi_back_transaction_begin(fixup_pb) != LDAP_SUCCESS){
ba46c7
+                    slapi_log_error(SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM,
ba46c7
+                            "linked_attrs_fixup_links: failed to start transaction\n");
ba46c7
+                }
ba46c7
+            } else {
ba46c7
+                slapi_log_error(SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM,
ba46c7
+                        "linked_attrs_fixup_links: failed to get be backend from %s\n",
ba46c7
+                        config->scope);
ba46c7
+            }
ba46c7
+        }
ba46c7
+
ba46c7
         /* Find all entries with the managed type present
ba46c7
          * within the scope and remove the managed type. */
ba46c7
         slapi_search_internal_set_pb(pb, config->scope, LDAP_SCOPE_SUBTREE,
ba46c7
                 del_filter, 0, 0, 0, 0, linked_attrs_get_plugin_id(), 0);
ba46c7
 
ba46c7
-        slapi_search_internal_callback_pb(pb, config->managedtype, 0,
ba46c7
+        rc = slapi_search_internal_callback_pb(pb, config->managedtype, 0,
ba46c7
                 linked_attrs_remove_backlinks_callback, 0);
ba46c7
 
ba46c7
         /* Clean out pblock for reuse. */
ba46c7
@@ -246,16 +269,46 @@ linked_attrs_fixup_links(struct configEntry *config)
ba46c7
 
ba46c7
         slapi_search_internal_callback_pb(pb, config, 0,
ba46c7
                 linked_attrs_add_backlinks_callback, 0);
ba46c7
+        /*
ba46c7
+         *  Finish the transaction.
ba46c7
+         */
ba46c7
+        if (plugin_is_betxn && fixup_pb){
ba46c7
+            if(rc == 0){
ba46c7
+                slapi_back_transaction_commit(fixup_pb);
ba46c7
+            } else {
ba46c7
+            	slapi_back_transaction_abort(fixup_pb);
ba46c7
+            }
ba46c7
+            slapi_pblock_destroy(fixup_pb);
ba46c7
+        }
ba46c7
     } else {
ba46c7
         /* Loop through all non-private backend suffixes and
ba46c7
          * remove the managed type from any entry that has it.
ba46c7
          * We then find any entry with the linktype present and
ba46c7
          * generate the proper backlinks. */
ba46c7
         void *node = NULL;
ba46c7
-        Slapi_DN * suffix = slapi_get_first_suffix (&node, 0);
ba46c7
+        config->suffix = slapi_get_first_suffix (&node, 0);
ba46c7
+
ba46c7
+        while (config->suffix) {
ba46c7
+            /*
ba46c7
+             * If this is a backend txn plugin, start the transaction
ba46c7
+             */
ba46c7
+            if (plugin_is_betxn) {
ba46c7
+                Slapi_Backend *be = slapi_be_select(config->suffix);
ba46c7
+                if (be) {
ba46c7
+                    fixup_pb = slapi_pblock_new();
ba46c7
+                    slapi_pblock_set(fixup_pb, SLAPI_BACKEND, be);
ba46c7
+                    if(slapi_back_transaction_begin(fixup_pb) != LDAP_SUCCESS){
ba46c7
+                        slapi_log_error(SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM,
ba46c7
+                                "linked_attrs_fixup_links: failed to start transaction\n");
ba46c7
+                    }
ba46c7
+                } else {
ba46c7
+                    slapi_log_error(SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM,
ba46c7
+                            "linked_attrs_fixup_links: failed to get be backend from %s\n",
ba46c7
+                            slapi_sdn_get_dn(config->suffix));
ba46c7
+                }
ba46c7
+            }
ba46c7
 
ba46c7
-        while (suffix) {
ba46c7
-            slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(suffix),
ba46c7
+            slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(config->suffix),
ba46c7
                                          LDAP_SCOPE_SUBTREE, del_filter,
ba46c7
                                          0, 0, 0, 0,
ba46c7
                                          linked_attrs_get_plugin_id(), 0);
ba46c7
@@ -266,18 +319,29 @@ linked_attrs_fixup_links(struct configEntry *config)
ba46c7
             /* Clean out pblock for reuse. */
ba46c7
             slapi_pblock_init(pb);
ba46c7
 
ba46c7
-            slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(suffix),
ba46c7
+            slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(config->suffix),
ba46c7
                                          LDAP_SCOPE_SUBTREE, add_filter,
ba46c7
                                          0, 0, 0, 0,
ba46c7
                                          linked_attrs_get_plugin_id(), 0);
ba46c7
 
ba46c7
-            slapi_search_internal_callback_pb(pb, config, 0,
ba46c7
+            rc = slapi_search_internal_callback_pb(pb, config, 0,
ba46c7
                     linked_attrs_add_backlinks_callback, 0);
ba46c7
 
ba46c7
             /* Clean out pblock for reuse. */
ba46c7
             slapi_pblock_init(pb);
ba46c7
 
ba46c7
-            suffix = slapi_get_next_suffix (&node, 0);
ba46c7
+            config->suffix = slapi_get_next_suffix (&node, 0);
ba46c7
+            /*
ba46c7
+             *  Finish the transaction.
ba46c7
+             */
ba46c7
+            if (plugin_is_betxn && fixup_pb){
ba46c7
+                if(rc == 0){
ba46c7
+                    slapi_back_transaction_commit(fixup_pb);
ba46c7
+                } else {
ba46c7
+                	slapi_back_transaction_abort(fixup_pb);
ba46c7
+                }
ba46c7
+                slapi_pblock_destroy(fixup_pb);
ba46c7
+            }
ba46c7
         }
ba46c7
     }
ba46c7
 
ba46c7
diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.c b/ldap/servers/plugins/linkedattrs/linked_attrs.c
ba46c7
index 30a8653..1945828 100644
ba46c7
--- a/ldap/servers/plugins/linkedattrs/linked_attrs.c
ba46c7
+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.c
ba46c7
@@ -55,6 +55,7 @@ static Slapi_RWLock *g_config_lock;
ba46c7
 static void *_PluginID = NULL;
ba46c7
 static char *_PluginDN = NULL;
ba46c7
 static int g_plugin_started = 0;
ba46c7
+int plugin_is_betxn = 0;
ba46c7
 
ba46c7
 static Slapi_PluginDesc pdesc = { LINK_FEATURE_DESC,
ba46c7
                                   VENDOR,
ba46c7
@@ -164,8 +165,6 @@ linked_attrs_get_plugin_dn()
ba46c7
     return _PluginDN;
ba46c7
 }
ba46c7
 
ba46c7
-static int plugin_is_betxn = 0;
ba46c7
-
ba46c7
 /*
ba46c7
  * Plug-in initialization functions
ba46c7
  */
ba46c7
diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.h b/ldap/servers/plugins/linkedattrs/linked_attrs.h
ba46c7
index d0909ca..4721151 100644
ba46c7
--- a/ldap/servers/plugins/linkedattrs/linked_attrs.h
ba46c7
+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.h
ba46c7
@@ -82,6 +82,7 @@ struct configEntry {
ba46c7
     char *linktype;
ba46c7
     char *managedtype;
ba46c7
     char *scope;
ba46c7
+    Slapi_DN *suffix;
ba46c7
     Slapi_Mutex *lock;
ba46c7
 };
ba46c7
 
ba46c7
@@ -142,3 +143,4 @@ int linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
ba46c7
  * misc
ba46c7
  */
ba46c7
 int linked_attrs_is_started();
ba46c7
+extern int plugin_is_betxn;
ba46c7
-- 
ba46c7
1.7.1
ba46c7