Memory leak fixes
authorJens Axboe <axboe@kernel.dk>
Fri, 14 Oct 2011 08:55:16 +0000 (10:55 +0200)
committerJens Axboe <axboe@kernel.dk>
Fri, 14 Oct 2011 08:55:16 +0000 (10:55 +0200)
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fio.c
init.c
options.c
options.h
parse.c
parse.h

diff --git a/fio.c b/fio.c
index e5d3bbf3c204790e7f98b2b36b749f870acdac22..856ca753fdd472e7c435c9138422e343ff08edfa 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -1361,7 +1361,6 @@ err:
        if (td->o.write_iolog_file)
                write_iolog_close(td);
 
-       options_mem_free(td);
        td_set_runstate(td, TD_EXITED);
        return (void *) (unsigned long) td->error;
 }
@@ -1773,11 +1772,17 @@ static void run_threads(void)
 
 int exec_run(void)
 {
+       struct thread_data *td;
+       int i;
+
        if (nr_clients)
                return fio_handle_clients();
-       if (exec_profile && load_profile(exec_profile))
-               return 1;
-
+       if (exec_profile) {
+               if (load_profile(exec_profile))
+                       return 1;
+               free(exec_profile);
+               exec_profile = NULL;
+       }
        if (!thread_number)
                return 0;
 
@@ -1810,6 +1815,9 @@ int exec_run(void)
                }
        }
 
+       for_each_td(td, i)
+               fio_options_free(td);
+
        cgroup_kill(cgroup_list);
        sfree(cgroup_list);
        sfree(cgroup_mnt);
diff --git a/init.c b/init.c
index fa71eea8829adb6eb77920211c524e56efaa5dfc..0ccb18573389906a9b8900b00f9053924ea4baf8 100644 (file)
--- a/init.c
+++ b/init.c
@@ -318,6 +318,8 @@ static void put_job(struct thread_data *td)
        if (td->error)
                log_info("fio: %s\n", td->verror);
 
+       fio_options_free(td);
+
        memset(&threads[td->thread_number - 1], 0, sizeof(*td));
        thread_number--;
 }
@@ -1070,6 +1072,12 @@ int parse_jobs_ini(char *file, int is_buf, int stonewall_flag)
        if (dump_cmdline)
                log_info("\n");
 
+       i = 0;
+       while (i < nr_job_sections) {
+               free(job_sections[i]);
+               i++;
+       }
+
        for (i = 0; i < num_opts; i++)
                free(opts[i]);
 
@@ -1497,7 +1505,7 @@ int parse_options(int argc, char *argv[])
        }
 
        free(ini_file);
-       options_mem_free(&def_thread);
+       fio_options_free(&def_thread);
 
        if (!thread_number) {
                if (dump_cmdline)
index 48bb2a4d318fb005ac6463f5864769682bfdaddb..4207537e9c4a4bf4958213b6dd3cf6783582b766 100644 (file)
--- a/options.c
+++ b/options.c
@@ -2347,7 +2347,10 @@ int fio_show_option_help(const char *opt)
        return show_cmd_help(options, opt);
 }
 
-static void __options_mem(struct thread_data *td, int alloc)
+/*
+ * dupe FIO_OPT_STR_STORE options
+ */
+void options_mem_dupe(struct thread_data *td)
 {
        struct thread_options *o = &td->o;
        struct fio_option *opt;
@@ -2359,32 +2362,13 @@ static void __options_mem(struct thread_data *td, int alloc)
                        continue;
 
                ptr = (void *) o + opt->off1;
-               if (*ptr) {
-                       if (alloc)
-                               *ptr = strdup(*ptr);
-                       else {
-                               free(*ptr);
-                               *ptr = NULL;
-                       }
-               }
+               if (!*ptr)
+                       ptr = td_var(o, opt->off1);
+               if (*ptr)
+                       *ptr = strdup(*ptr);
        }
 }
 
-/*
- * dupe FIO_OPT_STR_STORE options
- */
-void options_mem_dupe(struct thread_data *td)
-{
-       __options_mem(td, 1);
-}
-
-void options_mem_free(struct thread_data fio_unused *td)
-{
-#if 0
-       __options_mem(td, 0);
-#endif
-}
-
 unsigned int fio_get_kb_base(void *data)
 {
        struct thread_data *td = data;
@@ -2465,3 +2449,8 @@ void del_opt_posval(const char *optname, const char *ival)
                o->posval[i].help = NULL;
        }
 }
+
+void fio_options_free(struct thread_data *td)
+{
+       options_free(options, td);
+}
index c6c2086e0a76286a87f44bbb469307ccdddc09e4..ed6b9c2da47a5699cb9b4d3f1808eba4b8ede019 100644 (file)
--- a/options.h
+++ b/options.h
@@ -15,6 +15,8 @@ extern char *exec_profile;
 
 void add_opt_posval(const char *, const char *, const char *);
 void del_opt_posval(const char *, const char *);
+struct thread_data;
+void fio_options_free(struct thread_data *);
 
 static inline int o_match(struct fio_option *o, const char *opt)
 {
diff --git a/parse.c b/parse.c
index 27e7336b49af99720886905928a69058e42f3bf1..afbde61ef6f7c281ea5d1fb10ba0661f4ad30b4d 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -1094,3 +1094,22 @@ void options_init(struct fio_option *options)
        for (o = &options[0]; o->name; o++)
                option_init(o);
 }
+
+void options_free(struct fio_option *options, void *data)
+{
+       struct fio_option *o;
+       char **ptr;
+
+       dprint(FD_PARSE, "free options\n");
+
+       for (o = &options[0]; o->name; o++) {
+               if (o->type != FIO_OPT_STR_STORE)
+                       continue;
+
+               ptr = td_var(data, o->off1);
+               if (*ptr) {
+                       free(*ptr);
+                       *ptr = NULL;
+               }
+       }
+}
diff --git a/parse.h b/parse.h
index f2265a43226cf1584baf6f31fcf0e981351568fc..cb0b48f5d95801093cf850ad74803228a889c717 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -72,6 +72,7 @@ extern int show_cmd_help(struct fio_option *, const char *);
 extern void fill_default_options(void *, struct fio_option *);
 extern void option_init(struct fio_option *);
 extern void options_init(struct fio_option *);
+extern void options_free(struct fio_option *, void *);
 
 extern void strip_blank_front(char **);
 extern void strip_blank_end(char *);