1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
|
#!/bin/bash
set -x -e
CI_PKGS=()
X86_64_PKGS=(gcc-multilib)
# Convert from string to array.
IFS=" " read -r -a ZDTM_OPTS <<< "$ZDTM_OPTS"
UNAME_M=$(uname -m)
if [ "$UNAME_M" != "x86_64" ]; then
# Some tests rely on kernel features that may not be available
# when running in a container. Here we assume that x86_64 systems
# are baremetal, and skip the tests for all other CPU architectures.
# The RUN_TESTS environment variable can override this, e.g., for aarch64.
[ -n "$RUN_TESTS" ] || SKIP_CI_TEST=1
fi
ci_prep () {
[ -n "$SKIP_CI_PREP" ] && return
cd ../../
# At least one of the test cases run by this script (others/rpc)
# expects a user with the ID 1000. sudo from 20.04 (focal) does
# not run anymore with 'sudo -u \#1000' if the UID does not exist.
adduser -u 1000 --disabled-password --gecos "criutest" criutest || :
# This can fail on aarch64
service apport stop || :
# Ubuntu has set up AppArmor in 24.04 so that it blocks use of user
# namespaces by unprivileged users. We need this for some of our tests.
sysctl kernel.apparmor_restrict_unprivileged_userns=0 || :
if [ "$CLANG" = "1" ]; then
# clang support
CC=clang
# If this is running in an environment without gcc installed
# compel-host-bin will fail as it is using HOSTCC. Also
# set HOSTCC to clang to build compel-host-bin with it.
export HOSTCC=clang
else
CC=gcc
fi
CI_PKGS+=("$CC")
# Do not install x86_64 specific packages on other architectures
if [ "$UNAME_M" = "x86_64" ]; then
CI_PKGS+=("${X86_64_PKGS[@]}")
fi
contrib/dependencies/apt-packages.sh
contrib/apt-install "${CI_PKGS[@]}"
chmod a+x "$HOME"
}
test_stream() {
# Testing CRIU streaming to criu-image-streamer
# FIXME: Currently, hugetlb mappings is not premapped, so in the restore content
# phase, we skip page read these pages, enqueue the iovec for later reading in
# restorer and eventually close the page read. However, image-streamer expects the
# whole image to be read and the image is not reopened, sent twice. These MAP_HUGETLB
# test cases will result in EPIPE error at the moment.
STREAM_TEST_EXCLUDE=(-x maps09 -x maps10)
./test/zdtm.py run --stream -p 2 --keep-going -a "${STREAM_TEST_EXCLUDE[@]}" "${ZDTM_OPTS[@]}"
}
print_header() {
echo "############### $1 ###############"
}
print_env() {
set +x
# As this script can run on multiple different CI systems
# the following lines should give some context to the
# evnvironment of this CI run.
print_header "Environment variables"
printenv
print_header "uname -a"
uname -a || :
print_header "Mounted file systems"
cat /proc/self/mountinfo || :
print_header "Kernel command line"
cat /proc/cmdline || :
print_header "Kernel modules"
lsmod || :
print_header "Distribution information"
[ -e /etc/lsb-release ] && cat /etc/lsb-release
[ -e /etc/redhat-release ] && cat /etc/redhat-release
[ -e /etc/alpine-release ] && cat /etc/alpine-release
print_header "ulimit -a"
ulimit -a
print_header "Available memory"
if [ -e /etc/alpine-release ]; then
# Alpine's busybox based free does not understand -h
free
else
free -h
fi
print_header "Available CPUs"
lscpu || :
set -x
}
# FIXME: workaround for the issue https://github.com/checkpoint-restore/criu/issues/1866
modprobe -v sit || :
print_env
ci_prep
if [ "${CD_TO_TOP}" = "1" ]; then
cd ../../
fi
export GCOV CC
if [ -z "$COMPILE_FLAGS" ]; then
LOCAL_COMPILE_FLAGS=("V=1")
else
IFS=" " read -r -a LOCAL_COMPILE_FLAGS <<< "$COMPILE_FLAGS"
LOCAL_COMPILE_FLAGS=("V=1" "${LOCAL_COMPILE_FLAGS[@]}")
fi
$CC --version
time make CC="$CC" -j4 "${LOCAL_COMPILE_FLAGS[@]}"
./criu/criu -v4 cpuinfo dump || :
./criu/criu -v4 cpuinfo check || :
# Check that help output fits into 80 columns
WIDTH=$(./criu/criu --help | wc --max-line-length)
if [ "$WIDTH" -gt 80 ]; then
echo "criu --help output does not obey 80 characters line width!"
exit 1
fi
# Unit tests at this point do not require any kernel or hardware capabilities.
# Just try to run it everywhere for now.
time make unittest
[ -n "$SKIP_CI_TEST" ] && exit 0
# Umount cpuset in cgroupv1 to make it move to cgroupv2
if [ -d /sys/fs/cgroup/cpuset ]; then
umount /sys/fs/cgroup/cpuset
fi
ulimit -c unlimited
cgid=$$
cleanup_cgroup() {
./test/zdtm_umount_cgroups $cgid
dmesg
}
trap cleanup_cgroup EXIT
./test/zdtm_mount_cgroups $cgid
echo "|$(pwd)/test/abrt.sh %P %p %s %e" > /proc/sys/kernel/core_pattern
if [ "${COMPAT_TEST}x" = "yx" ] ; then
# Dirty hack to keep both ia32 & x86_64 shared libs on a machine:
# headers are probably not compatible, so apt-get doesn't allow
# installing both versions, while we need one for CRIU and one
# for 32-bit tests. A better way would involve launching docker..
# But it would require making zdtm.py aware of docker and launching
# tests inside the CT.
INCOMPATIBLE_LIBS=(libaio-dev libcap-dev libnl-3-dev libnl-route-3-dev)
IA32_PKGS=()
REFUGE=64-refuge
mkdir "$REFUGE"
for i in "${INCOMPATIBLE_LIBS[@]}" ; do
for j in $(dpkg --listfiles "$i" | grep '\.so$') ; do
cp "$j" "$REFUGE/"
done
IA32_PKGS+=("$i:i386")
done
apt-get remove "${INCOMPATIBLE_LIBS[@]}"
dpkg --add-architecture i386
contrib/apt-install "${IA32_PKGS[@]}"
mkdir -p /usr/lib/x86_64-linux-gnu/
mv "$REFUGE"/* /usr/lib/x86_64-linux-gnu/
fi
time make CC="$CC" -j4 -C test/zdtm V=1
if [ "${COMPAT_TEST}x" = "yx" ] ; then
# Cross-verify that zdtm tests are 32-bit
file test/zdtm/static/env00 | grep 'ELF 32-bit' -q
fi
# umask has to be called before a first criu run, so that .gcda (coverage data)
# files are created with read-write permissions for all.
umask 0000
./criu/criu check
./criu/criu check --all || echo $?
if [ "$UNAME_M" == "x86_64" ]; then
# This fails on aarch64 (aws-graviton2)
./criu/criu cpuinfo dump
./criu/criu cpuinfo check
fi
export SKIP_PREP=1
chmod 0777 test/
chmod 0777 test/zdtm/static
chmod 0777 test/zdtm/transition
# We run streaming tests separately to improve test completion times,
# hence the exit 0.
if [ "${STREAM_TEST}" = "1" ]; then
./scripts/install-criu-image-streamer.sh
test_stream
exit 0
fi
./test/zdtm.py run -a -p 2 --keep-going "${ZDTM_OPTS[@]}"
if criu/criu check --feature move_mount_set_group; then
./test/zdtm.py run -a -p 2 --mntns-compat-mode --keep-going "${ZDTM_OPTS[@]}"
fi
./test/zdtm.py run -a -p 2 --keep-going --criu-config "${ZDTM_OPTS[@]}"
# Newer kernels are blocking access to userfaultfd:
# uffd: Set unprivileged_userfaultfd sysctl knob to 1 if kernel faults must be handled without obtaining CAP_SYS_PTRACE capability
if [ -e /proc/sys/vm/unprivileged_userfaultfd ]; then
echo 1 > /proc/sys/vm/unprivileged_userfaultfd
fi
LAZY_EXCLUDE=(-x maps04 -x cmdlinenv00 -x maps007)
LAZY_TESTS='.*(maps0|uffd-events|lazy-thp|futex|fork).*'
LAZY_OPTS=(-p 2 -T "$LAZY_TESTS" "${LAZY_EXCLUDE[@]}" "${ZDTM_OPTS[@]}")
./test/zdtm.py run "${LAZY_OPTS[@]}" --lazy-pages
./test/zdtm.py run "${LAZY_OPTS[@]}" --remote-lazy-pages
./test/zdtm.py run "${LAZY_OPTS[@]}" --remote-lazy-pages --tls
bash -x ./test/jenkins/criu-fault.sh
if [ "$UNAME_M" == "x86_64" ]; then
# This fails on aarch64 (aws-graviton2) with:
# 33: ERR: thread-bomb.c:49: pthread_attr_setstacksize(): 22
bash -x ./test/jenkins/criu-fcg.sh
fi
bash -x ./test/jenkins/criu-inhfd.sh
if [ -z "$SKIP_EXT_DEV_TEST" ]; then
make -C test/others/mnt-ext-dev/ run
if criu/criu check --feature move_mount_set_group; then
EXTRA_OPTS=--mntns-compat-mode make -C test/others/mnt-ext-dev/ run
fi
fi
make -C test/others/make/ run CC="$CC"
if [ -n "$CIRCLECI" ]; then
# GitHub Actions (and Cirrus CI) does not provide a real TTY and CRIU will fail with:
# Error (criu/tty.c:1014): tty: Don't have tty to inherit session from, aborting
make -C test/others/shell-job/ run
fi
make -C test/others/criu-ns/ run
make -C test/others/skip-file-rwx-check/ run
make -C test/others/rpc/ run
./test/zdtm.py run -t zdtm/static/env00 --sibling
./test/zdtm.py run -t zdtm/static/maps00 --preload-libfault
./test/zdtm.py run -t zdtm/static/maps02 --preload-libfault
./test/zdtm.py run -t zdtm/transition/maps007 --pre 2 --dedup
./test/zdtm.py run -t zdtm/transition/maps007 --pre 2 --noauto-dedup
./test/zdtm.py run -t zdtm/transition/maps007 --pre 2 --page-server
./test/zdtm.py run -t zdtm/transition/maps007 --pre 2 --page-server --dedup
./test/zdtm.py run -t zdtm/transition/maps007 --pre 2 --pre-dump-mode read
./test/zdtm.py run -t zdtm/transition/pid_reuse --pre 2 # start time based pid reuse detection
./test/zdtm.py run -t zdtm/transition/pidfd_store_sk --rpc --pre 2 # pidfd based pid reuse detection
./test/zdtm.py run -t zdtm/static/socket-tcp-local --norst
ip net add test
./test/zdtm.py run -t zdtm/static/env00 -f h --join-ns
# RPC testing
./test/zdtm.py run -t zdtm/static/env00 --rpc # Basic
./test/zdtm.py run -t zdtm/static/env00 --rpc --pre 2 --page-server
./test/zdtm.py run -t zdtm/static/ptrace_sig -f h --rpc # Error handling (crfail test)
./test/zdtm.py run --empty-ns -T zdtm/static/socket-tcp*-local --iter 2
./test/zdtm.py run -t zdtm/static/env00 -t zdtm/transition/fork -t zdtm/static/ghost_holes00 -t zdtm/static/socket-tcp -t zdtm/static/msgque -k always
./test/crit-recode.py
# Rootless tests
# Check if cap_checkpoint_restore is supported and also if unshare -c is supported.
#
# Do not run this test in a container (see https://github.com/checkpoint-restore/criu/issues/2312).
# Before v6.8-rc1~215^2~6, the kernel currently did not show correct device and
# inode numbers in /proc/pid/maps for stackable file systems.
skip=0
findmnt -no FSTYPE / | grep overlay && {
./criu/criu check --feature overlayfs_maps || skip=1
}
unshare -c /bin/true || skip=1
capsh --supports=cap_checkpoint_restore || skip=1
if [ "$skip" == 0 ]; then
make -C test/zdtm/ cleanout
rm -rf test/dump
setcap cap_checkpoint_restore,cap_sys_ptrace+eip criu/criu
if [ -d /sys/fs/selinux ] && command -v getenforce &>/dev/null; then
# Note: selinux in Enforcing mode prevents us from calling clone3() or writing to ns_last_pid on restore; hence set to Permissive for the test and then set back.
selinuxmode=$(getenforce)
if [ "$selinuxmode" != "Disabled" ]; then
setenforce Permissive
fi
fi
# Run it as non-root in a user namespace. Since CAP_CHECKPOINT_RESTORE behaves differently in non-user namespaces (e.g. no access to map_files) this tests that we can dump and restore
# under those conditions. Note that the "... && true" part is necessary; we need at least one statement after the tests so that bash can reap zombies in the user namespace,
# otherwise it will exec the last statement and get replaced and nobody will be left to reap our zombies.
sudo --user=#65534 --group=#65534 unshare -Ucfpm --mount-proc -- bash -c "./test/zdtm.py run -t zdtm/static/maps00 -f h --rootless && true"
if [ -d /sys/fs/selinux ] && command -v getenforce &>/dev/null; then
if [ "$selinuxmode" != "Disabled" ]; then
setenforce "$selinuxmode"
fi
fi
setcap -r criu/criu
else
echo "Skipping unprivileged mode tests"
fi
# more crit testing
make -C test/others/crit run
# coredump testing
make -C test/others/criu-coredump run
# libcriu testing
make -C test/others/libcriu run
# external namespace testing
make -C test/others/ns_ext run
# config file parser and parameter testing
make -C test/others/config-file run
# action script testing
make -C test/others/action-script run
# Skip all further tests when running with GCOV=1
# The one test which currently cannot handle GCOV testing is compel/test
# Probably because the GCOV Makefile infrastructure does not exist in compel
[ -n "$GCOV" ] && exit 0
# compel testing
make -C compel/test
# amdgpu and cuda plugin testing
make amdgpu_plugin
make -C plugins/amdgpu/ test_topology_remap
./plugins/amdgpu/test_topology_remap
./test/zdtm.py run -t zdtm/static/maps00 -t zdtm/static/maps02 --criu-plugin cuda
./test/zdtm.py run -t zdtm/static/maps00 -t zdtm/static/maps02 --criu-plugin amdgpu
./test/zdtm.py run -t zdtm/static/maps00 -t zdtm/static/maps02 --criu-plugin amdgpu cuda
./test/zdtm.py run -t zdtm/static/busyloop00 --criu-plugin inventory_test_enabled inventory_test_disabled
./test/zdtm.py run -t zdtm/static/sigpending -t zdtm/static/pthread00 --mocked-cuda-checkpoint --fault 138
|