mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-12 09:46:25 +08:00
bc9a7bda58
errors.Wrap(err, "some error") returns nil if err is nil, so it's slightly clearer to just return early than to set the error to nil and call errors.Wrap(). This is also somewhat defensive in case we decide to replace `errors.Wrap()` for golang's native `%w` wrapping. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
// +build linux
|
|
|
|
package fs2
|
|
|
|
import (
|
|
stdErrors "errors"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
|
"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:
|
|
return nil
|
|
case configs.Frozen:
|
|
stateStr = "1"
|
|
case configs.Thawed:
|
|
stateStr = "0"
|
|
default:
|
|
return errors.Errorf("invalid freezer state %q requested", state)
|
|
}
|
|
|
|
if err := fscommon.WriteFile(dirPath, "cgroup.freeze", stateStr); err != nil {
|
|
return err
|
|
}
|
|
// Confirm that the cgroup did actually change states.
|
|
if actualState, err := getFreezer(dirPath); 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)
|
|
}
|
|
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")
|
|
if err != nil {
|
|
// If the kernel is too old, then we just treat the freezer as being in
|
|
// an "undefined" state.
|
|
if os.IsNotExist(err) || stdErrors.Is(err, unix.ENODEV) {
|
|
err = nil
|
|
}
|
|
return configs.Undefined, err
|
|
}
|
|
switch strings.TrimSpace(state) {
|
|
case "0":
|
|
return configs.Thawed, nil
|
|
case "1":
|
|
return configs.Frozen, nil
|
|
default:
|
|
return configs.Undefined, errors.Errorf(`unknown "cgroup.freeze" state: %q`, state)
|
|
}
|
|
}
|