diff --git a/libpod/container_api.go b/libpod/container_api.go index 14d0b7e634..35fed93e64 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -521,21 +521,11 @@ func (c *Container) WaitForExit(ctx context.Context, pollInterval time.Duration) var conmonTimer time.Timer conmonTimerSet := false - conmonPidFd := -1 - conmonPidFdTriggered := false - - if c.state.ConmonPID != 0 { - // Track lifetime of conmon precisely using pidfd_open + poll. - // There are many cases for this to fail, for instance conmon is dead - // or pidfd_open is not supported (pre linux 5.3), so fall back to the - // traditional loop with poll + sleep - if fd, err := unix.PidfdOpen(c.state.ConmonPID, 0); err == nil { - conmonPidFd = fd - defer unix.Close(conmonPidFd) - } else if err != unix.ENOSYS && err != unix.ESRCH { - logrus.Debugf("PidfdOpen(%d) failed: %v", c.state.ConmonPID, err) - } + conmonPidFd := c.getConmonPidFd() + if conmonPidFd != -1 { + defer unix.Close(conmonPidFd) } + conmonPidFdTriggered := false getExitCode := func() (bool, int32, error) { containerRemoved := false diff --git a/libpod/container_internal_freebsd.go b/libpod/container_internal_freebsd.go index 67f87a98d3..468f5725c7 100644 --- a/libpod/container_internal_freebsd.go +++ b/libpod/container_internal_freebsd.go @@ -272,3 +272,10 @@ func setVolumeAtime(mountPoint string, st os.FileInfo) error { func (c *Container) makePlatformBindMounts() error { return nil } + +func (c *Container) getConmonPidFd() int { + // Note: kqueue(2) could be used here but that would require + // factoring out the call to unix.PollFd from WaitForExit so + // keeping things simple for now. + return -1 +} diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index ef86497761..7161383a08 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -665,3 +665,18 @@ func (c *Container) makePlatformBindMounts() error { } return nil } + +func (c *Container) getConmonPidFd() int { + if c.state.ConmonPID != 0 { + // Track lifetime of conmon precisely using pidfd_open + poll. + // There are many cases for this to fail, for instance conmon is dead + // or pidfd_open is not supported (pre linux 5.3), so fall back to the + // traditional loop with poll + sleep + if fd, err := unix.PidfdOpen(c.state.ConmonPID, 0); err == nil { + return fd + } else if err != unix.ENOSYS && err != unix.ESRCH { + logrus.Debugf("PidfdOpen(%d) failed: %v", c.state.ConmonPID, err) + } + } + return -1 +}