diff --git a/runsc/sandbox/BUILD b/runsc/sandbox/BUILD index e89b19552..a961c3cc7 100644 --- a/runsc/sandbox/BUILD +++ b/runsc/sandbox/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "sandbox", @@ -28,3 +28,17 @@ go_library( "@org_golang_x_sys//unix:go_default_library", ], ) + +go_test( + name = "sandbox_test", + size = "small", + srcs = ["sandbox_test.go"], + data = [ + "//runsc", + ], + embed = [":sandbox"], + deps = [ + "//pkg/log", + "//runsc/test/testutil", + ], +) diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index a9486cfdc..91c44c996 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -195,7 +195,7 @@ func (s *Sandbox) createGoferProcess(spec *specs.Spec, conf *boot.Config, bundle goferEnds := make([]*os.File, 0, mountCount) for i := 0; i < mountCount; i++ { // Create socket that connects the sandbox and gofer. - fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) + fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0) if err != nil { return nil, err } diff --git a/runsc/sandbox/sandbox_test.go b/runsc/sandbox/sandbox_test.go new file mode 100644 index 000000000..e25290d5e --- /dev/null +++ b/runsc/sandbox/sandbox_test.go @@ -0,0 +1,74 @@ +// Copyright 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sandbox + +import ( + "os" + "testing" + + "gvisor.googlesource.com/gvisor/pkg/log" + "gvisor.googlesource.com/gvisor/runsc/test/testutil" +) + +func init() { + log.SetLevel(log.Debug) + if err := testutil.ConfigureExePath(); err != nil { + panic(err.Error()) + } +} + +func TestGoferExits(t *testing.T) { + spec := testutil.NewSpecWithArgs("/bin/sleep", "10000") + rootDir, bundleDir, conf, err := testutil.SetupContainer(spec) + if err != nil { + t.Fatalf("error setting up container: %v", err) + } + defer os.RemoveAll(rootDir) + defer os.RemoveAll(bundleDir) + + // Create, start and wait for the container. + s, err := Create(testutil.UniqueContainerID(), spec, conf, bundleDir, "") + if err != nil { + t.Fatalf("error creating container: %v", err) + } + defer s.Destroy() + if err := s.Start("123", spec, conf); err != nil { + t.Fatalf("error starting container: %v", err) + } + + sandboxProc, err := os.FindProcess(s.Pid) + if err != nil { + t.Fatalf("error finding sandbox process: %v", err) + } + gofer, err := os.FindProcess(s.GoferPid) + if err != nil { + t.Fatalf("error finding sandbox process: %v", err) + } + + // Kill sandbox and expect gofer to exit on its own. + if err := sandboxProc.Kill(); err != nil { + t.Fatalf("error killing sandbox process: %v", err) + } + if _, err := sandboxProc.Wait(); err != nil { + t.Fatalf("error waiting for sandbox process: %v", err) + } + + if _, err := gofer.Wait(); err != nil { + t.Fatalf("error waiting for gofer process: %v", err) + } + if s.IsRunning() { + t.Errorf("Sandbox shouldn't be running, sandbox: %+v", s) + } +}