]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: pools: make sure to also destroy shared pools in pool_destroy_all()
authorWilly Tarreau <w@1wt.eu>
Wed, 27 Apr 2022 09:33:13 +0000 (11:33 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 27 Apr 2022 09:33:13 +0000 (11:33 +0200)
In issue #1677, Tim reported that we don't correctly free some shared
pools on exit. What happens in fact is that pool_destroy() is meant to
be called once per pool *pointer*, as it decrements the use count for
each pass and only releases the pool when it reaches zero. But since
pool_destroy_all() iterates over the pools list, it visits each pool
only once and will not eliminate some of them, which thus remain in the
list.

In an ideal case, the function should loop over all pools for as long
as the list is not empty, but that's pointless as we know we're exiting,
so let's just set the users count to 1 before the call so that
pool_destroy() knows it can delete and release the entry.

This could be backported to all versions (memory.c in 2.0 and older) but
it's not a real problem in practice.

src/pool.c

index 4c39978cf0c5e9c7e6f467424198a342abd4da12..83525311f1741ea6851cbc6fe0633ac33fa3610d 100644 (file)
@@ -837,8 +837,14 @@ void pool_destroy_all()
 {
        struct pool_head *entry, *back;
 
-       list_for_each_entry_safe(entry, back, &pools, list)
+       list_for_each_entry_safe(entry, back, &pools, list) {
+               /* there's only one occurrence of each pool in the list,
+                * and we're existing instead of looping on the whole
+                * list just to decrement users, force it to 1 here.
+                */
+               entry->users = 1;
                pool_destroy(entry);
+       }
 }
 
 /* This function dumps memory usage information into the trash buffer. */