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

Reply via email to