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);
openSUSE Build Service is sponsored by