Browse Source

515805 - Stop "initialize Database" crashes the server

https://bugzilla.redhat.com/show_bug.cgi?id=515805

Fix Description:
SLAPI_TASK_CANCELLED could be set in task_modify any time by
users' modifying nsTaskCancel value to TRUE.  Then the following
slapi_task_status_changed destroys the task, which is called
even via a simple logging call slapi_task_log_status.  After the
task is destroyed, any task related calls such as another
slapi_task_log_status or slapi_task_finish crashes the server.

This fix changes the behaviour to destroy the task only when
task_state is SLAPI_TASK_FINISHED.  Once SLAPI_TASK_CANCELLED
is set to task_state, changing the state to SLAPI_TASK_FINISHED
by calling slapi_task_finish is the responsibility of the task
application (e.g., import).  Until then, it is guranteed that
the task is available.
Noriko Hosoi 15 years ago
parent
commit
6236bb36b7
2 changed files with 28 additions and 2 deletions
  1. 22 0
      ldap/servers/slapd/back-ldbm/import.c
  2. 6 2
      ldap/servers/slapd/task.c

+ 22 - 0
ldap/servers/slapd/back-ldbm/import.c

@@ -1076,6 +1076,7 @@ int import_main_offline(void *arg)
     int finished = 0;
     int status = 0;
     int verbose = 1;
+    int aborted = 0;
     ImportWorkerInfo *producer = NULL;
 
     if (job->task)
@@ -1194,6 +1195,7 @@ int import_main_offline(void *arg)
              */
             import_set_abort_flag_all(job, 1); 
             import_log_notice(job, "Import threads aborted.");
+            aborted = 1;
             goto error;
         }
 
@@ -1301,6 +1303,26 @@ error:
     if (entryrdn_get_switch()) {
         cache_clear(&job->inst->inst_dncache, CACHE_TYPE_DN);
     }
+    if (aborted) {
+        /* If aborted, it's safer to rebuild the caches. */
+        cache_destroy_please(&job->inst->inst_cache, CACHE_TYPE_ENTRY);
+        if (entryrdn_get_switch()) { /* subtree-rename: on */
+            cache_destroy_please(&job->inst->inst_dncache, CACHE_TYPE_DN);
+        }
+        /* initialize the entry cache */
+        if (! cache_init(&(inst->inst_cache), DEFAULT_CACHE_SIZE,
+                         DEFAULT_CACHE_ENTRIES, CACHE_TYPE_ENTRY)) {
+            LDAPDebug0Args(LDAP_DEBUG_ANY, "import_main_offline: "
+                        "cache_init failed.  Server should be restarted.\n");
+        }
+
+        /* initialize the dn cache */
+        if (! cache_init(&(inst->inst_dncache), DEFAULT_DNCACHE_SIZE,
+                     DEFAULT_DNCACHE_MAXCOUNT, CACHE_TYPE_DN)) {
+            LDAPDebug0Args(LDAP_DEBUG_ANY, "import_main_offline: "
+                        "dn cache_init failed.  Server should be restarted.\n");
+        }
+    }
     if (0 != ret) {
         dblayer_delete_instance_dir(be);
         dblayer_instance_close(job->inst->inst_be);

+ 6 - 2
ldap/servers/slapd/task.c

@@ -309,8 +309,11 @@ void slapi_task_status_changed(Slapi_Task *task)
     for (i = 0; i < cur; i++)
         slapi_ch_free((void **)&modlist[i].mod_values);
 
-    if (((task->task_state == SLAPI_TASK_FINISHED) ||
-         (task->task_state == SLAPI_TASK_CANCELLED)) &&
+    /*
+     * Removed (task->task_state == SLAPI_TASK_CANCELLED) from 
+     * task_state checking to fix bz 515805.
+     */
+    if ((task->task_state == SLAPI_TASK_FINISHED) &&
         !(task->task_flags & SLAPI_TASK_DESTROYING)) {
         Slapi_PBlock *pb = slapi_pblock_new();
         Slapi_Entry *e;
@@ -664,6 +667,7 @@ static void task_generic_destructor(Slapi_Task *task)
     }
     if (task->task_log_lock) {
         PR_DestroyLock(task->task_log_lock);
+        task->task_log_lock = NULL;
     }
     task->task_log = task->task_status = NULL;
 }