Blame SOURCES/022-memory-leak.patch

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