Files
wenlxieandGleb Chesnokov 359dfbf11c ci: Run the scst_user Ginkgo specs on Linux 5.8 and 5.9
scst_user pins its data buffers from Linux 5.9, the first release in
which fork() gives the child a copy of a pinned page (commit
70e806e4e645, "mm: Do early cow for pinned pages during fork() for
ptes"). The Ginkgo "handler forks" spec checks this, but CI boots only
the current Fedora kernel, so the boundary itself is never tested.

Add a Ginkgo job matrix that runs the local "user" specs on Fedora 33's
Linux 5.8.18 and 5.9.16, on both sides of the boundary. On 5.9.16 the
fork spec relies on the pin alone; on 5.8.18 the handler protects its
buffers with MADV_DONTFORK, as required there. Both must keep correct
geometry and data. The jobs are named after their kernels, like the
regression jobs.

- kernel-5.8.env, kernel-5.9.env and their SHA256SUMS pin those kernels'
  rpms from Fedora's koji, like kernel.env and kernel.SHA256SUMS.
  Fedora's only 5.9.0 build is a rawhide kernel that defines RHEL_MAJOR 8
  and RHEL_MINOR 99, so SCST's backports treat it as RHEL and the build
  fails; 5.9.16 has the same fork() behavior.
- build-image takes an optional pin name, such as "kernel-5.9", for
  Ginkgo images. The image is otherwise built the same way.
- The Dockerfile downloads exactly the rpms listed in the selected
  checksum file, since 5.9 has no kernel-modules-core package.
- vm.py --local-only boots only the target guest, without the iSCSI
  initiator or the private network, and expects only the local report.
  The guest then writes a config without an iscsi section. The label
  filter is restricted to local specs: "local && (<filter>)", or "local"
  without one.
2026-10-20 08:43:01 +03:00

53 lines
2.3 KiB
Bash

#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-only
# Build a bootable, version-matched test image without booting or loading SCST.
set -euo pipefail
# KERNEL selects another pin pair, such as kernel-5.9.env and its SHA256SUMS.
if [[ ! ($# == 2 && $1 =~ ^(kunit|ginkgo)$ || $# == 3 && $1 == ginkgo && $3 =~ ^kernel-[0-9]+\.[0-9]+$) ]]; then
echo "Usage: $0 kunit|ginkgo OUTPUT_DIRECTORY" >&2
echo " $0 ginkgo OUTPUT_DIRECTORY kernel-MAJOR.MINOR" >&2
exit 2
fi
suite=$1
out=$(realpath -m "$2")
kernel=${3:-kernel}
mkdir "$out"
root=$(git rev-parse --show-toplevel)
commit=$(git rev-parse HEAD)
# shellcheck source=kernel.env
source "$root/scripts/ci/$kernel.env"
work=$(mktemp -d)
cleanup() {
rm -rf -- "$work"
}
trap cleanup EXIT
mkdir "$work/source" "$work/root"
# A committed snapshot excludes local profiles, generated files and Git credentials.
git -C "$root" archive "$commit" | tar -x -C "$work/source"
docker build --progress=plain \
--build-arg "KERNEL_BUILD=$KERNEL_BUILD" --build-arg "KERNEL_SUMS=$kernel.SHA256SUMS" \
--build-arg "SUITE=$suite" \
--build-arg "SOURCE_COMMIT=$commit" --output "type=tar,dest=$work/rootfs.tar" \
-f "$work/source/scripts/ci/Dockerfile" "$work/source" 2>&1 | tee "$out/image-build.log"
# Preserve guest owners without host root, mounts or loop devices. Extraction
# and mkfs must share one fakeroot session so ownership metadata survives.
fakeroot -- bash -euo pipefail /dev/stdin "$work" "$out" <<'SH'
tar -xpf "$1/rootfs.tar" -C "$1/root"
rm "$1/rootfs.tar"
chown 0:0 "$1/root"
# Fedora ships these with mode 000. fakeroot preserves metadata but cannot
# bypass host DAC when mkfs reads file contents; keep them root-only.
for file in "$1/root/etc"/{shadow,gshadow}{,-}; do
if [[ -f $file ]]; then chmod 600 "$file"; fi
done
cp -a "$1/root/opt/ci-build/." "$2/"
cp "$1/root/boot/ci-vmlinuz" "$2/vmlinuz"
cp "$1/root/boot/ci-initramfs" "$2/initramfs"
# Otherwise systemd can mistake the VM for a container and skip udev.
rm -f "$1/root/.dockerenv" "$1/root/run/.containerenv"
size=$(du -sm "$1/root" | cut -f1)
truncate -s "$((size + 2048))M" "$2/rootfs.img"
mkfs.ext4 -q -F -d "$1/root" "$2/rootfs.img"
SH
(cd "$out" && sha256sum vmlinuz initramfs rootfs.img image.json > SHA256SUMS)