summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/sighandling/sighandling.go
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-10-17 12:27:58 -0700
committerShentubot <shentubot@google.com>2018-10-17 12:29:05 -0700
commit4e6f0892c96c374b1abcf5c39b75ba52d98c97f8 (patch)
treecb21538ad26a50ff61086d55c1bef36d5026e4c0 /pkg/sentry/sighandling/sighandling.go
parent578fe5a50dcf8e104b6bce3802987b0f8c069ade (diff)
runsc: Support job control signals for the root container.
Now containers run with "docker run -it" support control characters like ^C and ^Z. This required refactoring our signal handling a bit. Signals delivered to the "runsc boot" process are turned into loader.Signal calls with the appropriate delivery mode. Previously they were always sent directly to PID 1. PiperOrigin-RevId: 217566770 Change-Id: I5b7220d9a0f2b591a56335479454a200c6de8732
Diffstat (limited to 'pkg/sentry/sighandling/sighandling.go')
-rw-r--r--pkg/sentry/sighandling/sighandling.go25
1 files changed, 10 insertions, 15 deletions
diff --git a/pkg/sentry/sighandling/sighandling.go b/pkg/sentry/sighandling/sighandling.go
index 0946ab075..29bcf55ab 100644
--- a/pkg/sentry/sighandling/sighandling.go
+++ b/pkg/sentry/sighandling/sighandling.go
@@ -23,18 +23,17 @@ import (
"syscall"
"gvisor.googlesource.com/gvisor/pkg/abi/linux"
- "gvisor.googlesource.com/gvisor/pkg/sentry/arch"
- "gvisor.googlesource.com/gvisor/pkg/sentry/kernel"
)
// numSignals is the number of normal (non-realtime) signals on Linux.
const numSignals = 32
-// forwardSignals listens for incoming signals and delivers them to k.
+// handleSignals listens for incoming signals and calls the given handler
+// function.
//
// It starts when the start channel is closed, stops when the stop channel
// is closed, and closes done once it will no longer deliver signals to k.
-func forwardSignals(k *kernel.Kernel, sigchans []chan os.Signal, start, stop, done chan struct{}) {
+func handleSignals(sigchans []chan os.Signal, handler func(linux.Signal), start, stop, done chan struct{}) {
// Build a select case.
sc := []reflect.SelectCase{{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(start)}}
for _, sigchan := range sigchans {
@@ -98,18 +97,19 @@ func forwardSignals(k *kernel.Kernel, sigchans []chan os.Signal, start, stop, do
}
}
- k.SendExternalSignal(&arch.SignalInfo{Signo: int32(signal)}, "sentry")
+ // Pass the signal to the handler.
+ handler(signal)
}
}
-// PrepareForwarding ensures that synchronous signals are forwarded to k and
-// returns a callback that starts signal delivery, which itself returns a
-// callback that stops signal forwarding.
+// PrepareHandler ensures that synchronous signals are passed to the given
+// handler function and returns a callback that starts signal delivery, which
+// itself returns a callback that stops signal handling.
//
// Note that this function permanently takes over signal handling. After the
// stop callback, signals revert to the default Go runtime behavior, which
// cannot be overridden with external calls to signal.Notify.
-func PrepareForwarding(k *kernel.Kernel, skipSignal syscall.Signal) func() func() {
+func PrepareHandler(handler func(linux.Signal)) func() func() {
start := make(chan struct{})
stop := make(chan struct{})
done := make(chan struct{})
@@ -125,15 +125,10 @@ func PrepareForwarding(k *kernel.Kernel, skipSignal syscall.Signal) func() func(
for sig := 1; sig <= numSignals+1; sig++ {
sigchan := make(chan os.Signal, 1)
sigchans = append(sigchans, sigchan)
-
- if syscall.Signal(sig) == skipSignal {
- continue
- }
-
signal.Notify(sigchan, syscall.Signal(sig))
}
// Start up our listener.
- go forwardSignals(k, sigchans, start, stop, done) // S/R-SAFE: synchronized by Kernel.extMu.
+ go handleSignals(sigchans, handler, start, stop, done) // S/R-SAFE: synchronized by Kernel.extMu.
return func() func() {
close(start)