From 599a3d0fb4cabbe6c56f4ac34dc9381eee365f52 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Thu, 7 Jan 2021 11:17:43 -0800 Subject: Implement the semtimedop syscall Signed-off-by: Andrei Vagin --- pkg/sentry/syscalls/linux/linux64.go | 4 ++-- pkg/sentry/syscalls/linux/sys_sem.go | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index b815e498f..a72df62f6 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -272,7 +272,7 @@ var AMD64 = &kernel.SyscallTable{ 217: syscalls.Supported("getdents64", Getdents64), 218: syscalls.Supported("set_tid_address", SetTidAddress), 219: syscalls.Supported("restart_syscall", RestartSyscall), - 220: syscalls.ErrorWithEvent("semtimedop", syserror.ENOSYS, "", []string{"gvisor.dev/issue/137"}), + 220: syscalls.PartiallySupported("semtimedop", Semtimedop, "A non-zero timeout argument isn't supported.", []string{"gvisor.dev/issue/137"}), 221: syscalls.PartiallySupported("fadvise64", Fadvise64, "Not all options are supported.", nil), 222: syscalls.Supported("timer_create", TimerCreate), 223: syscalls.Supported("timer_settime", TimerSettime), @@ -620,7 +620,7 @@ var ARM64 = &kernel.SyscallTable{ 189: syscalls.ErrorWithEvent("msgsnd", syserror.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921) 190: syscalls.Supported("semget", Semget), 191: syscalls.PartiallySupported("semctl", Semctl, "Options SEM_STAT_ANY not supported.", nil), - 192: syscalls.ErrorWithEvent("semtimedop", syserror.ENOSYS, "", []string{"gvisor.dev/issue/137"}), + 192: syscalls.PartiallySupported("semtimedop", Semtimedop, "A non-zero timeout argument isn't supported.", []string{"gvisor.dev/issue/137"}), 193: syscalls.PartiallySupported("semop", Semop, "Option SEM_UNDO not supported.", nil), 194: syscalls.PartiallySupported("shmget", Shmget, "Option SHM_HUGETLB is not supported.", nil), 195: syscalls.PartiallySupported("shmctl", Shmctl, "Options SHM_LOCK, SHM_UNLOCK are not supported.", nil), diff --git a/pkg/sentry/syscalls/linux/sys_sem.go b/pkg/sentry/syscalls/linux/sys_sem.go index 1166cd7bb..d324461a3 100644 --- a/pkg/sentry/syscalls/linux/sys_sem.go +++ b/pkg/sentry/syscalls/linux/sys_sem.go @@ -48,6 +48,15 @@ func Semget(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal return uintptr(set.ID), nil, nil } +// Semtimedop handles: semop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +func Semtimedop(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + // TODO(gvisor.dev/issue/137): A non-zero timeout isn't supported. + if args[3].Pointer() != 0 { + return 0, nil, syserror.ENOSYS + } + return Semop(t, args) +} + // Semop handles: semop(int semid, struct sembuf *sops, size_t nsops) func Semop(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { id := args[0].Int() -- cgit v1.2.3 From 8de562b79942f5383ffbe67873df07509ca7fcb0 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Wed, 30 Dec 2020 01:28:26 -0800 Subject: Add ARM smoke test make BAZEL_CONFIG=aarch64 arm-qemu-smoke-test Signed-off-by: Andrei Vagin --- .bazelrc | 5 +++++ .buildkite/pipeline.yaml | 5 +++++ .travis.yml | 47 ------------------------------------------ Makefile | 8 +++++++ WORKSPACE | 14 +++++++++++++ images/arm-qemu/Dockerfile | 12 +++++++++++ images/arm-qemu/initramfs/init | 39 +++++++++++++++++++++++++++++++++++ images/arm-qemu/test.sh | 28 +++++++++++++++++++++++++ images/default/Dockerfile | 35 +++++++++++++++++++------------ tools/bazel.mk | 7 ++++--- tools/bazeldefs/cc.bzl | 12 +++++++++-- 11 files changed, 147 insertions(+), 65 deletions(-) delete mode 100644 .travis.yml create mode 100644 images/arm-qemu/Dockerfile create mode 100755 images/arm-qemu/initramfs/init create mode 100755 images/arm-qemu/test.sh diff --git a/.bazelrc b/.bazelrc index 9eee6bea5..413cee3b0 100644 --- a/.bazelrc +++ b/.bazelrc @@ -20,3 +20,8 @@ build --cxxopt=-std=c++17 # Display the current git revision in the info block. build --stamp --workspace_status_command tools/workspace_status.sh + +# Set flags for aarch64. +build:cross-aarch64 --crosstool_top=@crosstool//:toolchains --compiler=gcc +build:cross-aarch64 --cpu=aarch64 +build:cross-aarch64 --platforms=@io_bazel_rules_go//go/toolchain:linux_arm64 diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index ee993c46a..58a5ea68a 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -147,6 +147,11 @@ steps: parallelism: 10 if: build.message =~ /VFS1/ || build.branch == "master" + # ARM tests. + - <<: *common + label: ":mechanical_arm: ARM" + command: make arm-qemu-smoke-test + # Run basic benchmarks smoke tests (no upload). - <<: *common label: ":fire: Benchmarks smoke test" diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2d9fa80a1..000000000 --- a/.travis.yml +++ /dev/null @@ -1,47 +0,0 @@ -language: shell -dist: xenial -git: - clone: false # Clone manually in before_install -before_install: - - set -e -o pipefail - - | - if [ "${TRAVIS_PULL_REQUEST}" = false ]; then - # This is not a PR build, fetch and checkout the commit being tested - git clone -q --depth 1 "https://github.com/${TRAVIS_REPO_SLUG}.git" "${TRAVIS_REPO_SLUG}" - cd "${TRAVIS_REPO_SLUG}" - git fetch origin "${TRAVIS_COMMIT}" --depth 1 - git checkout -qf "${TRAVIS_COMMIT}" - else - # This is a PR build, simulate +refs/pull/{num}/merge. - # We can do that by fetching +refs/pull/{num}/head and cherry picking it - # onto the target branch. - git clone -q --branch "${TRAVIS_BRANCH}" --depth 1 "https://github.com/${TRAVIS_REPO_SLUG}.git" "${TRAVIS_REPO_SLUG}" - cd "${TRAVIS_REPO_SLUG}" - git fetch origin "+refs/pull/${TRAVIS_PULL_REQUEST}/head" --depth 1 - git config --global user.email "$(git log -1 FETCH_HEAD --pretty="%cE")" - git config --global user.name "$(git log -1 FETCH_HEAD --pretty="%aN")" - git cherry-pick --strategy=recursive -X theirs --keep-redundant-commits FETCH_HEAD - fi -cache: - directories: - - /home/travis/.cache/bazel/ -os: linux -services: - - docker -jobs: - include: - # AMD64 builds are tested on kokoro, so don't run them in travis to save - # capacity for arm64 builds. - # - os: linux - # arch: amd64 - - os: linux - arch: arm64 -script: - # On arm64, we need to create our own pipes for stderr and stdout, - # otherwise we will not be able to open /dev/stderr. This is probably - # due to AppArmor rules. - - bash -xeo pipefail -c 'uname -a && make smoke-tests 2>&1 | cat' -branches: - except: - # Skip copybara branches. - - /^test\/cl.*$/ diff --git a/Makefile b/Makefile index 8ead2cfb2..44d882838 100644 --- a/Makefile +++ b/Makefile @@ -232,6 +232,14 @@ do-tests: @$(call sudo,//runsc,do true) .PHONY: do-tests +arm-qemu-smoke-test: BAZEL_OPTIONS=--config=cross-aarch64 +arm-qemu-smoke-test: load-arm-qemu + export T=$$(mktemp -d --tmpdir release.XXXXXX); \ + mkdir -p $$T/bin/arm64/ && \ + $(call copy,//runsc:runsc,$$T/bin/arm64) && \ + docker run --rm -v $$T/bin/arm64/runsc:/workdir/initramfs/runsc gvisor.dev/images/arm-qemu +.PHONY: arm-qemu-smoke-test + simple-tests: unit-tests # Compatibility target. .PHONY: simple-tests diff --git a/WORKSPACE b/WORKSPACE index 72f9a89cc..1bea0a3c6 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -83,6 +83,20 @@ http_archive( ], ) +# Load C++ cross-compilation toolchains. +http_archive( + name = "coral_crosstool", + sha256 = "088ef98b19a45d7224be13636487e3af57b1564880b67df7be8b3b7eee4a1bfc", + strip_prefix = "crosstool-142e930ac6bf1295ff3ba7ba2b5b6324dfb42839", + urls = [ + "https://github.com/google-coral/crosstool/archive/142e930ac6bf1295ff3ba7ba2b5b6324dfb42839.tar.gz", + ], +) + +load("@coral_crosstool//:configure.bzl", "cc_crosstool") + +cc_crosstool(name = "crosstool") + # Load protobuf dependencies. http_archive( name = "rules_proto", diff --git a/images/arm-qemu/Dockerfile b/images/arm-qemu/Dockerfile new file mode 100644 index 000000000..1a2ecaf42 --- /dev/null +++ b/images/arm-qemu/Dockerfile @@ -0,0 +1,12 @@ +FROM fedora:33 + +RUN dnf install -y qemu-system-aarch64 gzip cpio wget + +WORKDIR /workdir +RUN wget -4 http://dl-cdn.alpinelinux.org/alpine/edge/releases/aarch64/netboot/vmlinuz-lts +RUN wget -4 http://dl-cdn.alpinelinux.org/alpine/edge/releases/aarch64/netboot/initramfs-lts + +COPY initramfs /workdir/initramfs +COPY test.sh /workdir/ + +CMD ./test.sh diff --git a/images/arm-qemu/initramfs/init b/images/arm-qemu/initramfs/init new file mode 100755 index 000000000..b355daadd --- /dev/null +++ b/images/arm-qemu/initramfs/init @@ -0,0 +1,39 @@ +#!/bin/sh + +# Copyright 2020 The gVisor Authors. +# +# 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 script is started as the init process in a test virtual machine, +# it does all required initialization steps and run a test command inside a +# gVisor instance. + +set -x -e + +/bin/busybox mkdir -p /usr/bin /usr/sbin /proc /sys /dev /tmp + +/bin/busybox --install -s +export PATH=/usr/bin:/bin:/usr/sbin:/sbin + +mount -t proc -o noexec,nosuid,nodev proc /proc +mount -t sysfs -o noexec,nosuid,nodev sysfs /sys +mount -t devtmpfs -o exec,nosuid,mode=0755,size=2M devtmpfs /dev + +uname -a +/runsc --TESTONLY-unsafe-nonroot --rootless --network none --debug --alsologtostderr do uname -a +echo "runsc exited with code $?" + +# Shutdown the VM. poweroff and halt doesn't work for unknown reasons. +# qemu is started with the -no-reboot flag, so the VM will be terminated. +reboot -f +exit 1 diff --git a/images/arm-qemu/test.sh b/images/arm-qemu/test.sh new file mode 100755 index 000000000..2c9336015 --- /dev/null +++ b/images/arm-qemu/test.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Copyright 2020 The gVisor Authors. +# +# 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. + +set -xeuo pipefail -m + +cd initramfs +find . | cpio -v -o -c -R root:root | gzip -9 >> ../initramfs-lts +cd .. + +qemu-system-aarch64 -M virt -m 512M -cpu cortex-a57 \ + -kernel vmlinuz-lts -initrd initramfs-lts \ + -append "console=ttyAMA0 panic=-1" -nographic -no-reboot \ + | tee /dev/stderr | grep "runsc exited with code 0" + +echo "PASS" diff --git a/images/default/Dockerfile b/images/default/Dockerfile index 224469267..19b340237 100644 --- a/images/default/Dockerfile +++ b/images/default/Dockerfile @@ -1,20 +1,29 @@ -FROM fedora:31 +FROM ubuntu:focal -# Install bazel. -RUN dnf install -y dnf-plugins-core && dnf copr enable -y vbatts/bazel -RUN dnf install -y git gcc make golang gcc-c++ glibc-devel python3 which python3-pip python3-devel libffi-devel openssl-devel pkg-config glibc-static libstdc++-static patch diffutils -RUN pip install --no-cache-dir pycparser -RUN dnf install -y bazel3 +ENV DEBIAN_FRONTEND="noninteractive" +RUN apt-get update && apt-get install -y curl gnupg2 git \ + python python3 python3-distutils python3-pip \ + build-essential crossbuild-essential-arm64 qemu-user-static \ + openjdk-11-jdk-headless zip unzip \ + apt-transport-https ca-certificates gnupg-agent \ + software-properties-common \ + pkg-config libffi-dev patch diffutils libssl-dev -# Install gcloud. Note that while this is "x86_64", it doesn't actually matter. +# Install Docker client for the website build. +RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +RUN add-apt-repository \ + "deb https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" +RUN apt-get install docker-ce-cli + +# Install gcloud. RUN curl https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-289.0.0-linux-x86_64.tar.gz | \ tar zxf - google-cloud-sdk && \ - google-cloud-sdk/install.sh && \ + google-cloud-sdk/install.sh --quiet && \ ln -s /google-cloud-sdk/bin/gcloud /usr/bin/gcloud -# Install Docker client for the website build. -RUN dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo -RUN dnf install -y docker-ce-cli - +# Download the official bazel binary. The APT repository isn't used because there is not packages for arm64. +RUN sh -c 'curl -o /usr/local/bin/bazel https://releases.bazel.build/3.5.1/release/bazel-3.5.1-linux-$(uname -m | sed s/aarch64/arm64/) && chmod ugo+x /usr/local/bin/bazel' WORKDIR /workspace -ENTRYPOINT ["/usr/bin/bazel"] +ENTRYPOINT ["/usr/local/bin/bazel"] diff --git a/tools/bazel.mk b/tools/bazel.mk index af8e53d3f..7e06d09be 100644 --- a/tools/bazel.mk +++ b/tools/bazel.mk @@ -61,6 +61,7 @@ DOCKER_CONFIG := /etc/docker ## STARTUP_OPTIONS - Startup options passed to Bazel. ## STARTUP_OPTIONS := +BAZEL_OPTIONS := BAZEL := bazel $(STARTUP_OPTIONS) BASE_OPTIONS := --color=no --curses=no TEST_OPTIONS := $(BASE_OPTIONS) \ @@ -155,7 +156,7 @@ bazel-image: load-default ## Ensures that the local builder exists. @$(call header,DOCKER BUILD) @docker rm -f $(BUILDER_NAME) 2>/dev/null || true @docker run --user 0:0 --entrypoint "" --name $(BUILDER_NAME) gvisor.dev/images/default \ - sh -c "$(GROUPADD_DOCKER) $(USERADD_DOCKER) if test -e /dev/kvm; then chmod a+rw /dev/kvm; fi" >&2 + bash -c "$(GROUPADD_DOCKER) $(USERADD_DOCKER) if test -e /dev/kvm; then chmod a+rw /dev/kvm; fi" >&2 @docker commit $(BUILDER_NAME) gvisor.dev/images/builder >&2 .PHONY: bazel-image @@ -170,7 +171,7 @@ bazel-server: bazel-image ## Ensures that the server exists. --workdir "$(CURDIR)" \ $(DOCKER_RUN_OPTIONS) \ gvisor.dev/images/builder \ - sh -c "set -x; tail -f --pid=\$$($(BAZEL) info server_pid) /dev/null" >&2 + bash -c "set -x; tail -f --pid=\$$($(BAZEL) info server_pid) /dev/null" >&2 else bazel-server: @ @@ -187,7 +188,7 @@ endif # The last line is used to prevent terminal shenanigans. build_paths = \ (set -euo pipefail; \ - $(call wrapper,$(BAZEL) build $(BASE_OPTIONS) $(1)) 2>&1 \ + $(call wrapper,$(BAZEL) build $(BASE_OPTIONS) $(BAZEL_OPTIONS) $(1)) 2>&1 \ | tee /proc/self/fd/2 \ | sed -n -e '/^Target/,$$p' \ | sed -n -e '/^ \($(subst /,\/,$(subst $(SPACE),\|,$(BUILD_ROOTS)))\)/p' \ diff --git a/tools/bazeldefs/cc.bzl b/tools/bazeldefs/cc.bzl index 7f41a0142..2831eac5f 100644 --- a/tools/bazeldefs/cc.bzl +++ b/tools/bazeldefs/cc.bzl @@ -1,11 +1,9 @@ """C++ rules.""" -load("@bazel_tools//tools/cpp:cc_flags_supplier.bzl", _cc_flags_supplier = "cc_flags_supplier") load("@rules_cc//cc:defs.bzl", _cc_binary = "cc_binary", _cc_library = "cc_library", _cc_proto_library = "cc_proto_library", _cc_test = "cc_test") load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", _cc_grpc_library = "cc_grpc_library") cc_library = _cc_library -cc_flags_supplier = _cc_flags_supplier cc_proto_library = _cc_proto_library cc_test = _cc_test cc_toolchain = "@bazel_tools//tools/cpp:current_cc_toolchain" @@ -14,6 +12,16 @@ gbenchmark = "@com_google_benchmark//:benchmark" grpcpp = "@com_github_grpc_grpc//:grpc++" vdso_linker_option = "-fuse-ld=gold " +def _cc_flags_supplier_impl(ctx): + variables = platform_common.TemplateVariableInfo({ + "CC_FLAGS": "", + }) + return [variables] + +cc_flags_supplier = rule( + implementation = _cc_flags_supplier_impl, +) + def cc_grpc_library(name, **kwargs): _cc_grpc_library(name = name, grpc_only = True, **kwargs) -- cgit v1.2.3