diff options
-rw-r--r-- | runsc/boot/loader.go | 19 | ||||
-rw-r--r-- | runsc/test/integration/exec_test.go | 9 |
2 files changed, 18 insertions, 10 deletions
diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index c419b366f..5716ef217 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -698,8 +698,6 @@ func newEmptyNetworkStack(conf *Config, clock tcpip.Clock) (inet.Stack, error) { // sendToFGProcess is true, then the signal will be sent to the foreground // process group in the same session that PID belongs to. func (l *Loader) signalProcess(cid string, pid, signo int32, sendToFGProcess bool) error { - si := arch.SignalInfo{Signo: signo} - if pid <= 0 { return fmt.Errorf("failed to signal container %q PID %d: PID must be positive", cid, pid) } @@ -718,7 +716,7 @@ func (l *Loader) signalProcess(cid string, pid, signo int32, sendToFGProcess boo if !sendToFGProcess { // Send signal directly to exec process. - return ep.tg.SendSignal(&si) + return ep.tg.SendSignal(&arch.SignalInfo{Signo: signo}) } // Lookup foreground process group from the TTY for the given process, @@ -731,11 +729,20 @@ func (l *Loader) signalProcess(cid string, pid, signo int32, sendToFGProcess boo // No foreground process group has been set. Signal the // original thread group. log.Warningf("No foreground process group for container %q and PID %d. Sending signal directly to PID %d.", cid, pid, pid) - return ep.tg.SendSignal(&si) + return ep.tg.SendSignal(&arch.SignalInfo{Signo: signo}) } - // Send the signal. - return pg.Originator().SendSignal(&si) + // Send the signal to all processes in the process group. + var lastErr error + for _, tg := range l.k.TaskSet().Root.ThreadGroups() { + if tg.ProcessGroup() != pg { + continue + } + if err := tg.SendSignal(&arch.SignalInfo{Signo: signo}); err != nil { + lastErr = err + } + } + return lastErr } // signalContainer sends a signal to the root container process, or to all diff --git a/runsc/test/integration/exec_test.go b/runsc/test/integration/exec_test.go index 014254aab..d08140ad3 100644 --- a/runsc/test/integration/exec_test.go +++ b/runsc/test/integration/exec_test.go @@ -81,16 +81,17 @@ func TestExecJobControl(t *testing.T) { } defer ptmx.Close() - // Call "sleep 100" in the shell. - if _, err := ptmx.Write([]byte("sleep 100\n")); err != nil { + // Call "sleep 100 | cat" in the shell. We pipe to cat so that there + // will be two processes in the foreground process group. + if _, err := ptmx.Write([]byte("sleep 100 | cat\n")); err != nil { t.Fatalf("error writing to pty: %v", err) } // Give shell a few seconds to start executing the sleep. time.Sleep(2 * time.Second) - // Send a ^C to the pty, which should kill sleep, but not the shell. - // \x03 is ASCII "end of text", which is the same as ^C. + // Send a ^C to the pty, which should kill sleep and cat, but not the + // shell. \x03 is ASCII "end of text", which is the same as ^C. if _, err := ptmx.Write([]byte{'\x03'}); err != nil { t.Fatalf("error writing to pty: %v", err) } |