File bug-950450_pacemaker-lrmd-finalize-all-ops.patch of Package pacemaker.9287
commit d706719cde73ebca4abfac16ed0c7a3caabb5562
Author: Gao,Yan <ygao@suse.com>
Date: Fri Oct 23 17:13:25 2015 +0200
Fix: lrmd: Finalize all pending and recurring operations when cleaning up a resource
When cleaning up or reprobing a resource, the resource will be
unregistered from lrmd. In free_rsc(), when it loops over
rsc->pending_ops and rsc->recurring_ops GLists, cmd_finalize() is
invoked either directly or via a callback, which removes elements from
the GLists. Previously, with the for loops, this could break the
iterating of the lists and miss the following elements in the lists.
If a resource was configured with multiple monitor operations, cleanup
command would not cancel all existing monitor operations. This could
cause unexpected monitor failures to occur after the resource was
stopped on the node.
The while loops are more appropriate for handling them.
diff --git a/lrmd/lrmd.c b/lrmd/lrmd.c
index 1b8a1f3..a64b430 100644
--- a/lrmd/lrmd.c
+++ b/lrmd/lrmd.c
@@ -1322,17 +1322,23 @@ free_rsc(gpointer data)
lrmd_rsc_t *rsc = data;
int is_stonith = safe_str_eq(rsc->class, "stonith");
- for (gIter = rsc->pending_ops; gIter != NULL; gIter = gIter->next) {
+ gIter = rsc->pending_ops;
+ while (gIter != NULL) {
+ GListPtr next = gIter->next;
lrmd_cmd_t *cmd = gIter->data;
/* command was never executed */
cmd->lrmd_op_status = PCMK_LRM_OP_CANCELLED;
cmd_finalize(cmd, NULL);
+
+ gIter = next;
}
/* frees list, but not list elements. */
g_list_free(rsc->pending_ops);
- for (gIter = rsc->recurring_ops; gIter != NULL; gIter = gIter->next) {
+ gIter = rsc->recurring_ops;
+ while (gIter != NULL) {
+ GListPtr next = gIter->next;
lrmd_cmd_t *cmd = gIter->data;
if (is_stonith) {
@@ -1350,6 +1356,8 @@ free_rsc(gpointer data)
* even if we are waiting for the cancel result */
services_action_cancel(rsc->rsc_id, normalize_action_name(rsc, cmd->action), cmd->interval);
}
+
+ gIter = next;
}
/* frees list, but not list elements. */
g_list_free(rsc->recurring_ops);