mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 14:13:58 +08:00
a75076b4a4
This removes libcontainer/cgroups packages and starts
using those from github.com/opencontainers/cgroups repo.
Mostly generated by:
git rm -f libcontainer/cgroups
find . -type f -name "*.go" -exec sed -i \
's|github.com/opencontainers/runc/libcontainer/cgroups|github.com/opencontainers/cgroups|g' \
{} +
go get github.com/opencontainers/cgroups@v0.0.1
make vendor
gofumpt -w .
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
84 lines
2.1 KiB
Go
84 lines
2.1 KiB
Go
package devices
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"reflect"
|
|
|
|
"github.com/moby/sys/userns"
|
|
"github.com/opencontainers/cgroups"
|
|
devices "github.com/opencontainers/cgroups/devices/config"
|
|
)
|
|
|
|
var testingSkipFinalCheck bool
|
|
|
|
func setV1(path string, r *cgroups.Resources) error {
|
|
if userns.RunningInUserNS() || r.SkipDevices {
|
|
return nil
|
|
}
|
|
// Generate two emulators, one for the current state of the cgroup and one
|
|
// for the requested state by the user.
|
|
current, err := loadEmulator(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
target, err := buildEmulator(r.Devices)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Compute the minimal set of transition rules needed to achieve the
|
|
// requested state.
|
|
transitionRules, err := current.Transition(target)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, rule := range transitionRules {
|
|
file := "devices.deny"
|
|
if rule.Allow {
|
|
file = "devices.allow"
|
|
}
|
|
if err := cgroups.WriteFile(path, file, rule.CgroupString()); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Final safety check -- ensure that the resulting state is what was
|
|
// requested. This is only really correct for white-lists, but for
|
|
// black-lists we can at least check that the cgroup is in the right mode.
|
|
//
|
|
// This safety-check is skipped for the unit tests because we cannot
|
|
// currently mock devices.list correctly.
|
|
if !testingSkipFinalCheck {
|
|
currentAfter, err := loadEmulator(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !target.IsBlacklist() && !reflect.DeepEqual(currentAfter, target) {
|
|
return errors.New("resulting devices cgroup doesn't precisely match target")
|
|
} else if target.IsBlacklist() != currentAfter.IsBlacklist() {
|
|
return errors.New("resulting devices cgroup doesn't match target mode")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func loadEmulator(path string) (*emulator, error) {
|
|
list, err := cgroups.ReadFile(path, "devices.list")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return emulatorFromList(bytes.NewBufferString(list))
|
|
}
|
|
|
|
func buildEmulator(rules []*devices.Rule) (*emulator, error) {
|
|
// This defaults to a white-list -- which is what we want!
|
|
emu := &emulator{}
|
|
for _, rule := range rules {
|
|
if err := emu.Apply(*rule); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return emu, nil
|
|
}
|