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