diff --git a/cmd/containerd-shim-runhcs-v1/task.go b/cmd/containerd-shim-runhcs-v1/task.go index 34be8d668e..1b8ffbb56c 100644 --- a/cmd/containerd-shim-runhcs-v1/task.go +++ b/cmd/containerd-shim-runhcs-v1/task.go @@ -110,5 +110,6 @@ func isStatsNotFound(err error) bool { hcs.IsNotExist(err) || hcs.IsOperationInvalidState(err) || gcs.IsNotExist(err) || - hcs.IsAccessIsDenied(err) + hcs.IsAccessIsDenied(err) || + hcs.IsErrorInvalidHandle(err) } diff --git a/cmd/containerd-shim-runhcs-v1/task_hcs.go b/cmd/containerd-shim-runhcs-v1/task_hcs.go index 5af5443cfa..4a8fb82b90 100644 --- a/cmd/containerd-shim-runhcs-v1/task_hcs.go +++ b/cmd/containerd-shim-runhcs-v1/task_hcs.go @@ -920,9 +920,13 @@ func hcsPropertiesToWindowsStats(props *hcsschema.Properties) *stats.Statistics_ func (ht *hcsTask) Stats(ctx context.Context) (*stats.Statistics, error) { s := &stats.Statistics{} props, err := ht.c.PropertiesV2(ctx, hcsschema.PTStatistics) - if err != nil && !isStatsNotFound(err) { + if err != nil { + if isStatsNotFound(err) { + return nil, errors.Wrapf(errdefs.ErrNotFound, "failed to fetch stats: %s", err) + } return nil, err } + if props != nil { if ht.isWCOW { s.Container = hcsPropertiesToWindowsStats(props) diff --git a/internal/hcs/errors.go b/internal/hcs/errors.go index 08a6631451..e21354ffd6 100644 --- a/internal/hcs/errors.go +++ b/internal/hcs/errors.go @@ -81,6 +81,10 @@ var ( // ErrProcessAlreadyStopped is returned by hcs if the process we're trying to kill has already been stopped. ErrProcessAlreadyStopped = syscall.Errno(0x8037011f) + + // ErrInvalidHandle is an error that can be encountrered when querying the properties of a compute system when the handle to that + // compute system has already been closed. + ErrInvalidHandle = syscall.Errno(0x6) ) type ErrorEvent struct { @@ -252,6 +256,14 @@ func IsNotExist(err error) bool { err == ErrElementNotFound } +// IsErrorInvalidHandle checks whether the error is the result of an operation carried +// out on a handle that is invalid/closed. This error popped up while trying to query +// stats on a container in the process of being stopped. +func IsErrorInvalidHandle(err error) bool { + err = getInnerError(err) + return err == ErrInvalidHandle +} + // IsAlreadyClosed checks if an error is caused by the Container or Process having been // already closed by a call to the Close() method. func IsAlreadyClosed(err error) bool { diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go index 08a6631451..e21354ffd6 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go @@ -81,6 +81,10 @@ var ( // ErrProcessAlreadyStopped is returned by hcs if the process we're trying to kill has already been stopped. ErrProcessAlreadyStopped = syscall.Errno(0x8037011f) + + // ErrInvalidHandle is an error that can be encountrered when querying the properties of a compute system when the handle to that + // compute system has already been closed. + ErrInvalidHandle = syscall.Errno(0x6) ) type ErrorEvent struct { @@ -252,6 +256,14 @@ func IsNotExist(err error) bool { err == ErrElementNotFound } +// IsErrorInvalidHandle checks whether the error is the result of an operation carried +// out on a handle that is invalid/closed. This error popped up while trying to query +// stats on a container in the process of being stopped. +func IsErrorInvalidHandle(err error) bool { + err = getInnerError(err) + return err == ErrInvalidHandle +} + // IsAlreadyClosed checks if an error is caused by the Container or Process having been // already closed by a call to the Close() method. func IsAlreadyClosed(err error) bool {