move pkg/system: process to a separate package

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2022-10-15 15:10:25 +02:00
parent 0040fb93d6
commit 9d5e754caa
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
9 changed files with 85 additions and 39 deletions

View File

@ -15,8 +15,8 @@ import (
"github.com/docker/docker/errdefs"
"github.com/docker/docker/libnetwork"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/process"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/runconfig"
"github.com/moby/sys/mount"
"github.com/opencontainers/selinux/go-selinux/label"
@ -352,9 +352,9 @@ func killProcessDirectly(container *container.Container) error {
}
// In case there were some exceptions(e.g., state of zombie and D)
if system.IsProcessAlive(pid) {
if process.Alive(pid) {
// Since we can not kill a zombie pid, add zombie check here
isZombie, err := system.IsProcessZombie(pid)
isZombie, err := process.Zombie(pid)
if err != nil {
logrus.WithError(err).WithField("container", container.ID).Warn("Container state is invalid")
return err

View File

@ -14,6 +14,7 @@ import (
"github.com/containerd/containerd"
"github.com/containerd/containerd/services/server/config"
"github.com/containerd/containerd/sys"
"github.com/docker/docker/pkg/process"
"github.com/docker/docker/pkg/system"
"github.com/pelletier/go-toml"
"github.com/pkg/errors"
@ -145,7 +146,7 @@ func (r *remote) getContainerdPid() (int, error) {
if err != nil {
return -1, err
}
if system.IsProcessAlive(int(pid)) {
if process.Alive(int(pid)) {
return int(pid), nil
}
}
@ -238,7 +239,7 @@ func (r *remote) startContainerd() error {
err = os.WriteFile(r.pidFile, []byte(strconv.Itoa(r.daemonPid)), 0660)
if err != nil {
system.KillProcess(r.daemonPid)
process.Kill(r.daemonPid)
return errors.Wrap(err, "libcontainerd: failed to save daemon pid to disk")
}
@ -357,7 +358,7 @@ func (r *remote) monitorDaemon(ctx context.Context) {
r.logger.WithError(err).WithField("binary", binaryName).Debug("daemon is not responding")
transientFailureCount++
if transientFailureCount < maxConnectionRetryCount || system.IsProcessAlive(r.daemonPid) {
if transientFailureCount < maxConnectionRetryCount || process.Alive(r.daemonPid) {
delay = time.Duration(transientFailureCount) * 200 * time.Millisecond
continue
}
@ -365,7 +366,7 @@ func (r *remote) monitorDaemon(ctx context.Context) {
client = nil
}
if system.IsProcessAlive(r.daemonPid) {
if process.Alive(r.daemonPid) {
r.logger.WithField("pid", r.daemonPid).Info("killing and restarting containerd")
r.killDaemon()
}

View File

@ -7,7 +7,7 @@ import (
"time"
"github.com/containerd/containerd/defaults"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/pkg/process"
)
const (
@ -35,13 +35,13 @@ func (r *remote) stopDaemon() {
syscall.Kill(r.daemonPid, syscall.SIGTERM)
// Wait up to 15secs for it to stop
for i := time.Duration(0); i < shutdownTimeout; i += time.Second {
if !system.IsProcessAlive(r.daemonPid) {
if !process.Alive(r.daemonPid) {
break
}
time.Sleep(time.Second)
}
if system.IsProcessAlive(r.daemonPid) {
if process.Alive(r.daemonPid) {
r.logger.WithField("pid", r.daemonPid).Warn("daemon didn't stop within 15 secs, killing it")
syscall.Kill(r.daemonPid, syscall.SIGKILL)
}
@ -51,7 +51,7 @@ func (r *remote) killDaemon() {
// Try to get a stack trace
syscall.Kill(r.daemonPid, syscall.SIGUSR1)
<-time.After(100 * time.Millisecond)
system.KillProcess(r.daemonPid)
process.Kill(r.daemonPid)
}
func (r *remote) platformCleanup() {

View File

@ -3,7 +3,7 @@ package supervisor // import "github.com/docker/docker/libcontainerd/supervisor"
import (
"os"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/pkg/process"
)
const (
@ -40,7 +40,7 @@ func (r *remote) stopDaemon() {
}
func (r *remote) killDaemon() {
system.KillProcess(r.daemonPid)
process.Kill(r.daemonPid)
}
func (r *remote) platformCleanup() {

3
pkg/process/doc.go Normal file
View File

@ -0,0 +1,3 @@
// Package process provides a set of basic functions to manage individual
// processes.
package process

View File

@ -1,7 +1,7 @@
//go:build linux || freebsd || darwin
// +build linux freebsd darwin
package system // import "github.com/docker/docker/pkg/system"
package process
import (
"bytes"
@ -11,8 +11,8 @@ import (
"golang.org/x/sys/unix"
)
// IsProcessAlive returns true if process with a given pid is running.
func IsProcessAlive(pid int) bool {
// Alive returns true if process with a given pid is running.
func Alive(pid int) bool {
err := unix.Kill(pid, 0)
if err == nil || err == unix.EPERM {
return true
@ -21,14 +21,18 @@ func IsProcessAlive(pid int) bool {
return false
}
// KillProcess force-stops a process.
func KillProcess(pid int) {
unix.Kill(pid, unix.SIGKILL)
// Kill force-stops a process.
func Kill(pid int) error {
err := unix.Kill(pid, unix.SIGKILL)
if err != nil && err != unix.ESRCH {
return err
}
return nil
}
// IsProcessZombie return true if process has a state with "Z"
// Zombie return true if process has a state with "Z"
// http://man7.org/linux/man-pages/man5/proc.5.html
func IsProcessZombie(pid int) (bool, error) {
func Zombie(pid int) (bool, error) {
data, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid))
if err != nil {
if os.IsNotExist(err) {

View File

@ -0,0 +1,29 @@
package process
import "os"
// Alive returns true if process with a given pid is running.
func Alive(pid int) bool {
_, err := os.FindProcess(pid)
return err == nil
}
// Kill force-stops a process.
func Kill(pid int) error {
p, err := os.FindProcess(pid)
if err == nil {
err = p.Kill()
if err != nil && err != os.ErrProcessDone {
return err
}
}
return nil
}
// Zombie is not supported on Windows.
//
// TODO(thaJeztah): remove once we remove the stubs from pkg/system.
func Zombie(_ int) (bool, error) {
return false, nil
}

View File

@ -0,0 +1,27 @@
//go:build linux || freebsd || darwin || windows
// +build linux freebsd darwin windows
package system
import "github.com/docker/docker/pkg/process"
var (
// IsProcessAlive returns true if process with a given pid is running.
//
// Deprecated: use [process.Alive].
IsProcessAlive = process.Alive
// IsProcessZombie return true if process has a state with "Z"
//
// Deprecated: use [process.Zombie].
//
// TODO(thaJeztah): remove the Windows implementation in process once we remove this stub.
IsProcessZombie = process.Zombie
)
// KillProcess force-stops a process.
//
// Deprecated: use [process.Kill].
func KillProcess(pid int) {
_ = process.Kill(pid)
}

View File

@ -1,18 +0,0 @@
package system // import "github.com/docker/docker/pkg/system"
import "os"
// IsProcessAlive returns true if process with a given pid is running.
func IsProcessAlive(pid int) bool {
_, err := os.FindProcess(pid)
return err == nil
}
// KillProcess force-stops a process.
func KillProcess(pid int) {
p, err := os.FindProcess(pid)
if err == nil {
_ = p.Kill()
}
}