vendor: github.com/containerd/cgroups v1.0.3
full diff: https://github.com/containerd/cgroups/compare/v1.0.1...v1.0.3 - cgroup v1: implement AddProc() - cgroup v1: reduce duplicated code - cgroup v2: Fix potential dirfd leak - cgroup v2: remove unimplemented errors and ErrorHandler, IgnoreNotExist - cgroup v2: v2: Fix inotify fd leak when cgroup is deleted - cgroup.go: avoid panic on nil interface - cgroup: Optionally add process and task to a subsystems subset - fix Implicit memory aliasing in for loop - go.mod: coreos/go-systemd/v22 v22.3.2 to prepare for deprecations - Improvements on cgroup v2 support - replace pkg/errors from vendor - Use /proc/partitions to get device names - utils: export ParseCgroupFile() Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
7876c53424
commit
461845bfbc
17 changed files with 264 additions and 257 deletions
|
@ -17,7 +17,7 @@ require (
|
|||
github.com/aws/aws-sdk-go v1.28.11
|
||||
github.com/bsphere/le_go v0.0.0-20170215134836-7a984a84b549
|
||||
github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5
|
||||
github.com/containerd/cgroups v1.0.1
|
||||
github.com/containerd/cgroups v1.0.3
|
||||
github.com/containerd/containerd v1.5.9
|
||||
github.com/containerd/continuity v0.1.0
|
||||
github.com/containerd/fifo v1.0.0
|
||||
|
|
|
@ -125,8 +125,9 @@ github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1
|
|||
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
||||
github.com/containerd/cgroups v1.0.1 h1:iJnMvco9XGvKUvNQkv88bE4uJXxRQH18efbKo9w5vHQ=
|
||||
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
|
||||
github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4=
|
||||
github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8=
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
||||
|
@ -725,6 +726,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
|
|||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
|
@ -739,6 +741,8 @@ go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
|||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
@ -804,6 +808,7 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
|
@ -879,8 +884,10 @@ golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210313202042-bd2e13477e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
8
vendor/github.com/containerd/cgroups/README.md
generated
vendored
8
vendor/github.com/containerd/cgroups/README.md
generated
vendored
|
@ -1,7 +1,7 @@
|
|||
# cgroups
|
||||
|
||||
[![Build Status](https://github.com/containerd/cgroups/workflows/CI/badge.svg)](https://github.com/containerd/cgroups/actions?query=workflow%3ACI)
|
||||
[![codecov](https://codecov.io/gh/containerd/cgroups/branch/master/graph/badge.svg)](https://codecov.io/gh/containerd/cgroups)
|
||||
[![codecov](https://codecov.io/gh/containerd/cgroups/branch/main/graph/badge.svg)](https://codecov.io/gh/containerd/cgroups)
|
||||
[![GoDoc](https://godoc.org/github.com/containerd/cgroups?status.svg)](https://godoc.org/github.com/containerd/cgroups)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/cgroups)](https://goreportcard.com/report/github.com/containerd/cgroups)
|
||||
|
||||
|
@ -142,8 +142,8 @@ All static path should not include `/sys/fs/cgroup/` prefix, it should start wit
|
|||
Cgroups is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
|
||||
As a containerd sub-project, you will find the:
|
||||
|
||||
* [Project governance](https://github.com/containerd/project/blob/master/GOVERNANCE.md),
|
||||
* [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS),
|
||||
* and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md)
|
||||
* [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md),
|
||||
* [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS),
|
||||
* and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md)
|
||||
|
||||
information in our [`containerd/project`](https://github.com/containerd/project) repository.
|
||||
|
|
9
vendor/github.com/containerd/cgroups/blkio.go
generated
vendored
9
vendor/github.com/containerd/cgroups/blkio.go
generated
vendored
|
@ -130,7 +130,7 @@ func (b *blkioController) Stat(path string, stats *v1.Metrics) error {
|
|||
}
|
||||
}
|
||||
|
||||
f, err := os.Open(filepath.Join(b.procRoot, "diskstats"))
|
||||
f, err := os.Open(filepath.Join(b.procRoot, "partitions"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -335,7 +335,10 @@ func getDevices(r io.Reader) (map[deviceKey]string, error) {
|
|||
s = bufio.NewScanner(r)
|
||||
devices = make(map[deviceKey]string)
|
||||
)
|
||||
for s.Scan() {
|
||||
for i := 0; s.Scan(); i++ {
|
||||
if i < 2 {
|
||||
continue
|
||||
}
|
||||
fields := strings.Fields(s.Text())
|
||||
major, err := strconv.Atoi(fields[0])
|
||||
if err != nil {
|
||||
|
@ -352,7 +355,7 @@ func getDevices(r io.Reader) (map[deviceKey]string, error) {
|
|||
if _, ok := devices[key]; ok {
|
||||
continue
|
||||
}
|
||||
devices[key] = filepath.Join("/dev", fields[2])
|
||||
devices[key] = filepath.Join("/dev", fields[3])
|
||||
}
|
||||
return devices, s.Err()
|
||||
}
|
||||
|
|
161
vendor/github.com/containerd/cgroups/cgroup.go
generated
vendored
161
vendor/github.com/containerd/cgroups/cgroup.go
generated
vendored
|
@ -17,6 +17,7 @@
|
|||
package cgroups
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -25,8 +26,8 @@ import (
|
|||
"sync"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// New returns a new control via the cgroup cgroups interface
|
||||
|
@ -83,7 +84,7 @@ func Load(hierarchy Hierarchy, path Path, opts ...InitOpts) (Cgroup, error) {
|
|||
for _, s := range pathers(subsystems) {
|
||||
p, err := path(s.Name())
|
||||
if err != nil {
|
||||
if os.IsNotExist(errors.Cause(err)) {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil, ErrCgroupDeleted
|
||||
}
|
||||
if err == ErrControllerNotActive {
|
||||
|
@ -149,8 +150,50 @@ func (c *cgroup) Subsystems() []Subsystem {
|
|||
return c.subsystems
|
||||
}
|
||||
|
||||
// Add moves the provided process into the new cgroup
|
||||
func (c *cgroup) Add(process Process) error {
|
||||
func (c *cgroup) subsystemsFilter(subsystems ...Name) []Subsystem {
|
||||
if len(subsystems) == 0 {
|
||||
return c.subsystems
|
||||
}
|
||||
|
||||
var filteredSubsystems = []Subsystem{}
|
||||
for _, s := range c.subsystems {
|
||||
for _, f := range subsystems {
|
||||
if s.Name() == f {
|
||||
filteredSubsystems = append(filteredSubsystems, s)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filteredSubsystems
|
||||
}
|
||||
|
||||
// Add moves the provided process into the new cgroup.
|
||||
// Without additional arguments, the process is added to all the cgroup subsystems.
|
||||
// When giving Add a list of subsystem names, the process is only added to those
|
||||
// subsystems, provided that they are active in the targeted cgroup.
|
||||
func (c *cgroup) Add(process Process, subsystems ...Name) error {
|
||||
return c.add(process, cgroupProcs, subsystems...)
|
||||
}
|
||||
|
||||
// AddProc moves the provided process id into the new cgroup.
|
||||
// Without additional arguments, the process with the given id is added to all
|
||||
// the cgroup subsystems. When giving AddProc a list of subsystem names, the process
|
||||
// id is only added to those subsystems, provided that they are active in the targeted
|
||||
// cgroup.
|
||||
func (c *cgroup) AddProc(pid uint64, subsystems ...Name) error {
|
||||
return c.add(Process{Pid: int(pid)}, cgroupProcs, subsystems...)
|
||||
}
|
||||
|
||||
// AddTask moves the provided tasks (threads) into the new cgroup.
|
||||
// Without additional arguments, the task is added to all the cgroup subsystems.
|
||||
// When giving AddTask a list of subsystem names, the task is only added to those
|
||||
// subsystems, provided that they are active in the targeted cgroup.
|
||||
func (c *cgroup) AddTask(process Process, subsystems ...Name) error {
|
||||
return c.add(process, cgroupTasks, subsystems...)
|
||||
}
|
||||
|
||||
func (c *cgroup) add(process Process, pType procType, subsystems ...Name) error {
|
||||
if process.Pid <= 0 {
|
||||
return ErrInvalidPid
|
||||
}
|
||||
|
@ -159,52 +202,19 @@ func (c *cgroup) Add(process Process) error {
|
|||
if c.err != nil {
|
||||
return c.err
|
||||
}
|
||||
return c.add(process)
|
||||
}
|
||||
|
||||
func (c *cgroup) add(process Process) error {
|
||||
for _, s := range pathers(c.subsystems) {
|
||||
for _, s := range pathers(c.subsystemsFilter(subsystems...)) {
|
||||
p, err := c.path(s.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := retryingWriteFile(
|
||||
filepath.Join(s.Path(p), cgroupProcs),
|
||||
err = retryingWriteFile(
|
||||
filepath.Join(s.Path(p), pType),
|
||||
[]byte(strconv.Itoa(process.Pid)),
|
||||
defaultFilePerm,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddTask moves the provided tasks (threads) into the new cgroup
|
||||
func (c *cgroup) AddTask(process Process) error {
|
||||
if process.Pid <= 0 {
|
||||
return ErrInvalidPid
|
||||
}
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.err != nil {
|
||||
return c.err
|
||||
}
|
||||
return c.addTask(process)
|
||||
}
|
||||
|
||||
func (c *cgroup) addTask(process Process) error {
|
||||
for _, s := range pathers(c.subsystems) {
|
||||
p, err := c.path(s.Name())
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := retryingWriteFile(
|
||||
filepath.Join(s.Path(p), cgroupTasks),
|
||||
[]byte(strconv.Itoa(process.Pid)),
|
||||
defaultFilePerm,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -326,15 +336,29 @@ func (c *cgroup) Processes(subsystem Name, recursive bool) ([]Process, error) {
|
|||
if c.err != nil {
|
||||
return nil, c.err
|
||||
}
|
||||
return c.processes(subsystem, recursive)
|
||||
return c.processes(subsystem, recursive, cgroupProcs)
|
||||
}
|
||||
|
||||
func (c *cgroup) processes(subsystem Name, recursive bool) ([]Process, error) {
|
||||
// Tasks returns the tasks running inside the cgroup along
|
||||
// with the subsystem used, pid, and path
|
||||
func (c *cgroup) Tasks(subsystem Name, recursive bool) ([]Task, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.err != nil {
|
||||
return nil, c.err
|
||||
}
|
||||
return c.processes(subsystem, recursive, cgroupTasks)
|
||||
}
|
||||
|
||||
func (c *cgroup) processes(subsystem Name, recursive bool, pType procType) ([]Process, error) {
|
||||
s := c.getSubsystem(subsystem)
|
||||
sp, err := c.path(subsystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if s == nil {
|
||||
return nil, fmt.Errorf("cgroups: %s doesn't exist in %s subsystem", sp, subsystem)
|
||||
}
|
||||
path := s.(pather).Path(sp)
|
||||
var processes []Process
|
||||
err = filepath.Walk(path, func(p string, info os.FileInfo, err error) error {
|
||||
|
@ -348,10 +372,10 @@ func (c *cgroup) processes(subsystem Name, recursive bool) ([]Process, error) {
|
|||
return filepath.SkipDir
|
||||
}
|
||||
dir, name := filepath.Split(p)
|
||||
if name != cgroupProcs {
|
||||
if name != pType {
|
||||
return nil
|
||||
}
|
||||
procs, err := readPids(dir, subsystem)
|
||||
procs, err := readPids(dir, subsystem, pType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -361,49 +385,6 @@ func (c *cgroup) processes(subsystem Name, recursive bool) ([]Process, error) {
|
|||
return processes, err
|
||||
}
|
||||
|
||||
// Tasks returns the tasks running inside the cgroup along
|
||||
// with the subsystem used, pid, and path
|
||||
func (c *cgroup) Tasks(subsystem Name, recursive bool) ([]Task, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.err != nil {
|
||||
return nil, c.err
|
||||
}
|
||||
return c.tasks(subsystem, recursive)
|
||||
}
|
||||
|
||||
func (c *cgroup) tasks(subsystem Name, recursive bool) ([]Task, error) {
|
||||
s := c.getSubsystem(subsystem)
|
||||
sp, err := c.path(subsystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path := s.(pather).Path(sp)
|
||||
var tasks []Task
|
||||
err = filepath.Walk(path, func(p string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !recursive && info.IsDir() {
|
||||
if p == path {
|
||||
return nil
|
||||
}
|
||||
return filepath.SkipDir
|
||||
}
|
||||
dir, name := filepath.Split(p)
|
||||
if name != cgroupTasks {
|
||||
return nil
|
||||
}
|
||||
procs, err := readTasksPids(dir, subsystem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tasks = append(tasks, procs...)
|
||||
return nil
|
||||
})
|
||||
return tasks, err
|
||||
}
|
||||
|
||||
// Freeze freezes the entire cgroup and all the processes inside it
|
||||
func (c *cgroup) Freeze() error {
|
||||
c.mu.Lock()
|
||||
|
@ -511,7 +492,7 @@ func (c *cgroup) MoveTo(destination Cgroup) error {
|
|||
return c.err
|
||||
}
|
||||
for _, s := range c.subsystems {
|
||||
processes, err := c.processes(s.Name(), true)
|
||||
processes, err := c.processes(s.Name(), true, cgroupProcs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
43
vendor/github.com/containerd/cgroups/control.go
generated
vendored
43
vendor/github.com/containerd/cgroups/control.go
generated
vendored
|
@ -23,10 +23,12 @@ import (
|
|||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
type procType = string
|
||||
|
||||
const (
|
||||
cgroupProcs = "cgroup.procs"
|
||||
cgroupTasks = "tasks"
|
||||
defaultDirPerm = 0755
|
||||
cgroupProcs procType = "cgroup.procs"
|
||||
cgroupTasks procType = "tasks"
|
||||
defaultDirPerm = 0755
|
||||
)
|
||||
|
||||
// defaultFilePerm is a var so that the test framework can change the filemode
|
||||
|
@ -37,32 +39,37 @@ const (
|
|||
var defaultFilePerm = os.FileMode(0)
|
||||
|
||||
type Process struct {
|
||||
// Subsystem is the name of the subsystem that the process is in
|
||||
// Subsystem is the name of the subsystem that the process / task is in.
|
||||
Subsystem Name
|
||||
// Pid is the process id of the process
|
||||
// Pid is the process id of the process / task.
|
||||
Pid int
|
||||
// Path is the full path of the subsystem and location that the process is in
|
||||
// Path is the full path of the subsystem and location that the process / task is in.
|
||||
Path string
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
// Subsystem is the name of the subsystem that the task is in
|
||||
Subsystem Name
|
||||
// Pid is the process id of the task
|
||||
Pid int
|
||||
// Path is the full path of the subsystem and location that the task is in
|
||||
Path string
|
||||
}
|
||||
type Task = Process
|
||||
|
||||
// Cgroup handles interactions with the individual groups to perform
|
||||
// actions on them as them main interface to this cgroup package
|
||||
type Cgroup interface {
|
||||
// New creates a new cgroup under the calling cgroup
|
||||
New(string, *specs.LinuxResources) (Cgroup, error)
|
||||
// Add adds a process to the cgroup (cgroup.procs)
|
||||
Add(Process) error
|
||||
// AddTask adds a process to the cgroup (tasks)
|
||||
AddTask(Process) error
|
||||
// Add adds a process to the cgroup (cgroup.procs). Without additional arguments,
|
||||
// the process is added to all the cgroup subsystems. When giving Add a list of
|
||||
// subsystem names, the process is only added to those subsystems, provided that
|
||||
// they are active in the targeted cgroup.
|
||||
Add(Process, ...Name) error
|
||||
// AddProc adds the process with the given id to the cgroup (cgroup.procs).
|
||||
// Without additional arguments, the process with the given id is added to all
|
||||
// the cgroup subsystems. When giving AddProc a list of subsystem names, the process
|
||||
// id is only added to those subsystems, provided that they are active in the targeted
|
||||
// cgroup.
|
||||
AddProc(uint64, ...Name) error
|
||||
// AddTask adds a process to the cgroup (tasks). Without additional arguments, the
|
||||
// task is added to all the cgroup subsystems. When giving AddTask a list of subsystem
|
||||
// names, the task is only added to those subsystems, provided that they are active in
|
||||
// the targeted cgroup.
|
||||
AddTask(Process, ...Name) error
|
||||
// Delete removes the cgroup as a whole
|
||||
Delete() error
|
||||
// MoveTo moves all the processes under the calling cgroup to the provided one
|
||||
|
|
2
vendor/github.com/containerd/cgroups/opts.go
generated
vendored
2
vendor/github.com/containerd/cgroups/opts.go
generated
vendored
|
@ -17,7 +17,7 @@
|
|||
package cgroups
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
9
vendor/github.com/containerd/cgroups/paths.go
generated
vendored
9
vendor/github.com/containerd/cgroups/paths.go
generated
vendored
|
@ -17,10 +17,9 @@
|
|||
package cgroups
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Path func(subsystem Name) (string, error)
|
||||
|
@ -39,7 +38,7 @@ func StaticPath(path string) Path {
|
|||
// NestedPath will nest the cgroups based on the calling processes cgroup
|
||||
// placing its child processes inside its own path
|
||||
func NestedPath(suffix string) Path {
|
||||
paths, err := parseCgroupFile("/proc/self/cgroup")
|
||||
paths, err := ParseCgroupFile("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
return errorPath(err)
|
||||
}
|
||||
|
@ -50,9 +49,9 @@ func NestedPath(suffix string) Path {
|
|||
// This is commonly used for the Load function to restore an existing container
|
||||
func PidPath(pid int) Path {
|
||||
p := fmt.Sprintf("/proc/%d/cgroup", pid)
|
||||
paths, err := parseCgroupFile(p)
|
||||
paths, err := ParseCgroupFile(p)
|
||||
if err != nil {
|
||||
return errorPath(errors.Wrapf(err, "parse cgroup file %s", p))
|
||||
return errorPath(fmt.Errorf("parse cgroup file %s: %w", p, err))
|
||||
}
|
||||
return existingPath(paths, "")
|
||||
}
|
||||
|
|
1
vendor/github.com/containerd/cgroups/rdma.go
generated
vendored
1
vendor/github.com/containerd/cgroups/rdma.go
generated
vendored
|
@ -67,6 +67,7 @@ func (p *rdmaController) Create(path string, resources *specs.LinuxResources) er
|
|||
|
||||
for device, limit := range resources.Rdma {
|
||||
if device != "" && (limit.HcaHandles != nil || limit.HcaObjects != nil) {
|
||||
limit := limit
|
||||
return retryingWriteFile(
|
||||
filepath.Join(p.Path(path), "rdma.max"),
|
||||
[]byte(createCmdString(device, &limit)),
|
||||
|
|
15
vendor/github.com/containerd/cgroups/systemd.go
generated
vendored
15
vendor/github.com/containerd/cgroups/systemd.go
generated
vendored
|
@ -17,6 +17,7 @@
|
|||
package cgroups
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -78,7 +79,8 @@ func (s *SystemdController) Name() Name {
|
|||
}
|
||||
|
||||
func (s *SystemdController) Create(path string, _ *specs.LinuxResources) error {
|
||||
conn, err := systemdDbus.New()
|
||||
ctx := context.TODO()
|
||||
conn, err := systemdDbus.NewWithContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -90,7 +92,7 @@ func (s *SystemdController) Create(path string, _ *specs.LinuxResources) error {
|
|||
checkDelegate := func() {
|
||||
canDelegate = true
|
||||
dlSlice := newProperty("Delegate", true)
|
||||
if _, err := conn.StartTransientUnit(slice, "testdelegate", []systemdDbus.Property{dlSlice}, nil); err != nil {
|
||||
if _, err := conn.StartTransientUnitContext(ctx, slice, "testdelegate", []systemdDbus.Property{dlSlice}, nil); err != nil {
|
||||
if dbusError, ok := err.(dbus.Error); ok {
|
||||
// Starting with systemd v237, Delegate is not even a property of slices anymore,
|
||||
// so the D-Bus call fails with "InvalidArgs" error.
|
||||
|
@ -100,7 +102,7 @@ func (s *SystemdController) Create(path string, _ *specs.LinuxResources) error {
|
|||
}
|
||||
}
|
||||
|
||||
conn.StopUnit(slice, "testDelegate", nil)
|
||||
_, _ = conn.StopUnitContext(ctx, slice, "testDelegate", nil)
|
||||
}
|
||||
once.Do(checkDelegate)
|
||||
properties := []systemdDbus.Property{
|
||||
|
@ -118,7 +120,7 @@ func (s *SystemdController) Create(path string, _ *specs.LinuxResources) error {
|
|||
}
|
||||
|
||||
ch := make(chan string)
|
||||
_, err = conn.StartTransientUnit(name, "replace", properties, ch)
|
||||
_, err = conn.StartTransientUnitContext(ctx, name, "replace", properties, ch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -127,14 +129,15 @@ func (s *SystemdController) Create(path string, _ *specs.LinuxResources) error {
|
|||
}
|
||||
|
||||
func (s *SystemdController) Delete(path string) error {
|
||||
conn, err := systemdDbus.New()
|
||||
ctx := context.TODO()
|
||||
conn, err := systemdDbus.NewWithContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
_, name := splitName(path)
|
||||
ch := make(chan string)
|
||||
_, err = conn.StopUnit(name, "replace", ch)
|
||||
_, err = conn.StopUnitContext(ctx, name, "replace", ch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
47
vendor/github.com/containerd/cgroups/utils.go
generated
vendored
47
vendor/github.com/containerd/cgroups/utils.go
generated
vendored
|
@ -164,9 +164,9 @@ func remove(path string) error {
|
|||
return fmt.Errorf("cgroups: unable to remove path %q", path)
|
||||
}
|
||||
|
||||
// readPids will read all the pids of processes in a cgroup by the provided path
|
||||
func readPids(path string, subsystem Name) ([]Process, error) {
|
||||
f, err := os.Open(filepath.Join(path, cgroupProcs))
|
||||
// readPids will read all the pids of processes or tasks in a cgroup by the provided path
|
||||
func readPids(path string, subsystem Name, pType procType) ([]Process, error) {
|
||||
f, err := os.Open(filepath.Join(path, pType))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -195,36 +195,6 @@ func readPids(path string, subsystem Name) ([]Process, error) {
|
|||
return out, nil
|
||||
}
|
||||
|
||||
// readTasksPids will read all the pids of tasks in a cgroup by the provided path
|
||||
func readTasksPids(path string, subsystem Name) ([]Task, error) {
|
||||
f, err := os.Open(filepath.Join(path, cgroupTasks))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
var (
|
||||
out []Task
|
||||
s = bufio.NewScanner(f)
|
||||
)
|
||||
for s.Scan() {
|
||||
if t := s.Text(); t != "" {
|
||||
pid, err := strconv.Atoi(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, Task{
|
||||
Pid: pid,
|
||||
Subsystem: subsystem,
|
||||
Path: path,
|
||||
})
|
||||
}
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func hugePageSizes() ([]string, error) {
|
||||
var (
|
||||
pageSizes []string
|
||||
|
@ -285,7 +255,16 @@ func parseKV(raw string) (string, uint64, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func parseCgroupFile(path string) (map[string]string, error) {
|
||||
// ParseCgroupFile parses the given cgroup file, typically /proc/self/cgroup
|
||||
// or /proc/<pid>/cgroup, into a map of subsystems to cgroup paths, e.g.
|
||||
// "cpu": "/user.slice/user-1000.slice"
|
||||
// "pids": "/user.slice/user-1000.slice"
|
||||
// etc.
|
||||
//
|
||||
// Note that for cgroup v2 unified hierarchy, there are no per-controller
|
||||
// cgroup paths, so the resulting map will have a single element where the key
|
||||
// is empty string ("") and the value is the cgroup path the <pid> is in.
|
||||
func ParseCgroupFile(path string) (map[string]string, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
11
vendor/github.com/containerd/cgroups/v2/devicefilter.go
generated
vendored
11
vendor/github.com/containerd/cgroups/v2/devicefilter.go
generated
vendored
|
@ -23,15 +23,16 @@
|
|||
//
|
||||
// This particular Go implementation based on runc version
|
||||
// https://github.com/opencontainers/runc/blob/master/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
|
@ -106,13 +107,13 @@ func (p *program) appendDevice(dev specs.LinuxDeviceCgroup) error {
|
|||
hasType = false
|
||||
default:
|
||||
// if not specified in OCI json, typ is set to DeviceTypeAll
|
||||
return errors.Errorf("invalid DeviceType %q", dev.Type)
|
||||
return fmt.Errorf("invalid DeviceType %q", dev.Type)
|
||||
}
|
||||
if *dev.Major > math.MaxUint32 {
|
||||
return errors.Errorf("invalid major %d", *dev.Major)
|
||||
return fmt.Errorf("invalid major %d", *dev.Major)
|
||||
}
|
||||
if *dev.Minor > math.MaxUint32 {
|
||||
return errors.Errorf("invalid minor %d", *dev.Major)
|
||||
return fmt.Errorf("invalid minor %d", *dev.Major)
|
||||
}
|
||||
hasMajor := *dev.Major >= 0 // if not specified in OCI json, major is set to -1
|
||||
hasMinor := *dev.Minor >= 0
|
||||
|
@ -126,7 +127,7 @@ func (p *program) appendDevice(dev specs.LinuxDeviceCgroup) error {
|
|||
case 'm':
|
||||
bpfAccess |= unix.BPF_DEVCG_ACC_MKNOD
|
||||
default:
|
||||
return errors.Errorf("unknown device access %v", r)
|
||||
return fmt.Errorf("unknown device access %v", r)
|
||||
}
|
||||
}
|
||||
// If the access is rwm, skip the check.
|
||||
|
|
7
vendor/github.com/containerd/cgroups/v2/ebpf.go
generated
vendored
7
vendor/github.com/containerd/cgroups/v2/ebpf.go
generated
vendored
|
@ -17,11 +17,12 @@
|
|||
package v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/cilium/ebpf/link"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
|
@ -50,7 +51,7 @@ func LoadAttachCgroupDeviceFilter(insts asm.Instructions, license string, dirFD
|
|||
Flags: unix.BPF_F_ALLOW_MULTI,
|
||||
})
|
||||
if err != nil {
|
||||
return nilCloser, errors.Wrap(err, "failed to call BPF_PROG_ATTACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI)")
|
||||
return nilCloser, fmt.Errorf("failed to call BPF_PROG_ATTACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI): %w", err)
|
||||
}
|
||||
closer := func() error {
|
||||
err = link.RawDetachProgram(link.RawDetachProgramOptions{
|
||||
|
@ -59,7 +60,7 @@ func LoadAttachCgroupDeviceFilter(insts asm.Instructions, license string, dirFD
|
|||
Attach: ebpf.AttachCGroupDevice,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE)")
|
||||
return fmt.Errorf("failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE): %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
24
vendor/github.com/containerd/cgroups/v2/errors.go
generated
vendored
24
vendor/github.com/containerd/cgroups/v2/errors.go
generated
vendored
|
@ -18,29 +18,9 @@ package v2
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidPid = errors.New("cgroups: pid must be greater than 0")
|
||||
ErrMountPointNotExist = errors.New("cgroups: cgroup mountpoint does not exist")
|
||||
ErrInvalidFormat = errors.New("cgroups: parsing file with invalid format failed")
|
||||
ErrFreezerNotSupported = errors.New("cgroups: freezer cgroup (v2) not supported on this system")
|
||||
ErrMemoryNotSupported = errors.New("cgroups: memory cgroup (v2) not supported on this system")
|
||||
ErrPidsNotSupported = errors.New("cgroups: pids cgroup (v2) not supported on this system")
|
||||
ErrCPUNotSupported = errors.New("cgroups: cpu cgroup (v2) not supported on this system")
|
||||
ErrCgroupDeleted = errors.New("cgroups: cgroup deleted")
|
||||
ErrNoCgroupMountDestination = errors.New("cgroups: cannot find cgroup mount destination")
|
||||
ErrInvalidGroupPath = errors.New("cgroups: invalid group path")
|
||||
ErrInvalidFormat = errors.New("cgroups: parsing file with invalid format failed")
|
||||
ErrInvalidGroupPath = errors.New("cgroups: invalid group path")
|
||||
)
|
||||
|
||||
// ErrorHandler is a function that handles and acts on errors
|
||||
type ErrorHandler func(err error) error
|
||||
|
||||
// IgnoreNotExist ignores any errors that are for not existing files
|
||||
func IgnoreNotExist(err error) error {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
165
vendor/github.com/containerd/cgroups/v2/manager.go
generated
vendored
165
vendor/github.com/containerd/cgroups/v2/manager.go
generated
vendored
|
@ -18,6 +18,9 @@ package v2
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
|
@ -28,10 +31,10 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/containerd/cgroups/v2/stats"
|
||||
|
||||
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
||||
"github.com/godbus/dbus/v5"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
@ -270,7 +273,9 @@ func (c *Manager) ToggleControllers(controllers []string, t ControllerToggle) er
|
|||
// When running as rootless, the user may face EPERM on parent groups, but it is neglible when the
|
||||
// controller is already written.
|
||||
// So we only return the last error.
|
||||
lastErr = errors.Wrapf(err, "failed to write subtree controllers %+v to %q", controllers, filePath)
|
||||
lastErr = fmt.Errorf("failed to write subtree controllers %+v to %q: %w", controllers, filePath, err)
|
||||
} else {
|
||||
lastErr = nil
|
||||
}
|
||||
}
|
||||
return lastErr
|
||||
|
@ -300,15 +305,23 @@ func (c *Manager) NewChild(name string, resources *Resources) (*Manager, error)
|
|||
if err := os.MkdirAll(path, defaultDirPerm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := Manager{
|
||||
unifiedMountpoint: c.unifiedMountpoint,
|
||||
path: path,
|
||||
}
|
||||
if resources != nil {
|
||||
if err := m.ToggleControllers(resources.EnabledControllers(), Enable); err != nil {
|
||||
// clean up cgroup dir on failure
|
||||
os.Remove(path)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := setResources(path, resources); err != nil {
|
||||
// clean up cgroup dir on failure
|
||||
os.Remove(path)
|
||||
return nil, err
|
||||
}
|
||||
return &Manager{
|
||||
unifiedMountpoint: c.unifiedMountpoint,
|
||||
path: path,
|
||||
}, nil
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Manager) AddProc(pid uint64) error {
|
||||
|
@ -515,7 +528,7 @@ func readKVStatsFile(path string, file string, out map[string]interface{}) error
|
|||
for s.Scan() {
|
||||
name, value, err := parseKV(s.Text())
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error while parsing %s (line=%q)", filepath.Join(path, file), s.Text())
|
||||
return fmt.Errorf("error while parsing %s (line=%q): %w", filepath.Join(path, file), s.Text(), err)
|
||||
}
|
||||
out[name] = value
|
||||
}
|
||||
|
@ -547,17 +560,39 @@ func (c *Manager) freeze(path string, state State) error {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Manager) isCgroupEmpty() bool {
|
||||
// In case of any error we return true so that we exit and don't leak resources
|
||||
out := make(map[string]interface{})
|
||||
if err := readKVStatsFile(c.path, "cgroup.events", out); err != nil {
|
||||
return true
|
||||
}
|
||||
if v, ok := out["populated"]; ok {
|
||||
populated, ok := v.(uint64)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
return populated == 0
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MemoryEventFD returns inotify file descriptor and 'memory.events' inotify watch descriptor
|
||||
func (c *Manager) MemoryEventFD() (int, uint32, error) {
|
||||
fpath := filepath.Join(c.path, "memory.events")
|
||||
fd, err := syscall.InotifyInit()
|
||||
if err != nil {
|
||||
return 0, 0, errors.Errorf("Failed to create inotify fd")
|
||||
return 0, 0, errors.New("failed to create inotify fd")
|
||||
}
|
||||
wd, err := syscall.InotifyAddWatch(fd, fpath, unix.IN_MODIFY)
|
||||
if wd < 0 {
|
||||
if err != nil {
|
||||
syscall.Close(fd)
|
||||
return 0, 0, errors.Errorf("Failed to add inotify watch for %q", fpath)
|
||||
return 0, 0, fmt.Errorf("failed to add inotify watch for %q: %w", fpath, err)
|
||||
}
|
||||
// monitor to detect process exit/cgroup deletion
|
||||
evpath := filepath.Join(c.path, "cgroup.events")
|
||||
if _, err = syscall.InotifyAddWatch(fd, evpath, unix.IN_MODIFY); err != nil {
|
||||
syscall.Close(fd)
|
||||
return 0, 0, fmt.Errorf("failed to add inotify watch for %q: %w", evpath, err)
|
||||
}
|
||||
|
||||
return fd, uint32(wd), nil
|
||||
|
@ -565,22 +600,56 @@ func (c *Manager) MemoryEventFD() (int, uint32, error) {
|
|||
|
||||
func (c *Manager) EventChan() (<-chan Event, <-chan error) {
|
||||
ec := make(chan Event)
|
||||
errCh := make(chan error)
|
||||
errCh := make(chan error, 1)
|
||||
go c.waitForEvents(ec, errCh)
|
||||
|
||||
return ec, nil
|
||||
return ec, errCh
|
||||
}
|
||||
|
||||
func parseMemoryEvents(out map[string]interface{}) (Event, error) {
|
||||
e := Event{}
|
||||
if v, ok := out["high"]; ok {
|
||||
e.High, ok = v.(uint64)
|
||||
if !ok {
|
||||
return Event{}, fmt.Errorf("cannot convert high to uint64: %+v", v)
|
||||
}
|
||||
}
|
||||
if v, ok := out["low"]; ok {
|
||||
e.Low, ok = v.(uint64)
|
||||
if !ok {
|
||||
return Event{}, fmt.Errorf("cannot convert low to uint64: %+v", v)
|
||||
}
|
||||
}
|
||||
if v, ok := out["max"]; ok {
|
||||
e.Max, ok = v.(uint64)
|
||||
if !ok {
|
||||
return Event{}, fmt.Errorf("cannot convert max to uint64: %+v", v)
|
||||
}
|
||||
}
|
||||
if v, ok := out["oom"]; ok {
|
||||
e.OOM, ok = v.(uint64)
|
||||
if !ok {
|
||||
return Event{}, fmt.Errorf("cannot convert oom to uint64: %+v", v)
|
||||
}
|
||||
}
|
||||
if v, ok := out["oom_kill"]; ok {
|
||||
e.OOMKill, ok = v.(uint64)
|
||||
if !ok {
|
||||
return Event{}, fmt.Errorf("cannot convert oom_kill to uint64: %+v", v)
|
||||
}
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (c *Manager) waitForEvents(ec chan<- Event, errCh chan<- error) {
|
||||
fd, wd, err := c.MemoryEventFD()
|
||||
|
||||
defer syscall.InotifyRmWatch(fd, wd)
|
||||
defer syscall.Close(fd)
|
||||
defer close(errCh)
|
||||
|
||||
fd, _, err := c.MemoryEventFD()
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
defer syscall.Close(fd)
|
||||
|
||||
for {
|
||||
buffer := make([]byte, syscall.SizeofInotifyEvent*10)
|
||||
|
@ -591,48 +660,22 @@ func (c *Manager) waitForEvents(ec chan<- Event, errCh chan<- error) {
|
|||
}
|
||||
if bytesRead >= syscall.SizeofInotifyEvent {
|
||||
out := make(map[string]interface{})
|
||||
if err := readKVStatsFile(c.path, "memory.events", out); err == nil {
|
||||
e := Event{}
|
||||
if v, ok := out["high"]; ok {
|
||||
e.High, ok = v.(uint64)
|
||||
if !ok {
|
||||
errCh <- errors.Errorf("cannot convert high to uint64: %+v", v)
|
||||
return
|
||||
}
|
||||
if err := readKVStatsFile(c.path, "memory.events", out); err != nil {
|
||||
// When cgroup is deleted read may return -ENODEV instead of -ENOENT from open.
|
||||
if _, statErr := os.Lstat(filepath.Join(c.path, "memory.events")); !os.IsNotExist(statErr) {
|
||||
errCh <- err
|
||||
}
|
||||
if v, ok := out["low"]; ok {
|
||||
e.Low, ok = v.(uint64)
|
||||
if !ok {
|
||||
errCh <- errors.Errorf("cannot convert low to uint64: %+v", v)
|
||||
return
|
||||
}
|
||||
}
|
||||
if v, ok := out["max"]; ok {
|
||||
e.Max, ok = v.(uint64)
|
||||
if !ok {
|
||||
errCh <- errors.Errorf("cannot convert max to uint64: %+v", v)
|
||||
return
|
||||
}
|
||||
}
|
||||
if v, ok := out["oom"]; ok {
|
||||
e.OOM, ok = v.(uint64)
|
||||
if !ok {
|
||||
errCh <- errors.Errorf("cannot convert oom to uint64: %+v", v)
|
||||
return
|
||||
}
|
||||
}
|
||||
if v, ok := out["oom_kill"]; ok {
|
||||
e.OOMKill, ok = v.(uint64)
|
||||
if !ok {
|
||||
errCh <- errors.Errorf("cannot convert oom_kill to uint64: %+v", v)
|
||||
return
|
||||
}
|
||||
}
|
||||
ec <- e
|
||||
} else {
|
||||
return
|
||||
}
|
||||
e, err := parseMemoryEvents(out)
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
ec <- e
|
||||
if c.isCgroupEmpty() {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -645,9 +688,9 @@ func setDevices(path string, devices []specs.LinuxDeviceCgroup) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dirFD, err := unix.Open(path, unix.O_DIRECTORY|unix.O_RDONLY, 0600)
|
||||
dirFD, err := unix.Open(path, unix.O_DIRECTORY|unix.O_RDONLY|unix.O_CLOEXEC, 0600)
|
||||
if err != nil {
|
||||
return errors.Errorf("cannot get dir FD for %s", path)
|
||||
return fmt.Errorf("cannot get dir FD for %s", path)
|
||||
}
|
||||
defer unix.Close(dirFD)
|
||||
if _, err := LoadAttachCgroupDeviceFilter(insts, license, dirFD); err != nil {
|
||||
|
@ -662,8 +705,9 @@ func NewSystemd(slice, group string, pid int, resources *Resources) (*Manager, e
|
|||
if slice == "" {
|
||||
slice = defaultSlice
|
||||
}
|
||||
ctx := context.TODO()
|
||||
path := filepath.Join(defaultCgroup2Path, slice, group)
|
||||
conn, err := systemdDbus.New()
|
||||
conn, err := systemdDbus.NewWithContext(ctx)
|
||||
if err != nil {
|
||||
return &Manager{}, err
|
||||
}
|
||||
|
@ -733,7 +777,7 @@ func NewSystemd(slice, group string, pid int, resources *Resources) (*Manager, e
|
|||
}
|
||||
|
||||
statusChan := make(chan string, 1)
|
||||
if _, err := conn.StartTransientUnit(group, "replace", properties, statusChan); err == nil {
|
||||
if _, err := conn.StartTransientUnitContext(ctx, group, "replace", properties, statusChan); err == nil {
|
||||
select {
|
||||
case <-statusChan:
|
||||
case <-time.After(time.Second):
|
||||
|
@ -759,14 +803,15 @@ func LoadSystemd(slice, group string) (*Manager, error) {
|
|||
}
|
||||
|
||||
func (c *Manager) DeleteSystemd() error {
|
||||
conn, err := systemdDbus.New()
|
||||
ctx := context.TODO()
|
||||
conn, err := systemdDbus.NewWithContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
group := systemdUnitFromPath(c.path)
|
||||
ch := make(chan string)
|
||||
_, err = conn.StopUnit(group, "replace", ch)
|
||||
_, err = conn.StopUnitContext(ctx, group, "replace", ch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
4
vendor/github.com/containerd/cgroups/v2/utils.go
generated
vendored
4
vendor/github.com/containerd/cgroups/v2/utils.go
generated
vendored
|
@ -29,9 +29,9 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/containerd/cgroups/v2/stats"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -61,7 +61,7 @@ func remove(path string) error {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
return errors.Wrapf(err, "cgroups: unable to remove path %q", path)
|
||||
return fmt.Errorf("cgroups: unable to remove path %q: %w", path, err)
|
||||
}
|
||||
|
||||
// parseCgroupProcsFile parses /sys/fs/cgroup/$GROUPPATH/cgroup.procs
|
||||
|
|
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
|
@ -131,8 +131,8 @@ github.com/cloudflare/cfssl/log
|
|||
github.com/cloudflare/cfssl/ocsp/config
|
||||
github.com/cloudflare/cfssl/signer
|
||||
github.com/cloudflare/cfssl/signer/local
|
||||
# github.com/containerd/cgroups v1.0.1
|
||||
## explicit; go 1.13
|
||||
# github.com/containerd/cgroups v1.0.3
|
||||
## explicit; go 1.16
|
||||
github.com/containerd/cgroups
|
||||
github.com/containerd/cgroups/stats/v1
|
||||
github.com/containerd/cgroups/v2
|
||||
|
|
Loading…
Reference in a new issue