• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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