github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/cgroups/cpuset.go (about) 1 package cgroups 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "path/filepath" 7 "strings" 8 9 spec "github.com/opencontainers/runtime-spec/specs-go" 10 "github.com/pkg/errors" 11 ) 12 13 type cpusetHandler struct { 14 } 15 16 func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) { 17 if dir == cgroupRoot { 18 return nil, fmt.Errorf("could not find parent to initialize cpuset %s", file) 19 } 20 path := filepath.Join(dir, file) 21 parentPath := path 22 if cgroupv2 { 23 parentPath = fmt.Sprintf("%s.effective", parentPath) 24 } 25 data, err := ioutil.ReadFile(parentPath) 26 if err != nil { 27 return nil, errors.Wrapf(err, "open %s", path) 28 } 29 if len(strings.Trim(string(data), "\n")) != 0 { 30 return data, nil 31 } 32 data, err = cpusetCopyFileFromParent(filepath.Dir(dir), file, cgroupv2) 33 if err != nil { 34 return nil, err 35 } 36 if err := ioutil.WriteFile(path, data, 0644); err != nil { 37 return nil, errors.Wrapf(err, "write %s", path) 38 } 39 return data, nil 40 } 41 42 func cpusetCopyFromParent(path string, cgroupv2 bool) error { 43 for _, file := range []string{"cpuset.cpus", "cpuset.mems"} { 44 if _, err := cpusetCopyFileFromParent(path, file, cgroupv2); err != nil { 45 return err 46 } 47 } 48 return nil 49 } 50 51 func getCpusetHandler() *cpusetHandler { 52 return &cpusetHandler{} 53 } 54 55 // Apply set the specified constraints 56 func (c *cpusetHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error { 57 if res.CPU == nil { 58 return nil 59 } 60 return fmt.Errorf("cpuset apply not implemented yet") 61 } 62 63 // Create the cgroup 64 func (c *cpusetHandler) Create(ctr *CgroupControl) (bool, error) { 65 if ctr.cgroup2 { 66 path := filepath.Join(cgroupRoot, ctr.path) 67 return true, cpusetCopyFromParent(path, true) 68 } 69 70 created, err := ctr.createCgroupDirectory(CPUset) 71 if !created || err != nil { 72 return created, err 73 } 74 return true, cpusetCopyFromParent(ctr.getCgroupv1Path(CPUset), false) 75 } 76 77 // Destroy the cgroup 78 func (c *cpusetHandler) Destroy(ctr *CgroupControl) error { 79 return rmDirRecursively(ctr.getCgroupv1Path(CPUset)) 80 } 81 82 // Stat fills a metrics structure with usage stats for the controller 83 func (c *cpusetHandler) Stat(ctr *CgroupControl, m *Metrics) error { 84 return nil 85 }