You've already forked runc
mirror of
https://github.com/opencontainers/runc.git
synced 2025-08-01 05:06:52 +03:00
1. Instead of enabling all available controllers, figure out which ones are required, and only enable those. 2. Amend all setFoo() functions to call isFooSet(). While this might seem unnecessary, it might actually help to uncover a bug. Imagine someone: - adds a cgroup.Resources.CpuFoo setting; - modifies setCpu() to apply the new setting; - but forgets to amend isCpuSet() accordingly <-- BUG In this case, a test case modifying CpuFoo will help to uncover the BUG. This is the reason why it's added. This patch *could be* amended by enabling controllers on a best-effort basis, i.e. : - do not return an error early if we can't enable some controllers; - if we fail to enable all controllers at once (usually because one of them can't be enabled), try enabling them one by one. Currently this is not implemented, and it's not clear whether this would be a good way to go or not. [v2: add/use is${Controller}Set() functions] [v3: document neededControllers()] [v4: drop "best-effort" part] Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
80 lines
2.0 KiB
Go
80 lines
2.0 KiB
Go
// +build linux
|
|
|
|
package fs2
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
|
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
|
"github.com/opencontainers/runc/libcontainer/configs"
|
|
"github.com/pkg/errors"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func isPidsSet(cgroup *configs.Cgroup) bool {
|
|
return cgroup.Resources.PidsLimit != 0
|
|
}
|
|
|
|
func setPids(dirPath string, cgroup *configs.Cgroup) error {
|
|
if !isPidsSet(cgroup) {
|
|
return nil
|
|
}
|
|
if val := numToStr(cgroup.Resources.PidsLimit); val != "" {
|
|
if err := fscommon.WriteFile(dirPath, "pids.max", val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func statPidsWithoutController(dirPath string, stats *cgroups.Stats) error {
|
|
// if the controller is not enabled, let's read PIDS from cgroups.procs
|
|
// (or threads if cgroup.threads is enabled)
|
|
contents, err := ioutil.ReadFile(filepath.Join(dirPath, "cgroup.procs"))
|
|
if errors.Is(err, unix.ENOTSUP) {
|
|
contents, err = ioutil.ReadFile(filepath.Join(dirPath, "cgroup.threads"))
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pids := make(map[string]string)
|
|
for _, i := range strings.Split(string(contents), "\n") {
|
|
if i != "" {
|
|
pids[i] = i
|
|
}
|
|
}
|
|
stats.PidsStats.Current = uint64(len(pids))
|
|
stats.PidsStats.Limit = 0
|
|
return nil
|
|
}
|
|
|
|
func statPids(dirPath string, stats *cgroups.Stats) error {
|
|
current, err := fscommon.GetCgroupParamUint(dirPath, "pids.current")
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to parse pids.current")
|
|
}
|
|
|
|
maxString, err := fscommon.GetCgroupParamString(dirPath, "pids.max")
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to parse pids.max")
|
|
}
|
|
|
|
// Default if pids.max == "max" is 0 -- which represents "no limit".
|
|
var max uint64
|
|
if maxString != "max" {
|
|
max, err = fscommon.ParseUint(maxString, 10, 64)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to parse pids.max - unable to parse %q as a uint from Cgroup file %q",
|
|
maxString, filepath.Join(dirPath, "pids.max"))
|
|
}
|
|
}
|
|
|
|
stats.PidsStats.Current = current
|
|
stats.PidsStats.Limit = max
|
|
return nil
|
|
}
|