Merge pull request #29851 from amccabe/fix-pidhandle-esrch

Handle ESRCH from openByHandleAt in addition to ESTALE in NewPIDHandleFromString
This commit is contained in:
Jan Rodák 2026-09-30 17:35:17 +02:00 • committed by GitHub
commit 7eaeecd7f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 1 deletions

View file

@ -127,7 +127,9 @@ func NewPIDHandleFromString(pid int, pidData string) (PIDHandle, error) {
defer unix.Close(fd)
pidfd, err := openByHandleAt(fd, fh, unix.O_CLOEXEC)
if err != nil {
if errors.Is(err, unix.ESTALE) {
// The process is gone: ESTALE once it has been reaped, ESRCH
// while it is being reaped (pidfs_export_open).
if errors.Is(err, unix.ESTALE) || errors.Is(err, unix.ESRCH) {
h.normalHandle.pidData = noSuchProcessID
return &h, nil
}

View file

@ -7,6 +7,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sys/unix"
)
@ -151,6 +152,31 @@ func TestNewPIDHandleFromStringWrongPidData(t *testing.T) {
}
}
func TestNewPIDHandleFromStringProcessGone(t *testing.T) {
// openByHandleAt may report a process that no longer exists with either
// ESTALE or ESRCH; either must leave a handle to a dead process.
for _, openErr := range []error{unix.ESTALE, unix.ESRCH} {
t.Run(openErr.Error(), func(t *testing.T) {
original_openByHandleAt := openByHandleAt
t.Cleanup(func() {
openByHandleAt = original_openByHandleAt
})
openByHandleAt = func(_ int, _ unix.FileHandle, _ int) (fd int, err error) {
return -1, openErr
}
h, err := NewPIDHandleFromString(os.Getpid(), nameToHandlePrefix+"254 74657374")
require.NoError(t, err)
defer h.Close()
alive, err := h.IsAlive()
assert.NoError(t, err)
assert.False(t, alive)
assert.ErrorIs(t, h.Kill(unix.SIGTERM), unix.ESRCH)
})
}
}
func TestPIDHandlePidfdStartTime(t *testing.T) {
h, err := NewPIDHandleFromString(os.Getpid(), "start-time:1234567890")
assert.NoError(t, err)