vendor: bump runc to 1.0.0 pre
This is to check if runc 1.0.0 (to be released shortly) works with k8s. The commands used were (roughly): hack/pin-dependency.sh github.com/opencontainers/runc v1.0.0 hack/lint-dependencies.sh # Follow its recommendations. hack/pin-dependency.sh github.com/cilium/ebpf v0.6.1 hack/pin-dependency.sh github.com/opencontainers/selinux v1.8.2 hack/pin-dependency.sh github.com/sirupsen/logrus v1.8.1 # Recheck. hack/lint-dependencies.sh GO111MODULE=on go mod edit -dropreplace github.com/willf/bitset hack/update-vendor.sh # Recheck. hack/lint-dependencies.sh hack/update-internal-modules.sh # Recheck. hack/lint-dependencies.sh [v2: rebased, updated runc 3a0234e1fe2e82 -> 2f8e8e9d977500] [v3: testing master + runc pr 3019] [v4: updated to 93a01cd4d0b7a0f08a] [v5: updated to f093cca13d3cf8a484] [v6: rebased] [v7: updated to runc v1.0.0] [v8: rebased] Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
16
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
generated
vendored
Normal file
16
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
package apparmor
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
// IsEnabled returns true if apparmor is enabled for the host.
|
||||
IsEnabled = isEnabled
|
||||
|
||||
// ApplyProfile will apply the profile with the specified name to the process after
|
||||
// the next exec. It is only supported on Linux and produces an ErrApparmorNotEnabled
|
||||
// on other platforms.
|
||||
ApplyProfile = applyProfile
|
||||
|
||||
// ErrApparmorNotEnabled indicates that AppArmor is not enabled or not supported.
|
||||
ErrApparmorNotEnabled = errors.New("apparmor: config provided but apparmor not supported")
|
||||
)
|
11
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go
generated
vendored
11
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go
generated
vendored
@@ -15,8 +15,8 @@ var (
|
||||
checkAppArmor sync.Once
|
||||
)
|
||||
|
||||
// IsEnabled returns true if apparmor is enabled for the host.
|
||||
func IsEnabled() bool {
|
||||
// isEnabled returns true if apparmor is enabled for the host.
|
||||
func isEnabled() bool {
|
||||
checkAppArmor.Do(func() {
|
||||
if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil {
|
||||
buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
|
||||
@@ -57,9 +57,10 @@ func changeOnExec(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyProfile will apply the profile with the specified name to the process after
|
||||
// the next exec.
|
||||
func ApplyProfile(name string) error {
|
||||
// applyProfile will apply the profile with the specified name to the process after
|
||||
// the next exec. It is only supported on Linux and produces an error on other
|
||||
// platforms.
|
||||
func applyProfile(name string) error {
|
||||
if name == "" {
|
||||
return nil
|
||||
}
|
||||
|
10
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_unsupported.go
generated
vendored
10
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_unsupported.go
generated
vendored
@@ -2,17 +2,11 @@
|
||||
|
||||
package apparmor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var ErrApparmorNotEnabled = errors.New("apparmor: config provided but apparmor not supported")
|
||||
|
||||
func IsEnabled() bool {
|
||||
func isEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func ApplyProfile(name string) error {
|
||||
func applyProfile(name string) error {
|
||||
if name != "" {
|
||||
return ErrApparmorNotEnabled
|
||||
}
|
||||
|
13
vendor/github.com/opencontainers/runc/libcontainer/cgroups/devices/devices_emulator.go
generated
vendored
13
vendor/github.com/opencontainers/runc/libcontainer/cgroups/devices/devices_emulator.go
generated
vendored
@@ -258,9 +258,9 @@ func (e *Emulator) Apply(rule devices.Rule) error {
|
||||
|
||||
if rule.Allow {
|
||||
return e.allow(innerRule)
|
||||
} else {
|
||||
return e.deny(innerRule)
|
||||
}
|
||||
|
||||
return e.deny(innerRule)
|
||||
}
|
||||
|
||||
// EmulatorFromList takes a reader to a "devices.list"-like source, and returns
|
||||
@@ -371,3 +371,12 @@ func (source *Emulator) Transition(target *Emulator) ([]*devices.Rule, error) {
|
||||
}
|
||||
return transitionRules, nil
|
||||
}
|
||||
|
||||
// Rules returns the minimum set of rules necessary to convert a *deny-all*
|
||||
// cgroup to the emulated filter state (note that this is not the same as a
|
||||
// default cgroupv1 cgroup -- which is allow-all). This is effectively just a
|
||||
// wrapper around Transition() with the source emulator being an empty cgroup.
|
||||
func (e *Emulator) Rules() ([]*devices.Rule, error) {
|
||||
defaultCgroup := &Emulator{defaultAllow: false}
|
||||
return defaultCgroup.Transition(e)
|
||||
}
|
||||
|
119
vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
generated
vendored
119
vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
generated
vendored
@@ -11,6 +11,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/cilium/ebpf/asm"
|
||||
devicesemulator "github.com/opencontainers/runc/libcontainer/cgroups/devices"
|
||||
"github.com/opencontainers/runc/libcontainer/devices"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -22,11 +23,44 @@ const (
|
||||
)
|
||||
|
||||
// DeviceFilter returns eBPF device filter program and its license string
|
||||
func DeviceFilter(devices []*devices.Rule) (asm.Instructions, string, error) {
|
||||
p := &program{}
|
||||
func DeviceFilter(rules []*devices.Rule) (asm.Instructions, string, error) {
|
||||
// Generate the minimum ruleset for the device rules we are given. While we
|
||||
// don't care about minimum transitions in cgroupv2, using the emulator
|
||||
// gives us a guarantee that the behaviour of devices filtering is the same
|
||||
// as cgroupv1, including security hardenings to avoid misconfiguration
|
||||
// (such as punching holes in wildcard rules).
|
||||
emu := new(devicesemulator.Emulator)
|
||||
for _, rule := range rules {
|
||||
if err := emu.Apply(*rule); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
cleanRules, err := emu.Rules()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
p := &program{
|
||||
defaultAllow: emu.IsBlacklist(),
|
||||
}
|
||||
p.init()
|
||||
for i := len(devices) - 1; i >= 0; i-- {
|
||||
if err := p.appendDevice(devices[i]); err != nil {
|
||||
|
||||
for idx, rule := range cleanRules {
|
||||
if rule.Type == devices.WildcardDevice {
|
||||
// We can safely skip over wildcard entries because there should
|
||||
// only be one (at most) at the very start to instruct cgroupv1 to
|
||||
// go into allow-list mode. However we do double-check this here.
|
||||
if idx != 0 || rule.Allow != emu.IsBlacklist() {
|
||||
return nil, "", errors.Errorf("[internal error] emulated cgroupv2 devices ruleset had bad wildcard at idx %v (%s)", idx, rule.CgroupString())
|
||||
}
|
||||
continue
|
||||
}
|
||||
if rule.Allow == p.defaultAllow {
|
||||
// There should be no rules which have an action equal to the
|
||||
// default action, the emulator removes those.
|
||||
return nil, "", errors.Errorf("[internal error] emulated cgroupv2 devices ruleset had no-op rule at idx %v (%s)", idx, rule.CgroupString())
|
||||
}
|
||||
if err := p.appendRule(rule); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
@@ -35,9 +69,9 @@ func DeviceFilter(devices []*devices.Rule) (asm.Instructions, string, error) {
|
||||
}
|
||||
|
||||
type program struct {
|
||||
insts asm.Instructions
|
||||
hasWildCard bool
|
||||
blockID int
|
||||
insts asm.Instructions
|
||||
defaultAllow bool
|
||||
blockID int
|
||||
}
|
||||
|
||||
func (p *program) init() {
|
||||
@@ -67,39 +101,35 @@ func (p *program) init() {
|
||||
asm.LoadMem(asm.R5, asm.R1, 8, asm.Word))
|
||||
}
|
||||
|
||||
// appendDevice needs to be called from the last element of OCI linux.resources.devices to the head element.
|
||||
func (p *program) appendDevice(dev *devices.Rule) error {
|
||||
// appendRule rule converts an OCI rule to the relevant eBPF block and adds it
|
||||
// to the in-progress filter program. In order to operate properly, it must be
|
||||
// called with a "clean" rule list (generated by devices.Emulator.Rules() --
|
||||
// with any "a" rules removed).
|
||||
func (p *program) appendRule(rule *devices.Rule) error {
|
||||
if p.blockID < 0 {
|
||||
return errors.New("the program is finalized")
|
||||
}
|
||||
if p.hasWildCard {
|
||||
// All entries after wildcard entry are ignored
|
||||
return nil
|
||||
}
|
||||
|
||||
bpfType := int32(-1)
|
||||
hasType := true
|
||||
switch dev.Type {
|
||||
case 'c':
|
||||
var bpfType int32
|
||||
switch rule.Type {
|
||||
case devices.CharDevice:
|
||||
bpfType = int32(unix.BPF_DEVCG_DEV_CHAR)
|
||||
case 'b':
|
||||
case devices.BlockDevice:
|
||||
bpfType = int32(unix.BPF_DEVCG_DEV_BLOCK)
|
||||
case 'a':
|
||||
hasType = false
|
||||
default:
|
||||
// if not specified in OCI json, typ is set to DeviceTypeAll
|
||||
return errors.Errorf("invalid Type %q", string(dev.Type))
|
||||
// We do not permit 'a', nor any other types we don't know about.
|
||||
return errors.Errorf("invalid type %q", string(rule.Type))
|
||||
}
|
||||
if dev.Major > math.MaxUint32 {
|
||||
return errors.Errorf("invalid major %d", dev.Major)
|
||||
if rule.Major > math.MaxUint32 {
|
||||
return errors.Errorf("invalid major %d", rule.Major)
|
||||
}
|
||||
if dev.Minor > math.MaxUint32 {
|
||||
return errors.Errorf("invalid minor %d", dev.Major)
|
||||
if rule.Minor > math.MaxUint32 {
|
||||
return errors.Errorf("invalid minor %d", rule.Major)
|
||||
}
|
||||
hasMajor := dev.Major >= 0 // if not specified in OCI json, major is set to -1
|
||||
hasMinor := dev.Minor >= 0
|
||||
hasMajor := rule.Major >= 0 // if not specified in OCI json, major is set to -1
|
||||
hasMinor := rule.Minor >= 0
|
||||
bpfAccess := int32(0)
|
||||
for _, r := range dev.Permissions {
|
||||
for _, r := range rule.Permissions {
|
||||
switch r {
|
||||
case 'r':
|
||||
bpfAccess |= unix.BPF_DEVCG_ACC_READ
|
||||
@@ -119,12 +149,10 @@ func (p *program) appendDevice(dev *devices.Rule) error {
|
||||
nextBlockSym = "block-" + strconv.Itoa(p.blockID+1)
|
||||
prevBlockLastIdx = len(p.insts) - 1
|
||||
)
|
||||
if hasType {
|
||||
p.insts = append(p.insts,
|
||||
// if (R2 != bpfType) goto next
|
||||
asm.JNE.Imm(asm.R2, bpfType, nextBlockSym),
|
||||
)
|
||||
}
|
||||
p.insts = append(p.insts,
|
||||
// if (R2 != bpfType) goto next
|
||||
asm.JNE.Imm(asm.R2, bpfType, nextBlockSym),
|
||||
)
|
||||
if hasAccess {
|
||||
p.insts = append(p.insts,
|
||||
// if (R3 & bpfAccess != R3 /* use R1 as a temp var */) goto next
|
||||
@@ -136,19 +164,16 @@ func (p *program) appendDevice(dev *devices.Rule) error {
|
||||
if hasMajor {
|
||||
p.insts = append(p.insts,
|
||||
// if (R4 != major) goto next
|
||||
asm.JNE.Imm(asm.R4, int32(dev.Major), nextBlockSym),
|
||||
asm.JNE.Imm(asm.R4, int32(rule.Major), nextBlockSym),
|
||||
)
|
||||
}
|
||||
if hasMinor {
|
||||
p.insts = append(p.insts,
|
||||
// if (R5 != minor) goto next
|
||||
asm.JNE.Imm(asm.R5, int32(dev.Minor), nextBlockSym),
|
||||
asm.JNE.Imm(asm.R5, int32(rule.Minor), nextBlockSym),
|
||||
)
|
||||
}
|
||||
if !hasType && !hasAccess && !hasMajor && !hasMinor {
|
||||
p.hasWildCard = true
|
||||
}
|
||||
p.insts = append(p.insts, acceptBlock(dev.Allow)...)
|
||||
p.insts = append(p.insts, acceptBlock(rule.Allow)...)
|
||||
// set blockSym to the first instruction we added in this iteration
|
||||
p.insts[prevBlockLastIdx+1] = p.insts[prevBlockLastIdx+1].Sym(blockSym)
|
||||
p.blockID++
|
||||
@@ -156,14 +181,14 @@ func (p *program) appendDevice(dev *devices.Rule) error {
|
||||
}
|
||||
|
||||
func (p *program) finalize() (asm.Instructions, error) {
|
||||
if p.hasWildCard {
|
||||
// acceptBlock with asm.Return() is already inserted
|
||||
return p.insts, nil
|
||||
var v int32
|
||||
if p.defaultAllow {
|
||||
v = 1
|
||||
}
|
||||
blockSym := "block-" + strconv.Itoa(p.blockID)
|
||||
p.insts = append(p.insts,
|
||||
// R0 <- 0
|
||||
asm.Mov.Imm32(asm.R0, 0).Sym(blockSym),
|
||||
// R0 <- v
|
||||
asm.Mov.Imm32(asm.R0, v).Sym(blockSym),
|
||||
asm.Return(),
|
||||
)
|
||||
p.blockID = -1
|
||||
@@ -171,7 +196,7 @@ func (p *program) finalize() (asm.Instructions, error) {
|
||||
}
|
||||
|
||||
func acceptBlock(accept bool) asm.Instructions {
|
||||
v := int32(0)
|
||||
var v int32
|
||||
if accept {
|
||||
v = 1
|
||||
}
|
||||
|
57
vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/ebpf.go
generated
vendored
57
vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/ebpf.go
generated
vendored
@@ -1,57 +0,0 @@
|
||||
package ebpf
|
||||
|
||||
import (
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/cilium/ebpf/link"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// LoadAttachCgroupDeviceFilter installs eBPF device filter program to /sys/fs/cgroup/<foo> directory.
|
||||
//
|
||||
// Requires the system to be running in cgroup2 unified-mode with kernel >= 4.15 .
|
||||
//
|
||||
// https://github.com/torvalds/linux/commit/ebc614f687369f9df99828572b1d85a7c2de3d92
|
||||
func LoadAttachCgroupDeviceFilter(insts asm.Instructions, license string, dirFD int) (func() error, error) {
|
||||
nilCloser := func() error {
|
||||
return nil
|
||||
}
|
||||
// Increase `ulimit -l` limit to avoid BPF_PROG_LOAD error (#2167).
|
||||
// This limit is not inherited into the container.
|
||||
memlockLimit := &unix.Rlimit{
|
||||
Cur: unix.RLIM_INFINITY,
|
||||
Max: unix.RLIM_INFINITY,
|
||||
}
|
||||
_ = unix.Setrlimit(unix.RLIMIT_MEMLOCK, memlockLimit)
|
||||
spec := &ebpf.ProgramSpec{
|
||||
Type: ebpf.CGroupDevice,
|
||||
Instructions: insts,
|
||||
License: license,
|
||||
}
|
||||
prog, err := ebpf.NewProgram(spec)
|
||||
if err != nil {
|
||||
return nilCloser, err
|
||||
}
|
||||
err = link.RawAttachProgram(link.RawAttachProgramOptions{
|
||||
Target: dirFD,
|
||||
Program: prog,
|
||||
Attach: ebpf.AttachCGroupDevice,
|
||||
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)")
|
||||
}
|
||||
closer := func() error {
|
||||
err = link.RawDetachProgram(link.RawDetachProgramOptions{
|
||||
Target: dirFD,
|
||||
Program: prog,
|
||||
Attach: ebpf.AttachCGroupDevice,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return closer, nil
|
||||
}
|
240
vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/ebpf_linux.go
generated
vendored
Normal file
240
vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/ebpf_linux.go
generated
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
package ebpf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/cilium/ebpf/link"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func nilCloser() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func findAttachedCgroupDeviceFilters(dirFd int) ([]*ebpf.Program, error) {
|
||||
type bpfAttrQuery struct {
|
||||
TargetFd uint32
|
||||
AttachType uint32
|
||||
QueryType uint32
|
||||
AttachFlags uint32
|
||||
ProgIds uint64 // __aligned_u64
|
||||
ProgCnt uint32
|
||||
}
|
||||
|
||||
// Currently you can only have 64 eBPF programs attached to a cgroup.
|
||||
size := 64
|
||||
retries := 0
|
||||
for retries < 10 {
|
||||
progIds := make([]uint32, size)
|
||||
query := bpfAttrQuery{
|
||||
TargetFd: uint32(dirFd),
|
||||
AttachType: uint32(unix.BPF_CGROUP_DEVICE),
|
||||
ProgIds: uint64(uintptr(unsafe.Pointer(&progIds[0]))),
|
||||
ProgCnt: uint32(len(progIds)),
|
||||
}
|
||||
|
||||
// Fetch the list of program ids.
|
||||
_, _, errno := unix.Syscall(unix.SYS_BPF,
|
||||
uintptr(unix.BPF_PROG_QUERY),
|
||||
uintptr(unsafe.Pointer(&query)),
|
||||
unsafe.Sizeof(query))
|
||||
size = int(query.ProgCnt)
|
||||
runtime.KeepAlive(query)
|
||||
if errno != 0 {
|
||||
// On ENOSPC we get the correct number of programs.
|
||||
if errno == unix.ENOSPC {
|
||||
retries++
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("bpf_prog_query(BPF_CGROUP_DEVICE) failed: %w", errno)
|
||||
}
|
||||
|
||||
// Convert the ids to program handles.
|
||||
progIds = progIds[:size]
|
||||
programs := make([]*ebpf.Program, len(progIds))
|
||||
for idx, progId := range progIds {
|
||||
program, err := ebpf.NewProgramFromID(ebpf.ProgramID(progId))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot fetch program from id: %w", err)
|
||||
}
|
||||
programs[idx] = program
|
||||
}
|
||||
runtime.KeepAlive(progIds)
|
||||
return programs, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("could not get complete list of CGROUP_DEVICE programs")
|
||||
}
|
||||
|
||||
var (
|
||||
haveBpfProgReplaceBool bool
|
||||
haveBpfProgReplaceOnce sync.Once
|
||||
)
|
||||
|
||||
// Loosely based on the BPF_F_REPLACE support check in
|
||||
// <https://github.com/cilium/ebpf/blob/v0.6.0/link/syscalls.go>.
|
||||
//
|
||||
// TODO: move this logic to cilium/ebpf
|
||||
func haveBpfProgReplace() bool {
|
||||
haveBpfProgReplaceOnce.Do(func() {
|
||||
prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
|
||||
Type: ebpf.CGroupDevice,
|
||||
License: "MIT",
|
||||
Instructions: asm.Instructions{
|
||||
asm.Mov.Imm(asm.R0, 0),
|
||||
asm.Return(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Debugf("checking for BPF_F_REPLACE support: ebpf.NewProgram failed: %v", err)
|
||||
return
|
||||
}
|
||||
defer prog.Close()
|
||||
|
||||
devnull, err := os.Open("/dev/null")
|
||||
if err != nil {
|
||||
logrus.Debugf("checking for BPF_F_REPLACE support: open dummy target fd: %v", err)
|
||||
return
|
||||
}
|
||||
defer devnull.Close()
|
||||
|
||||
// We know that we have BPF_PROG_ATTACH since we can load
|
||||
// BPF_CGROUP_DEVICE programs. If passing BPF_F_REPLACE gives us EINVAL
|
||||
// we know that the feature isn't present.
|
||||
err = link.RawAttachProgram(link.RawAttachProgramOptions{
|
||||
// We rely on this fd being checked after attachFlags.
|
||||
Target: int(devnull.Fd()),
|
||||
// Attempt to "replace" bad fds with this program.
|
||||
Program: prog,
|
||||
Attach: ebpf.AttachCGroupDevice,
|
||||
Flags: unix.BPF_F_ALLOW_MULTI | unix.BPF_F_REPLACE,
|
||||
})
|
||||
if errors.Is(err, unix.EINVAL) {
|
||||
// not supported
|
||||
return
|
||||
}
|
||||
// attach_flags test succeded.
|
||||
if !errors.Is(err, unix.EBADF) {
|
||||
logrus.Debugf("checking for BPF_F_REPLACE: got unexpected (not EBADF or EINVAL) error: %v", err)
|
||||
}
|
||||
haveBpfProgReplaceBool = true
|
||||
})
|
||||
return haveBpfProgReplaceBool
|
||||
}
|
||||
|
||||
// LoadAttachCgroupDeviceFilter installs eBPF device filter program to /sys/fs/cgroup/<foo> directory.
|
||||
//
|
||||
// Requires the system to be running in cgroup2 unified-mode with kernel >= 4.15 .
|
||||
//
|
||||
// https://github.com/torvalds/linux/commit/ebc614f687369f9df99828572b1d85a7c2de3d92
|
||||
func LoadAttachCgroupDeviceFilter(insts asm.Instructions, license string, dirFd int) (func() error, error) {
|
||||
// Increase `ulimit -l` limit to avoid BPF_PROG_LOAD error (#2167).
|
||||
// This limit is not inherited into the container.
|
||||
memlockLimit := &unix.Rlimit{
|
||||
Cur: unix.RLIM_INFINITY,
|
||||
Max: unix.RLIM_INFINITY,
|
||||
}
|
||||
_ = unix.Setrlimit(unix.RLIMIT_MEMLOCK, memlockLimit)
|
||||
|
||||
// Get the list of existing programs.
|
||||
oldProgs, err := findAttachedCgroupDeviceFilters(dirFd)
|
||||
if err != nil {
|
||||
return nilCloser, err
|
||||
}
|
||||
useReplaceProg := haveBpfProgReplace() && len(oldProgs) == 1
|
||||
|
||||
// Generate new program.
|
||||
spec := &ebpf.ProgramSpec{
|
||||
Type: ebpf.CGroupDevice,
|
||||
Instructions: insts,
|
||||
License: license,
|
||||
}
|
||||
prog, err := ebpf.NewProgram(spec)
|
||||
if err != nil {
|
||||
return nilCloser, err
|
||||
}
|
||||
|
||||
// If there is only one old program, we can just replace it directly.
|
||||
var (
|
||||
replaceProg *ebpf.Program
|
||||
attachFlags uint32 = unix.BPF_F_ALLOW_MULTI
|
||||
)
|
||||
if useReplaceProg {
|
||||
replaceProg = oldProgs[0]
|
||||
attachFlags |= unix.BPF_F_REPLACE
|
||||
}
|
||||
err = link.RawAttachProgram(link.RawAttachProgramOptions{
|
||||
Target: dirFd,
|
||||
Program: prog,
|
||||
Replace: replaceProg,
|
||||
Attach: ebpf.AttachCGroupDevice,
|
||||
Flags: attachFlags,
|
||||
})
|
||||
if err != nil {
|
||||
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{
|
||||
Target: dirFd,
|
||||
Program: prog,
|
||||
Attach: ebpf.AttachCGroupDevice,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE): %w", err)
|
||||
}
|
||||
// TODO: Should we attach the old filters back in this case? Otherwise
|
||||
// we fail-open on a security feature, which is a bit scary.
|
||||
return nil
|
||||
}
|
||||
if !useReplaceProg {
|
||||
logLevel := logrus.DebugLevel
|
||||
// If there was more than one old program, give a warning (since this
|
||||
// really shouldn't happen with runc-managed cgroups) and then detach
|
||||
// all the old programs.
|
||||
if len(oldProgs) > 1 {
|
||||
// NOTE: Ideally this should be a warning but it turns out that
|
||||
// systemd-managed cgroups trigger this warning (apparently
|
||||
// systemd doesn't delete old non-systemd programs when
|
||||
// setting properties).
|
||||
logrus.Infof("found more than one filter (%d) attached to a cgroup -- removing extra filters!", len(oldProgs))
|
||||
logLevel = logrus.InfoLevel
|
||||
}
|
||||
for idx, oldProg := range oldProgs {
|
||||
// Output some extra debug info.
|
||||
if info, err := oldProg.Info(); err == nil {
|
||||
fields := logrus.Fields{
|
||||
"type": info.Type.String(),
|
||||
"tag": info.Tag,
|
||||
"name": info.Name,
|
||||
}
|
||||
if id, ok := info.ID(); ok {
|
||||
fields["id"] = id
|
||||
}
|
||||
if runCount, ok := info.RunCount(); ok {
|
||||
fields["run_count"] = runCount
|
||||
}
|
||||
if runtime, ok := info.Runtime(); ok {
|
||||
fields["runtime"] = runtime.String()
|
||||
}
|
||||
logrus.WithFields(fields).Logf(logLevel, "removing old filter %d from cgroup", idx)
|
||||
}
|
||||
err = link.RawDetachProgram(link.RawDetachProgramOptions{
|
||||
Target: dirFd,
|
||||
Program: oldProg,
|
||||
Attach: ebpf.AttachCGroupDevice,
|
||||
})
|
||||
if err != nil {
|
||||
return closer, fmt.Errorf("failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE) on old filter program: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return closer, nil
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package fscommon
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -10,6 +11,54 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// OpenFile opens a cgroup file in a given dir with given flags.
|
||||
// It is supposed to be used for cgroup files only.
|
||||
func OpenFile(dir, file string, flags int) (*os.File, error) {
|
||||
if dir == "" {
|
||||
return nil, errors.Errorf("no directory specified for %s", file)
|
||||
}
|
||||
return openFile(dir, file, flags)
|
||||
}
|
||||
|
||||
// ReadFile reads data from a cgroup file in dir.
|
||||
// It is supposed to be used for cgroup files only.
|
||||
func ReadFile(dir, file string) (string, error) {
|
||||
fd, err := OpenFile(dir, file, unix.O_RDONLY)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer fd.Close()
|
||||
var buf bytes.Buffer
|
||||
|
||||
_, err = buf.ReadFrom(fd)
|
||||
return buf.String(), err
|
||||
}
|
||||
|
||||
// WriteFile writes data to a cgroup file in dir.
|
||||
// It is supposed to be used for cgroup files only.
|
||||
func WriteFile(dir, file, data string) error {
|
||||
fd, err := OpenFile(dir, file, unix.O_WRONLY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
if err := retryingWriteFile(fd, data); err != nil {
|
||||
return errors.Wrapf(err, "failed to write %q", data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func retryingWriteFile(fd *os.File, data string) error {
|
||||
for {
|
||||
_, err := fd.Write([]byte(data))
|
||||
if errors.Is(err, unix.EINTR) {
|
||||
logrus.Infof("interrupted while writing %s to %s", data, fd.Name())
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
cgroupfsDir = "/sys/fs/cgroup"
|
||||
cgroupfsPrefix = cgroupfsDir + "/"
|
||||
@@ -28,7 +77,8 @@ var (
|
||||
func prepareOpenat2() error {
|
||||
prepOnce.Do(func() {
|
||||
fd, err := unix.Openat2(-1, cgroupfsDir, &unix.OpenHow{
|
||||
Flags: unix.O_DIRECTORY | unix.O_PATH})
|
||||
Flags: unix.O_DIRECTORY | unix.O_PATH,
|
||||
})
|
||||
if err != nil {
|
||||
prepErr = &os.PathError{Op: "openat2", Path: cgroupfsDir, Err: err}
|
||||
if err != unix.ENOSYS {
|
||||
@@ -52,7 +102,6 @@ func prepareOpenat2() error {
|
||||
// cgroupv2 has a single mountpoint and no "cpu,cpuacct" symlinks
|
||||
resolveFlags |= unix.RESOLVE_NO_XDEV | unix.RESOLVE_NO_SYMLINKS
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return prepErr
|
||||
@@ -60,10 +109,7 @@ func prepareOpenat2() error {
|
||||
|
||||
// OpenFile opens a cgroup file in a given dir with given flags.
|
||||
// It is supposed to be used for cgroup files only.
|
||||
func OpenFile(dir, file string, flags int) (*os.File, error) {
|
||||
if dir == "" {
|
||||
return nil, errors.Errorf("no directory specified for %s", file)
|
||||
}
|
||||
func openFile(dir, file string, flags int) (*os.File, error) {
|
||||
mode := os.FileMode(0)
|
||||
if TestMode && flags&os.O_WRONLY != 0 {
|
||||
// "emulate" cgroup fs for unit tests
|
59
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go
generated
vendored
59
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go
generated
vendored
@@ -6,15 +6,17 @@ import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
type BlkioGroup struct {
|
||||
weightFilename string
|
||||
weightDeviceFilename string
|
||||
}
|
||||
|
||||
func (s *BlkioGroup) Name() string {
|
||||
@@ -26,42 +28,47 @@ func (s *BlkioGroup) Apply(path string, d *cgroupData) error {
|
||||
}
|
||||
|
||||
func (s *BlkioGroup) Set(path string, r *configs.Resources) error {
|
||||
s.detectWeightFilenames(path)
|
||||
if r.BlkioWeight != 0 {
|
||||
if err := fscommon.WriteFile(path, "blkio.weight", strconv.FormatUint(uint64(r.BlkioWeight), 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, s.weightFilename, strconv.FormatUint(uint64(r.BlkioWeight), 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if r.BlkioLeafWeight != 0 {
|
||||
if err := fscommon.WriteFile(path, "blkio.leaf_weight", strconv.FormatUint(uint64(r.BlkioLeafWeight), 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "blkio.leaf_weight", strconv.FormatUint(uint64(r.BlkioLeafWeight), 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, wd := range r.BlkioWeightDevice {
|
||||
if err := fscommon.WriteFile(path, "blkio.weight_device", wd.WeightString()); err != nil {
|
||||
return err
|
||||
if wd.Weight != 0 {
|
||||
if err := cgroups.WriteFile(path, s.weightDeviceFilename, wd.WeightString()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := fscommon.WriteFile(path, "blkio.leaf_weight_device", wd.LeafWeightString()); err != nil {
|
||||
return err
|
||||
if wd.LeafWeight != 0 {
|
||||
if err := cgroups.WriteFile(path, "blkio.leaf_weight_device", wd.LeafWeightString()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleReadBpsDevice {
|
||||
if err := fscommon.WriteFile(path, "blkio.throttle.read_bps_device", td.String()); err != nil {
|
||||
if err := cgroups.WriteFile(path, "blkio.throttle.read_bps_device", td.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleWriteBpsDevice {
|
||||
if err := fscommon.WriteFile(path, "blkio.throttle.write_bps_device", td.String()); err != nil {
|
||||
if err := cgroups.WriteFile(path, "blkio.throttle.write_bps_device", td.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleReadIOPSDevice {
|
||||
if err := fscommon.WriteFile(path, "blkio.throttle.read_iops_device", td.String()); err != nil {
|
||||
if err := cgroups.WriteFile(path, "blkio.throttle.read_iops_device", td.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleWriteIOPSDevice {
|
||||
if err := fscommon.WriteFile(path, "blkio.throttle.write_iops_device", td.String()); err != nil {
|
||||
if err := cgroups.WriteFile(path, "blkio.throttle.write_iops_device", td.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -106,7 +113,7 @@ func splitBlkioStatLine(r rune) bool {
|
||||
|
||||
func getBlkioStat(dir, file string) ([]cgroups.BlkioStatEntry, error) {
|
||||
var blkioStats []cgroups.BlkioStatEntry
|
||||
f, err := fscommon.OpenFile(dir, file, os.O_RDONLY)
|
||||
f, err := cgroups.OpenFile(dir, file, os.O_RDONLY)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return blkioStats, nil
|
||||
@@ -161,7 +168,7 @@ func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
filename string
|
||||
blkioStatEntriesPtr *[]cgroups.BlkioStatEntry
|
||||
}
|
||||
var bfqDebugStats = []blkioStatInfo{
|
||||
bfqDebugStats := []blkioStatInfo{
|
||||
{
|
||||
filename: "blkio.bfq.sectors_recursive",
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.SectorsRecursive,
|
||||
@@ -195,7 +202,7 @@ func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
|
||||
},
|
||||
}
|
||||
var bfqStats = []blkioStatInfo{
|
||||
bfqStats := []blkioStatInfo{
|
||||
{
|
||||
filename: "blkio.bfq.io_serviced_recursive",
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive,
|
||||
@@ -205,7 +212,7 @@ func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
|
||||
},
|
||||
}
|
||||
var cfqStats = []blkioStatInfo{
|
||||
cfqStats := []blkioStatInfo{
|
||||
{
|
||||
filename: "blkio.sectors_recursive",
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.SectorsRecursive,
|
||||
@@ -239,7 +246,7 @@ func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
|
||||
},
|
||||
}
|
||||
var throttleRecursiveStats = []blkioStatInfo{
|
||||
throttleRecursiveStats := []blkioStatInfo{
|
||||
{
|
||||
filename: "blkio.throttle.io_serviced_recursive",
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive,
|
||||
@@ -249,7 +256,7 @@ func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
|
||||
},
|
||||
}
|
||||
var baseStats = []blkioStatInfo{
|
||||
baseStats := []blkioStatInfo{
|
||||
{
|
||||
filename: "blkio.throttle.io_serviced",
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive,
|
||||
@@ -259,7 +266,7 @@ func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
|
||||
},
|
||||
}
|
||||
var orderedStats = [][]blkioStatInfo{
|
||||
orderedStats := [][]blkioStatInfo{
|
||||
bfqDebugStats,
|
||||
bfqStats,
|
||||
cfqStats,
|
||||
@@ -280,7 +287,7 @@ func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return err
|
||||
}
|
||||
*statInfo.blkioStatEntriesPtr = blkioStats
|
||||
//finish if all stats are gathered
|
||||
// finish if all stats are gathered
|
||||
if i == len(statGroup)-1 {
|
||||
return nil
|
||||
}
|
||||
@@ -288,3 +295,17 @@ func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *BlkioGroup) detectWeightFilenames(path string) {
|
||||
if s.weightFilename != "" {
|
||||
// Already detected.
|
||||
return
|
||||
}
|
||||
if cgroups.PathExists(filepath.Join(path, "blkio.weight")) {
|
||||
s.weightFilename = "blkio.weight"
|
||||
s.weightDeviceFilename = "blkio.weight_device"
|
||||
} else {
|
||||
s.weightFilename = "blkio.bfq.weight"
|
||||
s.weightDeviceFilename = "blkio.bfq.weight_device"
|
||||
}
|
||||
}
|
||||
|
17
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
generated
vendored
17
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
generated
vendored
@@ -13,8 +13,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
type CpuGroup struct {
|
||||
}
|
||||
type CpuGroup struct{}
|
||||
|
||||
func (s *CpuGroup) Name() string {
|
||||
return "cpu"
|
||||
@@ -26,7 +25,7 @@ func (s *CpuGroup) Apply(path string, d *cgroupData) error {
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
if err := os.MkdirAll(path, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
// We should set the real-Time group scheduling settings before moving
|
||||
@@ -42,12 +41,12 @@ func (s *CpuGroup) Apply(path string, d *cgroupData) error {
|
||||
|
||||
func (s *CpuGroup) SetRtSched(path string, r *configs.Resources) error {
|
||||
if r.CpuRtPeriod != 0 {
|
||||
if err := fscommon.WriteFile(path, "cpu.rt_period_us", strconv.FormatUint(r.CpuRtPeriod, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "cpu.rt_period_us", strconv.FormatUint(r.CpuRtPeriod, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if r.CpuRtRuntime != 0 {
|
||||
if err := fscommon.WriteFile(path, "cpu.rt_runtime_us", strconv.FormatInt(r.CpuRtRuntime, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "cpu.rt_runtime_us", strconv.FormatInt(r.CpuRtRuntime, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -57,7 +56,7 @@ func (s *CpuGroup) SetRtSched(path string, r *configs.Resources) error {
|
||||
func (s *CpuGroup) Set(path string, r *configs.Resources) error {
|
||||
if r.CpuShares != 0 {
|
||||
shares := r.CpuShares
|
||||
if err := fscommon.WriteFile(path, "cpu.shares", strconv.FormatUint(shares, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "cpu.shares", strconv.FormatUint(shares, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
// read it back
|
||||
@@ -73,12 +72,12 @@ func (s *CpuGroup) Set(path string, r *configs.Resources) error {
|
||||
}
|
||||
}
|
||||
if r.CpuPeriod != 0 {
|
||||
if err := fscommon.WriteFile(path, "cpu.cfs_period_us", strconv.FormatUint(r.CpuPeriod, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "cpu.cfs_period_us", strconv.FormatUint(r.CpuPeriod, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if r.CpuQuota != 0 {
|
||||
if err := fscommon.WriteFile(path, "cpu.cfs_quota_us", strconv.FormatInt(r.CpuQuota, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "cpu.cfs_quota_us", strconv.FormatInt(r.CpuQuota, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -86,7 +85,7 @@ func (s *CpuGroup) Set(path string, r *configs.Resources) error {
|
||||
}
|
||||
|
||||
func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
f, err := fscommon.OpenFile(path, "cpu.stat", os.O_RDONLY)
|
||||
f, err := cgroups.OpenFile(path, "cpu.stat", os.O_RDONLY)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
|
11
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go
generated
vendored
11
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go
generated
vendored
@@ -32,8 +32,7 @@ const (
|
||||
clockTicks uint64 = 100
|
||||
)
|
||||
|
||||
type CpuacctGroup struct {
|
||||
}
|
||||
type CpuacctGroup struct{}
|
||||
|
||||
func (s *CpuacctGroup) Name() string {
|
||||
return "cpuacct"
|
||||
@@ -91,7 +90,7 @@ func getCpuUsageBreakdown(path string) (uint64, uint64, error) {
|
||||
// Expected format:
|
||||
// user <usage in ticks>
|
||||
// system <usage in ticks>
|
||||
data, err := fscommon.ReadFile(path, cgroupCpuacctStat)
|
||||
data, err := cgroups.ReadFile(path, cgroupCpuacctStat)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
@@ -117,7 +116,7 @@ func getCpuUsageBreakdown(path string) (uint64, uint64, error) {
|
||||
|
||||
func getPercpuUsage(path string) ([]uint64, error) {
|
||||
percpuUsage := []uint64{}
|
||||
data, err := fscommon.ReadFile(path, "cpuacct.usage_percpu")
|
||||
data, err := cgroups.ReadFile(path, "cpuacct.usage_percpu")
|
||||
if err != nil {
|
||||
return percpuUsage, err
|
||||
}
|
||||
@@ -135,7 +134,7 @@ func getPercpuUsageInModes(path string) ([]uint64, []uint64, error) {
|
||||
usageKernelMode := []uint64{}
|
||||
usageUserMode := []uint64{}
|
||||
|
||||
file, err := fscommon.OpenFile(path, cgroupCpuacctUsageAll, os.O_RDONLY)
|
||||
file, err := cgroups.OpenFile(path, cgroupCpuacctUsageAll, os.O_RDONLY)
|
||||
if os.IsNotExist(err) {
|
||||
return usageKernelMode, usageUserMode, nil
|
||||
} else if err != nil {
|
||||
@@ -144,7 +143,7 @@ func getPercpuUsageInModes(path string) ([]uint64, []uint64, error) {
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
scanner.Scan() //skipping header line
|
||||
scanner.Scan() // skipping header line
|
||||
|
||||
for scanner.Scan() {
|
||||
lineFields := strings.SplitN(scanner.Text(), " ", cuacctUsageAllColumnsNumber+1)
|
||||
|
19
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
generated
vendored
19
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
generated
vendored
@@ -16,8 +16,7 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type CpusetGroup struct {
|
||||
}
|
||||
type CpusetGroup struct{}
|
||||
|
||||
func (s *CpusetGroup) Name() string {
|
||||
return "cpuset"
|
||||
@@ -29,12 +28,12 @@ func (s *CpusetGroup) Apply(path string, d *cgroupData) error {
|
||||
|
||||
func (s *CpusetGroup) Set(path string, r *configs.Resources) error {
|
||||
if r.CpusetCpus != "" {
|
||||
if err := fscommon.WriteFile(path, "cpuset.cpus", r.CpusetCpus); err != nil {
|
||||
if err := cgroups.WriteFile(path, "cpuset.cpus", r.CpusetCpus); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if r.CpusetMems != "" {
|
||||
if err := fscommon.WriteFile(path, "cpuset.mems", r.CpusetMems); err != nil {
|
||||
if err := cgroups.WriteFile(path, "cpuset.mems", r.CpusetMems); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -156,7 +155,7 @@ func (s *CpusetGroup) ApplyDir(dir string, r *configs.Resources, pid int) error
|
||||
if err := cpusetEnsureParent(filepath.Dir(dir)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Mkdir(dir, 0755); err != nil && !os.IsExist(err) {
|
||||
if err := os.Mkdir(dir, 0o755); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
// We didn't inherit cpuset configs from parent, but we have
|
||||
@@ -176,10 +175,10 @@ func (s *CpusetGroup) ApplyDir(dir string, r *configs.Resources, pid int) error
|
||||
}
|
||||
|
||||
func getCpusetSubsystemSettings(parent string) (cpus, mems string, err error) {
|
||||
if cpus, err = fscommon.ReadFile(parent, "cpuset.cpus"); err != nil {
|
||||
if cpus, err = cgroups.ReadFile(parent, "cpuset.cpus"); err != nil {
|
||||
return
|
||||
}
|
||||
if mems, err = fscommon.ReadFile(parent, "cpuset.mems"); err != nil {
|
||||
if mems, err = cgroups.ReadFile(parent, "cpuset.mems"); err != nil {
|
||||
return
|
||||
}
|
||||
return cpus, mems, nil
|
||||
@@ -206,7 +205,7 @@ func cpusetEnsureParent(current string) error {
|
||||
if err := cpusetEnsureParent(parent); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Mkdir(current, 0755); err != nil && !os.IsExist(err) {
|
||||
if err := os.Mkdir(current, 0o755); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
return cpusetCopyIfNeeded(current, parent)
|
||||
@@ -225,12 +224,12 @@ func cpusetCopyIfNeeded(current, parent string) error {
|
||||
}
|
||||
|
||||
if isEmptyCpuset(currentCpus) {
|
||||
if err := fscommon.WriteFile(current, "cpuset.cpus", string(parentCpus)); err != nil {
|
||||
if err := cgroups.WriteFile(current, "cpuset.cpus", string(parentCpus)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if isEmptyCpuset(currentMems) {
|
||||
if err := fscommon.WriteFile(current, "cpuset.mems", string(parentMems)); err != nil {
|
||||
if err := cgroups.WriteFile(current, "cpuset.mems", string(parentMems)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
5
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go
generated
vendored
5
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go
generated
vendored
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
cgroupdevices "github.com/opencontainers/runc/libcontainer/cgroups/devices"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/devices"
|
||||
"github.com/opencontainers/runc/libcontainer/userns"
|
||||
@@ -36,7 +35,7 @@ func (s *DevicesGroup) Apply(path string, d *cgroupData) error {
|
||||
}
|
||||
|
||||
func loadEmulator(path string) (*cgroupdevices.Emulator, error) {
|
||||
list, err := fscommon.ReadFile(path, "devices.list")
|
||||
list, err := cgroups.ReadFile(path, "devices.list")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -81,7 +80,7 @@ func (s *DevicesGroup) Set(path string, r *configs.Resources) error {
|
||||
if rule.Allow {
|
||||
file = "devices.allow"
|
||||
}
|
||||
if err := fscommon.WriteFile(path, file, rule.CgroupString()); err != nil {
|
||||
if err := cgroups.WriteFile(path, file, rule.CgroupString()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go
generated
vendored
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go
generated
vendored
@@ -10,14 +10,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type FreezerGroup struct {
|
||||
}
|
||||
type FreezerGroup struct{}
|
||||
|
||||
func (s *FreezerGroup) Name() string {
|
||||
return "freezer"
|
||||
@@ -35,7 +33,7 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
|
||||
// Freezing failed, and it is bad and dangerous
|
||||
// to leave the cgroup in FROZEN or FREEZING
|
||||
// state, so (try to) thaw it back.
|
||||
_ = fscommon.WriteFile(path, "freezer.state", string(configs.Thawed))
|
||||
_ = cgroups.WriteFile(path, "freezer.state", string(configs.Thawed))
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -68,11 +66,11 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
|
||||
// the chances to succeed in freezing
|
||||
// in case new processes keep appearing
|
||||
// in the cgroup.
|
||||
_ = fscommon.WriteFile(path, "freezer.state", string(configs.Thawed))
|
||||
_ = cgroups.WriteFile(path, "freezer.state", string(configs.Thawed))
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
if err := fscommon.WriteFile(path, "freezer.state", string(configs.Frozen)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "freezer.state", string(configs.Frozen)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -83,7 +81,7 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
|
||||
// system.
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
}
|
||||
state, err := fscommon.ReadFile(path, "freezer.state")
|
||||
state, err := cgroups.ReadFile(path, "freezer.state")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -104,7 +102,7 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
|
||||
// Despite our best efforts, it got stuck in FREEZING.
|
||||
return errors.New("unable to freeze")
|
||||
case configs.Thawed:
|
||||
return fscommon.WriteFile(path, "freezer.state", string(configs.Thawed))
|
||||
return cgroups.WriteFile(path, "freezer.state", string(configs.Thawed))
|
||||
case configs.Undefined:
|
||||
return nil
|
||||
default:
|
||||
@@ -118,7 +116,7 @@ func (s *FreezerGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
|
||||
func (s *FreezerGroup) GetState(path string) (configs.FreezerState, error) {
|
||||
for {
|
||||
state, err := fscommon.ReadFile(path, "freezer.state")
|
||||
state, err := cgroups.ReadFile(path, "freezer.state")
|
||||
if err != nil {
|
||||
// If the kernel is too old, then we just treat the freezer as
|
||||
// being in an "undefined" state.
|
||||
|
8
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs.go
generated
vendored
8
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs.go
generated
vendored
@@ -64,8 +64,10 @@ func NewManager(cg *configs.Cgroup, paths map[string]string, rootless bool) cgro
|
||||
}
|
||||
|
||||
// The absolute path to the root of the cgroup hierarchies.
|
||||
var cgroupRootLock sync.Mutex
|
||||
var cgroupRoot string
|
||||
var (
|
||||
cgroupRootLock sync.Mutex
|
||||
cgroupRoot string
|
||||
)
|
||||
|
||||
const defaultCgroupRoot = "/sys/fs/cgroup"
|
||||
|
||||
@@ -393,7 +395,7 @@ func join(path string, pid int) error {
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
if err := os.MkdirAll(path, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
return cgroups.WriteCgroupProc(path, pid)
|
||||
|
5
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go
generated
vendored
5
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go
generated
vendored
@@ -11,8 +11,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
type HugetlbGroup struct {
|
||||
}
|
||||
type HugetlbGroup struct{}
|
||||
|
||||
func (s *HugetlbGroup) Name() string {
|
||||
return "hugetlb"
|
||||
@@ -24,7 +23,7 @@ func (s *HugetlbGroup) Apply(path string, d *cgroupData) error {
|
||||
|
||||
func (s *HugetlbGroup) Set(path string, r *configs.Resources) error {
|
||||
for _, hugetlb := range r.HugetlbLimit {
|
||||
if err := fscommon.WriteFile(path, "hugetlb."+hugetlb.Pagesize+".limit_in_bytes", strconv.FormatUint(hugetlb.Limit, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "hugetlb."+hugetlb.Pagesize+".limit_in_bytes", strconv.FormatUint(hugetlb.Limit, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
26
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
generated
vendored
26
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
generated
vendored
@@ -25,8 +25,7 @@ const (
|
||||
cgroupMemoryMaxUsage = "memory.max_usage_in_bytes"
|
||||
)
|
||||
|
||||
type MemoryGroup struct {
|
||||
}
|
||||
type MemoryGroup struct{}
|
||||
|
||||
func (s *MemoryGroup) Name() string {
|
||||
return "memory"
|
||||
@@ -41,7 +40,7 @@ func setMemory(path string, val int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := fscommon.WriteFile(path, cgroupMemoryLimit, strconv.FormatInt(val, 10))
|
||||
err := cgroups.WriteFile(path, cgroupMemoryLimit, strconv.FormatInt(val, 10))
|
||||
if !errors.Is(err, unix.EBUSY) {
|
||||
return err
|
||||
}
|
||||
@@ -65,7 +64,7 @@ func setSwap(path string, val int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fscommon.WriteFile(path, cgroupMemorySwapLimit, strconv.FormatInt(val, 10))
|
||||
return cgroups.WriteFile(path, cgroupMemorySwapLimit, strconv.FormatInt(val, 10))
|
||||
}
|
||||
|
||||
func setMemoryAndSwap(path string, r *configs.Resources) error {
|
||||
@@ -118,20 +117,20 @@ func (s *MemoryGroup) Set(path string, r *configs.Resources) error {
|
||||
// ignore KernelMemory and KernelMemoryTCP
|
||||
|
||||
if r.MemoryReservation != 0 {
|
||||
if err := fscommon.WriteFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(r.MemoryReservation, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(r.MemoryReservation, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if r.OomKillDisable {
|
||||
if err := fscommon.WriteFile(path, "memory.oom_control", "1"); err != nil {
|
||||
if err := cgroups.WriteFile(path, "memory.oom_control", "1"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if r.MemorySwappiness == nil || int64(*r.MemorySwappiness) == -1 {
|
||||
return nil
|
||||
} else if *r.MemorySwappiness <= 100 {
|
||||
if err := fscommon.WriteFile(path, "memory.swappiness", strconv.FormatUint(*r.MemorySwappiness, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "memory.swappiness", strconv.FormatUint(*r.MemorySwappiness, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@@ -143,7 +142,7 @@ func (s *MemoryGroup) Set(path string, r *configs.Resources) error {
|
||||
|
||||
func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
// Set stats from memory.stat.
|
||||
statsFile, err := fscommon.OpenFile(path, "memory.stat", os.O_RDONLY)
|
||||
statsFile, err := cgroups.OpenFile(path, "memory.stat", os.O_RDONLY)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
@@ -200,14 +199,6 @@ func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func memoryAssigned(cgroup *configs.Cgroup) bool {
|
||||
return cgroup.Resources.Memory != 0 ||
|
||||
cgroup.Resources.MemoryReservation != 0 ||
|
||||
cgroup.Resources.MemorySwap > 0 ||
|
||||
cgroup.Resources.OomKillDisable ||
|
||||
(cgroup.Resources.MemorySwappiness != nil && int64(*cgroup.Resources.MemorySwappiness) != -1)
|
||||
}
|
||||
|
||||
func getMemoryData(path, name string) (cgroups.MemoryData, error) {
|
||||
memoryData := cgroups.MemoryData{}
|
||||
|
||||
@@ -258,12 +249,13 @@ func getPageUsageByNUMA(cgroupPath string) (cgroups.PageUsageByNUMA, error) {
|
||||
)
|
||||
stats := cgroups.PageUsageByNUMA{}
|
||||
|
||||
file, err := fscommon.OpenFile(cgroupPath, filename, os.O_RDONLY)
|
||||
file, err := cgroups.OpenFile(cgroupPath, filename, os.O_RDONLY)
|
||||
if os.IsNotExist(err) {
|
||||
return stats, nil
|
||||
} else if err != nil {
|
||||
return stats, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// File format is documented in linux/Documentation/cgroup-v1/memory.txt
|
||||
// and it looks like this:
|
||||
|
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go
generated
vendored
@@ -6,12 +6,10 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
type NetClsGroup struct {
|
||||
}
|
||||
type NetClsGroup struct{}
|
||||
|
||||
func (s *NetClsGroup) Name() string {
|
||||
return "net_cls"
|
||||
@@ -23,7 +21,7 @@ func (s *NetClsGroup) Apply(path string, d *cgroupData) error {
|
||||
|
||||
func (s *NetClsGroup) Set(path string, r *configs.Resources) error {
|
||||
if r.NetClsClassid != 0 {
|
||||
if err := fscommon.WriteFile(path, "net_cls.classid", strconv.FormatUint(uint64(r.NetClsClassid), 10)); err != nil {
|
||||
if err := cgroups.WriteFile(path, "net_cls.classid", strconv.FormatUint(uint64(r.NetClsClassid), 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go
generated
vendored
@@ -4,12 +4,10 @@ package fs
|
||||
|
||||
import (
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
type NetPrioGroup struct {
|
||||
}
|
||||
type NetPrioGroup struct{}
|
||||
|
||||
func (s *NetPrioGroup) Name() string {
|
||||
return "net_prio"
|
||||
@@ -21,7 +19,7 @@ func (s *NetPrioGroup) Apply(path string, d *cgroupData) error {
|
||||
|
||||
func (s *NetPrioGroup) Set(path string, r *configs.Resources) error {
|
||||
for _, prioMap := range r.NetPrioIfpriomap {
|
||||
if err := fscommon.WriteFile(path, "net_prio.ifpriomap", prioMap.CgroupString()); err != nil {
|
||||
if err := cgroups.WriteFile(path, "net_prio.ifpriomap", prioMap.CgroupString()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
3
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go
generated
vendored
3
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go
generated
vendored
@@ -7,8 +7,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
type PerfEventGroup struct {
|
||||
}
|
||||
type PerfEventGroup struct{}
|
||||
|
||||
func (s *PerfEventGroup) Name() string {
|
||||
return "perf_event"
|
||||
|
5
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go
generated
vendored
5
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go
generated
vendored
@@ -12,8 +12,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
type PidsGroup struct {
|
||||
}
|
||||
type PidsGroup struct{}
|
||||
|
||||
func (s *PidsGroup) Name() string {
|
||||
return "pids"
|
||||
@@ -32,7 +31,7 @@ func (s *PidsGroup) Set(path string, r *configs.Resources) error {
|
||||
limit = strconv.FormatInt(r.PidsLimit, 10)
|
||||
}
|
||||
|
||||
if err := fscommon.WriteFile(path, "pids.max", limit); err != nil {
|
||||
if err := cgroups.WriteFile(path, "pids.max", limit); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
7
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpu.go
generated
vendored
7
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpu.go
generated
vendored
@@ -23,7 +23,7 @@ func setCpu(dirPath string, r *configs.Resources) error {
|
||||
|
||||
// NOTE: .CpuShares is not used here. Conversion is the caller's responsibility.
|
||||
if r.CpuWeight != 0 {
|
||||
if err := fscommon.WriteFile(dirPath, "cpu.weight", strconv.FormatUint(r.CpuWeight, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "cpu.weight", strconv.FormatUint(r.CpuWeight, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -40,15 +40,16 @@ func setCpu(dirPath string, r *configs.Resources) error {
|
||||
period = 100000
|
||||
}
|
||||
str += " " + strconv.FormatUint(period, 10)
|
||||
if err := fscommon.WriteFile(dirPath, "cpu.max", str); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "cpu.max", str); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func statCpu(dirPath string, stats *cgroups.Stats) error {
|
||||
f, err := fscommon.OpenFile(dirPath, "cpu.stat", os.O_RDONLY)
|
||||
f, err := cgroups.OpenFile(dirPath, "cpu.stat", os.O_RDONLY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpuset.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpuset.go
generated
vendored
@@ -3,7 +3,7 @@
|
||||
package fs2
|
||||
|
||||
import (
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
@@ -17,12 +17,12 @@ func setCpuset(dirPath string, r *configs.Resources) error {
|
||||
}
|
||||
|
||||
if r.CpusetCpus != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "cpuset.cpus", r.CpusetCpus); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "cpuset.cpus", r.CpusetCpus); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if r.CpusetMems != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "cpuset.mems", r.CpusetMems); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "cpuset.mems", r.CpusetMems); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
14
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/create.go
generated
vendored
14
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/create.go
generated
vendored
@@ -6,12 +6,12 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
func supportedControllers() (string, error) {
|
||||
return fscommon.ReadFile(UnifiedMountpoint, "/cgroup.controllers")
|
||||
return cgroups.ReadFile(UnifiedMountpoint, "/cgroup.controllers")
|
||||
}
|
||||
|
||||
// needAnyControllers returns whether we enable some supported controllers or not,
|
||||
@@ -92,7 +92,7 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
|
||||
for i, e := range elements {
|
||||
current = filepath.Join(current, e)
|
||||
if i > 0 {
|
||||
if err := os.Mkdir(current, 0755); err != nil {
|
||||
if err := os.Mkdir(current, 0o755); err != nil {
|
||||
if !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
|
||||
}
|
||||
}()
|
||||
}
|
||||
cgType, _ := fscommon.ReadFile(current, cgTypeFile)
|
||||
cgType, _ := cgroups.ReadFile(current, cgTypeFile)
|
||||
cgType = strings.TrimSpace(cgType)
|
||||
switch cgType {
|
||||
// If the cgroup is in an invalid mode (usually this means there's an internal
|
||||
@@ -122,7 +122,7 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
|
||||
// since that means we're a properly delegated cgroup subtree) but in
|
||||
// this case there's not much we can do and it's better than giving an
|
||||
// error.
|
||||
_ = fscommon.WriteFile(current, cgTypeFile, "threaded")
|
||||
_ = cgroups.WriteFile(current, cgTypeFile, "threaded")
|
||||
}
|
||||
// If the cgroup is in (threaded) or (domain threaded) mode, we can only use thread-aware controllers
|
||||
// (and you cannot usually take a cgroup out of threaded mode).
|
||||
@@ -136,11 +136,11 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
|
||||
}
|
||||
// enable all supported controllers
|
||||
if i < len(elements)-1 {
|
||||
if err := fscommon.WriteFile(current, cgStCtlFile, res); err != nil {
|
||||
if err := cgroups.WriteFile(current, cgStCtlFile, res); err != nil {
|
||||
// try write one by one
|
||||
allCtrs := strings.Split(res, " ")
|
||||
for _, ctr := range allCtrs {
|
||||
_ = fscommon.WriteFile(current, cgStCtlFile, ctr)
|
||||
_ = cgroups.WriteFile(current, cgStCtlFile, ctr)
|
||||
}
|
||||
}
|
||||
// Some controllers might not be enabled when rootless or containerized,
|
||||
|
4
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/defaultpath.go
generated
vendored
4
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/defaultpath.go
generated
vendored
@@ -82,9 +82,7 @@ func parseCgroupFile(path string) (string, error) {
|
||||
}
|
||||
|
||||
func parseCgroupFromReader(r io.Reader) (string, error) {
|
||||
var (
|
||||
s = bufio.NewScanner(r)
|
||||
)
|
||||
s := bufio.NewScanner(r)
|
||||
for s.Scan() {
|
||||
var (
|
||||
text = s.Text()
|
||||
|
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/devices.go
generated
vendored
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/devices.go
generated
vendored
@@ -58,29 +58,15 @@ func setDevices(dirPath string, r *configs.Resources) error {
|
||||
if r.SkipDevices {
|
||||
return nil
|
||||
}
|
||||
// XXX: This is currently a white-list (but all callers pass a blacklist of
|
||||
// devices). This is bad for a whole variety of reasons, but will need
|
||||
// to be fixed with co-ordinated effort with downstreams.
|
||||
insts, license, err := devicefilter.DeviceFilter(r.Devices)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dirFD, err := unix.Open(dirPath, unix.O_DIRECTORY|unix.O_RDONLY, 0600)
|
||||
dirFD, err := unix.Open(dirPath, unix.O_DIRECTORY|unix.O_RDONLY, 0o600)
|
||||
if err != nil {
|
||||
return errors.Errorf("cannot get dir FD for %s", dirPath)
|
||||
}
|
||||
defer unix.Close(dirFD)
|
||||
// XXX: This code is currently incorrect when it comes to updating an
|
||||
// existing cgroup with new rules (new rulesets are just appended to
|
||||
// the program list because this uses BPF_F_ALLOW_MULTI). If we didn't
|
||||
// use BPF_F_ALLOW_MULTI we could actually atomically swap the
|
||||
// programs.
|
||||
//
|
||||
// The real issue is that BPF_F_ALLOW_MULTI makes it hard to have a
|
||||
// race-free blacklist because it acts as a whitelist by default, and
|
||||
// having a deny-everything program cannot be overridden by other
|
||||
// programs. You could temporarily insert a deny-everything program
|
||||
// but that would result in spurrious failures during updates.
|
||||
if _, err := ebpf.LoadAttachCgroupDeviceFilter(insts, license, dirFD); err != nil {
|
||||
if !canSkipEBPFError(r) {
|
||||
return err
|
||||
|
101
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/freezer.go
generated
vendored
101
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/freezer.go
generated
vendored
@@ -3,27 +3,20 @@
|
||||
package fs2
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
stdErrors "errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func setFreezer(dirPath string, state configs.FreezerState) error {
|
||||
if err := supportsFreezer(dirPath); err != nil {
|
||||
// We can ignore this request as long as the user didn't ask us to
|
||||
// freeze the container (since without the freezer cgroup, that's a
|
||||
// no-op).
|
||||
if state == configs.Undefined || state == configs.Thawed {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrap(err, "freezer not supported")
|
||||
}
|
||||
|
||||
var stateStr string
|
||||
switch state {
|
||||
case configs.Undefined:
|
||||
@@ -36,11 +29,23 @@ func setFreezer(dirPath string, state configs.FreezerState) error {
|
||||
return errors.Errorf("invalid freezer state %q requested", state)
|
||||
}
|
||||
|
||||
if err := fscommon.WriteFile(dirPath, "cgroup.freeze", stateStr); err != nil {
|
||||
fd, err := cgroups.OpenFile(dirPath, "cgroup.freeze", unix.O_RDWR)
|
||||
if err != nil {
|
||||
// We can ignore this request as long as the user didn't ask us to
|
||||
// freeze the container (since without the freezer cgroup, that's a
|
||||
// no-op).
|
||||
if state != configs.Frozen {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrap(err, "freezer not supported")
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
if _, err := fd.WriteString(stateStr); err != nil {
|
||||
return err
|
||||
}
|
||||
// Confirm that the cgroup did actually change states.
|
||||
if actualState, err := getFreezer(dirPath); err != nil {
|
||||
if actualState, err := readFreezer(dirPath, fd); err != nil {
|
||||
return err
|
||||
} else if actualState != state {
|
||||
return errors.Errorf(`expected "cgroup.freeze" to be in state %q but was in %q`, state, actualState)
|
||||
@@ -48,13 +53,8 @@ func setFreezer(dirPath string, state configs.FreezerState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func supportsFreezer(dirPath string) error {
|
||||
_, err := fscommon.ReadFile(dirPath, "cgroup.freeze")
|
||||
return err
|
||||
}
|
||||
|
||||
func getFreezer(dirPath string) (configs.FreezerState, error) {
|
||||
state, err := fscommon.ReadFile(dirPath, "cgroup.freeze")
|
||||
fd, err := cgroups.OpenFile(dirPath, "cgroup.freeze", unix.O_RDONLY)
|
||||
if err != nil {
|
||||
// If the kernel is too old, then we just treat the freezer as being in
|
||||
// an "undefined" state.
|
||||
@@ -63,12 +63,67 @@ func getFreezer(dirPath string) (configs.FreezerState, error) {
|
||||
}
|
||||
return configs.Undefined, err
|
||||
}
|
||||
switch strings.TrimSpace(state) {
|
||||
case "0":
|
||||
defer fd.Close()
|
||||
|
||||
return readFreezer(dirPath, fd)
|
||||
}
|
||||
|
||||
func readFreezer(dirPath string, fd *os.File) (configs.FreezerState, error) {
|
||||
if _, err := fd.Seek(0, 0); err != nil {
|
||||
return configs.Undefined, err
|
||||
}
|
||||
state := make([]byte, 2)
|
||||
if _, err := fd.Read(state); err != nil {
|
||||
return configs.Undefined, err
|
||||
}
|
||||
switch string(state) {
|
||||
case "0\n":
|
||||
return configs.Thawed, nil
|
||||
case "1":
|
||||
return configs.Frozen, nil
|
||||
case "1\n":
|
||||
return waitFrozen(dirPath)
|
||||
default:
|
||||
return configs.Undefined, errors.Errorf(`unknown "cgroup.freeze" state: %q`, state)
|
||||
}
|
||||
}
|
||||
|
||||
// waitFrozen polls cgroup.events until it sees "frozen 1" in it.
|
||||
func waitFrozen(dirPath string) (configs.FreezerState, error) {
|
||||
fd, err := cgroups.OpenFile(dirPath, "cgroup.events", unix.O_RDONLY)
|
||||
if err != nil {
|
||||
return configs.Undefined, err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
// XXX: Simple wait/read/retry is used here. An implementation
|
||||
// based on poll(2) or inotify(7) is possible, but it makes the code
|
||||
// much more complicated. Maybe address this later.
|
||||
const (
|
||||
// Perform maxIter with waitTime in between iterations.
|
||||
waitTime = 10 * time.Millisecond
|
||||
maxIter = 1000
|
||||
)
|
||||
scanner := bufio.NewScanner(fd)
|
||||
for i := 0; scanner.Scan(); {
|
||||
if i == maxIter {
|
||||
return configs.Undefined, fmt.Errorf("timeout of %s reached waiting for the cgroup to freeze", waitTime*maxIter)
|
||||
}
|
||||
line := scanner.Text()
|
||||
val := strings.TrimPrefix(line, "frozen ")
|
||||
if val != line { // got prefix
|
||||
if val[0] == '1' {
|
||||
return configs.Frozen, nil
|
||||
}
|
||||
|
||||
i++
|
||||
// wait, then re-read
|
||||
time.Sleep(waitTime)
|
||||
_, err := fd.Seek(0, 0)
|
||||
if err != nil {
|
||||
return configs.Undefined, err
|
||||
}
|
||||
}
|
||||
}
|
||||
// Should only reach here either on read error,
|
||||
// or if the file does not contain "frozen " line.
|
||||
return configs.Undefined, scanner.Err()
|
||||
}
|
||||
|
8
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/fs2.go
generated
vendored
8
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/fs2.go
generated
vendored
@@ -51,7 +51,7 @@ func (m *manager) getControllers() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := fscommon.ReadFile(m.dirPath, "cgroup.controllers")
|
||||
data, err := cgroups.ReadFile(m.dirPath, "cgroup.controllers")
|
||||
if err != nil {
|
||||
if m.rootless && m.config.Path == "" {
|
||||
return nil
|
||||
@@ -98,9 +98,7 @@ func (m *manager) GetAllPids() ([]int, error) {
|
||||
}
|
||||
|
||||
func (m *manager) GetStats() (*cgroups.Stats, error) {
|
||||
var (
|
||||
errs []error
|
||||
)
|
||||
var errs []error
|
||||
|
||||
st := cgroups.NewStats()
|
||||
|
||||
@@ -199,7 +197,7 @@ func (m *manager) setUnified(res map[string]string) error {
|
||||
if strings.Contains(k, "/") {
|
||||
return fmt.Errorf("unified resource %q must be a file name (no slashes)", k)
|
||||
}
|
||||
if err := fscommon.WriteFile(m.dirPath, k, v); err != nil {
|
||||
if err := cgroups.WriteFile(m.dirPath, k, v); err != nil {
|
||||
errC := errors.Cause(err)
|
||||
// Check for both EPERM and ENOENT since O_CREAT is used by WriteFile.
|
||||
if errors.Is(errC, os.ErrPermission) || errors.Is(errC, os.ErrNotExist) {
|
||||
|
2
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/hugetlb.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/hugetlb.go
generated
vendored
@@ -21,7 +21,7 @@ func setHugeTlb(dirPath string, r *configs.Resources) error {
|
||||
return nil
|
||||
}
|
||||
for _, hugetlb := range r.HugetlbLimit {
|
||||
if err := fscommon.WriteFile(dirPath, "hugetlb."+hugetlb.Pagesize+".max", strconv.FormatUint(hugetlb.Limit, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "hugetlb."+hugetlb.Pagesize+".max", strconv.FormatUint(hugetlb.Limit, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
98
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/io.go
generated
vendored
98
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/io.go
generated
vendored
@@ -4,60 +4,95 @@ package fs2
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
func isIoSet(r *configs.Resources) bool {
|
||||
return r.BlkioWeight != 0 ||
|
||||
len(r.BlkioWeightDevice) > 0 ||
|
||||
len(r.BlkioThrottleReadBpsDevice) > 0 ||
|
||||
len(r.BlkioThrottleWriteBpsDevice) > 0 ||
|
||||
len(r.BlkioThrottleReadIOPSDevice) > 0 ||
|
||||
len(r.BlkioThrottleWriteIOPSDevice) > 0
|
||||
}
|
||||
|
||||
// bfqDeviceWeightSupported checks for per-device BFQ weight support (added
|
||||
// in kernel v5.4, commit 795fe54c2a8) by reading from "io.bfq.weight".
|
||||
func bfqDeviceWeightSupported(bfq *os.File) bool {
|
||||
if bfq == nil {
|
||||
return false
|
||||
}
|
||||
_, _ = bfq.Seek(0, 0)
|
||||
buf := make([]byte, 32)
|
||||
_, _ = bfq.Read(buf)
|
||||
// If only a single number (default weight) if read back, we have older kernel.
|
||||
_, err := strconv.ParseInt(string(bytes.TrimSpace(buf)), 10, 64)
|
||||
return err != nil
|
||||
}
|
||||
|
||||
func setIo(dirPath string, r *configs.Resources) error {
|
||||
if !isIoSet(r) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If BFQ IO scheduler is available, use it.
|
||||
var bfq *os.File
|
||||
if r.BlkioWeight != 0 || len(r.BlkioWeightDevice) > 0 {
|
||||
var err error
|
||||
bfq, err = cgroups.OpenFile(dirPath, "io.bfq.weight", os.O_RDWR)
|
||||
if err == nil {
|
||||
defer bfq.Close()
|
||||
} else if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if r.BlkioWeight != 0 {
|
||||
filename := "io.bfq.weight"
|
||||
if err := fscommon.WriteFile(dirPath, filename,
|
||||
strconv.FormatUint(uint64(r.BlkioWeight), 10)); err != nil {
|
||||
// if io.bfq.weight does not exist, then bfq module is not loaded.
|
||||
// Fallback to use io.weight with a conversion scheme
|
||||
if !os.IsNotExist(err) {
|
||||
if bfq != nil { // Use BFQ.
|
||||
if _, err := bfq.WriteString(strconv.FormatUint(uint64(r.BlkioWeight), 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Fallback to io.weight with a conversion scheme.
|
||||
v := cgroups.ConvertBlkIOToIOWeightValue(r.BlkioWeight)
|
||||
if err := fscommon.WriteFile(dirPath, "io.weight", strconv.FormatUint(v, 10)); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "io.weight", strconv.FormatUint(v, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if bfqDeviceWeightSupported(bfq) {
|
||||
for _, wd := range r.BlkioWeightDevice {
|
||||
if _, err := bfq.WriteString(wd.WeightString() + "\n"); err != nil {
|
||||
return fmt.Errorf("setting device weight %q: %w", wd.WeightString(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleReadBpsDevice {
|
||||
if err := fscommon.WriteFile(dirPath, "io.max", td.StringName("rbps")); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "io.max", td.StringName("rbps")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleWriteBpsDevice {
|
||||
if err := fscommon.WriteFile(dirPath, "io.max", td.StringName("wbps")); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "io.max", td.StringName("wbps")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleReadIOPSDevice {
|
||||
if err := fscommon.WriteFile(dirPath, "io.max", td.StringName("riops")); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "io.max", td.StringName("riops")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleWriteIOPSDevice {
|
||||
if err := fscommon.WriteFile(dirPath, "io.max", td.StringName("wiops")); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "io.max", td.StringName("wiops")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -67,7 +102,7 @@ func setIo(dirPath string, r *configs.Resources) error {
|
||||
|
||||
func readCgroup2MapFile(dirPath string, name string) (map[string][]string, error) {
|
||||
ret := map[string][]string{}
|
||||
f, err := fscommon.OpenFile(dirPath, name, os.O_RDONLY)
|
||||
f, err := cgroups.OpenFile(dirPath, name, os.O_RDONLY)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -88,22 +123,22 @@ func readCgroup2MapFile(dirPath string, name string) (map[string][]string, error
|
||||
}
|
||||
|
||||
func statIo(dirPath string, stats *cgroups.Stats) error {
|
||||
// more details on the io.stat file format: https://www.kernel.org/doc/Documentation/cgroup-v2.txt
|
||||
var ioServiceBytesRecursive []cgroups.BlkioStatEntry
|
||||
values, err := readCgroup2MapFile(dirPath, "io.stat")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// more details on the io.stat file format: https://www.kernel.org/doc/Documentation/cgroup-v2.txt
|
||||
var parsedStats cgroups.BlkioStats
|
||||
for k, v := range values {
|
||||
d := strings.Split(k, ":")
|
||||
if len(d) != 2 {
|
||||
continue
|
||||
}
|
||||
major, err := strconv.ParseUint(d[0], 10, 0)
|
||||
major, err := strconv.ParseUint(d[0], 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
minor, err := strconv.ParseUint(d[1], 10, 0)
|
||||
minor, err := strconv.ParseUint(d[1], 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -115,15 +150,32 @@ func statIo(dirPath string, stats *cgroups.Stats) error {
|
||||
}
|
||||
op := d[0]
|
||||
|
||||
// Accommodate the cgroup v1 naming
|
||||
// Map to the cgroupv1 naming and layout (in separate tables).
|
||||
var targetTable *[]cgroups.BlkioStatEntry
|
||||
switch op {
|
||||
// Equivalent to cgroupv1's blkio.io_service_bytes.
|
||||
case "rbytes":
|
||||
op = "read"
|
||||
op = "Read"
|
||||
targetTable = &parsedStats.IoServiceBytesRecursive
|
||||
case "wbytes":
|
||||
op = "write"
|
||||
op = "Write"
|
||||
targetTable = &parsedStats.IoServiceBytesRecursive
|
||||
// Equivalent to cgroupv1's blkio.io_serviced.
|
||||
case "rios":
|
||||
op = "Read"
|
||||
targetTable = &parsedStats.IoServicedRecursive
|
||||
case "wios":
|
||||
op = "Write"
|
||||
targetTable = &parsedStats.IoServicedRecursive
|
||||
default:
|
||||
// Skip over entries we cannot map to cgroupv1 stats for now.
|
||||
// In the future we should expand the stats struct to include
|
||||
// them.
|
||||
logrus.Debugf("cgroupv2 io stats: skipping over unmappable %s entry", item)
|
||||
continue
|
||||
}
|
||||
|
||||
value, err := strconv.ParseUint(d[1], 10, 0)
|
||||
value, err := strconv.ParseUint(d[1], 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -134,9 +186,9 @@ func statIo(dirPath string, stats *cgroups.Stats) error {
|
||||
Minor: minor,
|
||||
Value: value,
|
||||
}
|
||||
ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry)
|
||||
*targetTable = append(*targetTable, entry)
|
||||
}
|
||||
}
|
||||
stats.BlkioStats = cgroups.BlkioStats{IoServiceBytesRecursive: ioServiceBytesRecursive}
|
||||
stats.BlkioStats = parsedStats
|
||||
return nil
|
||||
}
|
||||
|
8
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go
generated
vendored
8
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go
generated
vendored
@@ -52,13 +52,13 @@ func setMemory(dirPath string, r *configs.Resources) error {
|
||||
}
|
||||
// never write empty string to `memory.swap.max`, it means set to 0.
|
||||
if swapStr != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "memory.swap.max", swapStr); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "memory.swap.max", swapStr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val := numToStr(r.Memory); val != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "memory.max", val); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "memory.max", val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ func setMemory(dirPath string, r *configs.Resources) error {
|
||||
// cgroup.Resources.KernelMemory is ignored
|
||||
|
||||
if val := numToStr(r.MemoryReservation); val != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "memory.low", val); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "memory.low", val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ func setMemory(dirPath string, r *configs.Resources) error {
|
||||
|
||||
func statMemory(dirPath string, stats *cgroups.Stats) error {
|
||||
// Set stats from memory.stat.
|
||||
statsFile, err := fscommon.OpenFile(dirPath, "memory.stat", os.O_RDONLY)
|
||||
statsFile, err := cgroups.OpenFile(dirPath, "memory.stat", os.O_RDONLY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/pids.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/pids.go
generated
vendored
@@ -23,7 +23,7 @@ func setPids(dirPath string, r *configs.Resources) error {
|
||||
return nil
|
||||
}
|
||||
if val := numToStr(r.PidsLimit); val != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "pids.max", val); err != nil {
|
||||
if err := cgroups.WriteFile(dirPath, "pids.max", val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -34,9 +34,9 @@ func setPids(dirPath string, r *configs.Resources) error {
|
||||
func statPidsFromCgroupProcs(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 := fscommon.ReadFile(dirPath, "cgroup.procs")
|
||||
contents, err := cgroups.ReadFile(dirPath, "cgroup.procs")
|
||||
if errors.Is(err, unix.ENOTSUP) {
|
||||
contents, err = fscommon.ReadFile(dirPath, "cgroup.threads")
|
||||
contents, err = cgroups.ReadFile(dirPath, "cgroup.threads")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
51
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/fscommon.go
generated
vendored
51
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/fscommon.go
generated
vendored
@@ -1,51 +0,0 @@
|
||||
// +build linux
|
||||
|
||||
package fscommon
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// WriteFile writes data to a cgroup file in dir.
|
||||
// It is supposed to be used for cgroup files only.
|
||||
func WriteFile(dir, file, data string) error {
|
||||
fd, err := OpenFile(dir, file, unix.O_WRONLY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
if err := retryingWriteFile(fd, data); err != nil {
|
||||
return errors.Wrapf(err, "failed to write %q", data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadFile reads data from a cgroup file in dir.
|
||||
// It is supposed to be used for cgroup files only.
|
||||
func ReadFile(dir, file string) (string, error) {
|
||||
fd, err := OpenFile(dir, file, unix.O_RDONLY)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer fd.Close()
|
||||
var buf bytes.Buffer
|
||||
|
||||
_, err = buf.ReadFrom(fd)
|
||||
return buf.String(), err
|
||||
}
|
||||
|
||||
func retryingWriteFile(fd *os.File, data string) error {
|
||||
for {
|
||||
_, err := fd.Write([]byte(data))
|
||||
if errors.Is(err, unix.EINTR) {
|
||||
logrus.Infof("interrupted while writing %s to %s", data, fd.Name())
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
15
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/utils.go
generated
vendored
15
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/utils.go
generated
vendored
@@ -8,10 +8,19 @@ import (
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotValidFormat = errors.New("line is not a valid key value format")
|
||||
|
||||
// Deprecated: use cgroups.OpenFile instead.
|
||||
OpenFile = cgroups.OpenFile
|
||||
// Deprecated: use cgroups.ReadFile instead.
|
||||
ReadFile = cgroups.ReadFile
|
||||
// Deprecated: use cgroups.WriteFile instead.
|
||||
WriteFile = cgroups.WriteFile
|
||||
)
|
||||
|
||||
// ParseUint converts a string to an uint64 integer.
|
||||
@@ -57,7 +66,7 @@ func ParseKeyValue(t string) (string, uint64, error) {
|
||||
// and returns a value of the specified key. ParseUint is used for value
|
||||
// conversion.
|
||||
func GetValueByKey(path, file, key string) (uint64, error) {
|
||||
content, err := ReadFile(path, file)
|
||||
content, err := cgroups.ReadFile(path, file)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -95,7 +104,7 @@ func GetCgroupParamUint(path, file string) (uint64, error) {
|
||||
// GetCgroupParamInt reads a single int64 value from specified cgroup file.
|
||||
// If the value read is "max", the math.MaxInt64 is returned.
|
||||
func GetCgroupParamInt(path, file string) (int64, error) {
|
||||
contents, err := ReadFile(path, file)
|
||||
contents, err := cgroups.ReadFile(path, file)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -113,7 +122,7 @@ func GetCgroupParamInt(path, file string) (int64, error) {
|
||||
|
||||
// GetCgroupParamString reads a string from the specified cgroup file.
|
||||
func GetCgroupParamString(path, file string) (string, error) {
|
||||
contents, err := ReadFile(path, file)
|
||||
contents, err := cgroups.ReadFile(path, file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
50
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go
generated
vendored
50
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go
generated
vendored
@@ -158,14 +158,27 @@ func findDeviceGroup(ruleType devices.Type, ruleMajor int64) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// DeviceAllow is the dbus type "a(ss)" which means we need a struct
|
||||
// to represent it in Go.
|
||||
type deviceAllowEntry struct {
|
||||
Path string
|
||||
Perms string
|
||||
}
|
||||
|
||||
func allowAllDevices() []systemdDbus.Property {
|
||||
// Setting mode to auto and removing all DeviceAllow rules
|
||||
// results in allowing access to all devices.
|
||||
return []systemdDbus.Property{
|
||||
newProp("DevicePolicy", "auto"),
|
||||
newProp("DeviceAllow", []deviceAllowEntry{}),
|
||||
}
|
||||
}
|
||||
|
||||
// generateDeviceProperties takes the configured device rules and generates a
|
||||
// corresponding set of systemd properties to configure the devices correctly.
|
||||
func generateDeviceProperties(rules []*devices.Rule) ([]systemdDbus.Property, error) {
|
||||
// DeviceAllow is the type "a(ss)" which means we need a temporary struct
|
||||
// to represent it in Go.
|
||||
type deviceAllowEntry struct {
|
||||
Path string
|
||||
Perms string
|
||||
func generateDeviceProperties(r *configs.Resources) ([]systemdDbus.Property, error) {
|
||||
if r.SkipDevices {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
properties := []systemdDbus.Property{
|
||||
@@ -177,7 +190,7 @@ func generateDeviceProperties(rules []*devices.Rule) ([]systemdDbus.Property, er
|
||||
|
||||
// Figure out the set of rules.
|
||||
configEmu := &cgroupdevices.Emulator{}
|
||||
for _, rule := range rules {
|
||||
for _, rule := range r.Devices {
|
||||
if err := configEmu.Apply(*rule); err != nil {
|
||||
return nil, errors.Wrap(err, "apply rule for systemd")
|
||||
}
|
||||
@@ -189,12 +202,7 @@ func generateDeviceProperties(rules []*devices.Rule) ([]systemdDbus.Property, er
|
||||
if configEmu.IsBlacklist() {
|
||||
// However, if we're dealing with an allow-all rule then we can do it.
|
||||
if configEmu.IsAllowAll() {
|
||||
return []systemdDbus.Property{
|
||||
// Run in white-list mode by setting to "auto" and removing all
|
||||
// DeviceAllow rules.
|
||||
newProp("DevicePolicy", "auto"),
|
||||
newProp("DeviceAllow", []deviceAllowEntry{}),
|
||||
}, nil
|
||||
return allowAllDevices(), nil
|
||||
}
|
||||
logrus.Warn("systemd doesn't support blacklist device rules -- applying temporary deny-all rule")
|
||||
return properties, nil
|
||||
@@ -203,8 +211,7 @@ func generateDeviceProperties(rules []*devices.Rule) ([]systemdDbus.Property, er
|
||||
// Now generate the set of rules we actually need to apply. Unlike the
|
||||
// normal devices cgroup, in "strict" mode systemd defaults to a deny-all
|
||||
// whitelist which is the default for devices.Emulator.
|
||||
baseEmu := &cgroupdevices.Emulator{}
|
||||
finalRules, err := baseEmu.Transition(configEmu)
|
||||
finalRules, err := configEmu.Rules()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get simplified rules for systemd")
|
||||
}
|
||||
@@ -306,7 +313,7 @@ func getUnitName(c *configs.Cgroup) string {
|
||||
// isDbusError returns true if the error is a specific dbus error.
|
||||
func isDbusError(err error, name string) bool {
|
||||
if err != nil {
|
||||
var derr *dbus.Error
|
||||
var derr dbus.Error
|
||||
if errors.As(err, &derr) {
|
||||
return strings.Contains(derr.Name, name)
|
||||
}
|
||||
@@ -355,6 +362,9 @@ func stopUnit(cm *dbusConnManager, unitName string) error {
|
||||
return err
|
||||
})
|
||||
if err == nil {
|
||||
timeout := time.NewTimer(30 * time.Second)
|
||||
defer timeout.Stop()
|
||||
|
||||
select {
|
||||
case s := <-statusChan:
|
||||
close(statusChan)
|
||||
@@ -362,8 +372,8 @@ func stopUnit(cm *dbusConnManager, unitName string) error {
|
||||
if s != "done" {
|
||||
logrus.Warnf("error removing unit `%s`: got `%s`. Continuing...", unitName, s)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
logrus.Warnf("Timed out while waiting for StopUnit(%s) completion signal from dbus. Continuing...", unitName)
|
||||
case <-timeout.C:
|
||||
return errors.New("Timed out while waiting for systemd to remove " + unitName)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -476,7 +486,7 @@ func addCpuset(cm *dbusConnManager, props *[]systemdDbus.Property, cpus, mems st
|
||||
}
|
||||
|
||||
if cpus != "" {
|
||||
bits, err := rangeToBits(cpus)
|
||||
bits, err := RangeToBits(cpus)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resources.CPU.Cpus=%q conversion error: %w",
|
||||
cpus, err)
|
||||
@@ -485,7 +495,7 @@ func addCpuset(cm *dbusConnManager, props *[]systemdDbus.Property, cpus, mems st
|
||||
newProp("AllowedCPUs", bits))
|
||||
}
|
||||
if mems != "" {
|
||||
bits, err := rangeToBits(mems)
|
||||
bits, err := RangeToBits(mems)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resources.CPU.Mems=%q conversion error: %w",
|
||||
mems, err)
|
||||
|
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/cpuset.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/cpuset.go
generated
vendored
@@ -5,15 +5,15 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/bits-and-blooms/bitset"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/willf/bitset"
|
||||
)
|
||||
|
||||
// rangeToBits converts a text representation of a CPU mask (as written to
|
||||
// RangeToBits converts a text representation of a CPU mask (as written to
|
||||
// or read from cgroups' cpuset.* files, e.g. "1,3-5") to a slice of bytes
|
||||
// with the corresponding bits set (as consumed by systemd over dbus as
|
||||
// AllowedCPUs/AllowedMemoryNodes unit property value).
|
||||
func rangeToBits(str string) ([]byte, error) {
|
||||
func RangeToBits(str string) ([]byte, error) {
|
||||
bits := &bitset.BitSet{}
|
||||
|
||||
for _, r := range strings.Split(str, ",") {
|
||||
|
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/dbus.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/dbus.go
generated
vendored
@@ -17,14 +17,16 @@ var (
|
||||
dbusRootless bool
|
||||
)
|
||||
|
||||
type dbusConnManager struct {
|
||||
}
|
||||
type dbusConnManager struct{}
|
||||
|
||||
// newDbusConnManager initializes systemd dbus connection manager.
|
||||
func newDbusConnManager(rootless bool) *dbusConnManager {
|
||||
dbusMu.Lock()
|
||||
defer dbusMu.Unlock()
|
||||
if dbusInited && rootless != dbusRootless {
|
||||
panic("can't have both root and rootless dbus")
|
||||
}
|
||||
dbusInited = true
|
||||
dbusRootless = rootless
|
||||
return &dbusConnManager{}
|
||||
}
|
||||
|
38
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v1.go
generated
vendored
38
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v1.go
generated
vendored
@@ -61,7 +61,7 @@ var legacySubsystems = []subsystem{
|
||||
func genV1ResourcesProperties(r *configs.Resources, cm *dbusConnManager) ([]systemdDbus.Property, error) {
|
||||
var properties []systemdDbus.Property
|
||||
|
||||
deviceProperties, err := generateDeviceProperties(r.Devices)
|
||||
deviceProperties, err := generateDeviceProperties(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -207,9 +207,10 @@ func (m *legacyManager) Destroy() error {
|
||||
|
||||
stopErr := stopUnit(m.dbus, getUnitName(m.cgroups))
|
||||
|
||||
// Both on success and on error, cleanup all the cgroups we are aware of.
|
||||
// Some of them were created directly by Apply() and are not managed by systemd.
|
||||
if err := cgroups.RemovePaths(m.paths); err != nil {
|
||||
// Both on success and on error, cleanup all the cgroups
|
||||
// we are aware of, as some of them were created directly
|
||||
// by Apply() and are not managed by systemd.
|
||||
if err := cgroups.RemovePaths(m.paths); err != nil && stopErr == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -237,7 +238,7 @@ func (m *legacyManager) joinCgroups(pid int) error {
|
||||
}
|
||||
default:
|
||||
if path, ok := m.paths[name]; ok {
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
if err := os.MkdirAll(path, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cgroups.WriteCgroupProc(path, pid); err != nil {
|
||||
@@ -338,27 +339,24 @@ func (m *legacyManager) Set(r *configs.Resources) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Figure out the current freezer state, so we can revert to it after we
|
||||
// temporarily freeze the container.
|
||||
targetFreezerState, err := m.GetFreezerState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if targetFreezerState == configs.Undefined {
|
||||
targetFreezerState = configs.Thawed
|
||||
}
|
||||
|
||||
// We have to freeze the container while systemd sets the cgroup settings.
|
||||
// The reason for this is that systemd's application of DeviceAllow rules
|
||||
// is done disruptively, resulting in spurrious errors to common devices
|
||||
// (unlike our fs driver, they will happily write deny-all rules to running
|
||||
// containers). So we freeze the container to avoid them hitting the cgroup
|
||||
// error. But if the freezer cgroup isn't supported, we just warn about it.
|
||||
targetFreezerState := configs.Undefined
|
||||
if !m.cgroups.SkipDevices {
|
||||
// Figure out the current freezer state, so we can revert to it after we
|
||||
// temporarily freeze the container.
|
||||
targetFreezerState, err = m.GetFreezerState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if targetFreezerState == configs.Undefined {
|
||||
targetFreezerState = configs.Thawed
|
||||
}
|
||||
|
||||
if err := m.Freeze(configs.Frozen); err != nil {
|
||||
logrus.Infof("freeze container before SetUnitProperties failed: %v", err)
|
||||
}
|
||||
if err := m.Freeze(configs.Frozen); err != nil {
|
||||
logrus.Infof("freeze container before SetUnitProperties failed: %v", err)
|
||||
}
|
||||
|
||||
if err := setUnitProperties(m.dbus, getUnitName(m.cgroups), properties...); err != nil {
|
||||
|
31
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v2.go
generated
vendored
31
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v2.go
generated
vendored
@@ -96,7 +96,7 @@ func unifiedResToSystemdProps(cm *dbusConnManager, res map[string]string) (props
|
||||
newProp("CPUWeight", num))
|
||||
|
||||
case "cpuset.cpus", "cpuset.mems":
|
||||
bits, err := rangeToBits(v)
|
||||
bits, err := RangeToBits(v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unified resource %q=%q conversion error: %w", k, v, err)
|
||||
}
|
||||
@@ -172,7 +172,7 @@ func genV2ResourcesProperties(r *configs.Resources, cm *dbusConnManager) ([]syst
|
||||
// aren't the end of the world, but it is a bit concerning. However
|
||||
// it's unclear if systemd removes all eBPF programs attached when
|
||||
// doing SetUnitProperties...
|
||||
deviceProperties, err := generateDeviceProperties(r.Devices)
|
||||
deviceProperties, err := generateDeviceProperties(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -418,27 +418,24 @@ func (m *unifiedManager) Set(r *configs.Resources) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Figure out the current freezer state, so we can revert to it after we
|
||||
// temporarily freeze the container.
|
||||
targetFreezerState, err := m.GetFreezerState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if targetFreezerState == configs.Undefined {
|
||||
targetFreezerState = configs.Thawed
|
||||
}
|
||||
|
||||
// We have to freeze the container while systemd sets the cgroup settings.
|
||||
// The reason for this is that systemd's application of DeviceAllow rules
|
||||
// is done disruptively, resulting in spurrious errors to common devices
|
||||
// (unlike our fs driver, they will happily write deny-all rules to running
|
||||
// containers). So we freeze the container to avoid them hitting the cgroup
|
||||
// error. But if the freezer cgroup isn't supported, we just warn about it.
|
||||
targetFreezerState := configs.Undefined
|
||||
if !m.cgroups.SkipDevices {
|
||||
// Figure out the current freezer state, so we can revert to it after we
|
||||
// temporarily freeze the container.
|
||||
targetFreezerState, err = m.GetFreezerState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if targetFreezerState == configs.Undefined {
|
||||
targetFreezerState = configs.Thawed
|
||||
}
|
||||
|
||||
if err := m.Freeze(configs.Frozen); err != nil {
|
||||
logrus.Infof("freeze container before SetUnitProperties failed: %v", err)
|
||||
}
|
||||
if err := m.Freeze(configs.Frozen); err != nil {
|
||||
logrus.Infof("freeze container before SetUnitProperties failed: %v", err)
|
||||
}
|
||||
|
||||
if err := setUnitProperties(m.dbus, getUnitName(m.cgroups), properties...); err != nil {
|
||||
|
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
generated
vendored
@@ -15,7 +15,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/userns"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -88,7 +87,7 @@ func GetAllSubsystems() ([]string, error) {
|
||||
// - freezer: implemented in kernel 5.2
|
||||
// We assume these are always available, as it is hard to detect availability.
|
||||
pseudo := []string{"devices", "freezer"}
|
||||
data, err := fscommon.ReadFile("/sys/fs/cgroup", "cgroup.controllers")
|
||||
data, err := ReadFile("/sys/fs/cgroup", "cgroup.controllers")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -267,7 +266,6 @@ func RemovePaths(paths map[string]string) (err error) {
|
||||
case retries - 1:
|
||||
logrus.WithError(err).Error("Failed to remove cgroup")
|
||||
}
|
||||
|
||||
}
|
||||
_, err := os.Stat(p)
|
||||
// We need this strange way of checking cgroups existence because
|
||||
@@ -376,7 +374,7 @@ func WriteCgroupProc(dir string, pid int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
file, err := fscommon.OpenFile(dir, CgroupProcesses, os.O_WRONLY)
|
||||
file, err := OpenFile(dir, CgroupProcesses, os.O_WRONLY)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err)
|
||||
}
|
||||
|
10
vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go
generated
vendored
10
vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go
generated
vendored
@@ -13,12 +13,12 @@ const (
|
||||
Thawed FreezerState = "THAWED"
|
||||
)
|
||||
|
||||
// Cgroup holds properties of a cgroup on Linux.
|
||||
type Cgroup struct {
|
||||
// Deprecated, use Path instead
|
||||
// Name specifies the name of the cgroup
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// name of parent of cgroup or slice
|
||||
// Deprecated, use Path instead
|
||||
// Parent specifies the name of parent of cgroup or slice
|
||||
Parent string `json:"parent,omitempty"`
|
||||
|
||||
// Path specifies the path to cgroups that are created and/or joined by the container.
|
||||
@@ -127,8 +127,8 @@ type Resources struct {
|
||||
|
||||
// SkipDevices allows to skip configuring device permissions.
|
||||
// Used by e.g. kubelet while creating a parent cgroup (kubepods)
|
||||
// common for many containers.
|
||||
// common for many containers, and by runc update.
|
||||
//
|
||||
// NOTE it is impossible to start a container which has this flag set.
|
||||
SkipDevices bool `json:"skip_devices"`
|
||||
SkipDevices bool `json:"-"`
|
||||
}
|
||||
|
4
vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unsupported.go
generated
vendored
4
vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unsupported.go
generated
vendored
@@ -2,7 +2,7 @@
|
||||
|
||||
package configs
|
||||
|
||||
// Cgroup holds properties of a cgroup on Linux
|
||||
// TODO Windows: This can ultimately be entirely factored out on Windows as
|
||||
// cgroups are a Unix-specific construct.
|
||||
type Cgroup struct {
|
||||
}
|
||||
type Cgroup struct{}
|
||||
|
10
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
generated
vendored
10
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
generated
vendored
@@ -208,9 +208,11 @@ type Config struct {
|
||||
RootlessCgroups bool `json:"rootless_cgroups,omitempty"`
|
||||
}
|
||||
|
||||
type HookName string
|
||||
type HookList []Hook
|
||||
type Hooks map[HookName]HookList
|
||||
type (
|
||||
HookName string
|
||||
HookList []Hook
|
||||
Hooks map[HookName]HookList
|
||||
)
|
||||
|
||||
const (
|
||||
// Prestart commands are executed after the container namespaces are created,
|
||||
@@ -387,7 +389,7 @@ func (c Command) Run(s *specs.State) error {
|
||||
case err := <-errC:
|
||||
return err
|
||||
case <-timerCh:
|
||||
cmd.Process.Kill()
|
||||
_ = cmd.Process.Kill()
|
||||
<-errC
|
||||
return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
|
||||
}
|
||||
|
17
vendor/github.com/opencontainers/runc/libcontainer/configs/devices.go
generated
vendored
17
vendor/github.com/opencontainers/runc/libcontainer/configs/devices.go
generated
vendored
@@ -1,17 +0,0 @@
|
||||
package configs
|
||||
|
||||
import "github.com/opencontainers/runc/libcontainer/devices"
|
||||
|
||||
type (
|
||||
// Deprecated: use libcontainer/devices.Device
|
||||
Device = devices.Device
|
||||
|
||||
// Deprecated: use libcontainer/devices.Rule
|
||||
DeviceRule = devices.Rule
|
||||
|
||||
// Deprecated: use libcontainer/devices.Type
|
||||
DeviceType = devices.Type
|
||||
|
||||
// Deprecated: use libcontainer/devices.Permissions
|
||||
DevicePermissions = devices.Permissions
|
||||
)
|
2
vendor/github.com/opencontainers/runc/libcontainer/configs/mount.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/configs/mount.go
generated
vendored
@@ -3,7 +3,7 @@ package configs
|
||||
const (
|
||||
// EXT_COPYUP is a directive to copy up the contents of a directory when
|
||||
// a tmpfs is mounted over it.
|
||||
EXT_COPYUP = 1 << iota
|
||||
EXT_COPYUP = 1 << iota //nolint:golint // ignore "don't use ALL_CAPS" warning
|
||||
)
|
||||
|
||||
type Mount struct {
|
||||
|
3
vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unsupported.go
generated
vendored
3
vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unsupported.go
generated
vendored
@@ -4,5 +4,4 @@ package configs
|
||||
|
||||
// Namespace defines configuration for each namespace. It specifies an
|
||||
// alternate path that is able to be joined via setns.
|
||||
type Namespace struct {
|
||||
}
|
||||
type Namespace struct{}
|
||||
|
13
vendor/github.com/opencontainers/runc/libcontainer/configs/network.go
generated
vendored
13
vendor/github.com/opencontainers/runc/libcontainer/configs/network.go
generated
vendored
@@ -50,7 +50,10 @@ type Network struct {
|
||||
HairpinMode bool `json:"hairpin_mode"`
|
||||
}
|
||||
|
||||
// Routes can be specified to create entries in the route table as the container is started
|
||||
// Route defines a routing table entry.
|
||||
//
|
||||
// Routes can be specified to create entries in the routing table as the container
|
||||
// is started.
|
||||
//
|
||||
// All of destination, source, and gateway should be either IPv4 or IPv6.
|
||||
// One of the three options must be present, and omitted entries will use their
|
||||
@@ -58,15 +61,15 @@ type Network struct {
|
||||
// gateway to 1.2.3.4 and the interface to eth0 will set up a standard
|
||||
// destination of 0.0.0.0(or *) when viewed in the route table.
|
||||
type Route struct {
|
||||
// Sets the destination and mask, should be a CIDR. Accepts IPv4 and IPv6
|
||||
// Destination specifies the destination IP address and mask in the CIDR form.
|
||||
Destination string `json:"destination"`
|
||||
|
||||
// Sets the source and mask, should be a CIDR. Accepts IPv4 and IPv6
|
||||
// Source specifies the source IP address and mask in the CIDR form.
|
||||
Source string `json:"source"`
|
||||
|
||||
// Sets the gateway. Accepts IPv4 and IPv6
|
||||
// Gateway specifies the gateway IP address.
|
||||
Gateway string `json:"gateway"`
|
||||
|
||||
// The device to set this route up for, for example: eth0
|
||||
// InterfaceName specifies the device to set this route up for, for example eth0.
|
||||
InterfaceName string `json:"interface_name"`
|
||||
}
|
||||
|
17
vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
generated
vendored
17
vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
generated
vendored
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/intelrdt"
|
||||
selinux "github.com/opencontainers/selinux/go-selinux"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -23,13 +24,13 @@ func New() Validator {
|
||||
return &ConfigValidator{}
|
||||
}
|
||||
|
||||
type ConfigValidator struct {
|
||||
}
|
||||
type ConfigValidator struct{}
|
||||
|
||||
type check func(config *configs.Config) error
|
||||
|
||||
func (v *ConfigValidator) Validate(config *configs.Config) error {
|
||||
checks := []check{
|
||||
v.cgroups,
|
||||
v.rootfs,
|
||||
v.network,
|
||||
v.hostname,
|
||||
@@ -39,17 +40,21 @@ func (v *ConfigValidator) Validate(config *configs.Config) error {
|
||||
v.sysctl,
|
||||
v.intelrdt,
|
||||
v.rootlessEUID,
|
||||
v.mounts,
|
||||
}
|
||||
for _, c := range checks {
|
||||
if err := c(config); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := v.cgroups(config); err != nil {
|
||||
return err
|
||||
// Relaxed validation rules for backward compatibility
|
||||
warns := []check{
|
||||
v.mounts, // TODO (runc v1.x.x): make this an error instead of a warning
|
||||
}
|
||||
for _, c := range warns {
|
||||
if err := c(config); err != nil {
|
||||
logrus.WithError(err).Warnf("invalid configuration")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/opencontainers/runc/libcontainer/console_linux.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/console_linux.go
generated
vendored
@@ -9,7 +9,7 @@ import (
|
||||
// mount initializes the console inside the rootfs mounting with the specified mount label
|
||||
// and applying the correct ownership of the console.
|
||||
func mountConsole(slavePath string) error {
|
||||
oldMask := unix.Umask(0000)
|
||||
oldMask := unix.Umask(0o000)
|
||||
defer unix.Umask(oldMask)
|
||||
f, err := os.Create("/dev/console")
|
||||
if err != nil && !os.IsExist(err) {
|
||||
|
33
vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
generated
vendored
33
vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
generated
vendored
@@ -437,8 +437,8 @@ func (c *linuxContainer) createExecFifo() error {
|
||||
if _, err := os.Stat(fifoName); err == nil {
|
||||
return fmt.Errorf("exec fifo %s already exists", fifoName)
|
||||
}
|
||||
oldMask := unix.Umask(0000)
|
||||
if err := unix.Mkfifo(fifoName, 0622); err != nil {
|
||||
oldMask := unix.Umask(0o000)
|
||||
if err := unix.Mkfifo(fifoName, 0o622); err != nil {
|
||||
unix.Umask(oldMask)
|
||||
return err
|
||||
}
|
||||
@@ -699,7 +699,6 @@ func (c *linuxContainer) NotifyMemoryPressure(level PressureLevel) (<-chan struc
|
||||
var criuFeatures *criurpc.CriuFeatures
|
||||
|
||||
func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.CriuOpts, criuFeat *criurpc.CriuFeatures) error {
|
||||
|
||||
t := criurpc.CriuReqType_FEATURE_CHECK
|
||||
|
||||
// make sure the features we are looking for are really not from
|
||||
@@ -761,7 +760,6 @@ func compareCriuVersion(criuVersion int, minVersion int) error {
|
||||
|
||||
// checkCriuVersion checks Criu version greater than or equal to minVersion
|
||||
func (c *linuxContainer) checkCriuVersion(minVersion int) error {
|
||||
|
||||
// If the version of criu has already been determined there is no need
|
||||
// to ask criu for the version again. Use the value from c.criuVersion.
|
||||
if c.criuVersion != 0 {
|
||||
@@ -970,7 +968,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
|
||||
// Since a container can be C/R'ed multiple times,
|
||||
// the checkpoint directory may already exist.
|
||||
if err := os.Mkdir(criuOpts.ImagesDirectory, 0700); err != nil && !os.IsExist(err) {
|
||||
if err := os.Mkdir(criuOpts.ImagesDirectory, 0o700); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -978,7 +976,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
criuOpts.WorkDirectory = filepath.Join(c.root, "criu.work")
|
||||
}
|
||||
|
||||
if err := os.Mkdir(criuOpts.WorkDirectory, 0700); err != nil && !os.IsExist(err) {
|
||||
if err := os.Mkdir(criuOpts.WorkDirectory, 0o700); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1048,7 +1046,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
}
|
||||
}
|
||||
|
||||
//pre-dump may need parentImage param to complete iterative migration
|
||||
// pre-dump may need parentImage param to complete iterative migration
|
||||
if criuOpts.ParentImage != "" {
|
||||
rpcOpts.ParentImg = proto.String(criuOpts.ParentImage)
|
||||
rpcOpts.TrackMem = proto.Bool(true)
|
||||
@@ -1146,7 +1144,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename), fdsJSON, 0600)
|
||||
err = ioutil.WriteFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename), fdsJSON, 0o600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1217,7 +1215,7 @@ func (c *linuxContainer) makeCriuRestoreMountpoints(m *configs.Mount) error {
|
||||
if err := checkProcMount(c.config.Rootfs, dest, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(dest, 0755); err != nil {
|
||||
if err := os.MkdirAll(dest, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1318,7 +1316,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
}
|
||||
// Since a container can be C/R'ed multiple times,
|
||||
// the work directory may already exist.
|
||||
if err := os.Mkdir(criuOpts.WorkDirectory, 0700); err != nil && !os.IsExist(err) {
|
||||
if err := os.Mkdir(criuOpts.WorkDirectory, 0o700); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
workDir, err := os.Open(criuOpts.WorkDirectory)
|
||||
@@ -1340,7 +1338,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
// c.config.Rootfs is bind-mounted to a temporary directory
|
||||
// to satisfy these requirements.
|
||||
root := filepath.Join(c.root, "criu-root")
|
||||
if err := os.Mkdir(root, 0755); err != nil {
|
||||
if err := os.Mkdir(root, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(root)
|
||||
@@ -1352,7 +1350,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer unix.Unmount(root, unix.MNT_DETACH)
|
||||
defer unix.Unmount(root, unix.MNT_DETACH) //nolint: errcheck
|
||||
t := criurpc.CriuReqType_RESTORE
|
||||
req := &criurpc.CriuReq{
|
||||
Type: &t,
|
||||
@@ -1377,6 +1375,15 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
},
|
||||
}
|
||||
|
||||
if criuOpts.LsmProfile != "" {
|
||||
// CRIU older than 3.16 has a bug which breaks the possibility
|
||||
// to set a different LSM profile.
|
||||
if err := c.checkCriuVersion(31600); err != nil {
|
||||
return errors.New("--lsm-profile requires at least CRIU 3.16")
|
||||
}
|
||||
req.Opts.LsmProfile = proto.String(criuOpts.LsmProfile)
|
||||
}
|
||||
|
||||
c.handleCriuConfigurationFile(req.Opts)
|
||||
|
||||
if err := c.handleRestoringNamespaces(req.Opts, &extraFiles); err != nil {
|
||||
@@ -1665,7 +1672,7 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
|
||||
break
|
||||
}
|
||||
|
||||
criuClientCon.CloseWrite()
|
||||
_ = criuClientCon.CloseWrite()
|
||||
// cmd.Wait() waits cmd.goroutines which are used for proxying file descriptors.
|
||||
// Here we want to wait only the CRIU process.
|
||||
criuProcessState, err = criuProcess.Wait()
|
||||
|
1
vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go
generated
vendored
1
vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go
generated
vendored
@@ -29,4 +29,5 @@ type CriuOpts struct {
|
||||
AutoDedup bool // auto deduplication for incremental dumps
|
||||
LazyPages bool // restore memory pages lazily using userfaultfd
|
||||
StatusFd int // fd for feedback when lazy server is ready
|
||||
LsmProfile string // LSM profile used to restore the container
|
||||
}
|
||||
|
11
vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go
generated
vendored
11
vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go
generated
vendored
@@ -11,10 +11,8 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNotADevice denotes that a file is not a valid linux device.
|
||||
ErrNotADevice = errors.New("not a device node")
|
||||
)
|
||||
// ErrNotADevice denotes that a file is not a valid linux device.
|
||||
var ErrNotADevice = errors.New("not a device node")
|
||||
|
||||
// Testing dependencies
|
||||
var (
|
||||
@@ -29,8 +27,9 @@ func mkDev(d *Rule) (uint64, error) {
|
||||
return unix.Mkdev(uint32(d.Major), uint32(d.Minor)), nil
|
||||
}
|
||||
|
||||
// Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the
|
||||
// information about a linux device and return that information as a Device struct.
|
||||
// DeviceFromPath takes the path to a device and its cgroup_permissions (which
|
||||
// cannot be easily queried) to look up the information about a linux device
|
||||
// and returns that information as a Device struct.
|
||||
func DeviceFromPath(path, permissions string) (*Device, error) {
|
||||
var stat unix.Stat_t
|
||||
err := unixLstat(path, &stat)
|
||||
|
8
vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
generated
vendored
8
vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
generated
vendored
@@ -196,7 +196,11 @@ func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
|
||||
Validator: validate.New(),
|
||||
CriuPath: "criu",
|
||||
}
|
||||
Cgroupfs(l)
|
||||
|
||||
if err := Cgroupfs(l); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, opt := range options {
|
||||
if opt == nil {
|
||||
continue
|
||||
@@ -287,7 +291,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
|
||||
if l.Root == "" {
|
||||
return nil, newGenericError(fmt.Errorf("invalid root"), ConfigInvalid)
|
||||
}
|
||||
//when load, we need to check id is valid or not.
|
||||
// when load, we need to check id is valid or not.
|
||||
if err := l.validateID(id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
14
vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
generated
vendored
14
vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
generated
vendored
@@ -112,9 +112,19 @@ func populateProcessEnvironment(env []string) error {
|
||||
for _, pair := range env {
|
||||
p := strings.SplitN(pair, "=", 2)
|
||||
if len(p) < 2 {
|
||||
return fmt.Errorf("invalid environment '%v'", pair)
|
||||
return fmt.Errorf("invalid environment variable: %q", pair)
|
||||
}
|
||||
if err := os.Setenv(p[0], p[1]); err != nil {
|
||||
name, val := p[0], p[1]
|
||||
if name == "" {
|
||||
return fmt.Errorf("environment variable name can't be empty: %q", pair)
|
||||
}
|
||||
if strings.IndexByte(name, 0) >= 0 {
|
||||
return fmt.Errorf("environment variable name can't contain null(\\x00): %q", pair)
|
||||
}
|
||||
if strings.IndexByte(val, 0) >= 0 {
|
||||
return fmt.Errorf("environment variable value can't contain null(\\x00): %q", pair)
|
||||
}
|
||||
if err := os.Setenv(name, val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
4
vendor/github.com/opencontainers/runc/libcontainer/intelrdt/cmt.go
generated
vendored
4
vendor/github.com/opencontainers/runc/libcontainer/intelrdt/cmt.go
generated
vendored
@@ -1,8 +1,6 @@
|
||||
package intelrdt
|
||||
|
||||
var (
|
||||
cmtEnabled bool
|
||||
)
|
||||
var cmtEnabled bool
|
||||
|
||||
// Check if Intel RDT/CMT is enabled.
|
||||
func IsCMTEnabled() bool {
|
||||
|
6
vendor/github.com/opencontainers/runc/libcontainer/intelrdt/mbm.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/intelrdt/mbm.go
generated
vendored
@@ -2,10 +2,8 @@
|
||||
|
||||
package intelrdt
|
||||
|
||||
var (
|
||||
// The flag to indicate if Intel RDT/MBM is enabled
|
||||
mbmEnabled bool
|
||||
)
|
||||
// The flag to indicate if Intel RDT/MBM is enabled
|
||||
var mbmEnabled bool
|
||||
|
||||
// Check if Intel RDT/MBM is enabled.
|
||||
func IsMBMEnabled() bool {
|
||||
|
4
vendor/github.com/opencontainers/runc/libcontainer/intelrdt/monitoring.go
generated
vendored
4
vendor/github.com/opencontainers/runc/libcontainer/intelrdt/monitoring.go
generated
vendored
@@ -10,9 +10,7 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
enabledMonFeatures monFeatures
|
||||
)
|
||||
var enabledMonFeatures monFeatures
|
||||
|
||||
type monFeatures struct {
|
||||
mbmTotalBytes bool
|
||||
|
10
vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
generated
vendored
10
vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
generated
vendored
@@ -14,18 +14,18 @@ import (
|
||||
type KeySerial uint32
|
||||
|
||||
func JoinSessionKeyring(name string) (KeySerial, error) {
|
||||
sessKeyId, err := unix.KeyctlJoinSessionKeyring(name)
|
||||
sessKeyID, err := unix.KeyctlJoinSessionKeyring(name)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "create session key")
|
||||
}
|
||||
return KeySerial(sessKeyId), nil
|
||||
return KeySerial(sessKeyID), nil
|
||||
}
|
||||
|
||||
// ModKeyringPerm modifies permissions on a keyring by reading the current permissions,
|
||||
// anding the bits with the given mask (clearing permissions) and setting
|
||||
// additional permission bits
|
||||
func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
|
||||
dest, err := unix.KeyctlString(unix.KEYCTL_DESCRIBE, int(ringId))
|
||||
func ModKeyringPerm(ringID KeySerial, mask, setbits uint32) error {
|
||||
dest, err := unix.KeyctlString(unix.KEYCTL_DESCRIBE, int(ringID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -43,5 +43,5 @@ func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
|
||||
|
||||
perm := (uint32(perm64) & mask) | setbits
|
||||
|
||||
return unix.KeyctlSetperm(int(ringId), perm)
|
||||
return unix.KeyctlSetperm(int(ringID), perm)
|
||||
}
|
||||
|
2
vendor/github.com/opencontainers/runc/libcontainer/logs/logs.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/logs/logs.go
generated
vendored
@@ -85,7 +85,7 @@ func ConfigureLogging(config Config) error {
|
||||
if config.LogPipeFd > 0 {
|
||||
logrus.SetOutput(os.NewFile(uintptr(config.LogPipeFd), "logpipe"))
|
||||
} else if config.LogFilePath != "" {
|
||||
f, err := os.OpenFile(config.LogFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0644)
|
||||
f, err := os.OpenFile(config.LogFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
3
vendor/github.com/opencontainers/runc/libcontainer/network_linux.go
generated
vendored
3
vendor/github.com/opencontainers/runc/libcontainer/network_linux.go
generated
vendored
@@ -83,8 +83,7 @@ func readSysfsNetworkStats(ethInterface, statsFile string) (uint64, error) {
|
||||
}
|
||||
|
||||
// loopback is a network strategy that provides a basic loopback device
|
||||
type loopback struct {
|
||||
}
|
||||
type loopback struct{}
|
||||
|
||||
func (l *loopback) create(n *network, nspid int) error {
|
||||
return nil
|
||||
|
2
vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go
generated
vendored
@@ -35,7 +35,7 @@ func registerMemoryEvent(cgDir string, evName string, arg string) (<-chan struct
|
||||
|
||||
eventControlPath := filepath.Join(cgDir, "cgroup.event_control")
|
||||
data := fmt.Sprintf("%d %d %s", eventfd.Fd(), evFile.Fd(), arg)
|
||||
if err := ioutil.WriteFile(eventControlPath, []byte(data), 0700); err != nil {
|
||||
if err := ioutil.WriteFile(eventControlPath, []byte(data), 0o700); err != nil {
|
||||
eventfd.Close()
|
||||
evFile.Close()
|
||||
return nil, err
|
||||
|
30
vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
generated
vendored
30
vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
generated
vendored
@@ -188,7 +188,7 @@ func (p *setnsProcess) start() (retErr error) {
|
||||
}
|
||||
// Must be done after Shutdown so the child will exit and we can wait for it.
|
||||
if ierr != nil {
|
||||
p.wait()
|
||||
_, _ = p.wait()
|
||||
return ierr
|
||||
}
|
||||
return nil
|
||||
@@ -201,16 +201,16 @@ func (p *setnsProcess) start() (retErr error) {
|
||||
func (p *setnsProcess) execSetns() error {
|
||||
status, err := p.cmd.Process.Wait()
|
||||
if err != nil {
|
||||
p.cmd.Wait()
|
||||
_ = p.cmd.Wait()
|
||||
return newSystemErrorWithCause(err, "waiting on setns process to finish")
|
||||
}
|
||||
if !status.Success() {
|
||||
p.cmd.Wait()
|
||||
_ = p.cmd.Wait()
|
||||
return newSystemError(&exec.ExitError{ProcessState: status})
|
||||
}
|
||||
var pid *pid
|
||||
if err := json.NewDecoder(p.messageSockPair.parent).Decode(&pid); err != nil {
|
||||
p.cmd.Wait()
|
||||
_ = p.cmd.Wait()
|
||||
return newSystemErrorWithCause(err, "reading pid from init pipe")
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ func (p *initProcess) externalDescriptors() []string {
|
||||
func (p *initProcess) getChildPid() (int, error) {
|
||||
var pid pid
|
||||
if err := json.NewDecoder(p.messageSockPair.parent).Decode(&pid); err != nil {
|
||||
p.cmd.Wait()
|
||||
_ = p.cmd.Wait()
|
||||
return -1, err
|
||||
}
|
||||
|
||||
@@ -309,11 +309,11 @@ func (p *initProcess) getChildPid() (int, error) {
|
||||
func (p *initProcess) waitForChildExit(childPid int) error {
|
||||
status, err := p.cmd.Process.Wait()
|
||||
if err != nil {
|
||||
p.cmd.Wait()
|
||||
_ = p.cmd.Wait()
|
||||
return err
|
||||
}
|
||||
if !status.Success() {
|
||||
p.cmd.Wait()
|
||||
_ = p.cmd.Wait()
|
||||
return &exec.ExitError{ProcessState: status}
|
||||
}
|
||||
|
||||
@@ -327,12 +327,12 @@ func (p *initProcess) waitForChildExit(childPid int) error {
|
||||
}
|
||||
|
||||
func (p *initProcess) start() (retErr error) {
|
||||
defer p.messageSockPair.parent.Close()
|
||||
defer p.messageSockPair.parent.Close() //nolint: errcheck
|
||||
err := p.cmd.Start()
|
||||
p.process.ops = p
|
||||
// close the write-side of the pipes (controlled by child)
|
||||
p.messageSockPair.child.Close()
|
||||
p.logFilePair.child.Close()
|
||||
_ = p.messageSockPair.child.Close()
|
||||
_ = p.logFilePair.child.Close()
|
||||
if err != nil {
|
||||
p.process.ops = nil
|
||||
return newSystemErrorWithCause(err, "starting init process command")
|
||||
@@ -371,9 +371,9 @@ func (p *initProcess) start() (retErr error) {
|
||||
logrus.WithError(err).Warn("unable to terminate initProcess")
|
||||
}
|
||||
|
||||
p.manager.Destroy()
|
||||
_ = p.manager.Destroy()
|
||||
if p.intelRdtManager != nil {
|
||||
p.intelRdtManager.Destroy()
|
||||
_ = p.intelRdtManager.Destroy()
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -553,7 +553,7 @@ func (p *initProcess) start() (retErr error) {
|
||||
|
||||
// Must be done after Shutdown so the child will exit and we can wait for it.
|
||||
if ierr != nil {
|
||||
p.wait()
|
||||
_, _ = p.wait()
|
||||
return ierr
|
||||
}
|
||||
return nil
|
||||
@@ -563,7 +563,7 @@ func (p *initProcess) wait() (*os.ProcessState, error) {
|
||||
err := p.cmd.Wait()
|
||||
// we should kill all processes in cgroup when init is died if we use host PID namespace
|
||||
if p.sharePidns {
|
||||
signalAllProcesses(p.manager, unix.SIGKILL)
|
||||
_ = signalAllProcesses(p.manager, unix.SIGKILL)
|
||||
}
|
||||
return p.cmd.ProcessState, err
|
||||
}
|
||||
@@ -668,7 +668,7 @@ func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
for _, fd := range fds {
|
||||
unix.Close(int(fd))
|
||||
_ = unix.Close(int(fd))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
4
vendor/github.com/opencontainers/runc/libcontainer/restored_process.go
generated
vendored
4
vendor/github.com/opencontainers/runc/libcontainer/restored_process.go
generated
vendored
@@ -11,9 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func newRestoredProcess(cmd *exec.Cmd, fds []string) (*restoredProcess, error) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
var err error
|
||||
pid := cmd.Process.Pid
|
||||
stat, err := system.Stat(pid)
|
||||
if err != nil {
|
||||
|
47
vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
generated
vendored
47
vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
generated
vendored
@@ -143,7 +143,7 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
|
||||
if cwd := iConfig.Cwd; cwd != "" {
|
||||
// Note that spec.Process.Cwd can contain unclean value like "../../../../foo/bar...".
|
||||
// However, we are safe to call MkDirAll directly because we are in the jail here.
|
||||
if err := os.MkdirAll(cwd, 0755); err != nil {
|
||||
if err := os.MkdirAll(cwd, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -176,7 +176,7 @@ func finalizeRootfs(config *configs.Config) (err error) {
|
||||
if config.Umask != nil {
|
||||
unix.Umask(int(*config.Umask))
|
||||
} else {
|
||||
unix.Umask(0022)
|
||||
unix.Umask(0o022)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -196,9 +196,9 @@ func prepareTmp(topTmpDir string) (string, error) {
|
||||
return tmpdir, nil
|
||||
}
|
||||
|
||||
func cleanupTmp(tmpdir string) error {
|
||||
unix.Unmount(tmpdir, 0)
|
||||
return os.RemoveAll(tmpdir)
|
||||
func cleanupTmp(tmpdir string) {
|
||||
_ = unix.Unmount(tmpdir, 0)
|
||||
_ = os.RemoveAll(tmpdir)
|
||||
}
|
||||
|
||||
func mountCmd(cmd configs.Command) error {
|
||||
@@ -262,7 +262,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
|
||||
for _, b := range binds {
|
||||
if c.cgroupns {
|
||||
subsystemPath := filepath.Join(c.root, b.Destination)
|
||||
if err := os.MkdirAll(subsystemPath, 0755); err != nil {
|
||||
if err := os.MkdirAll(subsystemPath, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := utils.WithProcfd(c.root, b.Destination, func(procfd string) error {
|
||||
@@ -306,7 +306,7 @@ func mountCgroupV2(m *configs.Mount, c *mountConfig) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(dest, 0755); err != nil {
|
||||
if err := os.MkdirAll(dest, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
return utils.WithProcfd(c.root, m.Destination, func(procfd string) error {
|
||||
@@ -398,13 +398,13 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
|
||||
} else if fi.Mode()&os.ModeDir == 0 {
|
||||
return fmt.Errorf("filesystem %q must be mounted on ordinary directory", m.Device)
|
||||
}
|
||||
if err := os.MkdirAll(dest, 0755); err != nil {
|
||||
if err := os.MkdirAll(dest, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
// Selinux kernels do not support labeling of /proc or /sys
|
||||
return mountPropagate(m, rootfs, "")
|
||||
case "mqueue":
|
||||
if err := os.MkdirAll(dest, 0755); err != nil {
|
||||
if err := os.MkdirAll(dest, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := mountPropagate(m, rootfs, ""); err != nil {
|
||||
@@ -414,7 +414,7 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
|
||||
case "tmpfs":
|
||||
stat, err := os.Stat(dest)
|
||||
if err != nil {
|
||||
if err := os.MkdirAll(dest, 0755); err != nil {
|
||||
if err := os.MkdirAll(dest, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -473,7 +473,7 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
|
||||
if err := checkProcMount(rootfs, dest, m.Source); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(dest, 0755); err != nil {
|
||||
if err := os.MkdirAll(dest, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
return mountPropagate(m, rootfs, mountLabel)
|
||||
@@ -582,7 +582,7 @@ func isProc(path string) (bool, error) {
|
||||
}
|
||||
|
||||
func setupDevSymlinks(rootfs string) error {
|
||||
var links = [][2]string{
|
||||
links := [][2]string{
|
||||
{"/proc/self/fd", "/dev/fd"},
|
||||
{"/proc/self/fd/0", "/dev/stdin"},
|
||||
{"/proc/self/fd/1", "/dev/stdout"},
|
||||
@@ -615,7 +615,7 @@ func reOpenDevNull() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to open /dev/null - %s", err)
|
||||
}
|
||||
defer file.Close()
|
||||
defer file.Close() //nolint: errcheck
|
||||
if err := unix.Fstat(int(file.Fd()), &devNullStat); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -636,7 +636,7 @@ func reOpenDevNull() error {
|
||||
// Create the device nodes in the container.
|
||||
func createDevices(config *configs.Config) error {
|
||||
useBindMount := userns.RunningInUserNS() || config.Namespaces.Contains(configs.NEWUSER)
|
||||
oldMask := unix.Umask(0000)
|
||||
oldMask := unix.Umask(0o000)
|
||||
for _, node := range config.Devices {
|
||||
|
||||
// The /dev/ptmx device is setup by setupPtmx()
|
||||
@@ -661,7 +661,7 @@ func bindMountDeviceNode(rootfs, dest string, node *devices.Device) error {
|
||||
return err
|
||||
}
|
||||
if f != nil {
|
||||
f.Close()
|
||||
_ = f.Close()
|
||||
}
|
||||
return utils.WithProcfd(rootfs, dest, func(procfd string) error {
|
||||
return unix.Mount(node.Path, procfd, "bind", unix.MS_BIND, "")
|
||||
@@ -678,7 +678,7 @@ func createDeviceNode(rootfs string, node *devices.Device, bind bool) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if bind {
|
||||
@@ -799,7 +799,6 @@ func setReadonly() error {
|
||||
}
|
||||
flags |= uintptr(s.Flags)
|
||||
return unix.Mount("", "/", "", flags, "")
|
||||
|
||||
}
|
||||
|
||||
func setupPtmx(config *configs.Config) error {
|
||||
@@ -826,13 +825,13 @@ func pivotRoot(rootfs string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer unix.Close(oldroot)
|
||||
defer unix.Close(oldroot) //nolint: errcheck
|
||||
|
||||
newroot, err := unix.Open(rootfs, unix.O_DIRECTORY|unix.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer unix.Close(newroot)
|
||||
defer unix.Close(newroot) //nolint: errcheck
|
||||
|
||||
// Change to the new root so that the pivot_root actually acts on it.
|
||||
if err := unix.Fchdir(newroot); err != nil {
|
||||
@@ -947,16 +946,16 @@ func createIfNotExists(path string, isDir bool) error {
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
if isDir {
|
||||
return os.MkdirAll(path, 0755)
|
||||
return os.MkdirAll(path, 0o755)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.OpenFile(path, os.O_CREATE, 0755)
|
||||
f, err := os.OpenFile(path, os.O_CREATE, 0o755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
_ = f.Close()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -1031,7 +1030,7 @@ func maskPath(path string, mountLabel string) error {
|
||||
// For e.g. net.ipv4.ip_forward translated to /proc/sys/net/ipv4/ip_forward.
|
||||
func writeSystemProperty(key, value string) error {
|
||||
keyPath := strings.Replace(key, ".", "/", -1)
|
||||
return ioutil.WriteFile(path.Join("/proc/sys", keyPath), []byte(value), 0644)
|
||||
return ioutil.WriteFile(path.Join("/proc/sys", keyPath), []byte(value), 0o644)
|
||||
}
|
||||
|
||||
func remount(m *configs.Mount, rootfs string) error {
|
||||
|
33
vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go
generated
vendored
33
vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go
generated
vendored
@@ -324,7 +324,8 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpGreaterThan,
|
||||
Val: uint32(sysno),
|
||||
SkipTrue: uint8(baseJumpEnosys + 1)},
|
||||
SkipTrue: uint8(baseJumpEnosys + 1),
|
||||
},
|
||||
// ja [baseJumpFilter]
|
||||
bpf.Jump{Skip: baseJumpFilter},
|
||||
}
|
||||
@@ -353,16 +354,20 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
case libseccomp.ArchAMD64:
|
||||
sectionTail = append([]bpf.Instruction{
|
||||
// jset (1<<30),[len(tail)-1]
|
||||
bpf.JumpIf{Cond: bpf.JumpBitsSet,
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpBitsSet,
|
||||
Val: 1 << 30,
|
||||
SkipTrue: uint8(len(sectionTail) - 1)},
|
||||
SkipTrue: uint8(len(sectionTail) - 1),
|
||||
},
|
||||
}, sectionTail...)
|
||||
case libseccomp.ArchX32:
|
||||
sectionTail = append([]bpf.Instruction{
|
||||
// jset (1<<30),0,[len(tail)-1]
|
||||
bpf.JumpIf{Cond: bpf.JumpBitsNotSet,
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpBitsNotSet,
|
||||
Val: 1 << 30,
|
||||
SkipTrue: uint8(len(sectionTail) - 1)},
|
||||
SkipTrue: uint8(len(sectionTail) - 1),
|
||||
},
|
||||
}, sectionTail...)
|
||||
default:
|
||||
return nil, errors.Errorf("unknown amd64 native architecture %#x", scmpArch)
|
||||
@@ -402,12 +407,14 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpGreaterThan,
|
||||
Val: uint32(x86sysno),
|
||||
SkipTrue: uint8(baseJumpEnosys + 2), SkipFalse: 1},
|
||||
SkipTrue: uint8(baseJumpEnosys + 2), SkipFalse: 1,
|
||||
},
|
||||
// jgt [x32 syscall],[baseJumpEnosys]
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpGreaterThan,
|
||||
Val: uint32(x32sysno),
|
||||
SkipTrue: uint8(baseJumpEnosys + 1)},
|
||||
SkipTrue: uint8(baseJumpEnosys + 1),
|
||||
},
|
||||
// ja [baseJumpFilter]
|
||||
bpf.Jump{Skip: baseJumpFilter},
|
||||
}...)
|
||||
@@ -426,12 +433,14 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpGreaterThan,
|
||||
Val: uint32(x86sysno),
|
||||
SkipTrue: 1, SkipFalse: 2},
|
||||
SkipTrue: 1, SkipFalse: 2,
|
||||
},
|
||||
// jle [x32 syscall],[baseJumpEnosys]
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpLessOrEqual,
|
||||
Val: uint32(x32sysno),
|
||||
SkipTrue: 1},
|
||||
SkipTrue: 1,
|
||||
},
|
||||
// ja [baseJumpEnosys+1]
|
||||
bpf.Jump{Skip: baseJumpEnosys + 1},
|
||||
// ja [baseJumpFilter]
|
||||
@@ -478,7 +487,8 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: uint32(nativeArch),
|
||||
SkipTrue: uint8(jump)},
|
||||
SkipTrue: uint8(jump),
|
||||
},
|
||||
}, programTail...)
|
||||
} else {
|
||||
programTail = append([]bpf.Instruction{
|
||||
@@ -486,7 +496,8 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpNotEqual,
|
||||
Val: uint32(nativeArch),
|
||||
SkipTrue: 1},
|
||||
SkipTrue: 1,
|
||||
},
|
||||
// ja [jump]
|
||||
bpf.Jump{Skip: jump},
|
||||
}, programTail...)
|
||||
|
4
vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go
generated
vendored
4
vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go
generated
vendored
@@ -37,7 +37,7 @@ func (l *linuxSetnsInit) Init() error {
|
||||
if err := selinux.SetKeyLabel(l.config.ProcessLabel); err != nil {
|
||||
return err
|
||||
}
|
||||
defer selinux.SetKeyLabel("")
|
||||
defer selinux.SetKeyLabel("") //nolint: errcheck
|
||||
// Do not inherit the parent's session keyring.
|
||||
if _, err := keys.JoinSessionKeyring(l.getSessionRingName()); err != nil {
|
||||
// Same justification as in standart_init_linux.go as to why we
|
||||
@@ -65,7 +65,7 @@ func (l *linuxSetnsInit) Init() error {
|
||||
if err := selinux.SetExecLabel(l.config.ProcessLabel); err != nil {
|
||||
return err
|
||||
}
|
||||
defer selinux.SetExecLabel("")
|
||||
defer selinux.SetExecLabel("") //nolint: errcheck
|
||||
// Without NoNewPrivileges seccomp is a privileged operation, so we need to
|
||||
// do this before dropping capabilities; otherwise do it as late as possible
|
||||
// just before execve so as few syscalls take place after it as possible.
|
||||
|
4
vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go
generated
vendored
4
vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go
generated
vendored
@@ -13,8 +13,8 @@ func Capture(userSkip int) Stacktrace {
|
||||
)
|
||||
for i := skip; ; i++ {
|
||||
pc, file, line, ok := runtime.Caller(i)
|
||||
//detect if caller is repeated to avoid loop, gccgo
|
||||
//currently runs into a loop without this check
|
||||
// detect if caller is repeated to avoid loop, gccgo
|
||||
// currently runs into a loop without this check
|
||||
if !ok || pc == prevPc {
|
||||
break
|
||||
}
|
||||
|
8
vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
generated
vendored
8
vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
generated
vendored
@@ -52,7 +52,7 @@ func (l *linuxStandardInit) Init() error {
|
||||
if err := selinux.SetKeyLabel(l.config.ProcessLabel); err != nil {
|
||||
return err
|
||||
}
|
||||
defer selinux.SetKeyLabel("")
|
||||
defer selinux.SetKeyLabel("") //nolint: errcheck
|
||||
ringname, keepperms, newperms := l.getSessionRingParams()
|
||||
|
||||
// Do not inherit the parent's session keyring.
|
||||
@@ -151,7 +151,7 @@ func (l *linuxStandardInit) Init() error {
|
||||
if err := selinux.SetExecLabel(l.config.ProcessLabel); err != nil {
|
||||
return errors.Wrap(err, "set process label")
|
||||
}
|
||||
defer selinux.SetExecLabel("")
|
||||
defer selinux.SetExecLabel("") //nolint: errcheck
|
||||
// Without NoNewPrivileges seccomp is a privileged operation, so we need to
|
||||
// do this before dropping capabilities; otherwise do it as late as possible
|
||||
// just before execve so as few syscalls take place after it as possible.
|
||||
@@ -183,7 +183,7 @@ func (l *linuxStandardInit) Init() error {
|
||||
}
|
||||
// Close the pipe to signal that we have completed our init.
|
||||
logrus.Debugf("init: closing the pipe to signal completion")
|
||||
l.pipe.Close()
|
||||
_ = l.pipe.Close()
|
||||
|
||||
// Close the log pipe fd so the parent's ForwardLogs can exit.
|
||||
if err := unix.Close(l.logFd); err != nil {
|
||||
@@ -207,7 +207,7 @@ func (l *linuxStandardInit) Init() error {
|
||||
// N.B. the core issue itself (passing dirfds to the host filesystem) has
|
||||
// since been resolved.
|
||||
// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
|
||||
unix.Close(l.fifoFd)
|
||||
_ = unix.Close(l.fifoFd)
|
||||
// Set seccomp as close to execve as possible, so as few syscalls take
|
||||
// place afterward (reducing the amount of syscalls that users need to
|
||||
// enable in their seccomp profiles).
|
||||
|
2
vendor/github.com/opencontainers/runc/libcontainer/state_linux.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/state_linux.go
generated
vendored
@@ -157,7 +157,7 @@ func (i *createdState) transition(s containerState) error {
|
||||
}
|
||||
|
||||
func (i *createdState) destroy() error {
|
||||
i.c.initProcess.signal(unix.SIGKILL)
|
||||
_ = i.c.initProcess.signal(unix.SIGKILL)
|
||||
return destroy(i.c)
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/opencontainers/runc/libcontainer/system/proc.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/system/proc.go
generated
vendored
@@ -96,7 +96,7 @@ func parseStat(data string) (stat Stat_t, err error) {
|
||||
// one (PID) and two (Name) in the paren-split.
|
||||
parts = strings.Split(data[i+2:], " ")
|
||||
var state int
|
||||
fmt.Sscanf(parts[3-3], "%c", &state)
|
||||
fmt.Sscanf(parts[3-3], "%c", &state) //nolint:staticcheck // "3-3" is more readable in this context.
|
||||
stat.State = State(state)
|
||||
fmt.Sscanf(parts[22-3], "%d", &stat.StartTime)
|
||||
return stat, nil
|
||||
|
5
vendor/github.com/opencontainers/runc/libcontainer/system/userns_deprecated.go
generated
vendored
5
vendor/github.com/opencontainers/runc/libcontainer/system/userns_deprecated.go
generated
vendored
@@ -1,5 +0,0 @@
|
||||
package system
|
||||
|
||||
import "github.com/opencontainers/runc/libcontainer/userns"
|
||||
|
||||
var RunningInUserNS = userns.RunningInUserNS
|
24
vendor/github.com/opencontainers/runc/libcontainer/user/user.go
generated
vendored
24
vendor/github.com/opencontainers/runc/libcontainer/user/user.go
generated
vendored
@@ -11,19 +11,17 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
minId = 0
|
||||
maxId = 1<<31 - 1 //for 32-bit systems compatibility
|
||||
minID = 0
|
||||
maxID = 1<<31 - 1 // for 32-bit systems compatibility
|
||||
)
|
||||
|
||||
var (
|
||||
// The current operating system does not provide the required data for user lookups.
|
||||
ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data")
|
||||
|
||||
// No matching entries found in file.
|
||||
// ErrNoPasswdEntries is returned if no matching entries were found in /etc/group.
|
||||
ErrNoPasswdEntries = errors.New("no matching entries in passwd file")
|
||||
ErrNoGroupEntries = errors.New("no matching entries in group file")
|
||||
|
||||
ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minId, maxId)
|
||||
// ErrNoGroupEntries is returned if no matching entries were found in /etc/passwd.
|
||||
ErrNoGroupEntries = errors.New("no matching entries in group file")
|
||||
// ErrRange is returned if a UID or GID is outside of the valid range.
|
||||
ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minID, maxID)
|
||||
)
|
||||
|
||||
type User struct {
|
||||
@@ -328,7 +326,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
|
||||
user.Uid = uidArg
|
||||
|
||||
// Must be inside valid uid range.
|
||||
if user.Uid < minId || user.Uid > maxId {
|
||||
if user.Uid < minID || user.Uid > maxID {
|
||||
return nil, ErrRange
|
||||
}
|
||||
|
||||
@@ -377,7 +375,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
|
||||
user.Gid = gidArg
|
||||
|
||||
// Must be inside valid gid range.
|
||||
if user.Gid < minId || user.Gid > maxId {
|
||||
if user.Gid < minID || user.Gid > maxID {
|
||||
return nil, ErrRange
|
||||
}
|
||||
|
||||
@@ -401,7 +399,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
|
||||
// or the given group data is nil, the id will be returned as-is
|
||||
// provided it is in the legal range.
|
||||
func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) {
|
||||
var groups = []Group{}
|
||||
groups := []Group{}
|
||||
if group != nil {
|
||||
var err error
|
||||
groups, err = ParseGroupFilter(group, func(g Group) bool {
|
||||
@@ -439,7 +437,7 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err
|
||||
return nil, fmt.Errorf("Unable to find group %s", ag)
|
||||
}
|
||||
// Ensure gid is inside gid range.
|
||||
if gid < minId || gid > maxId {
|
||||
if gid < minID || gid > maxID {
|
||||
return nil, ErrRange
|
||||
}
|
||||
gidMap[int(gid)] = struct{}{}
|
||||
|
Reference in New Issue
Block a user