woops
On Thu, 2009-03-26 at 18:48 -0500, Ryan O'Hara wrote:
> On Thu, Mar 26, 2009 at 03:55:10PM -0700, Steven Dake wrote:
> > This patch forward ports the ckpt service, especially the sync code
> > which is very defective in current trunk of openias.
>
> I think you forgot to attach the patch. :)
>
Index: services/ckpt.c
===================================================================
--- services/ckpt.c (revision 1758)
+++ services/ckpt.c (working copy)
@@ -62,6 +62,8 @@
LOGSYS_DECLARE_SUBSYS ("CKPT", LOG_INFO);
+#define GLOBALID_CHECKPOINT_NAME "global_checkpoint_name_do_not_use_in_an_application"
+
#define CKPT_MAX_SECTION_DATA_SEND (1024*400)
enum ckpt_message_req_types {
@@ -89,6 +91,9 @@
};
enum sync_state {
+ SYNC_STATE_NOT_STARTED,
+ SYNC_STATE_STARTED,
+ SYNC_STATE_GLOBALID,
SYNC_STATE_CHECKPOINT,
SYNC_STATE_REFCOUNT
};
@@ -153,6 +158,7 @@
struct checkpoint {
struct list_head list;
+ struct list_head expiry_list;
mar_name_t name;
mar_uint32_t ckpt_id;
mar_ckpt_checkpoint_creation_attributes_t checkpoint_creation_attributes;
@@ -345,6 +351,8 @@
static int nodeid_in_membership (unsigned int nodeid);
+static int nodeid_in_membership (unsigned int nodeid);
+
static void sync_refcount_increment (
struct checkpoint *checkpoint, unsigned int nodeid);
@@ -368,24 +376,33 @@
DECLARE_LIST_INIT(checkpoint_recovery_list_head);
-static struct corosync_api_v1 *api;
+DECLARE_LIST_INIT(my_checkpoint_expiry_list_head);
static mar_uint32_t global_ckpt_id = 0;
-static enum sync_state my_sync_state;
+static enum sync_state my_sync_state = SYNC_STATE_NOT_STARTED;
static enum iteration_state my_iteration_state;
-static struct list_head *my_iteration_state_checkpoint;
+static struct list_head *my_iteration_state_checkpoint_list;
-static struct list_head *my_iteration_state_section;
+static struct list_head *my_iteration_state_section_list;
static unsigned int my_member_list[PROCESSOR_COUNT_MAX];
static unsigned int my_member_list_entries = 0;
-static unsigned int my_lowest_nodeid = 0;
+static unsigned int my_should_sync = 0;
+static unsigned int my_token_callback_active = 0;
+
+/* TODO SCHEDWRK
+static hdb_handle_t callback_expiry_handle;
+*/
+
+static void * my_token_callback_handle;
+
+static struct corosync_api_v1 *api;
struct checkpoint_cleanup {
struct list_head list;
mar_name_t checkpoint_name;
@@ -759,51 +776,11 @@
mar_refcount_set_t refcount_set[PROCESSOR_COUNT_MAX] __attribute__((aligned(8)));
};
+static int first_configuration = 1;
+
/*
* Implementation
*/
-
-void clean_checkpoint_list(struct list_head *head)
-{
- struct list_head *checkpoint_list;
- struct checkpoint *checkpoint;
-
- if (list_empty(head)) {
- log_printf (LOG_LEVEL_DEBUG, "clean_checkpoint_list: List is empty \n");
- return;
- }
-
- checkpoint_list = head->next;
- while (checkpoint_list != head) {
- checkpoint = list_entry (checkpoint_list,
- struct checkpoint, list);
- assert (checkpoint > 0);
-
- /*
- * If checkpoint has been unlinked and this is the last reference, delete it
- */
- if (checkpoint->unlinked && checkpoint->reference_count == 0) {
- log_printf (LOG_LEVEL_DEBUG,"clean_checkpoint_list: deallocating checkpoint %s.\n",
- checkpoint->name.value);
- checkpoint_list = checkpoint_list->next;
- checkpoint_release (checkpoint);
- continue;
-
- }
- else if (checkpoint->reference_count == 0) {
- log_printf (LOG_LEVEL_DEBUG, "clean_checkpoint_list: Starting timer to release checkpoint %s.\n",
- checkpoint->name.value);
- api->timer_delete (checkpoint->retention_timer);
- api->timer_add_duration (
- checkpoint->checkpoint_creation_attributes.retention_duration,
- checkpoint,
- timer_function_retention,
- &checkpoint->retention_timer);
- }
- checkpoint_list = checkpoint_list->next;
- }
-}
-
static void ckpt_confchg_fn (
enum totem_configuration_type configuration_type,
unsigned int *member_list, int member_list_entries,
@@ -812,40 +789,46 @@
struct memb_ring_id *ring_id)
{
unsigned int i, j;
+ unsigned int lowest_nodeid;
- /*
- * Determine lowest nodeid in old regular configuration for the
- * purpose of executing the synchronization algorithm
- */
- if (configuration_type == TOTEM_CONFIGURATION_TRANSITIONAL) {
- for (i = 0; i < left_list_entries; i++) {
- for (j = 0; j < my_member_list_entries; j++) {
- if (left_list[i] == my_member_list[j]) {
- my_member_list[j] = 0;
- }
- }
- }
- }
-
- my_lowest_nodeid = 0xffffffff;
+ memcpy (&my_saved_ring_id, ring_id,
+ sizeof (struct memb_ring_id));
+ if (configuration_type != TOTEM_CONFIGURATION_REGULAR) {
+ return;
+ }
+ if (my_sync_state != SYNC_STATE_NOT_STARTED) {
+ return;
+ }
+ my_sync_state = SYNC_STATE_STARTED;
+
+ my_should_sync = 0;
+
/*
* Handle regular configuration
*/
- if (configuration_type == TOTEM_CONFIGURATION_REGULAR) {
- memcpy (my_member_list, member_list,
- sizeof (unsigned int) * member_list_entries);
- my_member_list_entries = member_list_entries;
- memcpy (&my_saved_ring_id, ring_id,
- sizeof (struct memb_ring_id));
- for (i = 0; i < my_member_list_entries; i++) {
- if ((my_member_list[i] != 0) &&
- (my_member_list[i] < my_lowest_nodeid)) {
+ lowest_nodeid = 0xffffffff;
- my_lowest_nodeid = my_member_list[i];
+ for (i = 0; i < my_member_list_entries; i++) {
+ for (j = 0; j < member_list_entries; j++) {
+ if (my_member_list[i] == member_list[j]) {
+ if (lowest_nodeid > member_list[j]) {
+ lowest_nodeid = member_list[j];
+ }
}
}
}
+ memcpy (my_member_list, member_list,
+ sizeof (unsigned int) * member_list_entries);
+ my_member_list_entries = member_list_entries;
+
+ if ((first_configuration) ||
+ (lowest_nodeid == api->totem_nodeid_get())) {
+
+ my_should_sync = 1;
+ }
+
+ first_configuration = 0;
}
static struct checkpoint *checkpoint_find (
@@ -1020,6 +1003,9 @@
api->timer_delete (checkpoint->retention_timer);
+ list_del (&checkpoint->expiry_list);
+ list_init (&checkpoint->expiry_list);
+
/*
* Release all checkpoint sections for this checkpoint
*/
@@ -1060,14 +1046,12 @@
iovec.iov_base = (char *)&req_exec_ckpt_checkpointclose;
iovec.iov_len = sizeof (req_exec_ckpt_checkpointclose);
- assert (api->totem_mcast (&iovec, 1, TOTEM_AGREED) == 0);
-
- return (-1);
+ return (api->totem_mcast (&iovec, 1, TOTEM_AGREED));
}
-static int ckpt_exec_init_fn (struct corosync_api_v1 *corosync_api)
+static int ckpt_exec_init_fn (struct corosync_api_v1 *corosync_api_v1)
{
- api = corosync_api;
+ api = corosync_api_v1;
return (0);
}
@@ -1304,6 +1288,7 @@
checkpoint->unlinked = 0;
list_init (&checkpoint->list);
list_init (&checkpoint->sections_list_head);
+ list_init (&checkpoint->expiry_list);
list_add (&checkpoint->list, &checkpoint_list_head);
checkpoint->reference_count = 1;
checkpoint->retention_timer = 0;
@@ -1351,6 +1336,12 @@
checkpoint_section->expiration_timer = 0;
}
} else {
+ /*
+ * We have to ignore the retention_duration attribute
+ */
+ req_exec_ckpt_checkpointopen->checkpoint_creation_attributes.retention_duration =
+ checkpoint->checkpoint_creation_attributes.retention_duration;
+
if (req_exec_ckpt_checkpointopen->checkpoint_creation_attributes_set &&
memcmp (&checkpoint->checkpoint_creation_attributes,
&req_exec_ckpt_checkpointopen->checkpoint_creation_attributes,
@@ -1510,29 +1501,80 @@
}
-void timer_function_retention (void *data)
+int callback_expiry (enum totem_callback_token_type type, void *data)
{
struct checkpoint *checkpoint = (struct checkpoint *)data;
- struct req_exec_ckpt_checkpointretentiondurationexpire req_exec_ckpt_checkpointretentiondurationexpire;
+ struct req_exec_ckpt_checkpointunlink req_exec_ckpt_checkpointunlink;
struct iovec iovec;
+ unsigned int res;
+ struct list_head *list;
+ list = my_checkpoint_expiry_list_head.next;
+ while (!list_empty(&my_checkpoint_expiry_list_head)) {
+ checkpoint = list_entry (list,
+ struct checkpoint, expiry_list);
+
+ log_printf (LOG_LEVEL_DEBUG,
+ "refcnt checkpoint %s %d\n",
+ get_mar_name_t (&checkpoint->name), checkpoint->reference_count);
+ if (checkpoint->reference_count == 0) {
+ req_exec_ckpt_checkpointunlink.header.size =
+ sizeof (struct req_exec_ckpt_checkpointunlink);
+ req_exec_ckpt_checkpointunlink.header.id =
+ SERVICE_ID_MAKE (CKPT_SERVICE,
+ MESSAGE_REQ_EXEC_CKPT_CHECKPOINTUNLINK);
+
+ req_exec_ckpt_checkpointunlink.source.conn = 0;
+ req_exec_ckpt_checkpointunlink.source.nodeid = 0;
+
+ memcpy (&req_exec_ckpt_checkpointunlink.checkpoint_name,
+ &checkpoint->name,
+ sizeof (mar_name_t));
+
+ iovec.iov_base = (char *)&req_exec_ckpt_checkpointunlink;
+ iovec.iov_len = sizeof (req_exec_ckpt_checkpointunlink);
+
+ res = api->totem_mcast (&iovec, 1, TOTEM_AGREED);
+ if (res == -1) {
+ return (-1);
+ }
+ log_printf (LOG_LEVEL_DEBUG,
+ "Expiring checkpoint %s\n",
+ get_mar_name_t (&checkpoint->name));
+ }
+
+ list_del (&checkpoint->expiry_list);
+ list_init (&checkpoint->expiry_list);
+ list = my_checkpoint_expiry_list_head.next;
+ }
+ my_token_callback_active = 0;
+ return (0);
+}
+
+void timer_function_retention (void *data)
+{
+ struct checkpoint *checkpoint = (struct checkpoint *)data;
+
checkpoint->retention_timer = 0;
- req_exec_ckpt_checkpointretentiondurationexpire.header.size =
- sizeof (struct req_exec_ckpt_checkpointretentiondurationexpire);
- req_exec_ckpt_checkpointretentiondurationexpire.header.id =
- SERVICE_ID_MAKE (CKPT_SERVICE,
- MESSAGE_REQ_EXEC_CKPT_CHECKPOINTRETENTIONDURATIONEXPIRE);
+ list_add (&checkpoint->expiry_list, &my_checkpoint_expiry_list_head);
- memcpy (&req_exec_ckpt_checkpointretentiondurationexpire.checkpoint_name,
- &checkpoint->name,
- sizeof (mar_name_t));
- req_exec_ckpt_checkpointretentiondurationexpire.ckpt_id =
- checkpoint->ckpt_id;
+ if (my_token_callback_active == 0) {
+ api->totem_callback_token_create (
+ &my_token_callback_handle,
+ TOTEM_CALLBACK_TOKEN_SENT,
+ 1,
+ callback_expiry,
+ NULL);
- iovec.iov_base = (char *)&req_exec_ckpt_checkpointretentiondurationexpire;
- iovec.iov_len = sizeof (req_exec_ckpt_checkpointretentiondurationexpire);
+/* TODO use schedwrk instead of totempg callback token
+ schedwrk_create (
+ &callback_expiry_handle,
+ callback_expiry,
+ NULL);
+*/
- assert (api->totem_mcast (&iovec, 1, TOTEM_AGREED) == 0);
+ my_token_callback_active = 1;
+ }
}
static void message_handler_req_exec_ckpt_checkpointclose (
@@ -2395,6 +2437,7 @@
struct checkpoint_cleanup *checkpoint_cleanup;
struct list_head *list;
struct ckpt_pd *ckpt_pd = (struct ckpt_pd *)api->ipc_private_data_get (conn);
+ int res;
log_printf (LOG_LEVEL_DEBUG, "checkpoint exit conn %p\n", conn);
@@ -2408,9 +2451,16 @@
struct checkpoint_cleanup, list);
assert (checkpoint_cleanup->checkpoint_name.length != 0);
- ckpt_checkpoint_close (
+ res = ckpt_checkpoint_close (
&checkpoint_cleanup->checkpoint_name,
checkpoint_cleanup->ckpt_id);
+ /*
+ * If checkpoint_close fails because of full totem queue
+ * return -1 ande try again later
+ */
+ if (res == -1) {
+ return (-1);
+ }
list_del (&checkpoint_cleanup->list);
free (checkpoint_cleanup);
@@ -2570,15 +2620,11 @@
/*
* Make sure checkpoint is collocated and async update option
*/
- if (checkpoint == NULL) {
- error = SA_AIS_ERR_NOT_EXIST;
- } else
if (((checkpoint->checkpoint_creation_attributes.creation_flags & SA_CKPT_CHECKPOINT_COLLOCATED) == 0) ||
(checkpoint->checkpoint_creation_attributes.creation_flags & (SA_CKPT_WR_ACTIVE_REPLICA | SA_CKPT_WR_ACTIVE_REPLICA_WEAK)) == 0) {
error = SA_AIS_ERR_BAD_OPERATION;
- } else {
- checkpoint->active_replica_set = 1;
}
+ checkpoint->active_replica_set = 1;
res_lib_ckpt_activereplicaset.header.size = sizeof (struct res_lib_ckpt_activereplicaset);
res_lib_ckpt_activereplicaset.header.id = MESSAGE_RES_CKPT_ACTIVEREPLICASET;
res_lib_ckpt_activereplicaset.header.error = error;
@@ -2960,9 +3006,6 @@
&checkpoint_list_head,
&req_lib_ckpt_checkpointsynchronize->checkpoint_name,
req_lib_ckpt_checkpointsynchronize->ckpt_id);
- if (checkpoint == NULL) {
- res_lib_ckpt_checkpointsynchronize.header.error = SA_AIS_ERR_NOT_EXIST;
- } else
if ((checkpoint->checkpoint_creation_attributes.creation_flags & (SA_CKPT_WR_ACTIVE_REPLICA | SA_CKPT_WR_ACTIVE_REPLICA_WEAK)) == 0) {
res_lib_ckpt_checkpointsynchronize.header.error = SA_AIS_ERR_BAD_OPERATION;
} else
@@ -2993,9 +3036,6 @@
&checkpoint_list_head,
&req_lib_ckpt_checkpointsynchronizeasync->checkpoint_name,
req_lib_ckpt_checkpointsynchronizeasync->ckpt_id);
- if (checkpoint == NULL) {
- res_lib_ckpt_checkpointsynchronizeasync.header.error = SA_AIS_ERR_NOT_EXIST;
- } else
if ((checkpoint->checkpoint_creation_attributes.creation_flags & (SA_CKPT_WR_ACTIVE_REPLICA | SA_CKPT_WR_ACTIVE_REPLICA_WEAK)) == 0) {
res_lib_ckpt_checkpointsynchronizeasync.header.error = SA_AIS_ERR_BAD_OPERATION;
} else
@@ -3398,33 +3438,45 @@
list_init (ckpt_list_head);
}
-static inline void sync_checkpoints_enter (void)
+static inline void sync_gloalid_enter (void)
{
struct checkpoint *checkpoint;
ENTER();
- my_sync_state = SYNC_STATE_CHECKPOINT;
- my_iteration_state = ITERATION_STATE_CHECKPOINT;
- my_iteration_state_checkpoint = checkpoint_list_head.next;
+ my_sync_state = SYNC_STATE_GLOBALID;
+ my_iteration_state_checkpoint_list = checkpoint_list_head.next;
+
checkpoint = list_entry (checkpoint_list_head.next, struct checkpoint,
list);
- my_iteration_state_section = checkpoint->sections_list_head.next;
+ my_iteration_state_section_list = checkpoint->sections_list_head.next;
LEAVE();
}
+static inline void sync_checkpoints_enter (void)
+{
+ ENTER();
+
+ my_sync_state = SYNC_STATE_CHECKPOINT;
+ my_iteration_state = ITERATION_STATE_CHECKPOINT;
+
+ LEAVE();
+}
+
static inline void sync_refcounts_enter (void)
{
my_sync_state = SYNC_STATE_REFCOUNT;
+
+ my_iteration_state_checkpoint_list = checkpoint_list_head.next;
}
static void ckpt_sync_init (void)
{
ENTER();
- sync_checkpoints_enter();
+ sync_gloalid_enter();
LEAVE();
}
@@ -3464,6 +3516,19 @@
return (api->totem_mcast (&iovec, 1, TOTEM_AGREED));
}
+static int sync_checkpoint_globalid_transmit (void)
+{
+ struct checkpoint checkpoint;
+
+ strcpy ((char *)checkpoint.name.value, GLOBALID_CHECKPOINT_NAME);
+
+ checkpoint.name.length = strlen (GLOBALID_CHECKPOINT_NAME);
+ checkpoint.ckpt_id = global_ckpt_id;
+
+ return (sync_checkpoint_transmit(&checkpoint));
+}
+
+
static int sync_checkpoint_section_transmit (
struct checkpoint *checkpoint,
struct checkpoint_section *checkpoint_section)
@@ -3502,7 +3567,7 @@
iovecs[0].iov_base = (char *)&req_exec_ckpt_sync_checkpoint_section;
iovecs[0].iov_len = sizeof (req_exec_ckpt_sync_checkpoint_section);
- iovecs[1].iov_base = (char *)checkpoint_section->section_descriptor.section_id.id;
+ iovecs[1].iov_base = checkpoint_section->section_descriptor.section_id.id;
iovecs[1].iov_len = checkpoint_section->section_descriptor.section_id.id_len;
iovecs[2].iov_base = checkpoint_section->section_data;
iovecs[2].iov_len = checkpoint_section->section_descriptor.section_size;
@@ -3553,25 +3618,62 @@
struct list_head *section_list;
unsigned int res = 0;
- for (checkpoint_list = checkpoint_list_head.next;
+ /*
+ * iterate through all checkpoints or sections
+ * from the last successfully transmitted checkpoint or sectoin
+ */
+ for (checkpoint_list = my_iteration_state_checkpoint_list;
checkpoint_list != &checkpoint_list_head;
checkpoint_list = checkpoint_list->next) {
checkpoint = list_entry (checkpoint_list, struct checkpoint, list);
- res = sync_checkpoint_transmit (checkpoint);
- if (res != 0) {
- break;
+ /*
+ * Synchronize a checkpoint if there is room in the totem
+ * buffers and we didn't previously synchronize a checkpoint
+ */
+ if (my_iteration_state == ITERATION_STATE_CHECKPOINT) {
+ res = sync_checkpoint_transmit (checkpoint);
+ if (res != 0) {
+ /*
+ * Couldn't sync this checkpoint keep processing
+ */
+ return (-1);
+ }
+ my_iteration_state_section_list = checkpoint->sections_list_head.next;
+ my_iteration_state = ITERATION_STATE_SECTION;
}
- for (section_list = checkpoint->sections_list_head.next;
+
+ /*
+ * Synchronize a checkpoint section if there is room in the
+ * totem buffers
+ */
+ for (section_list = my_iteration_state_section_list;
section_list != &checkpoint->sections_list_head;
section_list = section_list->next) {
checkpoint_section = list_entry (section_list, struct checkpoint_section, list);
res = sync_checkpoint_section_transmit (checkpoint, checkpoint_section);
+ if (res != 0) {
+ /*
+ * Couldn't sync this section keep processing
+ */
+ return (-1);
+ }
+ my_iteration_state_section_list = section_list->next;
}
+
+ /*
+ * Continue to iterating checkpoints
+ */
+ my_iteration_state = ITERATION_STATE_CHECKPOINT;
+ my_iteration_state_checkpoint_list = checkpoint_list->next;
}
- return (res);
+
+ /*
+ * all checkpoints and sections iterated
+ */
+ return (0);
}
unsigned int sync_refcounts_iterate (void)
@@ -3580,7 +3682,7 @@
struct list_head *list;
unsigned int res = 0;
- for (list = checkpoint_list_head.next;
+ for (list = my_iteration_state_checkpoint_list;
list != &checkpoint_list_head;
list = list->next) {
@@ -3590,48 +3692,68 @@
if (res != 0) {
break;
}
+ my_iteration_state_checkpoint_list = list->next;
}
return (res);
}
static int ckpt_sync_process (void)
{
- unsigned int done_queueing = 1;
- unsigned int continue_processing = 0;
+ unsigned int done_queueing;
+ unsigned int continue_processing;
unsigned int res;
ENTER();
+ continue_processing = 0;
+
switch (my_sync_state) {
+ case SYNC_STATE_GLOBALID:
+ done_queueing = 1;
+ continue_processing = 1;
+ if (my_should_sync) {
+ res = sync_checkpoint_globalid_transmit ();
+ if (res != 0) {
+ done_queueing = 0;
+ }
+ }
+ if (done_queueing) {
+ sync_checkpoints_enter ();
+ }
+ break;
+
case SYNC_STATE_CHECKPOINT:
- if (my_lowest_nodeid == api->totem_nodeid_get ()) {
+ done_queueing = 1;
+ continue_processing = 1;
+
+ if (my_should_sync) {
TRACE1 ("should transmit checkpoints because lowest member in old configuration.\n");
res = sync_checkpoints_iterate ();
- if (res == 0) {
- done_queueing = 1;
+ /*
+ * Not done iterating checkpoints
+ */
+ if (res != 0) {
+ done_queueing = 0;
}
}
if (done_queueing) {
sync_refcounts_enter ();
}
-
- /*
- * TODO recover current iteration state
- */
- continue_processing = 1;
break;
case SYNC_STATE_REFCOUNT:
- done_queueing = 1;
- if (my_lowest_nodeid == api->totem_nodeid_get()) {
+ if (my_should_sync) {
TRACE1 ("transmit refcounts because this processor is the lowest member in old configuration.\n");
res = sync_refcounts_iterate ();
+ if (res != 0) {
+ continue_processing = 1;
+ }
}
- if (done_queueing) {
- continue_processing = 0;
- }
break;
+
+ default:
+ assert (0);
}
LEAVE();
@@ -3652,7 +3774,7 @@
list_init (&sync_checkpoint_list_head);
- my_sync_state = SYNC_STATE_CHECKPOINT;
+ my_sync_state = SYNC_STATE_NOT_STARTED;
LEAVE();
}
@@ -3680,6 +3802,22 @@
return;
}
+ /*
+ * Discard checkpoints that are used to synchronize the global_ckpt_id
+ * also setting the global ckpt_id as well.
+ */
+ if (memcmp (&req_exec_ckpt_sync_checkpoint->checkpoint_name.value,
+ GLOBALID_CHECKPOINT_NAME,
+ req_exec_ckpt_sync_checkpoint->checkpoint_name.length) == 0) {
+
+ if (req_exec_ckpt_sync_checkpoint->ckpt_id >= global_ckpt_id) {
+ global_ckpt_id = req_exec_ckpt_sync_checkpoint->ckpt_id + 1;
+ }
+
+ LEAVE();
+ return;
+ }
+
checkpoint = checkpoint_find_specific (
&sync_checkpoint_list_head,
&req_exec_ckpt_sync_checkpoint->checkpoint_name,
@@ -3718,7 +3856,11 @@
list_init (&checkpoint->list);
list_init (&checkpoint->sections_list_head);
+ list_init (&checkpoint->expiry_list);
list_add (&checkpoint->list, &sync_checkpoint_list_head);
+
+ memset (checkpoint->refcount_set, 0,
+ sizeof (struct refcount_set) * PROCESSOR_COUNT_MAX);
}
if (checkpoint->ckpt_id >= global_ckpt_id) {
@@ -3750,6 +3892,22 @@
return;
}
+ /*
+ * Discard checkpoints that are used to synchronize the global_ckpt_id
+ * also setting the global ckpt_id as well.
+ */
+ if (memcmp (&req_exec_ckpt_sync_checkpoint_section->checkpoint_name.value,
+ GLOBALID_CHECKPOINT_NAME,
+ req_exec_ckpt_sync_checkpoint_section->checkpoint_name.length) == 0) {
+
+ if (req_exec_ckpt_sync_checkpoint_section->ckpt_id >= global_ckpt_id) {
+ global_ckpt_id = req_exec_ckpt_sync_checkpoint_section->ckpt_id + 1;
+ }
+
+ LEAVE();
+ return;
+ }
+
checkpoint = checkpoint_find_specific (
&sync_checkpoint_list_head,
&req_exec_ckpt_sync_checkpoint_section->checkpoint_name,
@@ -3809,7 +3967,7 @@
*/
section_id = NULL;
}
-
+
memcpy (section_contents,
((char *)req_exec_ckpt_sync_checkpoint_section) +
sizeof (struct req_exec_ckpt_sync_checkpoint_section) +
@@ -3864,6 +4022,23 @@
return;
}
+ /*
+ * Discard checkpoints that are used to synchronize the global_ckpt_id
+ * also setting the global ckpt_id as well.
+ */
+ if (memcmp (&req_exec_ckpt_sync_checkpoint_refcount->checkpoint_name.value,
+ GLOBALID_CHECKPOINT_NAME,
+ req_exec_ckpt_sync_checkpoint_refcount->checkpoint_name.length) == 0) {
+
+ if (req_exec_ckpt_sync_checkpoint_refcount->ckpt_id >= global_ckpt_id) {
+ global_ckpt_id = req_exec_ckpt_sync_checkpoint_refcount->ckpt_id + 1;
+ }
+
+ LEAVE();
+ return;
+ }
+
+
checkpoint = checkpoint_find_specific (
&sync_checkpoint_list_head,
&req_exec_ckpt_sync_checkpoint_refcount->checkpoint_name,
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais