github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/libcontainer/cgroups/fs2/pids.go (about) 1 package fs2 2 3 import ( 4 "errors" 5 "math" 6 "os" 7 "strings" 8 9 "golang.org/x/sys/unix" 10 11 "github.com/opencontainers/runc/libcontainer/cgroups" 12 "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" 13 "github.com/opencontainers/runc/libcontainer/configs" 14 ) 15 16 func isPidsSet(r *configs.Resources) bool { 17 return r.PidsLimit != 0 18 } 19 20 func setPids(dirPath string, r *configs.Resources) error { 21 if !isPidsSet(r) { 22 return nil 23 } 24 if val := numToStr(r.PidsLimit); val != "" { 25 if err := cgroups.WriteFile(dirPath, "pids.max", val); err != nil { 26 return err 27 } 28 } 29 30 return nil 31 } 32 33 func statPidsFromCgroupProcs(dirPath string, stats *cgroups.Stats) error { 34 // if the controller is not enabled, let's read PIDS from cgroups.procs 35 // (or threads if cgroup.threads is enabled) 36 contents, err := cgroups.ReadFile(dirPath, "cgroup.procs") 37 if errors.Is(err, unix.ENOTSUP) { 38 contents, err = cgroups.ReadFile(dirPath, "cgroup.threads") 39 } 40 if err != nil { 41 return err 42 } 43 pids := strings.Count(contents, "\n") 44 stats.PidsStats.Current = uint64(pids) 45 stats.PidsStats.Limit = 0 46 return nil 47 } 48 49 func statPids(dirPath string, stats *cgroups.Stats) error { 50 current, err := fscommon.GetCgroupParamUint(dirPath, "pids.current") 51 if err != nil { 52 if os.IsNotExist(err) { 53 return statPidsFromCgroupProcs(dirPath, stats) 54 } 55 return err 56 } 57 58 max, err := fscommon.GetCgroupParamUint(dirPath, "pids.max") 59 if err != nil { 60 return err 61 } 62 // If no limit is set, read from pids.max returns "max", which is 63 // converted to MaxUint64 by GetCgroupParamUint. Historically, we 64 // represent "no limit" for pids as 0, thus this conversion. 65 if max == math.MaxUint64 { 66 max = 0 67 } 68 69 stats.PidsStats.Current = current 70 stats.PidsStats.Limit = max 71 return nil 72 }