From: Weng Meiling <wengmeiling.w...@huawei.com>

After setting memory.limit_in_bytes and memory.memsw.limit_in_bytes,
use cgsnapshot -f to save the current cgroup configure, then use
cgconfigparser to resume it according the configure file, but it failed.

The steps:

$ cgsnapshot -s memory -f config
$ cat config
mount {
        memory = /cgroup/memory;
}

group test {
        memory {
                memory.memsw.failcnt="0";
                memory.memsw.limit_in_bytes="2097152";
                memory.memsw.max_usage_in_bytes="0";
                memory.oom_control="oom_kill_disable 0
under_oom 0";
                memory.move_charge_at_immigrate="0";
                memory.swappiness="60";
                memory.use_hierarchy="0";
                memory.force_empty="";
                memory.failcnt="0";
                memory.soft_limit_in_bytes="18446744073709551615";
                memory.limit_in_bytes="1048576";
                memory.max_usage_in_bytes="0";
        }
}

$ cgclear
$ cgconfigparser -l config
/usr/sbin/cgconfigparser; error loading config: Failed to remove a non-empty 
group

cgconfigparser failed because the memory.memsw.limit_in_bytes is setted before
memory.limit_in_bytes, when setting memory.memsw.limit_in_bytes, 
memory.limit_in_bytes
is still the default value 18446744073709551615, so it failed. This patch fixes 
the
problem. It makes cgroup_get_cgroup() get controller's files in alphabet order, 
so that
the memory.memsw.limit_in_bytes will be setted after 
memory.memsw.limit_in_bytes.

After the patch:

$ cgsnapshot -s memory -f config

mount {
        memory = /cgroup/memory;
}
$ cat config
group test {
        memory {
                memory.failcnt="0";
                memory.force_empty="";
                memory.limit_in_bytes="1048576";
                memory.max_usage_in_bytes="0";
                memory.memsw.failcnt="0";
                memory.memsw.limit_in_bytes="2097152";
                memory.memsw.max_usage_in_bytes="0";
                memory.move_charge_at_immigrate="0";
                memory.oom_control="oom_kill_disable 0
under_oom 0";
                memory.soft_limit_in_bytes="18446744073709551615";
                memory.swappiness="60";
                memory.use_hierarchy="0";
        }
}
$ cgclear
$ cgconfigparser -l config
$ lssubsys
memory

v1 --> v2
free ctrl_dir's memory correctly.

Signed-off-by: Weng Meiling <wengmeiling.w...@huawei.com>
---
 src/api.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/api.c b/src/api.c
index 3fa604a..124689c 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2371,10 +2371,9 @@ fill_error:
  */
 int cgroup_get_cgroup(struct cgroup *cgroup)
 {
-       int i, j;
+       int i, j, k;
        char path[FILENAME_MAX];
-       DIR *dir = NULL;
-       struct dirent *ctrl_dir = NULL;
+       struct dirent **ctrl_dir = NULL;
        char *control_path = NULL;
        int error;
        int ret;
@@ -2395,6 +2394,7 @@ int cgroup_get_cgroup(struct cgroup *cgroup)
                struct cgroup_controller *cgc;
                struct stat stat_buffer;
                int path_len;
+               int count = 0;

                if (!cg_build_path_locked(NULL, path,
                                        cg_mount_table[i].name))
@@ -2446,30 +2446,37 @@ int cgroup_get_cgroup(struct cgroup *cgroup)
                        goto unlock_error;
                }

-               dir = opendir(path);
-               if (!dir) {
+               count = scandir(path, &ctrl_dir, 0, alphasort);
+               if (count < 0) {
                        last_errno = errno;
                        error = ECGOTHER;
                        goto unlock_error;
                }

-               while ((ctrl_dir = readdir(dir)) != NULL) {
+               for (k = 0; k < count; k++) {
                        /*
                         * Skip over non regular files
                         */
-                       if (ctrl_dir->d_type != DT_REG)
+                       if (ctrl_dir[k]->d_type != DT_REG) {
+                               free(ctrl_dir[k]);
                                continue;
+                       }

-                       error = cgroup_fill_cgc(ctrl_dir, cgroup, cgc, i);
+                       error = cgroup_fill_cgc(ctrl_dir[k], cgroup, cgc, i);
                        for (j = 0; j < cgc->index; j++)
                                cgc->values[j]->dirty = false;

                        if (error == ECGFAIL) {
-                               closedir(dir);
+                               while (k < count) {
+                                       free(ctrl_dir[k]);
+                                       k++;
+                               }
+                               free(ctrl_dir);
                                goto unlock_error;
                        }
+                       free(ctrl_dir[k]);
                }
-               closedir(dir);
+               free(ctrl_dir);
        }

        /* Check if the group really exists or not */
-- 1.8.3



------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135031&iu=/4140/ostg.clktrk
_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to