Quoting Dwight Engen (dwight.en...@oracle.com):
> There are fd leaks in lxc_cgroup_load_meta2() in particular in the success
> case. This change attempts to ensure resources are free'd/close'd, but it
> is possible there are still some error cases where leaks occur.
> 
> Signed-off-by: Dwight Engen <dwight.en...@oracle.com>
> ---
> Hi Christian,
> 
> These changes fix problems I was seeing with valgrind, but they may not be
> how you would do it, so feel free to rework them if I've messed up your
> code too bad :) The command I was using:
>  valgrind --leak-check=full --track-fds=yes ./lxc-test-concurrent -i 2 -j 1

Thanks for spotting them.  I think it'd be better to split that function
up first.  Then it should be easier both to spot the leaks and verify
patches.

I can take a stab at that sometime this week if (either of) you don't
have time.

>  src/lxc/cgroup.c | 83 
> ++++++++++++++++++++++++++++++++------------------------
>  1 file changed, 48 insertions(+), 35 deletions(-)
> 
> diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
> index 9417e77..101998b 100644
> --- a/src/lxc/cgroup.c
> +++ b/src/lxc/cgroup.c
> @@ -124,7 +124,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
> **subsystem_whitelist)
>       size_t token_capacity = 0;
>       char *line = NULL;
>       size_t sz = 0;
> -     int r, saved_errno = 0;
> +     int r, ret = ENOMEM;
>  
>       /* if the subsystem whitelist is not specified, include all
>        * hierarchies that contain kernel subsystems by default but
> @@ -149,8 +149,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>  
>       /* Step 1: determine all kernel subsystems */
>       proc_cgroups = fopen_cloexec("/proc/cgroups", "r");
> -     if (!proc_cgroups)
> -             goto out_error;
> +     if (!proc_cgroups) {
> +             ret = errno;
> +             goto out1;
> +     }
>  
>       while (getline(&line, &sz, proc_cgroups) != -1) {
>               char *tab1;
> @@ -179,10 +181,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>  
>               r = lxc_grow_array((void ***)&kernel_subsystems, 
> &kernel_subsystems_capacity, kernel_subsystems_count + 1, 12);
>               if (r < 0)
> -                     goto out_error;
> +                     goto out2;
>               kernel_subsystems[kernel_subsystems_count] = strdup(line);
>               if (!kernel_subsystems[kernel_subsystems_count])
> -                     goto out_error;
> +                     goto out2;
>               kernel_subsystems_count++;
>       }
>  
> @@ -198,8 +200,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>        * /proc/self is not valid, we try /proc/1/cgroup... */
>       if (!proc_self_cgroup)
>               proc_self_cgroup = fopen_cloexec("/proc/1/cgroup", "r");
> -     if (!proc_self_cgroup)
> -             goto out_error;
> +     if (!proc_self_cgroup) {
> +             ret = errno;
> +             goto out2;
> +     }
>  
>       while (getline(&line, &sz, proc_self_cgroup) != -1) {
>               /* file format: hierarchy:subsystems:group,
> @@ -234,25 +238,25 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>                       */
>                       r = lxc_grow_array((void ***)&meta_data->hierarchies, 
> &hierarchy_capacity, hierarchy_number + 1, 12);
>                       if (r < 0)
> -                             goto out_error;
> +                             goto out3;
>  
>                       meta_data->maximum_hierarchy = hierarchy_number;
>               }
>  
>               /* this shouldn't happen, we had this already */
>               if (meta_data->hierarchies[hierarchy_number])
> -                     goto out_error;
> +                     goto out3;
>  
>               h = calloc(1, sizeof(struct cgroup_hierarchy));
>               if (!h)
> -                     goto out_error;
> +                     goto out3;
>  
>               meta_data->hierarchies[hierarchy_number] = h;
>  
>               h->index = hierarchy_number;
>               h->subsystems = lxc_string_split_and_trim(colon1, ',');
>               if (!h->subsystems)
> -                     goto out_error;
> +                     goto out3;
>               /* see if this hierarchy should be considered */
>               if (!all_kernel_subsystems || !all_named_subsystems) {
>                       for (p = h->subsystems; *p; p++) {
> @@ -283,8 +287,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>        * /proc/self is not valid, we try /proc/1/cgroup... */
>       if (!proc_self_mountinfo)
>               proc_self_mountinfo = fopen_cloexec("/proc/1/mountinfo", "r");
> -     if (!proc_self_mountinfo)
> -             goto out_error;
> +     if (!proc_self_mountinfo) {
> +             ret = errno;
> +             goto out3;
> +     }
>  
>       while (getline(&line, &sz, proc_self_mountinfo) != -1) {
>               char *token, *saveptr = NULL;
> @@ -299,7 +305,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
> **subsystem_whitelist)
>               for (i = 0; (token = strtok_r(line, " ", &saveptr)); line = 
> NULL) {
>                       r = lxc_grow_array((void ***)&tokens, &token_capacity, 
> i + 1, 64);
>                       if (r < 0)
> -                             goto out_error;
> +                             goto out4;
>                       tokens[i++] = token;
>               }
>  
> @@ -335,7 +341,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
> **subsystem_whitelist)
>  
>               subsystems = subsystems_from_mount_options(tokens[j + 3], 
> kernel_subsystems);
>               if (!subsystems)
> -                     goto out_error;
> +                     goto out4;
>  
>               h = NULL;
>               for (k = 1; k <= meta_data->maximum_hierarchy; k++) {
> @@ -352,12 +358,12 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>  
>               r = lxc_grow_array((void ***)&meta_data->mount_points, 
> &mount_point_capacity, mount_point_count + 1, 12);
>               if (r < 0)
> -                     goto out_error;
> +                     goto out4;
>  
>               /* create mount point object */
>               mount_point = calloc(1, sizeof(*mount_point));
>               if (!mount_point)
> -                     goto out_error;
> +                     goto out4;
>  
>               meta_data->mount_points[mount_point_count++] = mount_point;
>  
> @@ -365,7 +371,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
> **subsystem_whitelist)
>               mount_point->mount_point = strdup(tokens[4]);
>               mount_point->mount_prefix = strdup(tokens[3]);
>               if (!mount_point->mount_point || !mount_point->mount_prefix)
> -                     goto out_error;
> +                     goto out4;
>               mount_point->read_only = !lxc_string_in_list("rw", tokens[5], 
> ',');
>  
>               if (!strcmp(mount_point->mount_prefix, "/")) {
> @@ -381,32 +387,39 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>               k = lxc_array_len((void **)h->all_mount_points);
>               r = lxc_grow_array((void ***)&h->all_mount_points, 
> &h->all_mount_point_capacity, k + 1, 4);
>               if (r < 0)
> -                     goto out_error;
> +                     goto out4;
>               h->all_mount_points[k] = mount_point;
>       }
>  
>       /* oops, we couldn't find anything */
>       if (!meta_data->hierarchies || !meta_data->mount_points) {
> -             errno = EINVAL;
> -             goto out_error;
> +             ret = EINVAL;
> +             goto out4;
>       }
>  
> -     return meta_data;
> -
> -out_error:
> -     saved_errno = errno;
> -     if (proc_cgroups)
> -             fclose(proc_cgroups);
> -     if (proc_self_cgroup)
> -             fclose(proc_self_cgroup);
> +     ret = 0;
> +out4:
>       if (proc_self_mountinfo)
>               fclose(proc_self_mountinfo);
> -     free(line);
> -     free(tokens);
> -     lxc_free_array((void **)kernel_subsystems, free);
> -     lxc_cgroup_put_meta(meta_data);
> -     errno = saved_errno;
> -     return NULL;
> +out3:
> +     if (proc_self_cgroup)
> +             fclose(proc_self_cgroup);
> +out2:
> +     if (proc_cgroups)
> +             fclose(proc_cgroups);
> +     if (line)
> +             free(line);
> +     if (tokens)
> +             free(tokens);
> +out1:
> +     if (ret != 0) {
> +             lxc_free_array((void **)kernel_subsystems, free);
> +             lxc_cgroup_put_meta(meta_data);
> +             free(meta_data);
> +             meta_data = NULL;
> +     }
> +     errno = ret;
> +     return meta_data;
>  }
>  
>  struct cgroup_meta_data *lxc_cgroup_get_meta(struct cgroup_meta_data 
> *meta_data)
> -- 
> 1.8.1.4
> 
> 
> ------------------------------------------------------------------------------
> LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99!
> 1,500+ hours of tutorials including VisualStudio 2012, Windows 8, SharePoint
> 2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack includes
> Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13. 
> http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel

------------------------------------------------------------------------------
LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99!
1,500+ hours of tutorials including VisualStudio 2012, Windows 8, SharePoint
2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack includes
Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13. 
http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to