Path: blob/master/tools/testing/selftests/hid/vmtest.sh
26302 views
#!/bin/bash1# SPDX-License-Identifier: GPL-2.023set -u4set -e56# This script currently only works for x86_647ARCH="$(uname -m)"8case "${ARCH}" in9x86_64)10QEMU_BINARY=qemu-system-x86_6411BZIMAGE="arch/x86/boot/bzImage"12;;13*)14echo "Unsupported architecture"15exit 116;;17esac18SCRIPT_DIR="$(dirname $(realpath $0))"19OUTPUT_DIR="$SCRIPT_DIR/results"20KCONFIG_REL_PATHS=("${SCRIPT_DIR}/config" "${SCRIPT_DIR}/config.common" "${SCRIPT_DIR}/config.${ARCH}")21B2C_URL="https://gitlab.freedesktop.org/gfx-ci/boot2container/-/raw/main/vm2c.py"22NUM_COMPILE_JOBS="$(nproc)"23LOG_FILE_BASE="$(date +"hid_selftests.%Y-%m-%d_%H-%M-%S")"24LOG_FILE="${LOG_FILE_BASE}.log"25EXIT_STATUS_FILE="${LOG_FILE_BASE}.exit_status"26CONTAINER_IMAGE="registry.freedesktop.org/bentiss/hid/fedora/39:2023-11-22.1"2728TARGETS="${TARGETS:=$(basename ${SCRIPT_DIR})}"29DEFAULT_COMMAND="pip3 install hid-tools; make -C tools/testing/selftests TARGETS=${TARGETS} run_tests"3031usage()32{33cat <<EOF34Usage: $0 [-j N] [-s] [-b] [-d <output_dir>] -- [<command>]3536<command> is the command you would normally run when you are in37the source kernel direcory. e.g:3839$0 -- ./tools/testing/selftests/hid/hid_bpf4041If no command is specified and a debug shell (-s) is not requested,42"${DEFAULT_COMMAND}" will be run by default.4344If you build your kernel using KBUILD_OUTPUT= or O= options, these45can be passed as environment variables to the script:4647O=<kernel_build_path> $0 -- ./tools/testing/selftests/hid/hid_bpf4849or5051KBUILD_OUTPUT=<kernel_build_path> $0 -- ./tools/testing/selftests/hid/hid_bpf5253Options:5455-u) Update the boot2container script to a newer version.56-d) Update the output directory (default: ${OUTPUT_DIR})57-b) Run only the build steps for the kernel and the selftests58-j) Number of jobs for compilation, similar to -j in make59(default: ${NUM_COMPILE_JOBS})60-s) Instead of powering off the VM, start an interactive61shell. If <command> is specified, the shell runs after62the command finishes executing63EOF64}6566download()67{68local file="$1"6970echo "Downloading $file..." >&271curl -Lsf "$file" -o "${@:2}"72}7374recompile_kernel()75{76local kernel_checkout="$1"77local make_command="$2"7879cd "${kernel_checkout}"8081${make_command} olddefconfig82${make_command} headers83${make_command}84}8586update_selftests()87{88local kernel_checkout="$1"89local selftests_dir="${kernel_checkout}/tools/testing/selftests/hid"9091cd "${selftests_dir}"92${make_command}93}9495run_vm()96{97local run_dir="$1"98local b2c="$2"99local kernel_bzimage="$3"100local command="$4"101local post_command=""102103cd "${run_dir}"104105if ! which "${QEMU_BINARY}" &> /dev/null; then106cat <<EOF107Could not find ${QEMU_BINARY}108Please install qemu or set the QEMU_BINARY environment variable.109EOF110exit 1111fi112113# alpine (used in post-container requires the PATH to have /bin114export PATH=$PATH:/bin115116if [[ "${debug_shell}" != "yes" ]]117then118touch ${OUTPUT_DIR}/${LOG_FILE}119command="mount bpffs -t bpf /sys/fs/bpf/; set -o pipefail ; ${command} 2>&1 | tee ${OUTPUT_DIR}/${LOG_FILE}"120post_command="cat ${OUTPUT_DIR}/${LOG_FILE}"121else122command="mount bpffs -t bpf /sys/fs/bpf/; ${command}"123fi124125set +e126$b2c --command "${command}" \127--kernel ${kernel_bzimage} \128--workdir ${OUTPUT_DIR} \129--image ${CONTAINER_IMAGE}130131echo $? > ${OUTPUT_DIR}/${EXIT_STATUS_FILE}132133set -e134135${post_command}136}137138is_rel_path()139{140local path="$1"141142[[ ${path:0:1} != "/" ]]143}144145do_update_kconfig()146{147local kernel_checkout="$1"148local kconfig_file="$2"149150rm -f "$kconfig_file" 2> /dev/null151152for config in "${KCONFIG_REL_PATHS[@]}"; do153local kconfig_src="${config}"154cat "$kconfig_src" >> "$kconfig_file"155done156}157158update_kconfig()159{160local kernel_checkout="$1"161local kconfig_file="$2"162163if [[ -f "${kconfig_file}" ]]; then164local local_modified="$(stat -c %Y "${kconfig_file}")"165166for config in "${KCONFIG_REL_PATHS[@]}"; do167local kconfig_src="${config}"168local src_modified="$(stat -c %Y "${kconfig_src}")"169# Only update the config if it has been updated after the170# previously cached config was created. This avoids171# unnecessarily compiling the kernel and selftests.172if [[ "${src_modified}" -gt "${local_modified}" ]]; then173do_update_kconfig "$kernel_checkout" "$kconfig_file"174# Once we have found one outdated configuration175# there is no need to check other ones.176break177fi178done179else180do_update_kconfig "$kernel_checkout" "$kconfig_file"181fi182}183184main()185{186local script_dir="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"187local kernel_checkout=$(realpath "${script_dir}"/../../../../)188# By default the script searches for the kernel in the checkout directory but189# it also obeys environment variables O= and KBUILD_OUTPUT=190local kernel_bzimage="${kernel_checkout}/${BZIMAGE}"191local command="${DEFAULT_COMMAND}"192local update_b2c="no"193local debug_shell="no"194local build_only="no"195196while getopts ':hsud:j:b' opt; do197case ${opt} in198u)199update_b2c="yes"200;;201d)202OUTPUT_DIR="$OPTARG"203;;204j)205NUM_COMPILE_JOBS="$OPTARG"206;;207s)208command="/bin/sh"209debug_shell="yes"210;;211b)212build_only="yes"213;;214h)215usage216exit 0217;;218\? )219echo "Invalid Option: -$OPTARG"220usage221exit 1222;;223: )224echo "Invalid Option: -$OPTARG requires an argument"225usage226exit 1227;;228esac229done230shift $((OPTIND -1))231232# trap 'catch "$?"' EXIT233if [[ "${build_only}" == "no" && "${debug_shell}" == "no" ]]; then234if [[ $# -eq 0 ]]; then235echo "No command specified, will run ${DEFAULT_COMMAND} in the vm"236else237command="$@"238239if [[ "${command}" == "/bin/bash" || "${command}" == "bash" ]]240then241debug_shell="yes"242fi243fi244fi245246local kconfig_file="${OUTPUT_DIR}/latest.config"247local make_command="make -j ${NUM_COMPILE_JOBS} KCONFIG_CONFIG=${kconfig_file}"248249# Figure out where the kernel is being built.250# O takes precedence over KBUILD_OUTPUT.251if [[ "${O:=""}" != "" ]]; then252if is_rel_path "${O}"; then253O="$(realpath "${PWD}/${O}")"254fi255kernel_bzimage="${O}/${BZIMAGE}"256make_command="${make_command} O=${O}"257elif [[ "${KBUILD_OUTPUT:=""}" != "" ]]; then258if is_rel_path "${KBUILD_OUTPUT}"; then259KBUILD_OUTPUT="$(realpath "${PWD}/${KBUILD_OUTPUT}")"260fi261kernel_bzimage="${KBUILD_OUTPUT}/${BZIMAGE}"262make_command="${make_command} KBUILD_OUTPUT=${KBUILD_OUTPUT}"263fi264265local b2c="${OUTPUT_DIR}/vm2c.py"266267echo "Output directory: ${OUTPUT_DIR}"268269mkdir -p "${OUTPUT_DIR}"270update_kconfig "${kernel_checkout}" "${kconfig_file}"271272recompile_kernel "${kernel_checkout}" "${make_command}"273update_selftests "${kernel_checkout}" "${make_command}"274275if [[ "${build_only}" == "no" ]]; then276if [[ "${update_b2c}" == "no" && ! -f "${b2c}" ]]; then277echo "vm2c script not found in ${b2c}"278update_b2c="yes"279fi280281if [[ "${update_b2c}" == "yes" ]]; then282download $B2C_URL $b2c283chmod +x $b2c284fi285286run_vm "${kernel_checkout}" $b2c "${kernel_bzimage}" "${command}"287if [[ "${debug_shell}" != "yes" ]]; then288echo "Logs saved in ${OUTPUT_DIR}/${LOG_FILE}"289fi290291exit $(cat ${OUTPUT_DIR}/${EXIT_STATUS_FILE})292fi293}294295main "$@"296297298