From 95fd7038a23f12f24ab375909cf9a1867e5c34b5 Mon Sep 17 00:00:00 2001 From: David Hankins Date: Tue, 7 Apr 2009 19:55:52 +0000 Subject: [PATCH] - Memory leak in the load_balance_mine() function is fixed. This would leak ~20-30 octets per DHCPDISCOVER packet while failover was in use and in normal state. [ISC-Bugs #19548] - Various compilation fixes have been included for the memory related DEBUG #defines in includes/site.h. [ISC-Bugs #19548] --- RELNOTES | 7 +++++++ includes/dhcpd.h | 3 +++ includes/site.h | 1 + omapip/alloc.c | 15 ++++++++------- omapip/message.c | 2 +- server/dhcp.c | 2 +- server/failover.c | 2 ++ server/mdb.c | 37 ++++++++++++++++++++++++++----------- 8 files changed, 49 insertions(+), 20 deletions(-) diff --git a/RELNOTES b/RELNOTES index f20a29c30..5760b126b 100644 --- a/RELNOTES +++ b/RELNOTES @@ -99,6 +99,13 @@ work on other platforms. Please report any problems and suggested fixes to be removed at expiration or release time. Thanks to a patch submitted by Christof Chen. +- Memory leak in the load_balance_mine() function is fixed. This would + leak ~20-30 octets per DHCPDISCOVER packet while failover was in use + and in normal state. + +- Various compilation fixes have been included for the memory related + DEBUG #defines in includes/site.h. + Changes since 4.1.0b1 - A missing "else" in dhcrelay.c could have caused an interface not to diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 8a014bc51..d020b5fcf 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -1673,6 +1673,9 @@ extern enum dhcp_shutdown_state shutdown_state; isc_result_t dhcp_io_shutdown (omapi_object_t *, void *); isc_result_t dhcp_set_control_state (control_object_state_t oldstate, control_object_state_t newstate); +#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) +void relinquish_ackqueue(void); +#endif /* conflex.c */ isc_result_t new_parse PROTO ((struct parse **, int, diff --git a/includes/site.h b/includes/site.h index 220e99597..651a98c2c 100644 --- a/includes/site.h +++ b/includes/site.h @@ -46,6 +46,7 @@ noticing memory leaks quickly. */ /* #define DEBUG_MEMORY_LEAKAGE */ +/* #define DEBUG_MEMORY_LEAKAGE_ON_EXIT */ /* Define this if you want exhaustive (and very slow) checking of the malloc pool for corruption. */ diff --git a/omapip/alloc.c b/omapip/alloc.c index 4572633c9..3a79d90ae 100644 --- a/omapip/alloc.c +++ b/omapip/alloc.c @@ -255,8 +255,9 @@ void dmalloc_dump_outstanding () { static unsigned long dmalloc_cutoff_point; struct dmalloc_preamble *dp; +#if defined(DEBUG_MALLOC_POOL) unsigned char *foo; - int i; +#endif if (!dmalloc_cutoff_point) dmalloc_cutoff_point = dmalloc_cutoff_generation; @@ -307,7 +308,7 @@ void dmalloc_dump_outstanding () if (rc_history [i].addr == dp + 1) { inhistory = 1; if (!noted) { - log_info (" %s(%d): %d", dp -> file, + log_info (" %s(%d): %ld", dp -> file, dp -> line, dp -> size); noted = 1; } @@ -320,7 +321,7 @@ void dmalloc_dump_outstanding () } while (count--); if (!inhistory) #endif - log_info (" %s(%d): %d", + log_info (" %s(%d): %ld", dp -> file, dp -> line, dp -> size); } #endif @@ -353,7 +354,7 @@ void dump_rc_history (void *addr) i += RC_HISTORY_MAX; } rc_history_count = 0; - + while (rc_history [i].file) { if (!addr || addr == rc_history [i].addr) print_rc_hist_entry (i); @@ -427,7 +428,6 @@ static int dmalloc_find_entry (struct dmalloc_preamble *dp, int min, int max) { int middle; - int cmp; middle = (min + max) / 2; if (middle == min) @@ -448,8 +448,7 @@ static int dmalloc_find_entry (struct dmalloc_preamble *dp, void omapi_print_dmalloc_usage_by_caller () { struct dmalloc_preamble *dp; - unsigned char *foo; - int ccur, cmax, i, j; + int ccur, cmax, i; struct caller cp [1024]; cmax = 1024; @@ -494,7 +493,9 @@ void omapi_print_dmalloc_usage_by_caller () for (i = 0; i < ccur; i++) { printf ("%d\t%s:%d\t%d\n", i, cp [i].dp -> file, cp [i].dp -> line, cp [i].count); +#if defined(DUMP_RC_HISTORY) dump_rc_history (cp [i].dp + 1); +#endif } } #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */ diff --git a/omapip/message.c b/omapip/message.c index 5b16bca75..add200064 100644 --- a/omapip/message.c +++ b/omapip/message.c @@ -364,7 +364,7 @@ omapi_message_process_internal (omapi_object_t *, omapi_object_t *); isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po) { isc_result_t status; -#if defined (DEBUG_MEMORY_LEAKAGE) +#if defined (DEBUG_MEMORY_LEAKAGE) && 0 unsigned long previous_outstanding = dmalloc_outstanding; #endif diff --git a/server/dhcp.c b/server/dhcp.c index ec1c2ef19..39edf24b5 100644 --- a/server/dhcp.c +++ b/server/dhcp.c @@ -2955,7 +2955,7 @@ relinquish_ackqueue(void) { struct leasequeue *q, *n; - for (q = ackqueue ; q ; q = n) { + for (q = ackqueue_head ; q ; q = n) { n = q->next; dfree(q, MDL); } diff --git a/server/failover.c b/server/failover.c index 5e1f3dff0..3f4b2fb6b 100644 --- a/server/failover.c +++ b/server/failover.c @@ -5729,6 +5729,8 @@ int load_balance_mine (struct packet *packet, dhcp_failover_state_t *state) packet -> options, (struct option_state *)0, &global_scope, oc, MDL)) { hbaix = loadb_p_hash (ds.data, ds.len); + + data_string_forget(&ds, MDL); } else { hbaix = loadb_p_hash (packet -> raw -> chaddr, packet -> raw -> hlen); diff --git a/server/mdb.c b/server/mdb.c index 004e94ad3..2f04aa3c4 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -714,7 +714,9 @@ void new_address_range (cfile, low, high, subnet, pool, lpchain) struct pool *pool; struct lease **lpchain; { +#if defined(COMPACT_LEASES) struct lease *address_range; +#endif unsigned min, max, i; char lowbuf [16], highbuf [16], netbuf [16]; struct shared_network *share = subnet -> shared_network; @@ -2614,7 +2616,7 @@ extern int end; extern struct lease *lease_hunks; #endif -void free_everything () +void free_everything(void) { struct subnet *sc = (struct subnet *)0, *sn = (struct subnet *)0; struct shared_network *nc = (struct shared_network *)0, @@ -2625,12 +2627,8 @@ void free_everything () *in = (struct interface_info *)0; struct class *cc = (struct class *)0, *cn = (struct class *)0; struct collection *lp; - void *st = (shared_networks - ? (shared_networks -> next - ? shared_networks -> next -> next : 0) : 0); int i; - /* Get rid of all the hash tables. */ if (host_hw_addr_hash) host_free_hash_table (&host_hw_addr_hash, MDL); @@ -2639,13 +2637,13 @@ void free_everything () host_free_hash_table (&host_uid_hash, MDL); host_uid_hash = 0; if (lease_uid_hash) - lease_free_hash_table (&lease_uid_hash, MDL); + lease_id_free_hash_table (&lease_uid_hash, MDL); lease_uid_hash = 0; if (lease_ip_addr_hash) - lease_free_hash_table (&lease_ip_addr_hash, MDL); + lease_ip_free_hash_table (&lease_ip_addr_hash, MDL); lease_ip_addr_hash = 0; if (lease_hw_addr_hash) - lease_free_hash_table (&lease_hw_addr_hash, MDL); + lease_id_free_hash_table (&lease_hw_addr_hash, MDL); lease_hw_addr_hash = 0; if (host_name_hash) host_free_hash_table (&host_name_hash, MDL); @@ -2751,7 +2749,15 @@ void free_everything () } /* So are shared networks. */ + /* XXX: this doesn't work presently, but i'm ok just filtering + * it out of the noise (you get a bigger spike on the real leaks). + * It would be good to fix this, but it is not a "real bug," so not + * today. This hack is incomplete, it doesn't trim out sub-values. + */ if (shared_networks) { + shared_network_dereference (&shared_networks, MDL); + /* This is the old method (tries to free memory twice, broken) */ + } else if (0) { shared_network_reference (&nn, shared_networks, MDL); do { if (nn) { @@ -2848,14 +2854,21 @@ void free_everything () universe_free_hash_table (&universe_hash, MDL); for (i = 0; i < universe_count; i++) { +#if 0 union { const char *c; char *s; } foo; +#endif if (universes [i]) { - if (universes [i] -> hash) - option_free_hash_table (&universes [i] -> hash, - MDL); + if (universes[i]->name_hash) + option_name_free_hash_table( + &universes[i]->name_hash, + MDL); + if (universes[i]->code_hash) + option_code_free_hash_table( + &universes[i]->code_hash, + MDL); #if 0 if (universes [i] -> name > (char *)&end) { foo.c = universes [i] -> name; @@ -2874,7 +2887,9 @@ void free_everything () relinquish_free_binding_values (); relinquish_free_option_caches (); relinquish_free_packets (); +#if defined(COMPACT_LEASES) relinquish_lease_hunks (); +#endif relinquish_hash_bucket_hunks (); omapi_type_relinquish (); } -- 2.39.5