mirror of
https://github.com/SCST-project/scst.git
synced 2026-10-22 06:02:33 +00:00
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.
110 lines
4.5 KiB
Bash
110 lines
4.5 KiB
Bash
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
# Invoked only by the dedicated guest target. The host owns the hard deadline.
|
|
set -euo pipefail
|
|
mount -t 9p -o trans=virtio,version=9p2000.L,ro ci-input /ci/input
|
|
mount -t 9p -o trans=virtio,version=9p2000.L ci-reports /ci/reports
|
|
mode=$(cat /ci/input/mode)
|
|
token=$(cat /ci/input/token)
|
|
finish() {
|
|
status=$?
|
|
trap - EXIT
|
|
dmesg --facility=kern > /ci/reports/dmesg.log || status=1
|
|
python3 - "$mode" "$token" "$status" <<'PY'
|
|
import json, os, pathlib, platform, sys
|
|
report = json.loads(pathlib.Path('/opt/ci-build/image.json').read_text())
|
|
report.update(mode=sys.argv[1], token=sys.argv[2], exit_code=int(sys.argv[3]),
|
|
running_kernel=platform.release())
|
|
path = pathlib.Path('/ci/reports/completion.tmp')
|
|
with path.open('w') as output:
|
|
json.dump(report, output)
|
|
output.flush()
|
|
os.fsync(output.fileno())
|
|
path.rename('/ci/reports/completion.json')
|
|
PY
|
|
sync
|
|
systemctl --no-block poweroff
|
|
exit "$status"
|
|
}
|
|
trap finish EXIT
|
|
test "$(uname -r)" = "$(python3 -c 'import json; print(json.load(open("/opt/ci-build/image.json"))["kernel"])')"
|
|
mountpoint -q /sys/kernel/debug || mount -t debugfs none /sys/kernel/debug
|
|
cd /scst
|
|
printf '%s\n' "$mode" > /ci/reports/started
|
|
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
|
export CGO_ENABLED=0 GOTOOLCHAIN=local GOPROXY=off
|
|
export GOCACHE=/opt/go-cache GOMODCACHE=/opt/go-mod
|
|
case "$mode" in
|
|
smoke) exit 0 ;;
|
|
panic) echo c > /proc/sysrq-trigger; exit 1 ;;
|
|
hang) sleep infinity ;;
|
|
kunit)
|
|
make kunit-run KUNIT_ARGS='--timeout 120 --output /ci/reports/kunit' \
|
|
2>&1 | tee /ci/reports/tests.log
|
|
;;
|
|
ginkgo|initiator)
|
|
# A local-only run has no initiator guest and no network.
|
|
local_only=
|
|
if [[ -e /ci/input/local-only ]]; then local_only=1; fi
|
|
if [[ ! $local_only ]]; then
|
|
while [[ ! -e /ci/input/ssh-ready ]]; do sleep 1; done
|
|
ip link set eth0 up
|
|
if [[ $mode == initiator ]]; then address=192.0.2.2; else address=192.0.2.1; fi
|
|
ip address add "$address/24" dev eth0
|
|
fi
|
|
if [[ $mode == initiator ]]; then
|
|
install -m 600 /ci/input/authorized_keys /root/.ssh/authorized_keys
|
|
install -m 600 /ci/input/ssh_host_key /run/ci-host-key
|
|
mkdir -p /run/sshd /etc/iscsi
|
|
printf '%s\n' 'InitiatorName=iqn.2026-10.org.scst:ci' > /etc/iscsi/initiatorname.iscsi
|
|
/usr/sbin/sshd -D -e -o HostKey=/run/ci-host-key -o UsePAM=yes \
|
|
-o PasswordAuthentication=no -o KbdInteractiveAuthentication=no \
|
|
-o PermitRootLogin=prohibit-password &
|
|
modprobe iscsi_tcp
|
|
systemctl start iscsid.service
|
|
# Publish readiness only once SSH accepts connections and iscsid is alive.
|
|
python3 - <<'PY'
|
|
import socket, time
|
|
for attempt in range(100):
|
|
try:
|
|
with socket.create_connection(('127.0.0.1', 22), timeout=1):
|
|
break
|
|
except OSError:
|
|
time.sleep(.1)
|
|
else:
|
|
raise SystemExit('sshd did not start')
|
|
PY
|
|
pgrep -x iscsid
|
|
touch /ci/reports/ready
|
|
sleep infinity
|
|
else
|
|
if [[ ! $local_only ]]; then
|
|
install -m 600 /ci/input/id_ed25519 /root/.ssh/id_ed25519
|
|
install -m 600 /ci/input/known_hosts /root/.ssh/known_hosts
|
|
while [[ ! -e /ci/input/peer-ready ]]; do sleep 1; done
|
|
fi
|
|
# This disk is created by the host supervisor exclusively for this run.
|
|
test "$(lsblk -dn -o SERIAL /dev/disk/by-id/virtio-scst-ci-data)" = scst-ci-data
|
|
python3 - "$local_only" <<'PY'
|
|
import json, pathlib, sys
|
|
config = dict(disposable_host=True,
|
|
admin_command=['/usr/bin/perl', '-I/scst/scstadmin/scstadmin.sysfs/scst-1.0.0/lib',
|
|
'/scst/scstadmin/scstadmin.sysfs/scstadmin'],
|
|
report_dir='/ci/reports/ginkgo', backing_dir='/ci/backing',
|
|
command_timeout='90s', cleanup_timeout='5m', settle_timeout='30s', suite_timeout='75m',
|
|
io=dict(block_device='/dev/disk/by-id/virtio-scst-ci-data', region_mb=16, timeout='5m'))
|
|
if not sys.argv[1]:
|
|
config['iscsi'] = dict(target_address='192.0.2.1', port=3260, login_timeout='30s',
|
|
initiator=dict(host='192.0.2.2', user='root', port=22,
|
|
identity_file='/root/.ssh/id_ed25519', lock_file='/tmp/scst-ginkgo.lock',
|
|
disposable_host=True))
|
|
pathlib.Path('/ci/config.json').write_text(json.dumps(config))
|
|
PY
|
|
label=$(cat /ci/input/ginkgo-label)
|
|
make ginkgo-test GINKGO_CONFIG=/ci/config.json GINKGO_LABEL="$label" \
|
|
2>&1 | tee /ci/reports/tests.log
|
|
fi
|
|
;;
|
|
*) echo "Unknown guest mode: $mode" >&2; exit 2 ;;
|
|
esac
|