소스 검색

defect 1113
Checkpoint iteration is totally broken. This patch makes checkpoint iteration
work properly for multiple checkpoint iterators and now is compliant with the
specifications for the trunk version.


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

Steven Dake 20 년 전
부모
커밋
0abc730b42
5개의 변경된 파일243개의 추가작업 그리고 153개의 파일을 삭제
  1. 175 123
      exec/ckpt.c
  2. 16 0
      include/hdb.h
  3. 12 10
      include/ipc_ckpt.h
  4. 24 17
      lib/ckpt.c
  5. 16 3
      test/testckpt.c

+ 175 - 123
exec/ckpt.c

@@ -50,6 +50,7 @@
 #include "../include/ipc_ckpt.h"
 #include "../include/list.h"
 #include "../include/queue.h"
+#include "../include/hdb.h"
 #include "../lcr/lcr_comp.h"
 #include "aispoll.h"
 #include "mempool.h"
@@ -93,7 +94,7 @@ struct saCkptCheckpoint {
 	struct list_head list;
 	SaNameT name;
 	SaCkptCheckpointCreationAttributesT checkpointCreationAttributes;
-	struct list_head checkpointSectionsListHead;
+	struct list_head sections_list_head;
 	int referenceCount;
 	int unlinked;
 	poll_timer_handle retention_timer;
@@ -103,21 +104,21 @@ struct saCkptCheckpoint {
 	struct ckpt_refcnt ckpt_refcount[32]; // SHOULD BE PROCESSOR COUNT MAX	
 };
 
-struct saCkptSectionIteratorEntry {
+struct iteration_entry {
 	int active;
-	struct saCkptCheckpointSection *checkpointSection;
+	struct saCkptCheckpointSection *checkpoint_section;
 };
 
-struct saCkptSectionIterator {
-	struct list_head list;
-	struct saCkptSectionIteratorEntry *sectionIteratorEntries;
-	int iteratorCount;
-	int iteratorPos;
+struct iteration_instance {
+	struct iteration_entry *iteration_entries;
+	int iteration_entries_count;
+	unsigned int iteration_pos;
 };
 
 struct ckpt_pd {
 	struct list_head checkpoint_list;
-	struct saCkptSectionIterator sectionIterator;
+	struct hdb_handle_database iteration_hdb;
+	unsigned int iteration_pos;
 };
 
 struct ckpt_identifier {
@@ -200,7 +201,7 @@ static void message_handler_req_lib_ckpt_sectioniterationfinalize (
 	void *conn,
 	void *msg);
 
-static void message_handler_req_lib_ckpt_sectioniteratornext (
+static void message_handler_req_lib_ckpt_sectioniterationnext (
 	void *conn,
 	void *msg);
 
@@ -290,7 +291,7 @@ static int process_localhost_transition = 0;
 
 DECLARE_LIST_INIT(checkpoint_list_head);
 
-DECLARE_LIST_INIT(checkpoint_iterator_list_head);
+DECLARE_LIST_INIT(checkpoint_iteration_list_head);
 
 DECLARE_LIST_INIT(checkpoint_recovery_list_head);
 
@@ -420,19 +421,19 @@ static struct openais_lib_handler ckpt_lib_handlers[] =
 	{ /* 15 */
 		.lib_handler_fn		= message_handler_req_lib_ckpt_sectioniterationinitialize,
 		.response_size		= sizeof (struct res_lib_ckpt_sectioniterationinitialize),
-		.response_id		= MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORINITIALIZE,
+		.response_id		= MESSAGE_RES_CKPT_SECTIONITERATIONINITIALIZE,
 		.flow_control		= OPENAIS_FLOW_CONTROL_NOT_REQUIRED
 	},
 	{ /* 16 */
 		.lib_handler_fn		= message_handler_req_lib_ckpt_sectioniterationfinalize,
 		.response_size		= sizeof (struct res_lib_ckpt_sectioniterationfinalize),
-		.response_id		= MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORFINALIZE,
+		.response_id		= MESSAGE_RES_CKPT_SECTIONITERATIONFINALIZE,
 		.flow_control		= OPENAIS_FLOW_CONTROL_NOT_REQUIRED
 	},
 	{ /* 17 */
-		.lib_handler_fn		= message_handler_req_lib_ckpt_sectioniteratornext,
-		.response_size		= sizeof (struct res_lib_ckpt_sectioniteratornext),
-		.response_id		= MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORNEXT,
+		.lib_handler_fn		= message_handler_req_lib_ckpt_sectioniterationnext,
+		.response_size		= sizeof (struct res_lib_ckpt_sectioniterationnext),
+		.response_id		= MESSAGE_RES_CKPT_SECTIONITERATIONNEXT,
 		.flow_control		= OPENAIS_FLOW_CONTROL_NOT_REQUIRED
 	}
 };
@@ -825,9 +826,9 @@ static void ckpt_recovery_initialize (void)
 		memcpy(savedCheckpoint, checkpoint, sizeof(struct saCkptCheckpoint));
 		list_init(&savedCheckpoint->list);		
 		list_add(&savedCheckpoint->list,&checkpoint_recovery_list_head);
-		list_init(&savedCheckpoint->checkpointSectionsListHead);
-		for (checkpoint_section_list = checkpoint->checkpointSectionsListHead.next;
-			checkpoint_section_list != &checkpoint->checkpointSectionsListHead;
+		list_init(&savedCheckpoint->sections_list_head);
+		for (checkpoint_section_list = checkpoint->sections_list_head.next;
+			checkpoint_section_list != &checkpoint->sections_list_head;
 			checkpoint_section_list = checkpoint_section_list->next) {
 			section = list_entry (checkpoint_section_list,
 								struct saCkptCheckpointSection, list);
@@ -837,7 +838,7 @@ static void ckpt_recovery_initialize (void)
 			poll_timer_delete_data (aisexec_poll_handle, section->expiration_timer);
 			memcpy(savedSection, section, sizeof(struct saCkptCheckpointSection));
 			list_init(&savedSection->list);		
-			list_add(&savedSection->list,&savedCheckpoint->checkpointSectionsListHead);
+			list_add(&savedSection->list,&savedCheckpoint->sections_list_head);
 		}
 	}
 	
@@ -847,7 +848,7 @@ static void ckpt_recovery_initialize (void)
 	recovery_ckpt_next = checkpoint_recovery_list_head.next;
 	savedCheckpoint = list_entry (recovery_ckpt_next,
 								struct saCkptCheckpoint, list);
-	recovery_ckpt_section_next = savedCheckpoint->checkpointSectionsListHead.next;
+	recovery_ckpt_section_next = savedCheckpoint->sections_list_head.next;
 }
 
 static int ckpt_recovery_process (void) 
@@ -886,9 +887,9 @@ static int ckpt_recovery_process (void)
 			checkpoint = list_entry (recovery_ckpt_next,
 							struct saCkptCheckpoint, list);
 			if (recovery_ckpt_section_next == 0) {
-				recovery_ckpt_section_next = checkpoint->checkpointSectionsListHead.next;
+				recovery_ckpt_section_next = checkpoint->sections_list_head.next;
 			}
-			if (recovery_ckpt_section_next != &checkpoint->checkpointSectionsListHead) {
+			if (recovery_ckpt_section_next != &checkpoint->sections_list_head) {
 				ckptCheckpointSection = list_entry (recovery_ckpt_section_next,
 											struct saCkptCheckpointSection, list);
 				/*
@@ -1085,15 +1086,15 @@ static void ckpt_recovery_finalize (void)
 		checkpoint = list_entry (checkpoint_list,
             			struct saCkptCheckpoint, list);
             			
-		checkpoint_section_list = checkpoint->checkpointSectionsListHead.next;	
-		while (!list_empty(&checkpoint->checkpointSectionsListHead)) {
+		checkpoint_section_list = checkpoint->sections_list_head.next;	
+		while (!list_empty(&checkpoint->sections_list_head)) {
 			section = list_entry (checkpoint_section_list,
 				struct saCkptCheckpointSection, list);
 			
 			list_del (&section->list);			
 			log_printf (LOG_LEVEL_DEBUG, "ckpt_recovery_finalize removed 0x%x.\n", section);
 			free (section);
-			checkpoint_section_list = checkpoint->checkpointSectionsListHead.next;
+			checkpoint_section_list = checkpoint->sections_list_head.next;
 		}
 		list_del(&checkpoint->list);
 		free(checkpoint);
@@ -1120,8 +1121,8 @@ static void ckpt_recovery_finalize (void)
 		checkpoint = list_entry (checkpoint_list,
 			struct saCkptCheckpoint, list);
 
-		for (checkpoint_section_list = checkpoint->checkpointSectionsListHead.next;
-                        checkpoint_section_list != &checkpoint->checkpointSectionsListHead;
+		for (checkpoint_section_list = checkpoint->sections_list_head.next;
+                        checkpoint_section_list != &checkpoint->sections_list_head;
                         checkpoint_section_list = checkpoint_section_list->next) {
                         section = list_entry (checkpoint_section_list,
                                                                 struct saCkptCheckpointSection, list);
@@ -1379,8 +1380,8 @@ static struct saCkptCheckpointSection *ckpt_checkpoint_find_globalSection (
 	else {
 		log_printf (LOG_LEVEL_DEBUG, "Finding default checkpoint section\n");
 	}
-	for (checkpoint_section_list = ckptCheckpoint->checkpointSectionsListHead.next;
-		checkpoint_section_list != &ckptCheckpoint->checkpointSectionsListHead;
+	for (checkpoint_section_list = ckptCheckpoint->sections_list_head.next;
+		checkpoint_section_list != &ckptCheckpoint->sections_list_head;
 		checkpoint_section_list = checkpoint_section_list->next) {
 
 		ckptCheckpointSection = list_entry (checkpoint_section_list,
@@ -1462,8 +1463,8 @@ void checkpoint_release (struct saCkptCheckpoint *checkpoint)
 	/*
 	 * Release all checkpoint sections for this checkpoint
 	 */
-	for (list = checkpoint->checkpointSectionsListHead.next;
-		list != &checkpoint->checkpointSectionsListHead;) {
+	for (list = checkpoint->sections_list_head.next;
+		list != &checkpoint->sections_list_head;) {
 
 		section = list_entry (list,
 			struct saCkptCheckpointSection, list);
@@ -1578,7 +1579,7 @@ static void message_handler_req_exec_ckpt_checkpointopen (
 			sizeof (SaCkptCheckpointCreationAttributesT));
 		ckptCheckpoint->unlinked = 0;
 		list_init (&ckptCheckpoint->list);
-		list_init (&ckptCheckpoint->checkpointSectionsListHead);
+		list_init (&ckptCheckpoint->sections_list_head);
 		list_add (&ckptCheckpoint->list, &checkpoint_list_head);
 		ckptCheckpoint->referenceCount = 0;
 		ckptCheckpoint->retention_timer = 0;
@@ -1601,7 +1602,7 @@ static void message_handler_req_exec_ckpt_checkpointopen (
 		 * Add in default checkpoint section
 		 */
 		list_init (&ckptCheckpointSection->list);
-		list_add (&ckptCheckpointSection->list, &ckptCheckpoint->checkpointSectionsListHead);
+		list_add (&ckptCheckpointSection->list, &ckptCheckpoint->sections_list_head);
 		
 		/*
 		 * Default section id
@@ -1779,7 +1780,7 @@ static int recovery_checkpoint_open(
 			sizeof (SaCkptCheckpointCreationAttributesT));
 		ckptCheckpoint->unlinked = 0;
 		list_init (&ckptCheckpoint->list);
-		list_init (&ckptCheckpoint->checkpointSectionsListHead);
+		list_init (&ckptCheckpoint->sections_list_head);
 		list_add (&ckptCheckpoint->list, &checkpoint_list_head);
 		ckptCheckpoint->retention_timer = 0;
 		ckptCheckpoint->expired = 0;
@@ -1788,7 +1789,7 @@ static int recovery_checkpoint_open(
 		 * Add in default checkpoint section
 		 */
 		list_init (&ckptCheckpointSection->list);
-		list_add (&ckptCheckpointSection->list, &ckptCheckpoint->checkpointSectionsListHead);
+		list_add (&ckptCheckpointSection->list, &ckptCheckpoint->sections_list_head);
 		
 		/*
 		 * Default section id
@@ -2352,7 +2353,7 @@ static int recovery_section_create (SaCkptSectionDescriptorT *sectionDescriptor,
 	 */
 	list_init (&ckptCheckpointSection->list);
 	list_add (&ckptCheckpointSection->list,
-		&ckptCheckpoint->checkpointSectionsListHead);
+		&ckptCheckpoint->sections_list_head);
 
 error_exit:
 	return (error);				
@@ -2485,7 +2486,7 @@ static void message_handler_req_exec_ckpt_sectioncreate (
 	 */
 	list_init (&ckptCheckpointSection->list);
 	list_add (&ckptCheckpointSection->list,
-		&ckptCheckpoint->checkpointSectionsListHead);
+		&ckptCheckpoint->sections_list_head);
 	ckptCheckpoint->sectionCount += 1;
 
 error_exit:
@@ -2971,13 +2972,12 @@ static int ckpt_lib_init_fn (void *conn)
 {
 	struct ckpt_pd *ckpt_pd = (struct ckpt_pd *)openais_conn_private_data_get (conn);
 
-	
-	list_init (&ckpt_pd->sectionIterator.list);
-	ckpt_pd->sectionIterator.sectionIteratorEntries = 0;
-	ckpt_pd->sectionIterator.iteratorCount = 0;
-	ckpt_pd->sectionIterator.iteratorPos = 0;
+	hdb_create (&ckpt_pd->iteration_hdb);
+
+	/* TODO
 	list_add (&ckpt_pd->sectionIterator.list,
-		&checkpoint_iterator_list_head);
+		&checkpoint_iteration_list_head);
+		*/
 	list_init (&ckpt_pd->checkpoint_list);
 
        return (0);
@@ -3011,10 +3011,12 @@ static int ckpt_lib_exit_fn (void *conn)
 		cleanup_list = ckpt_pd->checkpoint_list.next;
 	}
 
+	/* TODO
 	if (ckpt_pd->sectionIterator.sectionIteratorEntries) {
 		free (ckpt_pd->sectionIterator.sectionIteratorEntries);
 	}
 	list_del (&ckpt_pd->sectionIterator.list);
+	*/
 	return (0);
 }
 
@@ -3228,8 +3230,8 @@ static void message_handler_req_lib_ckpt_checkpointstatusget (
 	
 	if (checkpoint && (checkpoint->expired == 0)) {
 
-		for (checkpoint_section_list = checkpoint->checkpointSectionsListHead.next;
-			checkpoint_section_list != &checkpoint->checkpointSectionsListHead;
+		for (checkpoint_section_list = checkpoint->sections_list_head.next;
+			checkpoint_section_list != &checkpoint->sections_list_head;
 			checkpoint_section_list = checkpoint_section_list->next) {
 
 			checkpointSection = list_entry (checkpoint_section_list,
@@ -3717,69 +3719,101 @@ static void message_handler_req_lib_ckpt_sectioniterationinitialize (
 {
 	struct req_lib_ckpt_sectioniterationinitialize *req_lib_ckpt_sectioniterationinitialize = (struct req_lib_ckpt_sectioniterationinitialize *)msg;
 	struct res_lib_ckpt_sectioniterationinitialize res_lib_ckpt_sectioniterationinitialize;
-	struct saCkptCheckpoint *ckptCheckpoint;
-	struct saCkptCheckpointSection *ckptCheckpointSection;
-	struct saCkptSectionIteratorEntry *ckptSectionIteratorEntries;
-	struct saCkptSectionIterator *ckptSectionIterator;
-	struct list_head *checkpoint_section_list;
-	int addEntry = 0;
-	int iteratorEntries = 0;
+	struct saCkptCheckpoint *checkpoint;
+	struct saCkptCheckpointSection *checkpoint_section;
+	struct iteration_entry *iteration_entries;
+	struct list_head *section_list;
+	struct iteration_instance *iteration_instance;
+	unsigned int iteration_handle = 0;
+	int res;
 	SaAisErrorT error = SA_AIS_OK;
+
 	struct ckpt_pd *ckpt_pd = (struct ckpt_pd *)openais_conn_private_data_get (conn);
 
-	log_printf (LOG_LEVEL_DEBUG, "section iterator initialize\n");
-	ckptSectionIterator = &ckpt_pd->sectionIterator;
+	log_printf (LOG_LEVEL_DEBUG, "section iteration initialize\n");
 
-	ckptCheckpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_sectioniterationinitialize->checkpointName);
-	if (ckptCheckpoint == 0) {
+	checkpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_sectioniterationinitialize->checkpointName);
+	if (checkpoint == 0) {
 		error = SA_AIS_ERR_NOT_EXIST;
 		goto error_exit;
 	}
 
-	if (ckptCheckpoint->active_replica_set == 0) {
+	if (checkpoint->active_replica_set == 0) {
 		log_printf (LOG_LEVEL_NOTICE, "iterationinitialize: no active replica, returning error.\n");
 		error = SA_AIS_ERR_NOT_EXIST;
 		goto error_exit;
 	}
 
+	res = hdb_handle_create (&ckpt_pd->iteration_hdb, sizeof(struct iteration_instance),
+		&iteration_handle);
+	if (res != 0) {
+		goto error_exit;
+	}
+
+	res = hdb_handle_get (&ckpt_pd->iteration_hdb, iteration_handle,
+		(void **)&iteration_instance);
+	if (res != 0) {
+		hdb_handle_destroy (&ckpt_pd->iteration_hdb, iteration_handle);
+		goto error_exit;
+	}
+
+	iteration_instance->iteration_entries = NULL;
+	iteration_instance->iteration_entries_count = 0;
+	iteration_instance->iteration_pos = 0;
+
 	/*
 	 * Iterate list of checkpoint sections
 	 */
-	for (checkpoint_section_list = ckptCheckpoint->checkpointSectionsListHead.next;
-		checkpoint_section_list != &ckptCheckpoint->checkpointSectionsListHead;
-		checkpoint_section_list = checkpoint_section_list->next) {
+	for (section_list = checkpoint->sections_list_head.next;
+		section_list != &checkpoint->sections_list_head;
+		section_list = section_list->next) {
 
-		ckptCheckpointSection = list_entry (checkpoint_section_list,
+		checkpoint_section = list_entry (section_list,
 			struct saCkptCheckpointSection, list);
 
-		addEntry = 1;
-
-		/*
-		 * Item should be added to iterator list
-		 */
-		if (addEntry) {
-			iteratorEntries += 1;
-			ckptSectionIteratorEntries =
-				realloc (ckptSectionIterator->sectionIteratorEntries,
-				sizeof (struct saCkptSectionIteratorEntry) * iteratorEntries);
-			if (ckptSectionIteratorEntries == 0) {
-				if (ckptSectionIterator->sectionIteratorEntries) {
-					free (ckptSectionIterator->sectionIteratorEntries);
-				}
-				error = SA_AIS_ERR_NO_MEMORY;
-				goto error_exit;
+		switch (req_lib_ckpt_sectioniterationinitialize->sectionsChosen) {
+		case SA_CKPT_SECTIONS_FOREVER:
+			if (checkpoint_section->sectionDescriptor.expirationTime != SA_TIME_END) {
+				continue;
+			}
+			break;
+		case SA_CKPT_SECTIONS_LEQ_EXPIRATION_TIME:
+			if (checkpoint_section->sectionDescriptor.expirationTime > req_lib_ckpt_sectioniterationinitialize->expirationTime) {
+				continue;
+			}
+			break;
+		case SA_CKPT_SECTIONS_GEQ_EXPIRATION_TIME:
+			if (checkpoint_section->sectionDescriptor.expirationTime < req_lib_ckpt_sectioniterationinitialize->expirationTime) {
+				continue;
 			}
-			ckptSectionIteratorEntries[iteratorEntries - 1].active = 1;
-			ckptSectionIteratorEntries[iteratorEntries - 1].checkpointSection = ckptCheckpointSection;
-			ckptSectionIterator->sectionIteratorEntries = ckptSectionIteratorEntries;
+			break;
+		case SA_CKPT_SECTIONS_CORRUPTED:
+			/* there can be no corrupted sections - do nothing */
+			break;
+		case SA_CKPT_SECTIONS_ANY:
+			/* iterate all sections - do nothing */
+			break;
 		}
+		iteration_instance->iteration_entries_count += 1;
+		iteration_entries = realloc (iteration_instance->iteration_entries,
+			sizeof (struct iteration_entry) * iteration_instance->iteration_entries_count);
+		if (iteration_entries == NULL) {
+			error = SA_AIS_ERR_NO_MEMORY;
+			goto error_put;
+		}
+		iteration_instance->iteration_entries = iteration_entries;
+		iteration_entries[iteration_instance->iteration_entries_count - 1].active = 1;
+		iteration_entries[iteration_instance->iteration_entries_count - 1].checkpoint_section = checkpoint_section;
 	}
-	ckptSectionIterator->iteratorCount = iteratorEntries;
+
+error_put:
+	hdb_handle_put (&ckpt_pd->iteration_hdb, iteration_handle);
 
 error_exit:
 	res_lib_ckpt_sectioniterationinitialize.header.size = sizeof (struct res_lib_ckpt_sectioniterationinitialize);
-	res_lib_ckpt_sectioniterationinitialize.header.id = MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORINITIALIZE;
+	res_lib_ckpt_sectioniterationinitialize.header.id = MESSAGE_RES_CKPT_SECTIONITERATIONINITIALIZE;
 	res_lib_ckpt_sectioniterationinitialize.header.error = error;
+	res_lib_ckpt_sectioniterationinitialize.iteration_handle = iteration_handle;
 
 	openais_conn_send_response (
 		conn,
@@ -3793,23 +3827,33 @@ static void message_handler_req_lib_ckpt_sectioniterationfinalize (
 {
 	struct req_lib_ckpt_sectioniterationfinalize *req_lib_ckpt_sectioniterationfinalize = (struct req_lib_ckpt_sectioniterationfinalize *)msg;
 	struct res_lib_ckpt_sectioniterationfinalize res_lib_ckpt_sectioniterationfinalize;
-	struct saCkptCheckpoint *ckptCheckpoint;
 	SaAisErrorT error = SA_AIS_OK;
+	struct iteration_instance *iteration_instance;
+	unsigned int res;
 
-	ckptCheckpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_sectioniterationfinalize->checkpointName);
-	if (ckptCheckpoint == 0) {
-		error = SA_AIS_ERR_NOT_EXIST;
-		goto error_exit;
-	}
+	struct ckpt_pd *ckpt_pd = (struct ckpt_pd *)openais_conn_private_data_get (conn);
 
-	if (ckptCheckpoint->active_replica_set == 0) {
-		log_printf (LOG_LEVEL_NOTICE, "iterationfinalize: no active replica, returning error.\n");
-		error = SA_AIS_ERR_NOT_EXIST;
+	res = hdb_handle_get (&ckpt_pd->iteration_hdb,
+		req_lib_ckpt_sectioniterationfinalize->iteration_handle,
+		(void **)&iteration_instance);
+	if (res != 0) {
+		error = SA_AIS_ERR_LIBRARY;
 		goto error_exit;
 	}
+
+	free (iteration_instance->iteration_entries);
+
+	hdb_handle_put (&ckpt_pd->iteration_hdb,
+		req_lib_ckpt_sectioniterationfinalize->iteration_handle);
+
+	hdb_handle_destroy (&ckpt_pd->iteration_hdb,
+		req_lib_ckpt_sectioniterationfinalize->iteration_handle);
+
+	hdb_destroy (&ckpt_pd->iteration_hdb);
+
 error_exit:
 	res_lib_ckpt_sectioniterationfinalize.header.size = sizeof (struct res_lib_ckpt_sectioniterationfinalize);
-	res_lib_ckpt_sectioniterationfinalize.header.id = MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORFINALIZE;
+	res_lib_ckpt_sectioniterationfinalize.header.id = MESSAGE_RES_CKPT_SECTIONITERATIONFINALIZE;
 	res_lib_ckpt_sectioniterationfinalize.header.error = error;
 
 	openais_conn_send_response (
@@ -3818,73 +3862,81 @@ error_exit:
 		sizeof (struct res_lib_ckpt_sectioniterationfinalize));
 }
 
-static void message_handler_req_lib_ckpt_sectioniteratornext (
+static void message_handler_req_lib_ckpt_sectioniterationnext (
 	void *conn,
 	void *msg)
 {
-	struct req_lib_ckpt_sectioniteratornext *req_lib_ckpt_sectioniteratornext = (struct req_lib_ckpt_sectioniteratornext *)msg;
-	struct res_lib_ckpt_sectioniteratornext res_lib_ckpt_sectioniteratornext;
-	struct saCkptSectionIterator *ckptSectionIterator;
+	struct req_lib_ckpt_sectioniterationnext *req_lib_ckpt_sectioniterationnext = (struct req_lib_ckpt_sectioniterationnext *)msg;
+	struct res_lib_ckpt_sectioniterationnext res_lib_ckpt_sectioniterationnext;
 	SaAisErrorT error = SA_AIS_OK;
 	int sectionIdSize = 0;
-	int iteratorPos = 0;
-	struct ckpt_pd *ckpt_pd = (struct ckpt_pd *)openais_conn_private_data_get (conn);
+	unsigned int res;
+	struct iteration_instance *iteration_instance;
 
-	req_lib_ckpt_sectioniteratornext = 0; /* this variable not used */
+	struct ckpt_pd *ckpt_pd = (struct ckpt_pd *)openais_conn_private_data_get (conn);
 
-	log_printf (LOG_LEVEL_DEBUG, "section iterator next\n");
-	ckptSectionIterator = &ckpt_pd->sectionIterator;
+	log_printf (LOG_LEVEL_DEBUG, "section iteration next\n");
+	res = hdb_handle_get (&ckpt_pd->iteration_hdb,
+		req_lib_ckpt_sectioniterationnext->iteration_handle,
+		(void **)&iteration_instance);
+	if (res != 0) {
+		error = SA_AIS_ERR_LIBRARY;
+		goto error_exit;
+	}
 
 	/*
-	 * Find active iterator entry
+	 * Find active iteration entry
 	 */
 	for (;;) {
 		/*
-		 * No more sections in iterator
+		 * No more sections in iteration
 		 */
-		if (ckptSectionIterator->iteratorPos + 1 >= ckptSectionIterator->iteratorCount) {
+		if (iteration_instance->iteration_pos == iteration_instance->iteration_entries_count) {
 			error = SA_AIS_ERR_NO_SECTIONS;
-			goto error_exit;
+			goto error_put;
 		}
 
 		/*
-		 * active iterator entry
+		 * active iteration entry
 		 */
-		if (ckptSectionIterator->sectionIteratorEntries[ckptSectionIterator->iteratorPos].active == 1) {
+		if (iteration_instance->iteration_entries[iteration_instance->iteration_pos].active == 1) {
 			break;
 		}
 
-		ckptSectionIterator->iteratorPos += 1;
+		iteration_instance->iteration_pos += 1;
 	}
 
 	/*
 	 * Prepare response to API
 	 */
-	iteratorPos = ckptSectionIterator->iteratorPos;
-
-	sectionIdSize = ckptSectionIterator->sectionIteratorEntries[iteratorPos].checkpointSection->sectionDescriptor.sectionId.idLen;
+	sectionIdSize = iteration_instance->iteration_entries[iteration_instance->iteration_pos].checkpoint_section->sectionDescriptor.sectionId.idLen;
 
-	memcpy (&res_lib_ckpt_sectioniteratornext.sectionDescriptor, 
-		&ckptSectionIterator->sectionIteratorEntries[iteratorPos].checkpointSection->sectionDescriptor,
+	memcpy (&res_lib_ckpt_sectioniterationnext.sectionDescriptor, 
+		&iteration_instance->iteration_entries[iteration_instance->iteration_pos].checkpoint_section->sectionDescriptor,
 		sizeof (SaCkptSectionDescriptorT));
 
 	/*
-	 * Get to next iterator entry
+	 * Get to next iteration entry
 	 */
-	ckptSectionIterator->iteratorPos += 1;
+	iteration_instance->iteration_pos += 1;
+
+error_put:
+	hdb_handle_put (&ckpt_pd->iteration_hdb, req_lib_ckpt_sectioniterationnext->iteration_handle);
 
 error_exit:
-	res_lib_ckpt_sectioniteratornext.header.size = sizeof (struct res_lib_ckpt_sectioniteratornext) + sectionIdSize;
-	res_lib_ckpt_sectioniteratornext.header.id = MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORNEXT;
-	res_lib_ckpt_sectioniteratornext.header.error = error;
+	res_lib_ckpt_sectioniterationnext.header.size = sizeof (struct res_lib_ckpt_sectioniterationnext) + sectionIdSize;
+	res_lib_ckpt_sectioniterationnext.header.id = MESSAGE_RES_CKPT_SECTIONITERATIONNEXT;
+	res_lib_ckpt_sectioniterationnext.header.error = error;
 
 	openais_conn_send_response (
 		conn,
-		&res_lib_ckpt_sectioniteratornext,
-		sizeof (struct res_lib_ckpt_sectioniteratornext));
+		&res_lib_ckpt_sectioniterationnext,
+		sizeof (struct res_lib_ckpt_sectioniterationnext));
 
 	openais_conn_send_response (
 		conn,
-		ckptSectionIterator->sectionIteratorEntries[iteratorPos].checkpointSection->sectionDescriptor.sectionId.id,
-		sectionIdSize);
+		iteration_instance->iteration_entries[
+			iteration_instance->iteration_pos - 1].
+				checkpoint_section->sectionDescriptor.sectionId.id,
+			sectionIdSize);
 }

+ 16 - 0
include/hdb.h

@@ -57,6 +57,22 @@ struct hdb_handle_database {
 	unsigned int iterator;
 };
 
+static inline void hdb_create (
+	struct hdb_handle_database *handle_database)
+{
+	memset (handle_database, 0, sizeof (struct hdb_handle_database));
+}
+
+static inline void hdb_destroy (
+	struct hdb_handle_database *handle_database)
+{
+	if (handle_database->handles) {
+		free (handle_database->handles);
+	}
+	memset (handle_database, 0, sizeof (struct hdb_handle_database));
+}
+
+
 static inline int hdb_handle_create (
 	struct hdb_handle_database *handle_database,
 	int instance_size,

+ 12 - 10
include/ipc_ckpt.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002-2005 MontaVista Software, Inc.
+ * Copyright (c) 2002-2006 MontaVista Software, Inc.
  *
  * All rights reserved.
  *
@@ -54,9 +54,9 @@ enum req_lib_ckpt_checkpoint_types {
 	MESSAGE_REQ_CKPT_CHECKPOINT_SECTIONREAD = 12,
 	MESSAGE_REQ_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZE = 13,
 	MESSAGE_REQ_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZEASYNC = 14,
-	MESSAGE_REQ_CKPT_SECTIONITERATOR_SECTIONITERATORINITIALIZE = 15,
-	MESSAGE_REQ_CKPT_SECTIONITERATOR_SECTIONITERATORFINALIZE = 16,
-	MESSAGE_REQ_CKPT_SECTIONITERATOR_SECTIONITERATORNEXT = 17
+	MESSAGE_REQ_CKPT_SECTIONITERATIONINITIALIZE = 15,
+	MESSAGE_REQ_CKPT_SECTIONITERATIONFINALIZE = 16,
+	MESSAGE_REQ_CKPT_SECTIONITERATIONNEXT = 17
 };
 
 enum res_lib_ckpt_checkpoint_types {
@@ -75,9 +75,9 @@ enum res_lib_ckpt_checkpoint_types {
 	MESSAGE_RES_CKPT_CHECKPOINT_SECTIONREAD = 12,
 	MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZE = 13,
 	MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZEASYNC = 14,
-	MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORINITIALIZE = 15,
-	MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORFINALIZE = 16,
-	MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORNEXT = 17
+	MESSAGE_RES_CKPT_SECTIONITERATIONINITIALIZE = 15,
+	MESSAGE_RES_CKPT_SECTIONITERATIONFINALIZE = 16,
+	MESSAGE_RES_CKPT_SECTIONITERATIONNEXT = 17
 };
 
 struct req_lib_ckpt_checkpointopen {
@@ -197,22 +197,24 @@ struct req_lib_ckpt_sectioniterationinitialize {
 
 struct res_lib_ckpt_sectioniterationinitialize {
 	struct res_header header;
+	unsigned int iteration_handle;
 };
 
 struct req_lib_ckpt_sectioniterationfinalize {
 	struct req_header header;
-	SaNameT checkpointName;
+	unsigned int iteration_handle;
 };
 
 struct res_lib_ckpt_sectioniterationfinalize {
 	struct res_header header;
 };
 
-struct req_lib_ckpt_sectioniteratornext {
+struct req_lib_ckpt_sectioniterationnext {
 	struct req_header header;
+	unsigned int iteration_handle;
 };
 
-struct res_lib_ckpt_sectioniteratornext {
+struct res_lib_ckpt_sectioniterationnext {
 	struct res_header header;
 	SaCkptSectionDescriptorT sectionDescriptor;
 };

+ 24 - 17
lib/ckpt.c

@@ -89,6 +89,7 @@ struct ckptSectionIterationInstance {
 	SaNameT checkpointName;
 	struct list_head sectionIdListHead;
 	pthread_mutex_t response_mutex;
+	unsigned int executive_iteration_handle;
 	struct list_head list;
 };
 
@@ -1277,7 +1278,7 @@ saCkptSectionIterationInitialize (
 	list_init (&ckptSectionIterationInstance->sectionIdListHead);
 
 	req_lib_ckpt_sectioniterationinitialize.header.size = sizeof (struct req_lib_ckpt_sectioniterationinitialize); 
-	req_lib_ckpt_sectioniterationinitialize.header.id = MESSAGE_REQ_CKPT_SECTIONITERATOR_SECTIONITERATORINITIALIZE;
+	req_lib_ckpt_sectioniterationinitialize.header.id = MESSAGE_REQ_CKPT_SECTIONITERATIONINITIALIZE;
 	req_lib_ckpt_sectioniterationinitialize.sectionsChosen = sectionsChosen;
 	req_lib_ckpt_sectioniterationinitialize.expirationTime = expirationTime;
 	memcpy (&req_lib_ckpt_sectioniterationinitialize.checkpointName,
@@ -1299,9 +1300,15 @@ saCkptSectionIterationInitialize (
 
 	pthread_mutex_unlock (&ckptSectionIterationInstance->response_mutex);
 
+	if (error == SA_AIS_OK) {
+		ckptSectionIterationInstance->executive_iteration_handle =
+			res_lib_ckpt_sectioniterationinitialize.iteration_handle;
+	}
+
 	saHandleInstancePut (&ckptSectionIterationHandleDatabase, *sectionIterationHandle);
 	saHandleInstancePut (&checkpointHandleDatabase, checkpointHandle);
 
+
 	return (error == SA_AIS_OK ? res_lib_ckpt_sectioniterationinitialize.header.error : error);
 
 error_put_destroy:
@@ -1321,8 +1328,8 @@ saCkptSectionIterationNext (
 {
 	SaAisErrorT error;
 	struct ckptSectionIterationInstance *ckptSectionIterationInstance;
-	struct req_lib_ckpt_sectioniteratornext req_lib_ckpt_sectioniteratornext;
-	struct res_lib_ckpt_sectioniteratornext res_lib_ckpt_sectioniteratornext;
+	struct req_lib_ckpt_sectioniterationnext req_lib_ckpt_sectioniterationnext;
+	struct res_lib_ckpt_sectioniterationnext res_lib_ckpt_sectioniterationnext;
 	struct iteratorSectionIdListEntry *iteratorSectionIdListEntry;
 
 	if (sectionDescriptor == NULL) {
@@ -1346,39 +1353,40 @@ saCkptSectionIterationNext (
 		goto error_put_nounlock;
 	}
 
-	req_lib_ckpt_sectioniteratornext.header.size = sizeof (struct req_lib_ckpt_sectioniteratornext); 
-	req_lib_ckpt_sectioniteratornext.header.id = MESSAGE_REQ_CKPT_SECTIONITERATOR_SECTIONITERATORNEXT;
+	req_lib_ckpt_sectioniterationnext.header.size = sizeof (struct req_lib_ckpt_sectioniterationnext); 
+	req_lib_ckpt_sectioniterationnext.header.id = MESSAGE_REQ_CKPT_SECTIONITERATIONNEXT;
+	req_lib_ckpt_sectioniterationnext.iteration_handle = ckptSectionIterationInstance->executive_iteration_handle;
 
 	pthread_mutex_lock (&ckptSectionIterationInstance->response_mutex);
 
 	error = saSendRetry (ckptSectionIterationInstance->response_fd,
-		&req_lib_ckpt_sectioniteratornext,
-		sizeof (struct req_lib_ckpt_sectioniteratornext));
+		&req_lib_ckpt_sectioniterationnext,
+		sizeof (struct req_lib_ckpt_sectioniterationnext));
 
 	if (error != SA_AIS_OK) {
 		goto error_put_unlock;
 	}
 
-	error = saRecvRetry (ckptSectionIterationInstance->response_fd, &res_lib_ckpt_sectioniteratornext,
-		sizeof (struct res_lib_ckpt_sectioniteratornext));
+	error = saRecvRetry (ckptSectionIterationInstance->response_fd, &res_lib_ckpt_sectioniterationnext,
+		sizeof (struct res_lib_ckpt_sectioniterationnext));
 	if (error != SA_AIS_OK) {
 		goto error_put_unlock;
 	}
 
 	memcpy (sectionDescriptor,
-		&res_lib_ckpt_sectioniteratornext.sectionDescriptor,
+		&res_lib_ckpt_sectioniterationnext.sectionDescriptor,
 		sizeof (SaCkptSectionDescriptorT));
 
 	sectionDescriptor->sectionId.id = &iteratorSectionIdListEntry->data[0];
 	
-	if ((res_lib_ckpt_sectioniteratornext.header.size - sizeof (struct res_lib_ckpt_sectioniteratornext)) > 0) {
+	if ((res_lib_ckpt_sectioniterationnext.header.size - sizeof (struct res_lib_ckpt_sectioniterationnext)) > 0) {
 		error = saRecvRetry (ckptSectionIterationInstance->response_fd,
 			sectionDescriptor->sectionId.id,
-			res_lib_ckpt_sectioniteratornext.header.size -
-				sizeof (struct res_lib_ckpt_sectioniteratornext));
+			res_lib_ckpt_sectioniterationnext.header.size -
+				sizeof (struct res_lib_ckpt_sectioniterationnext));
 	}
 
-	error = (error == SA_AIS_OK ? res_lib_ckpt_sectioniteratornext.header.error : error);
+	error = (error == SA_AIS_OK ? res_lib_ckpt_sectioniterationnext.header.error : error);
 	
 	/*
 	 * Add to persistent memory list for this sectioniterator
@@ -1417,9 +1425,8 @@ saCkptSectionIterationFinalize (
 	}
 
 	req_lib_ckpt_sectioniterationfinalize.header.size = sizeof (struct req_lib_ckpt_sectioniterationfinalize); 
-	req_lib_ckpt_sectioniterationfinalize.header.id = MESSAGE_REQ_CKPT_SECTIONITERATOR_SECTIONITERATORFINALIZE;
-	memcpy (&req_lib_ckpt_sectioniterationfinalize.checkpointName,
-		&ckptSectionIterationInstance->checkpointName, sizeof (SaNameT));
+	req_lib_ckpt_sectioniterationfinalize.header.id = MESSAGE_REQ_CKPT_SECTIONITERATIONFINALIZE;
+	req_lib_ckpt_sectioniterationfinalize.iteration_handle = ckptSectionIterationInstance->executive_iteration_handle;
 
 	pthread_mutex_lock (&ckptSectionIterationInstance->response_mutex);
 

+ 16 - 3
test/testckpt.c

@@ -204,6 +204,7 @@ int main (void) {
 	struct timeval tv_elapsed;
 	SaSelectionObjectT sel_fd;
 	fd_set read_set;
+	int i;
 	
 	error = saCkptInitialize (&ckptHandle, &callbacks, &version);
 
@@ -460,6 +461,11 @@ printf ("Please wait, testing expiry of checkpoint sections.\n");
 			(int)checkpointStatus.memoryUsed,
 			(int)checkpointStatus.numberOfSections);
 	}
+	printf ("iterating all sections 5 times\n");
+	/*
+	 * iterate all sections 5 times
+	 */
+	for (i = 0; i < 5; i++) {
 	error = saCkptSectionIterationInitialize (checkpointHandle,
 		SA_CKPT_SECTIONS_ANY,
 		0,
@@ -467,14 +473,20 @@ printf ("Please wait, testing expiry of checkpoint sections.\n");
 	printf ("%s: initialize section iterator\n",
 		get_test_output (error, SA_AIS_OK));
 
+
 	/*
 	 * Iterate all sections
 	 */
 	do {
+		printf ("Starting iteration\n");
 		error = saCkptSectionIterationNext (sectionIterator,
 			&sectionDescriptor);
-		printf ("%s: Get next section in iteartion\n",
-			get_test_output (error, SA_AIS_OK));
+		if (error == SA_AIS_ERR_NO_SECTIONS) {
+			printf ("No more sections to iterate\n");
+		} else {
+			printf ("%s: Get next section in iteration\n",
+				get_test_output (error, SA_AIS_OK));
+		}
 		if (error == SA_AIS_OK) {
 			printf ("Section '%s' expires %llx size %llu state %x update %llx\n",
 				sectionDescriptor.sectionId.id,
@@ -484,12 +496,13 @@ printf ("Please wait, testing expiry of checkpoint sections.\n");
 				(unsigned long long)sectionDescriptor.lastUpdate);
 		}
 	} while (error == SA_AIS_OK);
-	printf ("The last iteration should fail\n");
 
 	error = saCkptSectionIterationFinalize (sectionIterator);
 	printf ("%s: Finalize iteration\n",
 		get_test_output (error, SA_AIS_OK));
 
+	}
+
 	error = saCkptSelectionObjectGet (ckptHandle, &sel_fd);
 
 	error = saCkptFinalize (ckptHandle);