diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-06-19 13:07:23 +0200 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-06-26 13:17:05 +0200 |
commit | 1778bfa5fef337158537a77344300e1a755a7ffe (patch) | |
tree | 1c384616b25d1386be0c448797aafe2b5f03f51c /pkg/cgroups/blkio.go | |
parent | 5d25a4793d465896fd1762735c8bb593c4aefdfd (diff) | |
download | podman-1778bfa5fef337158537a77344300e1a755a7ffe.tar.gz podman-1778bfa5fef337158537a77344300e1a755a7ffe.tar.bz2 podman-1778bfa5fef337158537a77344300e1a755a7ffe.zip |
pkg, cgroups: add initial support for cgroup v2
This is an initial implementation of cgroup v2 support for
pkg/cgroups. It currently works with crun, with this patch:
https://github.com/giuseppe/crun/pull/49).
It adds the pieces for:
- set PID limit to 1
- retrieve stats so that "podman stats" work.
the only missing part is the support for reading per
CPU stats (that is cpuacct.usage_percpu on cgroup v1), so for now it
always returns an empty result.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg/cgroups/blkio.go')
-rw-r--r-- | pkg/cgroups/blkio.go | 134 |
1 files changed, 91 insertions, 43 deletions
diff --git a/pkg/cgroups/blkio.go b/pkg/cgroups/blkio.go index 8eb54abec..ca9107d97 100644 --- a/pkg/cgroups/blkio.go +++ b/pkg/cgroups/blkio.go @@ -9,6 +9,7 @@ import ( "strings" spec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" ) type blkioHandler struct { @@ -29,7 +30,7 @@ func (c *blkioHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error // Create the cgroup func (c *blkioHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("function not implemented yet") + return false, fmt.Errorf("io create not implemented for cgroup v2") } return ctr.createCgroupDirectory(Blkio) } @@ -44,57 +45,104 @@ func (c *blkioHandler) Stat(ctr *CgroupControl, m *Metrics) error { var ioServiceBytesRecursive []BlkIOEntry if ctr.cgroup2 { - return fmt.Errorf("function not implemented yet") - } - - BlkioRoot := ctr.getCgroupv1Path(Blkio) - - p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive") - f, err := os.Open(p) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer f.Close() - - scanner := bufio.NewScanner(f) - for scanner.Scan() { - line := scanner.Text() - parts := strings.Fields(line) - if len(parts) < 3 { - continue - } - d := strings.Split(parts[0], ":") - if len(d) != 2 { - continue - } - minor, err := strconv.ParseUint(d[0], 10, 0) + // more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html + values, err := readCgroup2MapFile(ctr, "io.stat") if err != nil { return err } - major, err := strconv.ParseUint(d[1], 10, 0) + for k, v := range values { + d := strings.Split(k, ":") + if len(d) != 2 { + continue + } + minor, err := strconv.ParseUint(d[0], 10, 0) + if err != nil { + return err + } + major, err := strconv.ParseUint(d[1], 10, 0) + if err != nil { + return err + } + + for _, item := range v { + d := strings.Split(item, "=") + if len(d) != 2 { + continue + } + op := d[0] + + // Accommodate the cgroup v1 naming + switch op { + case "rbytes": + op = "read" + case "wbytes": + op = "write" + } + + value, err := strconv.ParseUint(d[1], 10, 0) + if err != nil { + return err + } + + entry := BlkIOEntry{ + Op: op, + Major: major, + Minor: minor, + Value: value, + } + ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) + } + } + } else { + BlkioRoot := ctr.getCgroupv1Path(Blkio) + + p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive") + f, err := os.Open(p) if err != nil { - return err + if os.IsNotExist(err) { + return nil + } + return errors.Wrapf(err, "open %s", p) } + defer f.Close() - op := parts[1] + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + parts := strings.Fields(line) + if len(parts) < 3 { + continue + } + d := strings.Split(parts[0], ":") + if len(d) != 2 { + continue + } + minor, err := strconv.ParseUint(d[0], 10, 0) + if err != nil { + return err + } + major, err := strconv.ParseUint(d[1], 10, 0) + if err != nil { + return err + } - value, err := strconv.ParseUint(parts[2], 10, 0) - if err != nil { - return err + op := parts[1] + + value, err := strconv.ParseUint(parts[2], 10, 0) + if err != nil { + return err + } + entry := BlkIOEntry{ + Op: op, + Major: major, + Minor: minor, + Value: value, + } + ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) } - entry := BlkIOEntry{ - Op: op, - Major: major, - Minor: minor, - Value: value, + if err := scanner.Err(); err != nil { + return errors.Wrapf(err, "parse %s", p) } - ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) - } - if err := scanner.Err(); err != nil { - return err } m.Blkio = BlkioMetrics{IoServiceBytesRecursive: ioServiceBytesRecursive} return nil |