Skip to content

Commit

Permalink
add D status check for container when killing it
Browse files Browse the repository at this point in the history
Signed-off-by: ningmingxiao <[email protected]>
  • Loading branch information
ningmingxiao committed Aug 17, 2023
1 parent a978888 commit 678a7b0
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
18 changes: 14 additions & 4 deletions daemon/container_operations_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,16 +351,26 @@ func killProcessDirectly(container *container.Container) error {
return err
}

// In case there were some exceptions(e.g., state of zombie and D)
if process.Alive(pid) {
// Since we can not kill a zombie pid, add zombie check here
isZombie, err := process.Zombie(pid)
status, err := process.Status(pid)
if err != nil {
logrus.WithError(err).WithField("container", container.ID).Warn("Container state is invalid")
return err
}
if isZombie {
// Since we can not kill a zombie and D status pid, add check here
switch status {
case "D":
return errdefs.System(errors.Errorf("container %s PID %d is uninterruptible and can not be killed", stringid.TruncateID(container.ID), pid))
case "Z":
return errdefs.System(errors.Errorf("container %s PID %d is zombie and can not be killed. Use the --init option when creating containers to run an init inside the container that forwards signals and reaps processes", stringid.TruncateID(container.ID), pid))
case "S":
return errdefs.System(errors.Errorf("container %s PID %d is %s and can not be killed", stringid.TruncateID(container.ID), pid, status))
case "T", "X", "x":
case "":
return errdefs.System(errors.Errorf("container %s PID %d status is nil", stringid.TruncateID(container.ID), pid))
default:
// If process can't be killed and status is not D or Z print some warning log.It is almost impossible to happen.
logrus.Warnf("container %s PID %d status is \"%s\"", container.ID, pid, status)
}
}
return nil
Expand Down
23 changes: 17 additions & 6 deletions pkg/process/process_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,29 @@ func Kill(pid int) error {
//
// [PROC(5)]: https://man7.org/linux/man-pages/man5/proc.5.html
func Zombie(pid int) (bool, error) {
status, err := Status(pid)
return status == "Z", err
}

// Status returns the status of the given process. It only considers positive
// PIDs; 0 (all processes in the current process group), -1 (all processes with
// a PID larger than 1), and negative (-n, all processes in process group "n")
// values for pid are ignored. Refer to [PROC(5)] for details.
//
// [PROC(5)]: https://man7.org/linux/man-pages/man5/proc.5.html
func Status(pid int) (string, error) {
if pid < 1 {
return false, nil
return "", nil
}
data, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid))
if err != nil {
if os.IsNotExist(err) {
return false, nil
return "", nil
}
return false, err
return "", err
}
if cols := bytes.SplitN(data, []byte(" "), 4); len(cols) >= 3 && string(cols[2]) == "Z" {
return true, nil
if cols := bytes.SplitN(data, []byte(" "), 4); len(cols) >= 3 {
return string(cols[2]), nil
}
return false, nil
return "", nil
}

0 comments on commit 678a7b0

Please sign in to comment.