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 Signed-off-by: Weng Meiling <wengmeiling.w...@huawei.com> --- src/api.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/api.c b/src/api.c index 61b852c..0fcfcf7 100644 --- a/src/api.c +++ b/src/api.c @@ -2393,10 +2393,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; @@ -2417,6 +2416,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)) @@ -2468,30 +2468,30 @@ 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) 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); + free(ctrl_dir); goto unlock_error; } } - 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=60134071&iu=/4140/ostg.clktrk _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel