Blame SOURCES/023-memory-leak.patch

d4e586
From 8034a203bbff0aa3b53f2946dc58e409bd7246c9 Mon Sep 17 00:00:00 2001
d4e586
From: Ken Gaillot <kgaillot@redhat.com>
d4e586
Date: Thu, 20 Jan 2022 15:03:31 -0600
d4e586
Subject: [PATCH] Fix: scheduler: avoid memory leak when displaying clones
d4e586
d4e586
Previously, pe__clone_default() unconditionally created a hash table for
d4e586
stopped instances, but didn't free it in every code path.
d4e586
d4e586
Now, only create the table when we have something to put in it and might
d4e586
actually use it, and ensure it always gets freed.
d4e586
---
d4e586
 lib/pengine/clone.c | 18 +++++++++++++-----
d4e586
 1 file changed, 13 insertions(+), 5 deletions(-)
d4e586
d4e586
diff --git a/lib/pengine/clone.c b/lib/pengine/clone.c
d4e586
index 742e2920b0..920a04c32c 100644
d4e586
--- a/lib/pengine/clone.c
d4e586
+++ b/lib/pengine/clone.c
d4e586
@@ -761,7 +761,7 @@ pe__clone_default(pcmk__output_t *out, va_list args)
d4e586
     GList *only_node = va_arg(args, GList *);
d4e586
     GList *only_rsc = va_arg(args, GList *);
d4e586
 
d4e586
-    GHashTable *stopped = pcmk__strkey_table(free, free);
d4e586
+    GHashTable *stopped = NULL;
d4e586
 
d4e586
     char *list_text = NULL;
d4e586
     size_t list_text_len = 0;
d4e586
@@ -818,7 +818,11 @@ pe__clone_default(pcmk__output_t *out, va_list args)
d4e586
         } else if (partially_active == FALSE) {
d4e586
             // List stopped instances when requested (except orphans)
d4e586
             if (!pcmk_is_set(child_rsc->flags, pe_rsc_orphan)
d4e586
+                && !pcmk_is_set(show_opts, pcmk_show_clone_detail)
d4e586
                 && pcmk_is_set(show_opts, pcmk_show_inactive_rscs)) {
d4e586
+                if (stopped == NULL) {
d4e586
+                    stopped = pcmk__strkey_table(free, free);
d4e586
+                }
d4e586
                 g_hash_table_insert(stopped, strdup(child_rsc->id), strdup("Stopped"));
d4e586
             }
d4e586
 
d4e586
@@ -873,7 +877,6 @@ pe__clone_default(pcmk__output_t *out, va_list args)
d4e586
     }
d4e586
 
d4e586
     if (pcmk_is_set(show_opts, pcmk_show_clone_detail)) {
d4e586
-        g_hash_table_destroy(stopped);
d4e586
         PCMK__OUTPUT_LIST_FOOTER(out, rc);
d4e586
         return pcmk_rc_ok;
d4e586
     }
d4e586
@@ -948,8 +951,10 @@ pe__clone_default(pcmk__output_t *out, va_list args)
d4e586
             GList *list = g_hash_table_get_values(rsc->allowed_nodes);
d4e586
 
d4e586
             /* Custom stopped table for non-unique clones */
d4e586
-            g_hash_table_destroy(stopped);
d4e586
-            stopped = pcmk__strkey_table(free, free);
d4e586
+            if (stopped != NULL) {
d4e586
+                g_hash_table_destroy(stopped);
d4e586
+                stopped = NULL;
d4e586
+            }
d4e586
 
d4e586
             if (list == NULL) {
d4e586
                 /* Clusters with symmetrical=false haven't calculated allowed_nodes yet
d4e586
@@ -972,6 +977,9 @@ pe__clone_default(pcmk__output_t *out, va_list args)
d4e586
                         state = "Stopped (disabled)";
d4e586
                     }
d4e586
 
d4e586
+                    if (stopped == NULL) {
d4e586
+                        stopped = pcmk__strkey_table(free, free);
d4e586
+                    }
d4e586
                     if (probe_op != NULL) {
d4e586
                         int rc;
d4e586
 
d4e586
@@ -987,7 +995,7 @@ pe__clone_default(pcmk__output_t *out, va_list args)
d4e586
             g_list_free(list);
d4e586
         }
d4e586
 
d4e586
-        if (g_hash_table_size(stopped) > 0) {
d4e586
+        if (stopped != NULL) {
d4e586
             GList *list = sorted_hash_table_values(stopped);
d4e586
 
d4e586
             clone_header(out, &rc, rsc, clone_data);
d4e586
-- 
d4e586
2.27.0
d4e586