Merge pull request #2291 from kolyshkin/errors-unwrap-v2
Use errors.As() and errors.Is() to unwrap errors
This commit is contained in:
commit
e4363b0387
|
@ -8,6 +8,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
|
@ -110,14 +111,18 @@ func isIgnorableError(rootless bool, err error) bool {
|
||||||
if !rootless {
|
if !rootless {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
// TODO: rm errors.Cause once we switch to %w everywhere
|
||||||
err = errors.Cause(err)
|
err = errors.Cause(err)
|
||||||
// Is it an ordinary EPERM?
|
// Is it an ordinary EPERM?
|
||||||
if os.IsPermission(err) {
|
if errors.Is(err, os.ErrPermission) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Handle some specific syscall errors.
|
// Handle some specific syscall errors.
|
||||||
errno := errors.Unwrap(err)
|
var errno syscall.Errno
|
||||||
return errno == unix.EROFS || errno == unix.EPERM || errno == unix.EACCES
|
if errors.As(err, &errno) {
|
||||||
|
return errno == unix.EROFS || errno == unix.EPERM || errno == unix.EACCES
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) getSubsystems() subsystemSet {
|
func (m *Manager) getSubsystems() subsystemSet {
|
||||||
|
|
|
@ -47,7 +47,7 @@ func setKernelMemory(path string, kernelMemoryLimit int64) error {
|
||||||
// The EBUSY signal is returned on attempts to write to the
|
// The EBUSY signal is returned on attempts to write to the
|
||||||
// memory.kmem.limit_in_bytes file if the cgroup has children or
|
// memory.kmem.limit_in_bytes file if the cgroup has children or
|
||||||
// once tasks have been attached to the cgroup
|
// once tasks have been attached to the cgroup
|
||||||
if errors.Unwrap(err) == unix.EBUSY {
|
if errors.Is(err, unix.EBUSY) {
|
||||||
return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit)
|
return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to write %v to %v: %v", kernelMemoryLimit, cgroupKernelMemoryLimit, err)
|
return fmt.Errorf("failed to write %v to %v: %v", kernelMemoryLimit, cgroupKernelMemoryLimit, err)
|
||||||
|
|
|
@ -28,7 +28,7 @@ func statPidsWithoutController(dirPath string, stats *cgroups.Stats) error {
|
||||||
// if the controller is not enabled, let's read PIDS from cgroups.procs
|
// if the controller is not enabled, let's read PIDS from cgroups.procs
|
||||||
// (or threads if cgroup.threads is enabled)
|
// (or threads if cgroup.threads is enabled)
|
||||||
contents, err := ioutil.ReadFile(filepath.Join(dirPath, "cgroup.procs"))
|
contents, err := ioutil.ReadFile(filepath.Join(dirPath, "cgroup.procs"))
|
||||||
if err != nil && errors.Unwrap(err) == unix.ENOTSUP {
|
if errors.Is(err, unix.ENOTSUP) {
|
||||||
contents, err = ioutil.ReadFile(filepath.Join(dirPath, "cgroup.threads"))
|
contents, err = ioutil.ReadFile(filepath.Join(dirPath, "cgroup.threads"))
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -41,10 +41,20 @@ func ReadFile(dir, file string) (string, error) {
|
||||||
func retryingWriteFile(filename string, data []byte, perm os.FileMode) error {
|
func retryingWriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
for {
|
for {
|
||||||
err := ioutil.WriteFile(filename, data, perm)
|
err := ioutil.WriteFile(filename, data, perm)
|
||||||
if errors.Unwrap(err) == syscall.EINTR {
|
if isInterruptedWriteFile(err) {
|
||||||
logrus.Infof("interrupted while writing %s to %s", string(data), filename)
|
logrus.Infof("interrupted while writing %s to %s", string(data), filename)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isInterruptedWriteFile(err error) bool {
|
||||||
|
if patherr, ok := err.(*os.PathError); ok {
|
||||||
|
errno, ok2 := patherr.Err.(syscall.Errno)
|
||||||
|
if ok2 && errno == syscall.EINTR {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -576,7 +576,7 @@ func WriteCgroupProc(dir string, pid int) error {
|
||||||
|
|
||||||
// EINVAL might mean that the task being added to cgroup.procs is in state
|
// EINVAL might mean that the task being added to cgroup.procs is in state
|
||||||
// TASK_NEW. We should attempt to do so again.
|
// TASK_NEW. We should attempt to do so again.
|
||||||
if errors.Unwrap(err) == unix.EINVAL {
|
if errors.Is(err, unix.EINVAL) {
|
||||||
time.Sleep(30 * time.Millisecond)
|
time.Sleep(30 * time.Millisecond)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -1855,7 +1855,7 @@ func (c *linuxContainer) isPaused() (bool, error) {
|
||||||
data, err := ioutil.ReadFile(filepath.Join(fcg, filename))
|
data, err := ioutil.ReadFile(filepath.Join(fcg, filename))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If freezer cgroup is not mounted, the container would just be not paused.
|
// If freezer cgroup is not mounted, the container would just be not paused.
|
||||||
if os.IsNotExist(err) || errors.Unwrap(err) == syscall.ENODEV {
|
if os.IsNotExist(err) || errors.Is(err, syscall.ENODEV) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
return false, newSystemErrorWithCause(err, "checking if container is paused")
|
return false, newSystemErrorWithCause(err, "checking if container is paused")
|
||||||
|
|
Loading…
Reference in New Issue