// Signal handles `docker stop` on Windows. While Linux has support for // the full range of signals, signals aren't really implemented on Windows. // We fake supporting regular stop and -9 to force kill. func (clnt *client) Signal(containerID string, sig int) error { var ( cont *container err error ) // Get the container as we need it to find the pid of the process. clnt.lock(containerID) defer clnt.unlock(containerID) if cont, err = clnt.getContainer(containerID); err != nil { return err } cont.manualStopRequested = true logrus.Debugf("lcd: Signal() containerID=%s sig=%d pid=%d", containerID, sig, cont.systemPid) context := fmt.Sprintf("Signal: sig=%d pid=%d", sig, cont.systemPid) if syscall.Signal(sig) == syscall.SIGKILL { // Terminate the compute system if err := hcsshim.TerminateComputeSystem(containerID, hcsshim.TimeoutInfinite, context); err != nil { logrus.Errorf("Failed to terminate %s - %q", containerID, err) } } else { // Terminate Process if err = hcsshim.TerminateProcessInComputeSystem(containerID, cont.systemPid); err != nil { logrus.Warnf("Failed to terminate pid %d in %s: %q", cont.systemPid, containerID, err) // Ignore errors err = nil } } return nil }
func kill(id string, pid int, sig syscall.Signal) error { logrus.Debugf("WindowsExec: kill() id=%s pid=%d sig=%d", id, pid, sig) var err error context := fmt.Sprintf("kill: sig=%d pid=%d", sig, pid) if sig == syscall.SIGKILL || forceKill { // Terminate the compute system if errno, err := hcsshim.TerminateComputeSystem(id, hcsshim.TimeoutInfinite, context); err != nil { logrus.Errorf("Failed to terminate %s - 0x%X %q", id, errno, err) } } else { // Terminate Process if err = hcsshim.TerminateProcessInComputeSystem(id, uint32(pid)); err != nil { logrus.Warnf("Failed to terminate pid %d in %s: %q", pid, id, err) // Ignore errors err = nil } // Shutdown the compute system if errno, err := hcsshim.ShutdownComputeSystem(id, hcsshim.TimeoutInfinite, context); err != nil { logrus.Errorf("Failed to shutdown %s - 0x%X %q", id, errno, err) } } return err }
func kill(id string, pid int) error { logrus.Debugln("kill() ", id, pid) var err error // Terminate Process if err = hcsshim.TerminateProcessInComputeSystem(id, uint32(pid)); err != nil { logrus.Warnf("Failed to terminate pid %d in %s: %q", pid, id, err) // Ignore errors err = nil } if terminateMode { // Terminate the compute system if err = hcsshim.TerminateComputeSystem(id); err != nil { logrus.Errorf("Failed to terminate %s - %q", id, err) } } else { // Shutdown the compute system if err = hcsshim.ShutdownComputeSystem(id); err != nil { logrus.Errorf("Failed to shutdown %s - %q", id, err) } } return err }
// Signal handles `docker stop` on Windows. While Linux has support for // the full range of signals, signals aren't really implemented on Windows. // We fake supporting regular stop and -9 to force kill. func (clnt *client) Signal(containerID string, sig int) error { var ( cont *container err error ) // Get the container as we need it to find the pid of the process. clnt.lock(containerID) defer clnt.unlock(containerID) if cont, err = clnt.getContainer(containerID); err != nil { return err } logrus.Debugf("lcd: Signal() containerID=%s sig=%d pid=%d", containerID, sig, cont.systemPid) context := fmt.Sprintf("Signal: sig=%d pid=%d", sig, cont.systemPid) if syscall.Signal(sig) == syscall.SIGKILL { // Terminate the compute system if err := hcsshim.TerminateComputeSystem(containerID, hcsshim.TimeoutInfinite, context); err != nil { logrus.Errorf("Failed to terminate %s - %q", containerID, err) } } else { // Terminate Process if err = hcsshim.TerminateProcessInComputeSystem(containerID, cont.systemPid); err != nil { logrus.Warnf("Failed to terminate pid %d in %s: %q", cont.systemPid, containerID, err) // Ignore errors err = nil } // Shutdown the compute system const shutdownTimeout = 5 * 60 * 1000 // 5 minutes if err := hcsshim.ShutdownComputeSystem(containerID, shutdownTimeout, context); err != nil { if herr, ok := err.(*hcsshim.HcsError); !ok || (herr.Err != hcsshim.ERROR_SHUTDOWN_IN_PROGRESS && herr.Err != ErrorBadPathname && herr.Err != syscall.ERROR_PATH_NOT_FOUND) { logrus.Debugf("signal - error from ShutdownComputeSystem %v on %s. Calling TerminateComputeSystem", err, containerID) if err := hcsshim.TerminateComputeSystem(containerID, shutdownTimeout, "signal"); err != nil { logrus.Debugf("signal - ignoring error from TerminateComputeSystem on %s %v", containerID, err) } else { logrus.Debugf("Successful TerminateComputeSystem after failed ShutdownComputeSystem on %s during signal %v", containerID, sig) } } logrus.Errorf("Failed to shutdown %s - %q", containerID, err) } } return nil }
// While Linux has support for the full range of signals, signals aren't really implemented on Windows. // We try to terminate the specified process whatever signal is requested. func (clnt *client) SignalProcess(containerID string, processFriendlyName string, sig int) error { clnt.lock(containerID) defer clnt.unlock(containerID) cont, err := clnt.getContainer(containerID) if err != nil { return err } for _, p := range cont.processes { if p.friendlyName == processFriendlyName { return hcsshim.TerminateProcessInComputeSystem(containerID, p.systemPid) } } return fmt.Errorf("SignalProcess could not find process %s in %s", processFriendlyName, containerID) }