From aee46862ec39ed80b66de2309387b0c715696164 Mon Sep 17 00:00:00 2001 From: Qiang Huang Date: Fri, 18 Nov 2016 15:20:43 +0800 Subject: [PATCH] Fix cpuset issue with cpuset.cpu_exclusive This PR fix issue in this scenario: ``` in terminal 1: ~# cd /sys/fs/cgroup/cpuset ~# mkdir test ~# cd test ~# cat cpuset.cpus 0-3 ~# echo 1 > cpuset.cpu_exclusive (make sure you don't have other cgroups under root) in terminal 2: ~# echo $$ > /sys/fs/cgroup/cpuset/test/tasks // set resources.cpu.cpus="0-2" in config.json ~# runc run test1 back to terminal 1: ~# cd test1 ~# cat cpuset.cpus 0-2 ~# echo 1 > cpuset.cpu_exclusive in terminal 3: ~# echo $$ > /sys/fs/cgroup/test/tasks // set resources.cpu.cpus="3" in config.json ~# runc run test2 container_linux.go:247: starting container process caused "process_linux.go:258: applying cgroup configuration for process caused \"failed to write 0-3\\n to cpuset.cpus: write /sys/fs/cgroup/cpuset/test2/cpuset.cpus: invalid argument\"" ``` Signed-off-by: Qiang Huang --- libcontainer/cgroups/fs/cpuset.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go index 29265c70..918b9a30 100644 --- a/libcontainer/cgroups/fs/cpuset.go +++ b/libcontainer/cgroups/fs/cpuset.go @@ -61,9 +61,26 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro if err != nil { return err } - if err := s.ensureParent(dir, root); err != nil { + // 'ensureParent' start with parent because we don't want to + // explicitly inherit from parent, it could conflict with + // 'cpuset.cpu_exclusive'. + if err := s.ensureParent(filepath.Dir(dir), root); err != nil { return err } + if err := os.MkdirAll(dir, 0755); err != nil { + return err + } + // We didn't inherit cpuset configs from parent, but we have + // to ensure cpuset configs are set before moving task into the + // cgroup. + // The logic is, if user specified cpuset configs, use these + // specified configs, otherwise, inherit from parent. This makes + // cpuset configs work correctly with 'cpuset.cpu_exclusive', and + // keep backward compatbility. + if err := s.ensureCpusAndMems(dir, cgroup); err != nil { + return err + } + // because we are not using d.join we need to place the pid into the procs file // unlike the other subsystems if err := cgroups.WriteCgroupProc(dir, pid); err != nil { @@ -136,3 +153,10 @@ func (s *CpusetGroup) copyIfNeeded(current, parent string) error { func (s *CpusetGroup) isEmpty(b []byte) bool { return len(bytes.Trim(b, "\n")) == 0 } + +func (s *CpusetGroup) ensureCpusAndMems(path string, cgroup *configs.Cgroup) error { + if err := s.Set(path, cgroup); err != nil { + return err + } + return s.copyIfNeeded(path, filepath.Dir(path)) +}