summaryrefslogtreecommitdiff
path: root/pkg/cgroups/blkio.go
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2019-06-19 13:07:23 +0200
committerGiuseppe Scrivano <gscrivan@redhat.com>2019-06-26 13:17:05 +0200
commit1778bfa5fef337158537a77344300e1a755a7ffe (patch)
tree1c384616b25d1386be0c448797aafe2b5f03f51c /pkg/cgroups/blkio.go
parent5d25a4793d465896fd1762735c8bb593c4aefdfd (diff)
downloadpodman-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.go134
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