From: Yehuda Sadeh Date: Mon, 27 Apr 2009 23:17:53 +0000 (-0700) Subject: conf: some more leak fixes X-Git-Tag: v0.7.3~44 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bd4e779fbda6268bce637f5b48121ade69dbc702;p=ceph.git conf: some more leak fixes --- diff --git a/src/common/ConfUtils.cc b/src/common/ConfUtils.cc index 63aba77e714..ceead011a4b 100644 --- a/src/common/ConfUtils.cc +++ b/src/common/ConfUtils.cc @@ -849,6 +849,7 @@ int ConfFile::_read(const char *section, const char *var, T *val, T def_val) { ConfLine *cl; char *str_val; + bool should_free = false; cl = _find_var(section, var); if (!cl || !cl->get_val()) @@ -858,9 +859,12 @@ int ConfFile::_read(const char *section, const char *var, T *val, T def_val) if (post_process_func) { str_val = post_process_func(str_val); + should_free = true; } _conf_decode(val, str_val); + if (should_free) + free(str_val); return 1; notfound: diff --git a/src/config.cc b/src/config.cc index 9e1176c4179..0c8ee68c5a7 100644 --- a/src/config.cc +++ b/src/config.cc @@ -44,6 +44,8 @@ static bool show_config = false; static ConfFile *cf = NULL; static ExportControl *ec = NULL; +static void fini_g_conf(); + class ConfFileDestructor { public: @@ -52,6 +54,7 @@ public: if (cf) { delete cf; cf = NULL; + fini_g_conf(); } } }; @@ -665,6 +668,9 @@ static bool init_g_conf() for (i = 0; ival_ptr) { + *(char **)opt->val_ptr = NULL; + } if (!conf_set_conf_val(opt->val_ptr, opt->type, opt->def_str, @@ -680,6 +686,21 @@ static bool init_g_conf() return true; } +static void fini_g_conf() +{ + int len = sizeof(config_optionsp)/sizeof(config_option); + int i; + config_option *opt; + + for (i = 0; itype == OPT_STR) { + free(*(char **)opt->val_ptr); + } + free((void *)opt->conf_name); + } +} + static bool g_conf_initialized = init_g_conf(); static bool cmd_is_char(const char *cmd) @@ -818,10 +839,12 @@ do { \ int conf_read_key_ext(const char *conf_name, const char *conf_alt_name, const char *conf_type, - const char *alt_section, const char *key, opt_type_t type, void *out, void *def) + const char *alt_section, const char *key, opt_type_t type, void *out, void *def, + bool free_old_val) { int s; int ret; + char *tmp; for (s=0; s<5; s++) { const char *section; @@ -851,7 +874,12 @@ int conf_read_key_ext(const char *conf_name, const char *conf_alt_name, const ch switch (type) { case OPT_STR: + if (free_old_val) + tmp = *(char **)out; OPT_READ_TYPE(ret, section, key, char *, out, def); + if (free_old_val && + *(char **)out != tmp) + free(tmp); break; case OPT_BOOL: OPT_READ_TYPE(ret, section, key, bool, out, def); @@ -877,10 +905,10 @@ int conf_read_key_ext(const char *conf_name, const char *conf_alt_name, const ch return ret; } -int conf_read_key(const char *alt_section, const char *key, opt_type_t type, void *out, void *def) +int conf_read_key(const char *alt_section, const char *key, opt_type_t type, void *out, void *def, bool free_old_val) { return conf_read_key_ext(g_conf.name, g_conf.alt_name, g_conf.type, - alt_section, key, type, out, def); + alt_section, key, type, out, def, free_old_val); } bool parse_config_file(ConfFile *cf, bool auto_update) @@ -894,7 +922,7 @@ bool parse_config_file(ConfFile *cf, bool auto_update) for (int i=0; iconf_name, opt->type, opt->val_ptr, opt->val_ptr); + conf_read_key(NULL, opt->conf_name, opt->type, opt->val_ptr, opt->val_ptr, true); } return true; diff --git a/src/config.h b/src/config.h index eff01383a3e..693a7dbc274 100644 --- a/src/config.h +++ b/src/config.h @@ -379,7 +379,7 @@ class ConfFile; ConfFile *conf_get_conf_file(); char *conf_post_process_val(const char *val); -int conf_read_key(const char *alt_section, const char *key, opt_type_t type, void *out, void *def); +int conf_read_key(const char *alt_section, const char *key, opt_type_t type, void *out, void *def, bool free_old_val = false); bool conf_set_conf_val(void *field, opt_type_t type, const char *val); bool conf_cmd_equals(const char *cmd, const char *opt, char char_opt, unsigned int *val_pos);