On 2013/10/12 16:35, Weng Meiling wrote: > > 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.
Hi Ivana, In fact, this patch just resolve the situation mentioned above, the problem still will occur if user use an custom config in which memory.memsw.limit_in_bytes is before memory.limit_in_bytes. For memory.memsw.limit_in_bytes/memory.limit_in_bytes and cpu.rt_period_us/cpu.rt_runtime_us, in some situation, setting them by cgset --copy-from will fail due to the restriction between them. the situation example: $ cgget -g cpu:test1 test1: cpu.rt_period_us: 1000000 cpu.rt_runtime_us: 10000 cpu.stat: nr_periods 0 nr_throttled 0 throttled_time 0 cpu.cfs_period_us: 100000 cpu.cfs_quota_us: -1 cpu.shares: 1024 $ cgget -g cpu:test test: cpu.rt_period_us: 2000 cpu.rt_runtime_us: 100 cpu.stat: nr_periods 0 nr_throttled 0 throttled_time 0 cpu.cfs_period_us: 100000 cpu.cfs_quota_us: -1 cpu.shares: 1024 $ cgset --copy-from test test1 $ cgget -g cpu:test1 test1: cpu.rt_period_us: 1000000 cpu.rt_runtime_us: 100 cpu.stat: nr_periods 0 nr_throttled 0 throttled_time 0 cpu.cfs_period_us: 100000 cpu.cfs_quota_us: -1 cpu.shares: 1024 the cpu.rt_period_us copied failed. What do you think about this problem ? > > 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 */ > ------------------------------------------------------------------------------ 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