From 9769a8eaa4b384d1b7db9f06edf28a6331cd2b64 Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Mon, 12 Aug 2019 17:40:11 -0700 Subject: Handle ENOSPC with a partial write. Similar to the EPIPE case, we can return the number of bytes written before ENOSPC was encountered. If the app tries to write more, we can return ENOSPC on the next write. PiperOrigin-RevId: 263041648 --- pkg/sentry/syscalls/linux/error.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go index 264301bfa..1d9018c96 100644 --- a/pkg/sentry/syscalls/linux/error.go +++ b/pkg/sentry/syscalls/linux/error.go @@ -91,6 +91,10 @@ func handleIOError(t *kernel.Task, partialResult bool, err, intr error, op strin // TODO(gvisor.dev/issue/161): In some cases SIGPIPE should // also be sent to the application. return nil + case syserror.ENOSPC: + // Similar to EPIPE. Return what we wrote this time, and let + // ENOSPC be returned on the next call. + return nil case syserror.ECONNRESET: // For TCP sendfile connections, we may have a reset. But we // should just return n as the result. -- cgit v1.2.3 From fa3d0e6f63d6ecc9a6566ec80e4a8c7519c6cf76 Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Tue, 13 Aug 2019 11:20:43 -0700 Subject: Bump Bazel to v0.28.0 The new version has a change in behavior when using a custom platform: * Old behavior: rules that don't require a toolchain used host_platform, no matter what execution platforms are specified. * New behavior: rules that don't require a toolchain use standard platform resolution that starts with execution platforms. As part of this change, we cannot use the "extra_exectution_platforms" flag provided by the default bazelrc. I got rid of the default bazelrc file, and made our custom .bazelrc as minimal as possible. PiperOrigin-RevId: 263176802 --- .bazelrc | 28 +++++++----- WORKSPACE | 13 ++++-- test/BUILD | 2 +- tools/bazel-0.24.0.bazelrc | 106 --------------------------------------------- tools/run_tests.sh | 3 +- 5 files changed, 29 insertions(+), 123 deletions(-) delete mode 100644 tools/bazel-0.24.0.bazelrc diff --git a/.bazelrc b/.bazelrc index f6b21086d..eda884473 100644 --- a/.bazelrc +++ b/.bazelrc @@ -12,26 +12,34 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Start with a base bazelrc for a recent version of bazel. These can be -# downloaded from: -# https://github.com/bazelbuild/bazel-toolchains/tree/master/bazelrc -import %workspace%/tools/bazel-0.24.0.bazelrc - -# All changes below are gVisor-specific. - # Display the current git revision in the info block. build --workspace_status_command tools/workspace_status.sh -# Add a custom toolchain that builds in a privileged docker container, which is -# required by our syscall tests. +# Enable remote execution so actions are performed on the remote systems. +build:remote --remote_executor=grpcs://remotebuildexecution.googleapis.com + +# Add a custom platform and toolchain that builds in a privileged docker +# container, which is required by our syscall tests. +build:remote --host_platform=//test:rbe_ubuntu1604 build:remote --extra_toolchains=//test:cc-toolchain-clang-x86_64-default build:remote --extra_execution_platforms=//test:rbe_ubuntu1604 -build:remote --host_platform=//test:rbe_ubuntu1604 build:remote --platforms=//test:rbe_ubuntu1604 +# Use default image for crosstool toolchain. +build:remote --crosstool_top=@rbe_default//cc:toolchain + +# Default parallelism and timeout for remote jobs. +build:remote --jobs=50 +build:remote --remote_timeout=3600 + # RBE requires a strong hash function, such as SHA256. startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 +# Enable authentication. This will pick up application default credentials by +# default. You can use --google_credentials=some_file.json to use a service +# account credential instead. +build:remote --google_default_credentials=true + # Auth scope needed for authentication with RBE. build:remote --auth_scope="https://www.googleapis.com/auth/cloud-source-tools" diff --git a/WORKSPACE b/WORKSPACE index 11cc7ddf9..f19f90231 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -33,14 +33,19 @@ gazelle_dependencies() # See releases at https://releases.bazel.build/bazel-toolchains.html http_archive( name = "bazel_toolchains", - sha256 = "67335b3563d9b67dc2550b8f27cc689b64fadac491e69ce78763d9ba894cc5cc", - strip_prefix = "bazel-toolchains-cddc376d428ada2927ad359211c3e356bd9c9fbb", + sha256 = "e71eadcfcbdb47b4b740eb48b32ca4226e36aabc425d035a18dd40c2dda808c1", + strip_prefix = "bazel-toolchains-0.28.4", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/0.28.4.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/0.28.4.tar.gz", ], ) +# Creates a default toolchain config for RBE. +load("@bazel_toolchains//rules:rbe_repo.bzl", "rbe_autoconfig") + +rbe_autoconfig(name = "rbe_default") + # External repositories, in sorted order. go_repository( name = "com_github_cenkalti_backoff", diff --git a/test/BUILD b/test/BUILD index 8e1dc5228..01fa01f2e 100644 --- a/test/BUILD +++ b/test/BUILD @@ -39,6 +39,6 @@ toolchain( ], target_compatible_with = [ ], - toolchain = "@bazel_toolchains//configs/ubuntu16_04_clang/1.2/bazel_0.23.0/default:cc-compiler-k8", + toolchain = "@bazel_toolchains//configs/ubuntu16_04_clang/9.0.0/bazel_0.28.0/cc:cc-compiler-k8", toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) diff --git a/tools/bazel-0.24.0.bazelrc b/tools/bazel-0.24.0.bazelrc deleted file mode 100644 index a8348faab..000000000 --- a/tools/bazel-0.24.0.bazelrc +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2016 The Bazel Authors. All rights reserved. -# -# 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. - -# This file is auto-generated from release/bazelrc.tpl and should not be -# modified directly. - -# This .bazelrc file contains all of the flags required for the provided -# toolchain with Remote Build Execution. -# -# This .bazelrc file also contains all of the flags required for the local -# docker sandboxing. - -# Depending on how many machines are in the remote execution instance, setting -# this higher can make builds faster by allowing more jobs to run in parallel. -# Setting it too high can result in jobs that timeout, however, while waiting -# for a remote machine to execute them. -build:remote --jobs=50 - -# Set several flags related to specifying the platform, toolchain and java -# properties. -# These flags are duplicated rather than imported from (for example) -# %workspace%/configs/ubuntu16_04_clang/1.2/toolchain.bazelrc to make this -# bazelrc a standalone file that can be copied more easily. -# These flags should only be used as is for the rbe-ubuntu16-04 container -# and need to be adapted to work with other toolchain containers. -build:remote --host_javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:jdk8 -build:remote --javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:jdk8 -build:remote --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8 -build:remote --java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8 -build:remote --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.2/bazel_0.24.0/default:toolchain -build:remote --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 -# Platform flags: -# The toolchain container used for execution is defined in the target indicated -# by "extra_execution_platforms", "host_platform" and "platforms". -# If you are using your own toolchain container, you need to create a platform -# target with "constraint_values" that allow for the toolchain specified with -# "extra_toolchains" to be selected (given constraints defined in -# "exec_compatible_with"). -# More about platforms: https://docs.bazel.build/versions/master/platforms.html -build:remote --extra_toolchains=@bazel_toolchains//configs/ubuntu16_04_clang/1.2/bazel_0.24.0/cpp:cc-toolchain-clang-x86_64-default -build:remote --extra_execution_platforms=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:rbe_ubuntu1604 -build:remote --host_platform=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:rbe_ubuntu1604 -build:remote --platforms=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:rbe_ubuntu1604 - -# Set various strategies so that all actions execute remotely. Mixing remote -# and local execution will lead to errors unless the toolchain and remote -# machine exactly match the host machine. -build:remote --spawn_strategy=remote -build:remote --strategy=Javac=remote -build:remote --strategy=Closure=remote -build:remote --strategy=Genrule=remote -build:remote --define=EXECUTOR=remote - -# Enable the remote cache so action results can be shared across machines, -# developers, and workspaces. -build:remote --remote_cache=remotebuildexecution.googleapis.com - -# Enable remote execution so actions are performed on the remote systems. -build:remote --remote_executor=remotebuildexecution.googleapis.com - -# Enable encryption. -build:remote --tls_enabled=true - -# Set a higher timeout value, just in case. -build:remote --remote_timeout=3600 - -# Enable authentication. This will pick up application default credentials by -# default. You can use --auth_credentials=some_file.json to use a service -# account credential instead. -build:remote --auth_enabled=true - -# The following flags are only necessary for local docker sandboxing -# with the rbe-ubuntu16-04 container. Use of these flags is still experimental. -build:docker-sandbox --host_javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:jdk8 -build:docker-sandbox --javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:jdk8 -build:docker-sandbox --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.2/bazel_0.24.0/default:toolchain -build:docker-sandbox --experimental_docker_image=gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:da0f21c71abce3bbb92c3a0c44c3737f007a82b60f8bd2930abc55fe64fc2729 -build:docker-sandbox --spawn_strategy=docker -build:docker-sandbox --strategy=Javac=docker -build:docker-sandbox --strategy=Closure=docker -build:docker-sandbox --strategy=Genrule=docker -build:docker-sandbox --define=EXECUTOR=remote -build:docker-sandbox --experimental_docker_verbose -build:docker-sandbox --experimental_enable_docker_sandbox - -# The following flags enable the remote cache so action results can be shared -# across machines, developers, and workspaces. -build:remote-cache --remote_cache=remotebuildexecution.googleapis.com -build:remote-cache --tls_enabled=true -build:remote-cache --remote_timeout=3600 -build:remote-cache --auth_enabled=true -build:remote-cache --spawn_strategy=standalone -build:remote-cache --strategy=Javac=standalone -build:remote-cache --strategy=Closure=standalone -build:remote-cache --strategy=Genrule=standalone diff --git a/tools/run_tests.sh b/tools/run_tests.sh index 483b9cb50..3e7c4394d 100755 --- a/tools/run_tests.sh +++ b/tools/run_tests.sh @@ -45,8 +45,7 @@ readonly TEST_PACKAGES=("//pkg/..." "//runsc/..." "//tools/...") ####################### # Install the latest version of Bazel and log the version. -# FIXME(b/137285694): Unable to build runsc with bazel 0.28.0. -(which use_bazel.sh && use_bazel.sh 0.27.1) || which bazel +(which use_bazel.sh && use_bazel.sh 0.28.0) || which bazel bazel version # Load the kvm module. -- cgit v1.2.3 From 8d97b22aa8e565ff05c5e9209f13d2394e9706c8 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Tue, 13 Aug 2019 11:54:59 -0700 Subject: tests: print stack traces if test failed by timeout PiperOrigin-RevId: 263184083 --- runsc/main.go | 8 +++++++ runsc/sandbox/sandbox.go | 2 ++ test/syscalls/syscall_test_runner.go | 45 +++++++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/runsc/main.go b/runsc/main.go index 5823819f4..e864118b2 100644 --- a/runsc/main.go +++ b/runsc/main.go @@ -22,6 +22,7 @@ import ( "io" "io/ioutil" "os" + "os/signal" "path/filepath" "strings" "syscall" @@ -116,6 +117,13 @@ func main() { // All subcommands must be registered before flag parsing. flag.Parse() + if *testOnlyAllowRunAsCurrentUserWithoutChroot { + // SIGTERM is sent to all processes if a test exceeds its + // timeout and this case is handled by syscall_test_runner. + log.Warningf("Block the TERM signal. This is only safe in tests!") + signal.Ignore(syscall.SIGTERM) + } + // Are we showing the version? if *showVersion { // The format here is the same as runc. diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 851b1304b..df3c0c5ef 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -361,6 +361,8 @@ func (s *Sandbox) createSandboxProcess(conf *boot.Config, args *Args, startSyncF nextFD++ } + cmd.Args = append(cmd.Args, "--panic-signal="+strconv.Itoa(int(syscall.SIGTERM))) + // Add the "boot" command to the args. // // All flags after this must be for the boot command diff --git a/test/syscalls/syscall_test_runner.go b/test/syscalls/syscall_test_runner.go index 5936d66ff..d1f9552a2 100644 --- a/test/syscalls/syscall_test_runner.go +++ b/test/syscalls/syscall_test_runner.go @@ -23,11 +23,13 @@ import ( "math" "os" "os/exec" + "os/signal" "path/filepath" "strconv" "strings" "syscall" "testing" + "time" specs "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" @@ -189,6 +191,8 @@ func runTestCaseRunsc(testBin string, tc gtest.TestCase, t *testing.T) { "-log-format=text", "-TESTONLY-unsafe-nonroot=true", "-net-raw=true", + fmt.Sprintf("-panic-signal=%d", syscall.SIGTERM), + "-watchdog-action=panic", } if *overlay { args = append(args, "-overlay") @@ -220,8 +224,8 @@ func runTestCaseRunsc(testBin string, tc gtest.TestCase, t *testing.T) { // Current process doesn't have CAP_SYS_ADMIN, create user namespace and run // as root inside that namespace to get it. - args = append(args, "run", "--bundle", bundleDir, id) - cmd := exec.Command(*runscPath, args...) + rArgs := append(args, "run", "--bundle", bundleDir, id) + cmd := exec.Command(*runscPath, rArgs...) cmd.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: syscall.CLONE_NEWUSER | syscall.CLONE_NEWNS, // Set current user/group as root inside the namespace. @@ -239,9 +243,44 @@ func runTestCaseRunsc(testBin string, tc gtest.TestCase, t *testing.T) { } cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr + sig := make(chan os.Signal, 1) + signal.Notify(sig, syscall.SIGTERM) + go func() { + s, ok := <-sig + if !ok { + return + } + t.Errorf("%s: Got signal: %v", tc.FullName(), s) + done := make(chan bool) + go func() { + dArgs := append(args, "-alsologtostderr=true", "debug", "--stacks", id) + cmd := exec.Command(*runscPath, dArgs...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Run() + done <- true + }() + + timeout := time.Tick(3 * time.Second) + select { + case <-timeout: + t.Logf("runsc debug --stacks is timeouted") + case <-done: + } + + t.Logf("Send SIGTERM to the sandbox process") + dArgs := append(args, "debug", + fmt.Sprintf("--signal=%d", syscall.SIGTERM), + id) + cmd = exec.Command(*runscPath, dArgs...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Run() + }() if err = cmd.Run(); err != nil { t.Errorf("test %q exited with status %v, want 0", tc.FullName(), err) } + close(sig) } // filterEnv returns an environment with the blacklisted variables removed. @@ -277,7 +316,7 @@ func main() { fatalf("test-name flag must be provided") } - log.SetLevel(log.Warning) + log.SetLevel(log.Info) if *debug { log.SetLevel(log.Debug) } -- cgit v1.2.3