summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--runsc/boot/loader.go19
-rw-r--r--runsc/test/integration/exec_test.go9
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)
}