Blame SOURCES/022-memory-leak.patch

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