summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-08-08 10:24:53 -0700
committerShentubot <shentubot@google.com>2018-08-08 10:26:18 -0700
commit0d350aac7f70487bc28bae0d0f457155a4e19081 (patch)
treee4397f3cb6e28045f57ca3eacf4c873331f50328
parentcb23232c37c092b60d7e3ee91cb8dd8bed855028 (diff)
Enable SACK in runsc
SACK is disabled by default and needs to be manually enabled. It not only improves performance, but also fixes hangs downloading files from certain websites. PiperOrigin-RevId: 207906742 Change-Id: I4fb7277b67bfdf83ac8195f1b9c38265a0d51e8b
-rw-r--r--pkg/sentry/socket/hostinet/stack.go6
-rw-r--r--runsc/boot/controller.go5
-rw-r--r--runsc/boot/loader.go15
3 files changed, 19 insertions, 7 deletions
diff --git a/pkg/sentry/socket/hostinet/stack.go b/pkg/sentry/socket/hostinet/stack.go
index 44c3b9a3f..f64809d39 100644
--- a/pkg/sentry/socket/hostinet/stack.go
+++ b/pkg/sentry/socket/hostinet/stack.go
@@ -84,11 +84,13 @@ func (s *Stack) Configure() error {
log.Warningf("Failed to read TCP send buffer size, using default values")
}
- s.tcpSACKEnabled = false
+ // SACK is important for performance and even compatibility, assume it's
+ // enabled if we can't find the actual value.
+ s.tcpSACKEnabled = true
if sack, err := ioutil.ReadFile("/proc/sys/net/ipv4/tcp_sack"); err == nil {
s.tcpSACKEnabled = strings.TrimSpace(string(sack)) != "0"
} else {
- log.Warningf("Failed to read if TCP SACK if enabled, setting to false")
+ log.Warningf("Failed to read if TCP SACK if enabled, setting to true")
}
return nil
diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go
index c6e934e66..fc6ea326a 100644
--- a/runsc/boot/controller.go
+++ b/runsc/boot/controller.go
@@ -285,7 +285,10 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error {
fs.SetRestoreEnvironment(*renv)
// Prepare to load from the state file.
- networkStack := newEmptyNetworkStack(cm.l.conf, k)
+ networkStack, err := newEmptyNetworkStack(cm.l.conf, k)
+ if err != nil {
+ return fmt.Errorf("failed to create network: %v", err)
+ }
info, err := o.FilePayload.Files[0].Stat()
if err != nil {
return err
diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go
index 2f976cd52..f6c7bf223 100644
--- a/runsc/boot/loader.go
+++ b/runsc/boot/loader.go
@@ -174,7 +174,10 @@ func New(spec *specs.Spec, conf *Config, controllerFD int, ioFDs []int, console
// this point. Netns is configured before Run() is called. Netstack is
// configured using a control uRPC message. Host network is configured inside
// Run().
- networkStack := newEmptyNetworkStack(conf, k)
+ networkStack, err := newEmptyNetworkStack(conf, k)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create network: %v", err)
+ }
// Initiate the Kernel object, which is required by the Context passed
// to createVFS in order to mount (among other things) procfs.
@@ -525,16 +528,20 @@ func (l *Loader) WaitExit() kernel.ExitStatus {
return l.k.GlobalInit().ExitStatus()
}
-func newEmptyNetworkStack(conf *Config, clock tcpip.Clock) inet.Stack {
+func newEmptyNetworkStack(conf *Config, clock tcpip.Clock) (inet.Stack, error) {
switch conf.Network {
case NetworkHost:
- return hostinet.NewStack()
+ return hostinet.NewStack(), nil
case NetworkNone, NetworkSandbox:
// NetworkNone sets up loopback using netstack.
netProtos := []string{ipv4.ProtocolName, ipv6.ProtocolName, arp.ProtocolName}
protoNames := []string{tcp.ProtocolName, udp.ProtocolName, ping.ProtocolName4}
- return &epsocket.Stack{stack.New(netProtos, protoNames, stack.Options{Clock: clock})}
+ s := &epsocket.Stack{stack.New(netProtos, protoNames, stack.Options{Clock: clock})}
+ if err := s.Stack.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SACKEnabled(true)); err != nil {
+ return nil, fmt.Errorf("failed to enable SACK: %v", err)
+ }
+ return s, nil
default:
panic(fmt.Sprintf("invalid network configuration: %v", conf.Network))