mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Bump up Go 1.13 as minimum requirement
PiperOrigin-RevId: 284320186
This commit is contained in:
committed by
gVisor bot
parent
3c2e2f7d12
commit
01eadf51ea
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user