1#!/usr/bin/env bash 2# shellcheck disable=SC2086 # we want word splitting 3set -e 4 5# If run outside of a deqp-runner invoction (e.g. piglit trace replay), then act 6# the same as the first thread in its threadpool. 7THREAD=${DEQP_RUNNER_THREAD:-0} 8 9# 10# Helper to generate CIDs for virtio-vsock based communication with processes 11# running inside crosvm guests. 12# 13# A CID is a 32-bit Context Identifier to be assigned to a crosvm instance 14# and must be unique across the host system. For this purpose, let's take 15# the least significant 25 bits from CI_JOB_ID as a base and generate a 7-bit 16# prefix number to handle up to 128 concurrent crosvm instances per job runner. 17# 18# As a result, the following variables are set: 19# - VSOCK_CID: the crosvm unique CID to be passed as a run argument 20# 21# - VSOCK_STDOUT, VSOCK_STDERR: the port numbers the guest should accept 22# vsock connections on in order to transfer output messages 23# 24# - VM_TEMP_DIR: the temporary directory path used to pass additional 25# context data towards the guest 26# 27set_vsock_context() { 28 [ -n "${CI_JOB_ID}" ] || { 29 echo "Missing or unset CI_JOB_ID env variable" >&2 30 exit 1 31 } 32 33 VM_TEMP_DIR="/tmp-vm.${THREAD}" 34 # Clear out any leftover files from a previous run. 35 rm -rf $VM_TEMP_DIR 36 mkdir $VM_TEMP_DIR || return 1 37 38 VSOCK_CID=$(((CI_JOB_ID & 0x1ffffff) | ((THREAD & 0x7f) << 25))) 39 VSOCK_STDOUT=5001 40 VSOCK_STDERR=5002 41 42 return 0 43} 44 45# The dEQP binary needs to run from the directory it's in 46if [ -n "${1##*.sh}" ] && [ -z "${1##*"deqp"*}" ]; then 47 DEQP_BIN_DIR=$(dirname "$1") 48 export DEQP_BIN_DIR 49fi 50 51VM_SOCKET=crosvm-${THREAD}.sock 52 53# Terminate any existing crosvm, if a previous invocation of this shell script 54# was terminated due to timeouts. This "vm stop" may fail if the crosvm died 55# without cleaning itself up. 56if [ -e $VM_SOCKET ]; then 57 crosvm stop $VM_SOCKET || true 58 # Wait for socats from that invocation to drain 59 sleep 5 60 rm -rf $VM_SOCKET || true 61fi 62 63set_vsock_context || { echo "Could not generate crosvm vsock CID" >&2; exit 1; } 64 65# Securely pass the current variables to the crosvm environment 66echo "Variables passed through:" 67SCRIPT_DIR=$(readlink -en "${0%/*}") 68${SCRIPT_DIR}/common/generate-env.sh | tee ${VM_TEMP_DIR}/crosvm-env.sh 69cp ${SCRIPT_DIR}/setup-test-env.sh ${VM_TEMP_DIR}/setup-test-env.sh 70 71# Set the crosvm-script as the arguments of the current script 72echo ". ${VM_TEMP_DIR}/setup-test-env.sh" > ${VM_TEMP_DIR}/crosvm-script.sh 73echo "$@" >> ${VM_TEMP_DIR}/crosvm-script.sh 74 75# Setup networking 76/usr/sbin/iptables-legacy -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE 77echo 1 > /proc/sys/net/ipv4/ip_forward 78 79# Start background processes to receive output from guest 80socat -u vsock-connect:${VSOCK_CID}:${VSOCK_STDERR},retry=200,interval=0.1 stderr & 81socat -u vsock-connect:${VSOCK_CID}:${VSOCK_STDOUT},retry=200,interval=0.1 stdout & 82 83# Prepare to start crosvm 84unset DISPLAY 85unset XDG_RUNTIME_DIR 86 87CROSVM_KERN_ARGS="quiet console=null root=my_root rw rootfstype=virtiofs ip=192.168.30.2::192.168.30.1:255.255.255.0:crosvm:eth0" 88CROSVM_KERN_ARGS="${CROSVM_KERN_ARGS} init=${SCRIPT_DIR}/crosvm-init.sh -- ${VSOCK_STDOUT} ${VSOCK_STDERR} ${VM_TEMP_DIR}" 89 90[ "${CROSVM_GALLIUM_DRIVER}" = "llvmpipe" ] && \ 91 CROSVM_LIBGL_ALWAYS_SOFTWARE=true || CROSVM_LIBGL_ALWAYS_SOFTWARE=false 92 93set +e -x 94 95# We aren't testing the host driver here, so we don't need to validate NIR on the host 96NIR_DEBUG="novalidate" \ 97LIBGL_ALWAYS_SOFTWARE=${CROSVM_LIBGL_ALWAYS_SOFTWARE} \ 98GALLIUM_DRIVER=${CROSVM_GALLIUM_DRIVER} \ 99VK_ICD_FILENAMES=$CI_PROJECT_DIR/install/share/vulkan/icd.d/${CROSVM_VK_DRIVER}_icd.x86_64.json \ 100crosvm --no-syslog run \ 101 --gpu "${CROSVM_GPU_ARGS}" --gpu-render-server "path=/usr/local/libexec/virgl_render_server" \ 102 -m "${CROSVM_MEMORY:-4096}" -c "${CROSVM_CPU:-2}" --disable-sandbox \ 103 --shared-dir /:my_root:type=fs:writeback=true:timeout=60:cache=always \ 104 --net "host-ip=192.168.30.1,netmask=255.255.255.0,mac=AA:BB:CC:00:00:12" \ 105 -s $VM_SOCKET \ 106 --cid ${VSOCK_CID} -p "${CROSVM_KERN_ARGS}" \ 107 /lava-files/${KERNEL_IMAGE_NAME:-bzImage} > ${VM_TEMP_DIR}/crosvm 2>&1 108 109CROSVM_RET=$? 110 111[ ${CROSVM_RET} -eq 0 ] && { 112 # The actual return code is the crosvm guest script's exit code 113 CROSVM_RET=$(cat ${VM_TEMP_DIR}/exit_code 2>/dev/null) 114 # Force error when the guest script's exit code is not available 115 CROSVM_RET=${CROSVM_RET:-1} 116} 117 118# Show crosvm output on error to help with debugging 119[ ${CROSVM_RET} -eq 0 ] || { 120 set +x 121 echo "Dumping crosvm output.." >&2 122 cat ${VM_TEMP_DIR}/crosvm >&2 123 set -x 124} 125 126exit ${CROSVM_RET} 127