From 68ca1de0f39c11056a57b03a544520bd6708d855 Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Thu, 11 Jun 2020 15:39:59 +0200 Subject: [PATCH] Issue 50984 - Memory leaks in disk monitoring Description: Fix the rest of the leaks in disk monitoring which are present when we shutdown while being below half of the threshold (at the start-up in main.c). Free directories, sockets and ports before going to cleanup. https://pagure.io/389-ds-base/issue/50984 Reviewed by: mhonek, tbordaz (Thanks!) --- ldap/servers/slapd/daemon.c | 75 ++++++++++++++++++++----------------- ldap/servers/slapd/fe.h | 1 + ldap/servers/slapd/main.c | 49 +++++++++++++----------- 3 files changed, 70 insertions(+), 55 deletions(-) diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c index a70f40316..7091b570d 100644 --- a/ldap/servers/slapd/daemon.c +++ b/ldap/servers/slapd/daemon.c @@ -884,6 +884,46 @@ convert_pbe_des_to_aes(void) charray_free(attrs); } +void +slapd_sockets_ports_free(daemon_ports_t *ports_info) +{ + /* freeing PRFileDescs */ + PRFileDesc **fdesp = NULL; + for (fdesp = ports_info->n_socket; fdesp && *fdesp; fdesp++) { + PR_Close(*fdesp); + } + slapi_ch_free((void **)&ports_info->n_socket); + + for (fdesp = ports_info->s_socket; fdesp && *fdesp; fdesp++) { + PR_Close(*fdesp); + } + slapi_ch_free((void **)&ports_info->s_socket); +#if defined(ENABLE_LDAPI) + for (fdesp = ports_info->i_socket; fdesp && *fdesp; fdesp++) { + PR_Close(*fdesp); + } + slapi_ch_free((void **)&ports_info->i_socket); +#endif /* ENABLE_LDAPI */ + + /* freeing NetAddrs */ + PRNetAddr **nap; + for (nap = ports_info->n_listenaddr; nap && *nap; nap++) { + slapi_ch_free((void **)nap); + } + slapi_ch_free((void **)&ports_info->n_listenaddr); + + for (nap = ports_info->s_listenaddr; nap && *nap; nap++) { + slapi_ch_free((void **)nap); + } + slapi_ch_free((void **)&ports_info->s_listenaddr); +#if defined(ENABLE_LDAPI) + for (nap = ports_info->i_listenaddr; nap && *nap; nap++) { + slapi_ch_free((void **)nap); + } + slapi_ch_free((void **)&ports_info->i_listenaddr); +#endif +} + void slapd_daemon(daemon_ports_t *ports) { @@ -1099,40 +1139,7 @@ slapd_daemon(daemon_ports_t *ports) /* free the listener indexes */ slapi_ch_free((void **)&listener_idxs); - for (fdesp = n_tcps; fdesp && *fdesp; fdesp++) { - PR_Close(*fdesp); - } - slapi_ch_free((void **)&n_tcps); - - for (fdesp = i_unix; fdesp && *fdesp; fdesp++) { - PR_Close(*fdesp); - } - slapi_ch_free((void **)&i_unix); - - for (fdesp = s_tcps; fdesp && *fdesp; fdesp++) { - PR_Close(*fdesp); - } - slapi_ch_free((void **)&s_tcps); - - /* freeing NetAddrs */ - { - PRNetAddr **nap; - for (nap = ports->n_listenaddr; nap && *nap; nap++) { - slapi_ch_free((void **)nap); - } - slapi_ch_free((void **)&ports->n_listenaddr); - - for (nap = ports->s_listenaddr; nap && *nap; nap++) { - slapi_ch_free((void **)nap); - } - slapi_ch_free((void **)&ports->s_listenaddr); -#if defined(ENABLE_LDAPI) - for (nap = ports->i_listenaddr; nap && *nap; nap++) { - slapi_ch_free((void **)nap); - } - slapi_ch_free((void **)&ports->i_listenaddr); -#endif - } + slapd_sockets_ports_free(ports); op_thread_cleanup(); housekeeping_stop(); /* Run this after op_thread_cleanup() logged sth */ diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h index 2d9a0931b..9cd122881 100644 --- a/ldap/servers/slapd/fe.h +++ b/ldap/servers/slapd/fe.h @@ -120,6 +120,7 @@ int connection_table_iterate_active_connections(Connection_Table *ct, void *arg, */ int signal_listner(void); int daemon_pre_setuid_init(daemon_ports_t *ports); +void slapd_sockets_ports_free(daemon_ports_t *ports_info); void slapd_daemon(daemon_ports_t *ports); void daemon_register_connection(void); int slapd_listenhost2addr(const char *listenhost, PRNetAddr ***addr); diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c index e54b8e1c5..9e5219c4a 100644 --- a/ldap/servers/slapd/main.c +++ b/ldap/servers/slapd/main.c @@ -734,7 +734,6 @@ main(int argc, char **argv) * etc the backends need to start */ - /* Important: up 'till here we could be running as root (on unix). * we believe that we've not created any files before here, otherwise * they'd be owned by root, which is bad. We're about to change identity @@ -891,6 +890,34 @@ main(int argc, char **argv) } } + if (config_get_disk_monitoring()) { + char **dirs = NULL; + char *dirstr = NULL; + uint64_t disk_space = 0; + int64_t threshold = 0; + uint64_t halfway = 0; + threshold = config_get_disk_threshold(); + halfway = threshold / 2; + disk_mon_get_dirs(&dirs); + dirstr = disk_mon_check_diskspace(dirs, threshold, &disk_space); + if (dirstr != NULL && disk_space < halfway) { + slapi_log_err(SLAPI_LOG_EMERG, "main", + "Disk Monitoring is enabled and disk space on (%s) is too far below the threshold(%" PRIu64 " bytes). Exiting now.\n", + dirstr, threshold); + slapi_ch_array_free(dirs); + /* + * We should free the structs we allocated for sockets and addresses + * as they would be freed at the slapd_daemon but it was not initiated + * at that point of start-up. + */ + slapd_sockets_ports_free(&ports_info); + return_value = 1; + goto cleanup; + } + slapi_ch_array_free(dirs); + dirs = NULL; + } + /* initialize the normalized DN cache */ if (ndn_cache_init() != 0) { slapi_log_err(SLAPI_LOG_EMERG, "main", "Unable to create ndn cache\n"); @@ -940,26 +967,6 @@ main(int argc, char **argv) slapi_ch_free((void **)&versionstring); } - if (config_get_disk_monitoring()) { - char **dirs = NULL; - char *dirstr = NULL; - uint64_t disk_space = 0; - int64_t threshold = 0; - uint64_t halfway = 0; - threshold = config_get_disk_threshold(); - halfway = threshold / 2; - disk_mon_get_dirs(&dirs); - dirstr = disk_mon_check_diskspace(dirs, threshold, &disk_space); - if (dirstr != NULL && disk_space < halfway) { - slapi_log_err(SLAPI_LOG_EMERG, "main", - "Disk Monitoring is enabled and disk space on (%s) is too far below the threshold(%" PRIu64 " bytes). Exiting now.\n", - dirstr, threshold); - return_value = 1; - goto cleanup; - } - slapi_ch_array_free(dirs); - dirs = NULL; - } /* log the max fd limit as it is typically set in env/systemd */ slapi_log_err(SLAPI_LOG_INFO, "main", "Setting the maximum file descriptor limit to: %ld\n", -- 2.26.2