Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4set -u
5set -e
6
7# This script currently only works for x86_64
8ARCH="$(uname -m)"
9case "${ARCH}" in
10x86_64)
11 QEMU_BINARY=qemu-system-x86_64
12 BZIMAGE="arch/x86/boot/bzImage"
13 ;;
14*)
15 echo "Unsupported architecture"
16 exit 1
17 ;;
18esac
19SCRIPT_DIR="$(dirname $(realpath $0))"
20OUTPUT_DIR="$SCRIPT_DIR/results"
21KCONFIG_REL_PATHS=("${SCRIPT_DIR}/config" "${SCRIPT_DIR}/config.common" "${SCRIPT_DIR}/config.${ARCH}")
22B2C_URL="https://gitlab.freedesktop.org/mupuf/boot2container/-/raw/master/vm2c.py"
23NUM_COMPILE_JOBS="$(nproc)"
24LOG_FILE_BASE="$(date +"hid_selftests.%Y-%m-%d_%H-%M-%S")"
25LOG_FILE="${LOG_FILE_BASE}.log"
26EXIT_STATUS_FILE="${LOG_FILE_BASE}.exit_status"
27CONTAINER_IMAGE="registry.freedesktop.org/libevdev/hid-tools/fedora/37:2023-02-17.1"
28
29TARGETS="${TARGETS:=$(basename ${SCRIPT_DIR})}"
30DEFAULT_COMMAND="pip3 install hid-tools; make -C tools/testing/selftests TARGETS=${TARGETS} run_tests"
31
32usage()
33{
34 cat <<EOF
35Usage: $0 [-i] [-s] [-d <output_dir>] -- [<command>]
36
37<command> is the command you would normally run when you are in
38the source kernel direcory. e.g:
39
40 $0 -- ./tools/testing/selftests/hid/hid_bpf
41
42If no command is specified and a debug shell (-s) is not requested,
43"${DEFAULT_COMMAND}" will be run by default.
44
45If you build your kernel using KBUILD_OUTPUT= or O= options, these
46can be passed as environment variables to the script:
47
48 O=<kernel_build_path> $0 -- ./tools/testing/selftests/hid/hid_bpf
49
50or
51
52 KBUILD_OUTPUT=<kernel_build_path> $0 -- ./tools/testing/selftests/hid/hid_bpf
53
54Options:
55
56 -u) Update the boot2container script to a newer version.
57 -d) Update the output directory (default: ${OUTPUT_DIR})
58 -j) Number of jobs for compilation, similar to -j in make
59 (default: ${NUM_COMPILE_JOBS})
60 -s) Instead of powering off the VM, start an interactive
61 shell. If <command> is specified, the shell runs after
62 the command finishes executing
63EOF
64}
65
66download()
67{
68 local file="$1"
69
70 echo "Downloading $file..." >&2
71 curl -Lsf "$file" -o "${@:2}"
72}
73
74recompile_kernel()
75{
76 local kernel_checkout="$1"
77 local make_command="$2"
78
79 cd "${kernel_checkout}"
80
81 ${make_command} olddefconfig
82 ${make_command}
83}
84
85update_selftests()
86{
87 local kernel_checkout="$1"
88 local selftests_dir="${kernel_checkout}/tools/testing/selftests/hid"
89
90 cd "${selftests_dir}"
91 ${make_command}
92}
93
94run_vm()
95{
96 local run_dir="$1"
97 local b2c="$2"
98 local kernel_bzimage="$3"
99 local command="$4"
100 local post_command=""
101
102 cd "${run_dir}"
103
104 if ! which "${QEMU_BINARY}" &> /dev/null; then
105 cat <<EOF
106Could not find ${QEMU_BINARY}
107Please install qemu or set the QEMU_BINARY environment variable.
108EOF
109 exit 1
110 fi
111
112 # alpine (used in post-container requires the PATH to have /bin
113 export PATH=$PATH:/bin
114
115 if [[ "${debug_shell}" != "yes" ]]
116 then
117 touch ${OUTPUT_DIR}/${LOG_FILE}
118 command="mount bpffs -t bpf /sys/fs/bpf/; set -o pipefail ; ${command} 2>&1 | tee ${OUTPUT_DIR}/${LOG_FILE}"
119 post_command="cat ${OUTPUT_DIR}/${LOG_FILE}"
120 else
121 command="mount bpffs -t bpf /sys/fs/bpf/; ${command}"
122 fi
123
124 set +e
125 $b2c --command "${command}" \
126 --kernel ${kernel_bzimage} \
127 --workdir ${OUTPUT_DIR} \
128 --image ${CONTAINER_IMAGE}
129
130 echo $? > ${OUTPUT_DIR}/${EXIT_STATUS_FILE}
131
132 set -e
133
134 ${post_command}
135}
136
137is_rel_path()
138{
139 local path="$1"
140
141 [[ ${path:0:1} != "/" ]]
142}
143
144do_update_kconfig()
145{
146 local kernel_checkout="$1"
147 local kconfig_file="$2"
148
149 rm -f "$kconfig_file" 2> /dev/null
150
151 for config in "${KCONFIG_REL_PATHS[@]}"; do
152 local kconfig_src="${config}"
153 cat "$kconfig_src" >> "$kconfig_file"
154 done
155}
156
157update_kconfig()
158{
159 local kernel_checkout="$1"
160 local kconfig_file="$2"
161
162 if [[ -f "${kconfig_file}" ]]; then
163 local local_modified="$(stat -c %Y "${kconfig_file}")"
164
165 for config in "${KCONFIG_REL_PATHS[@]}"; do
166 local kconfig_src="${config}"
167 local src_modified="$(stat -c %Y "${kconfig_src}")"
168 # Only update the config if it has been updated after the
169 # previously cached config was created. This avoids
170 # unnecessarily compiling the kernel and selftests.
171 if [[ "${src_modified}" -gt "${local_modified}" ]]; then
172 do_update_kconfig "$kernel_checkout" "$kconfig_file"
173 # Once we have found one outdated configuration
174 # there is no need to check other ones.
175 break
176 fi
177 done
178 else
179 do_update_kconfig "$kernel_checkout" "$kconfig_file"
180 fi
181}
182
183main()
184{
185 local script_dir="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
186 local kernel_checkout=$(realpath "${script_dir}"/../../../../)
187 # By default the script searches for the kernel in the checkout directory but
188 # it also obeys environment variables O= and KBUILD_OUTPUT=
189 local kernel_bzimage="${kernel_checkout}/${BZIMAGE}"
190 local command="${DEFAULT_COMMAND}"
191 local update_b2c="no"
192 local debug_shell="no"
193
194 while getopts ':hsud:j:' opt; do
195 case ${opt} in
196 u)
197 update_b2c="yes"
198 ;;
199 d)
200 OUTPUT_DIR="$OPTARG"
201 ;;
202 j)
203 NUM_COMPILE_JOBS="$OPTARG"
204 ;;
205 s)
206 command="/bin/sh"
207 debug_shell="yes"
208 ;;
209 h)
210 usage
211 exit 0
212 ;;
213 \? )
214 echo "Invalid Option: -$OPTARG"
215 usage
216 exit 1
217 ;;
218 : )
219 echo "Invalid Option: -$OPTARG requires an argument"
220 usage
221 exit 1
222 ;;
223 esac
224 done
225 shift $((OPTIND -1))
226
227 # trap 'catch "$?"' EXIT
228
229 if [[ "${debug_shell}" == "no" ]]; then
230 if [[ $# -eq 0 ]]; then
231 echo "No command specified, will run ${DEFAULT_COMMAND} in the vm"
232 else
233 command="$@"
234
235 if [[ "${command}" == "/bin/bash" || "${command}" == "bash" ]]
236 then
237 debug_shell="yes"
238 fi
239 fi
240 fi
241
242 local kconfig_file="${OUTPUT_DIR}/latest.config"
243 local make_command="make -j ${NUM_COMPILE_JOBS} KCONFIG_CONFIG=${kconfig_file}"
244
245 # Figure out where the kernel is being built.
246 # O takes precedence over KBUILD_OUTPUT.
247 if [[ "${O:=""}" != "" ]]; then
248 if is_rel_path "${O}"; then
249 O="$(realpath "${PWD}/${O}")"
250 fi
251 kernel_bzimage="${O}/${BZIMAGE}"
252 make_command="${make_command} O=${O}"
253 elif [[ "${KBUILD_OUTPUT:=""}" != "" ]]; then
254 if is_rel_path "${KBUILD_OUTPUT}"; then
255 KBUILD_OUTPUT="$(realpath "${PWD}/${KBUILD_OUTPUT}")"
256 fi
257 kernel_bzimage="${KBUILD_OUTPUT}/${BZIMAGE}"
258 make_command="${make_command} KBUILD_OUTPUT=${KBUILD_OUTPUT}"
259 fi
260
261 local b2c="${OUTPUT_DIR}/vm2c.py"
262
263 echo "Output directory: ${OUTPUT_DIR}"
264
265 mkdir -p "${OUTPUT_DIR}"
266 update_kconfig "${kernel_checkout}" "${kconfig_file}"
267
268 recompile_kernel "${kernel_checkout}" "${make_command}"
269
270 if [[ "${update_b2c}" == "no" && ! -f "${b2c}" ]]; then
271 echo "vm2c script not found in ${b2c}"
272 update_b2c="yes"
273 fi
274
275 if [[ "${update_b2c}" == "yes" ]]; then
276 download $B2C_URL $b2c
277 chmod +x $b2c
278 fi
279
280 update_selftests "${kernel_checkout}" "${make_command}"
281 run_vm "${kernel_checkout}" $b2c "${kernel_bzimage}" "${command}"
282 if [[ "${debug_shell}" != "yes" ]]; then
283 echo "Logs saved in ${OUTPUT_DIR}/${LOG_FILE}"
284 fi
285
286 exit $(cat ${OUTPUT_DIR}/${EXIT_STATUS_FILE})
287}
288
289main "$@"