Bump up Go 1.13 as minimum requirement

PiperOrigin-RevId: 284320186
This commit is contained in:
Fabricio Voznika
2019-12-06 23:10:15 -08:00
committed by gVisor bot
parent 3c2e2f7d12
commit 01eadf51ea
7 changed files with 41 additions and 154 deletions
+16 -59
View File
@@ -16,7 +16,6 @@
package sighandling
import (
"fmt"
"os"
"os/signal"
"reflect"
@@ -31,37 +30,25 @@ const numSignals = 32
// 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 handleSignals(sigchans []chan os.Signal, handler func(linux.Signal), start, stop, done chan struct{}) {
// It stops when the stop channel is closed. The done channel is closed once it
// will no longer deliver signals to k.
func handleSignals(sigchans []chan os.Signal, handler func(linux.Signal), stop, done chan struct{}) {
// Build a select case.
sc := []reflect.SelectCase{{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(start)}}
sc := []reflect.SelectCase{{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(stop)}}
for _, sigchan := range sigchans {
sc = append(sc, reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(sigchan)})
}
started := false
for {
// Wait for a notification.
index, _, ok := reflect.Select(sc)
// Was it the start / stop channel?
// Was it the stop channel?
if index == 0 {
if !ok {
if !started {
// start channel; start forwarding and
// swap this case for the stop channel
// to select stop requests.
started = true
sc[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(stop)}
} else {
// stop channel; stop forwarding and
// clear this case so it is never
// selected again.
started = false
close(done)
sc[0].Chan = reflect.Value{}
}
// Stop forwarding and notify that it's done.
close(done)
return
}
continue
}
@@ -73,44 +60,17 @@ func handleSignals(sigchans []chan os.Signal, handler func(linux.Signal), start,
// Otherwise, it was a signal on channel N. Index 0 represents the stop
// channel, so index N represents the channel for signal N.
signal := linux.Signal(index)
if !started {
// Kernel cannot receive signals, either because it is
// not ready yet or is shutting down.
//
// Kill ourselves if this signal would have killed the
// process before PrepareForwarding was called. i.e., all
// _SigKill signals; see Go
// src/runtime/sigtab_linux_generic.go.
//
// Otherwise ignore the signal.
//
// TODO(b/114489875): Drop in Go 1.12, which uses tgkill
// in runtime.raise.
switch signal {
case linux.SIGHUP, linux.SIGINT, linux.SIGTERM:
dieFromSignal(signal)
panic(fmt.Sprintf("Failed to die from signal %d", signal))
default:
continue
}
}
// Pass the signal to the handler.
handler(signal)
handler(linux.Signal(index))
}
}
// 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.
// StartSignalForwarding ensures that synchronous signals are passed to the
// given handler function and returns a callback that stops signal delivery.
//
// 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 PrepareHandler(handler func(linux.Signal)) func() func() {
start := make(chan struct{})
func StartSignalForwarding(handler func(linux.Signal)) func() {
stop := make(chan struct{})
done := make(chan struct{})
@@ -128,13 +88,10 @@ func PrepareHandler(handler func(linux.Signal)) func() func() {
signal.Notify(sigchan, syscall.Signal(sig))
}
// Start up our listener.
go handleSignals(sigchans, handler, start, stop, done) // S/R-SAFE: synchronized by Kernel.extMu.
go handleSignals(sigchans, handler, stop, done) // S/R-SAFE: synchronized by Kernel.extMu.
return func() func() {
close(start)
return func() {
close(stop)
<-done
}
return func() {
close(stop)
<-done
}
}
@@ -15,8 +15,6 @@
package sighandling
import (
"fmt"
"runtime"
"syscall"
"unsafe"
@@ -48,27 +46,3 @@ func IgnoreChildStop() error {
return nil
}
// dieFromSignal kills the current process with sig.
//
// Preconditions: The default action of sig is termination.
func dieFromSignal(sig linux.Signal) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
sa := sigaction{handler: linux.SIG_DFL}
if _, _, e := syscall.RawSyscall6(syscall.SYS_RT_SIGACTION, uintptr(sig), uintptr(unsafe.Pointer(&sa)), 0, linux.SignalSetSize, 0, 0); e != 0 {
panic(fmt.Sprintf("rt_sigaction failed: %v", e))
}
set := linux.MakeSignalSet(sig)
if _, _, e := syscall.RawSyscall6(syscall.SYS_RT_SIGPROCMASK, linux.SIG_UNBLOCK, uintptr(unsafe.Pointer(&set)), 0, linux.SignalSetSize, 0, 0); e != 0 {
panic(fmt.Sprintf("rt_sigprocmask failed: %v", e))
}
if err := syscall.Tgkill(syscall.Getpid(), syscall.Gettid(), syscall.Signal(sig)); err != nil {
panic(fmt.Sprintf("tgkill failed: %v", err))
}
panic("failed to die")
}
-2
View File
@@ -31,8 +31,6 @@ go_template(
go_library(
name = "syncutil",
srcs = [
"downgradable_rwmutex_1_12_unsafe.go",
"downgradable_rwmutex_1_13_unsafe.go",
"downgradable_rwmutex_unsafe.go",
"memmove_unsafe.go",
"norace_unsafe.go",
@@ -1,21 +0,0 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2019 The gVisor Authors.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.12
// +build !go1.13
// TODO(b/133868570): Delete once Go 1.12 is no longer supported.
package syncutil
import _ "unsafe"
//go:linkname runtimeSemrelease112 sync.runtime_Semrelease
func runtimeSemrelease112(s *uint32, handoff bool)
func runtimeSemrelease(s *uint32, handoff bool, skipframes int) {
// 'skipframes' is only available starting from 1.13.
runtimeSemrelease112(s, handoff)
}
@@ -1,16 +0,0 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2019 The gVisor Authors.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.13
// +build !go1.15
// Check go:linkname function signatures when updating Go version.
package syncutil
import _ "unsafe"
//go:linkname runtimeSemrelease sync.runtime_Semrelease
func runtimeSemrelease(s *uint32, handoff bool, skipframes int)
+4 -1
View File
@@ -3,7 +3,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.12
// +build go1.13
// +build !go1.15
// Check go:linkname function signatures when updating Go version.
@@ -27,6 +27,9 @@ import (
//go:linkname runtimeSemacquire sync.runtime_Semacquire
func runtimeSemacquire(s *uint32)
//go:linkname runtimeSemrelease sync.runtime_Semrelease
func runtimeSemrelease(s *uint32, handoff bool, skipframes int)
// DowngradableRWMutex is identical to sync.RWMutex, but adds the DowngradeLock
// method.
type DowngradableRWMutex struct {
+21 -29
View File
@@ -93,10 +93,6 @@ type Loader struct {
// spec is the base configuration for the root container.
spec *specs.Spec
// startSignalForwarding enables forwarding of signals to the sandboxed
// container. It should be called after the init process is loaded.
startSignalForwarding func() func()
// stopSignalForwarding disables forwarding of signals to the sandboxed
// container. It should be called when a sandbox is destroyed.
stopSignalForwarding func()
@@ -336,29 +332,6 @@ func New(args Args) (*Loader, error) {
return nil, fmt.Errorf("ignore child stop signals failed: %v", err)
}
// Handle signals by forwarding them to the root container process
// (except for panic signal, which should cause a panic).
l.startSignalForwarding = sighandling.PrepareHandler(func(sig linux.Signal) {
// Panic signal should cause a panic.
if args.Conf.PanicSignal != -1 && sig == linux.Signal(args.Conf.PanicSignal) {
panic("Signal-induced panic")
}
// Otherwise forward to root container.
deliveryMode := DeliverToProcess
if args.Console {
// Since we are running with a console, we should
// forward the signal to the foreground process group
// so that job control signals like ^C can be handled
// properly.
deliveryMode = DeliverToForegroundProcessGroup
}
log.Infof("Received external signal %d, mode: %v", sig, deliveryMode)
if err := l.signal(args.ID, 0, int32(sig), deliveryMode); err != nil {
log.Warningf("error sending signal %v to container %q: %v", sig, args.ID, err)
}
})
// Create the control server using the provided FD.
//
// This must be done *after* we have initialized the kernel since the
@@ -566,8 +539,27 @@ func (l *Loader) run() error {
ep.tty.InitForegroundProcessGroup(ep.tg.ProcessGroup())
}
// Start signal forwarding only after an init process is created.
l.stopSignalForwarding = l.startSignalForwarding()
// Handle signals by forwarding them to the root container process
// (except for panic signal, which should cause a panic).
l.stopSignalForwarding = sighandling.StartSignalForwarding(func(sig linux.Signal) {
// Panic signal should cause a panic.
if l.conf.PanicSignal != -1 && sig == linux.Signal(l.conf.PanicSignal) {
panic("Signal-induced panic")
}
// Otherwise forward to root container.
deliveryMode := DeliverToProcess
if l.console {
// Since we are running with a console, we should forward the signal to
// the foreground process group so that job control signals like ^C can
// be handled properly.
deliveryMode = DeliverToForegroundProcessGroup
}
log.Infof("Received external signal %d, mode: %v", sig, deliveryMode)
if err := l.signal(l.sandboxID, 0, int32(sig), deliveryMode); err != nil {
log.Warningf("error sending signal %v to container %q: %v", sig, l.sandboxID, err)
}
})
log.Infof("Process should have started...")
l.watchdog.Start()