Sfoglia il codice sorgente

defect 591
If checkpoint open is called, but checkpoint close isn't called before
saCkptFinalize is called, the reference count of the checkpoints gets
out of kilter.

(Logical change 1.197)


git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@645 fd59a12c-fef9-0310-b244-a6a79926bd2f

Steven Dake 20 anni fa
parent
commit
4ad46bbf70
1 ha cambiato i file con 27 aggiunte e 4 eliminazioni
  1. 27 4
      lib/ckpt.c

+ 27 - 4
lib/ckpt.c

@@ -66,15 +66,18 @@ struct ckptInstance {
 	int finalize;
 	pthread_mutex_t response_mutex;
 	pthread_mutex_t dispatch_mutex;
+	struct list_head checkpoint_list;
 };
 
 struct ckptCheckpointInstance {
 	int response_fd;
 	SaCkptHandleT ckptHandle;
+	SaCkptCheckpointHandleT checkpointHandle;
 	SaCkptCheckpointOpenFlagsT checkpointOpenFlags;
 	SaNameT checkpointName;
 	SaUint32T maxSectionIdSize;
 	pthread_mutex_t response_mutex;
+	struct list_head list;
 };
 
 struct ckptSectionIterationInstance {
@@ -198,6 +201,8 @@ saCkptInitialize (
 
 	memcpy (&ckptInstance->callbacks, callbacks, sizeof (SaCkptCallbacksT));
 
+	list_init (&ckptInstance->checkpoint_list);
+
 	pthread_mutex_init (&ckptInstance->response_mutex, NULL);
 
 	saHandleInstancePut (&ckptHandleDatabase, *ckptHandle);
@@ -363,6 +368,8 @@ saCkptFinalize (
 {
 	struct ckptInstance *ckptInstance;
 	SaAisErrorT error;
+	struct list_head *list;
+	struct ckptCheckpointInstance *ckptCheckpointInstance;
 
 	error = saHandleInstanceGet (&ckptHandleDatabase, ckptHandle,
 		(void *)&ckptInstance);
@@ -385,9 +392,21 @@ saCkptFinalize (
 
 	pthread_mutex_unlock (&ckptInstance->response_mutex);
 
+
+	for (list = ckptInstance->checkpoint_list.next;
+		list != &ckptInstance->checkpoint_list;
+		list = list->next) {
+
+		ckptCheckpointInstance = list_entry (list,
+			struct ckptCheckpointInstance, list);
+
+		saHandleInstancePut (&checkpointHandleDatabase,
+			ckptCheckpointInstance->checkpointHandle);
+	}
+
 	saHandleInstancePut (&ckptHandleDatabase, ckptHandle);
 
-    saHandleDestroy (&ckptHandleDatabase, ckptHandle);
+	saHandleDestroy (&ckptHandleDatabase, ckptHandle);
 
 	return (SA_AIS_OK);
 }
@@ -413,8 +432,8 @@ saCkptCheckpointOpen (
 		goto error_no_destroy;
 	}
 
-	error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
-		(void *)&ckptCheckpointInstance);
+	error = saHandleInstanceGet (&checkpointHandleDatabase,
+		*checkpointHandle, (void *)&ckptCheckpointInstance);
 	if (error != SA_AIS_OK) {
 		goto error_destroy;
 	}
@@ -431,6 +450,7 @@ saCkptCheckpointOpen (
 		checkpointCreationAttributes->maxSectionIdSize;
 
 	ckptCheckpointInstance->ckptHandle = ckptHandle;
+	ckptCheckpointInstance->checkpointHandle = *checkpointHandle;
 	ckptCheckpointInstance->checkpointOpenFlags = checkpointOpenFlags;
 
 	req_lib_ckpt_checkpointopen.header.size = sizeof (struct req_lib_ckpt_checkpointopen);
@@ -463,6 +483,7 @@ saCkptCheckpointOpen (
 
 	saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
 
+	list_add (&ckptCheckpointInstance->list, &ckptInstance->checkpoint_list);
 	return (error);
 
 error_put_ckpt_destroy:
@@ -578,9 +599,11 @@ saCkptCheckpointClose (
 		sizeof (struct res_lib_ckpt_checkpointclose), MSG_WAITALL | MSG_NOSIGNAL);
 
 
+	list_del (&ckptCheckpointInstance->list);
+
 	saHandleInstancePut (&ckptHandleDatabase, ckptCheckpointInstance->ckptHandle);
 
-    saHandleDestroy (&checkpointHandleDatabase, checkpointHandle);
+	saHandleDestroy (&checkpointHandleDatabase, checkpointHandle);
 
 exit_put:
 	saHandleInstancePut (&checkpointHandleDatabase, checkpointHandle);