From e47cf6901a9837b3d80b13a6b09d1fb3d0f78869 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Sat, 9 May 2026 06:09:20 +0000 Subject: [PATCH 01/14] lkl: disable -Wnull-pointer-arithmetic for asm-generic/io.h clang builds generates a high volume of warnings regarding undefined behavior due to null pointer arithmetic in asm-generic/io.h: ./include/asm-generic/io.h:548:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 548 | val = __raw_readb(PCI_IOBASE + addr); Suppresses the -Wnull-pointer-arithmetic warning for these macros to reduce compiler noise. Signed-off-by: Octavian Purdila --- arch/lkl/include/asm/io.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/lkl/include/asm/io.h b/arch/lkl/include/asm/io.h index 4a2aba31d8f5e2..9652daf7d68605 100644 --- a/arch/lkl/include/asm/io.h +++ b/arch/lkl/include/asm/io.h @@ -106,7 +106,16 @@ static inline void __iounmap(void __iomem *addr) #define iounmap __iounmap #endif +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnull-pointer-arithmetic" +#endif + #include +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + #endif /* _ASM_LKL_IO_H */ From 679de542eae41f07a15f68b534d16deb9f8e65d4 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Sat, 9 May 2026 06:52:48 +0000 Subject: [PATCH 02/14] lkl: add support for cross compiling with clang Cross compiling with clang requires a sysroot, so do the require plumbing to make it work with compilation and linking in tools/lkl. If a SYSROOT option is provided pass it to clang as well as add standard paths relative to the sysroot for headers and libraries. Signed-off-by: Octavian Purdila --- tools/lkl/Makefile.autoconf | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/lkl/Makefile.autoconf b/tools/lkl/Makefile.autoconf index 5c4e0194b31a9b..acb6af941573cf 100644 --- a/tools/lkl/Makefile.autoconf +++ b/tools/lkl/Makefile.autoconf @@ -14,12 +14,12 @@ $(shell echo "CONFIG_$(1)=$(2)" >> $(OUTPUT)/kernel.config) endef define find_include - $(eval include_paths=$(shell $(CC) -E -Wp,-v -xc /dev/null 2>&1 | grep '^ ')) - $(foreach f, $(include_paths), $(wildcard $(f)/$(1))) + $(eval include_paths=$(shell $(CC) $(SYSROOT_FLAGS) -E -Wp,-v -xc /dev/null 2>&1 | grep '^ ')) + $(foreach f,$(include_paths),$(wildcard $(f)/$(1))) endef define is_defined -$(shell $(CC) -dM -E - Date: Sat, 9 May 2026 07:06:09 +0000 Subject: [PATCH 03/14] lkl: fix a warning and errors for newer FreeBSD releases Fixes the following warnings and errors: In file included from lib/virtio_net_fd.c:16: ~/freebsd-sysroot/usr/include/sys/syslimits.h:38:2: warning: "No user-serviceable parts inside." [-W#warnings] 38 | #warning "No user-serviceable parts inside." | ^ lklfuse.c:284:18: error: use of undeclared identifier 'O_LARGEFILE' 284 | if (fi->flags & O_LARGEFILE) | ^ lklfuse.c:290:18: error: use of undeclared identifier 'O_NOATIME' 290 | if (fi->flags & O_NOATIME) | ^ lklfuse.c:298:18: error: use of undeclared identifier 'O_TMPFILE' 298 | if (fi->flags & O_TMPFILE) | ^ lib/posix-host.c:266:6: error: call to undeclared function 'pthread_attr_get_np'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 266 | if (pthread_getattr_np(pthread_self(), &thread_attr)) Signed-off-by: Octavian Purdila --- tools/lkl/lib/posix-host.c | 3 +++ tools/lkl/lib/virtio_net_fd.c | 3 +-- tools/lkl/lklfuse.c | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/lkl/lib/posix-host.c b/tools/lkl/lib/posix-host.c index 89fea03891bd8e..2f4e0191dd78a7 100644 --- a/tools/lkl/lib/posix-host.c +++ b/tools/lkl/lib/posix-host.c @@ -21,6 +21,9 @@ #include #include #include +#ifdef __FreeBSD__ +#include +#endif #include #include "iomem.h" #include "jmp_buf.h" diff --git a/tools/lkl/lib/virtio_net_fd.c b/tools/lkl/lib/virtio_net_fd.c index 4e2b67bfda0a0c..ae7032dd54038e 100644 --- a/tools/lkl/lib/virtio_net_fd.c +++ b/tools/lkl/lib/virtio_net_fd.c @@ -12,10 +12,9 @@ #include #include #include +#include #ifdef __FreeBSD__ #include -#else -#include #endif #include #include diff --git a/tools/lkl/lklfuse.c b/tools/lkl/lklfuse.c index ac40f16b2fc387..446966a12f923b 100644 --- a/tools/lkl/lklfuse.c +++ b/tools/lkl/lklfuse.c @@ -249,6 +249,12 @@ static int lklfuse_truncate(const char *path, off_t off, return ret; } +#ifdef __FreeBSD__ +#define O_LARGEFILE 0 +#define O_NOATIME 0 +#define O_TMPFILE 0 +#endif + static int lklfuse_open3(const char *path, bool create, mode_t mode, struct fuse_file_info *fi) { From 711a377061d548115b9d708a260026082a43d9de Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Sat, 9 May 2026 07:23:18 +0000 Subject: [PATCH 04/14] lkl: enable clang cross compiled FreeBSD build Add script to create a FreeBSD sysroot and enable clang based build. Builds are enabled in CI as well, but tests are not yet enabled. Signed-off-by: Octavian Purdila --- .github/workflows/ci.yml | 10 ++++++++++ tools/lkl/Makefile.autoconf | 3 ++- tools/lkl/scripts/freebsd-make-sysroot.sh | 24 +++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100755 tools/lkl/scripts/freebsd-make-sysroot.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2eef1ab49648e5..d3bbda929547c1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,6 +38,12 @@ jobs: runs_on: ubuntu-22.04 shell: bash build_options: "LLVM=1 CROSS_COMPILE=x86_64-linux-gnu" + - displayTargetName: freebsd + os: unix + runs_on: ubuntu-22.04 + shell: bash + build_options: "LLVM=1 CROSS_COMPILE=x86_64-unknown-freebsd SYSROOT=~/freebsd-sysroot" + make_sysroot: "./tools/lkl/scripts/freebsd-make-sysroot.sh" timeout-minutes: 100 env: CCACHE_DIR: ${{ github.workspace }}/.ccache @@ -150,10 +156,14 @@ jobs: echo MYSSH="$MYSSH" >> $GITHUB_ENV echo MYSCP="$MYSCP" >> $GITHUB_ENV echo LKL_QEMU_TEST=1 >> $GITHUB_ENV + - name: Make sysroot + run: | + ${{ matrix.make_sysroot }} - name: Build run: | make -j4 -C tools/lkl ${{ matrix.build_options }} - name: Tests + if: matrix.displayTargetName != 'freebsd' run: mkdir junit && make -C tools/lkl run-tests tests="--junit-dir ../../junit" - name: Save test results uses: actions/upload-artifact@v5 diff --git a/tools/lkl/Makefile.autoconf b/tools/lkl/Makefile.autoconf index acb6af941573cf..b665f75bfefb9c 100644 --- a/tools/lkl/Makefile.autoconf +++ b/tools/lkl/Makefile.autoconf @@ -138,7 +138,8 @@ endef define llvm_target_to_ld_fmt $(if $(filter $(CROSS_COMPILE),x86_64-linux-gnu),elf64-x86-64,\ - $(error Unsupported LLVM target $(CROSS_COMPILE))) + $(if $(filter $(CROSS_COMPILE),x86_64-unknown-freebsd),elf64-x86-64-freebsd, \ + $(error Unsupported LLVM target $(CROSS_COMPILE)))) endef define llvm_sysroot diff --git a/tools/lkl/scripts/freebsd-make-sysroot.sh b/tools/lkl/scripts/freebsd-make-sysroot.sh new file mode 100755 index 00000000000000..a22abe903ece08 --- /dev/null +++ b/tools/lkl/scripts/freebsd-make-sysroot.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +function package_path() +{ + grep \"name\":\"$1\" packagesite.yaml | jq -r .repopath +} + +mkdir -p ~/freebsd-sysroot +cd ~/freebsd-sysroot +wget -q https://download.freebsd.org/releases/amd64/14.4-RELEASE/base.txz +tar -xf base.txz --exclude='./dev/*' --exclude='./chroot/*' + +# Get FreeBSD package index... +wget -q https://pkg.freebsd.org/FreeBSD:14:amd64/latest/packagesite.pkg +tar -xf packagesite.pkg packagesite.yaml + +wget -q https://pkg.freebsd.org/FreeBSD:14:amd64/latest/$(package_path argp-standalone) +wget -q https://pkg.freebsd.org/FreeBSD:14:amd64/latest/$(package_path fusefs-libs3) + +tar -xf argp-standalone-*.pkg +tar -xf fusefs-libs3-*.pkg + +rm fusefs-libs3-*.pkg argp-standalone-*.pkg base.txz packagesite.pkg packagesite.yaml From 3ac2b715503d74ff874fb37daafbf2a7d46016e7 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Wed, 3 Jun 2026 17:04:13 +0000 Subject: [PATCH 05/14] lkl/ci: enable QEMU for FreeBSD Add scripts to create FreeBSD images and to start a FreeBSD VM. Rename Linux VM scripts so that we can use the same logic in the workflow for both FreeBSD and Linux runs. Signed-off-by: Octavian Purdila --- .github/workflows/ci.yml | 10 ++-- tools/lkl/scripts/qemu-freebsd-make-images.sh | 60 +++++++++++++++++++ .../scripts/qemu-freebsd-start-and-set-env.sh | 13 ++++ ...ke-images.sh => qemu-linux-make-images.sh} | 0 ...env.sh => qemu-linux-start-and-set-env.sh} | 0 5 files changed, 79 insertions(+), 4 deletions(-) create mode 100755 tools/lkl/scripts/qemu-freebsd-make-images.sh create mode 100644 tools/lkl/scripts/qemu-freebsd-start-and-set-env.sh rename tools/lkl/scripts/{qemu-x86_64-make-images.sh => qemu-linux-make-images.sh} (100%) rename tools/lkl/scripts/{qemu-x86_64-start-and-set-env.sh => qemu-linux-start-and-set-env.sh} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3bbda929547c1..bbf26e5c8bda47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,7 @@ jobs: os: unix runs_on: ubuntu-22.04 shell: bash + run_qemu: true - displayTargetName: kunit os: unix runs_on: ubuntu-22.04 @@ -44,6 +45,7 @@ jobs: shell: bash build_options: "LLVM=1 CROSS_COMPILE=x86_64-unknown-freebsd SYSROOT=~/freebsd-sysroot" make_sysroot: "./tools/lkl/scripts/freebsd-make-sysroot.sh" + run_qemu: true timeout-minutes: 100 env: CCACHE_DIR: ${{ github.workspace }}/.ccache @@ -147,12 +149,12 @@ jobs: echo "setting env variable (debug)" echo "ZPOLINE_DEBUG=0" >> "$GITHUB_ENV" - name: Start QEMU - if: matrix.displayTargetName == 'linux' + if: matrix.run_qemu run: | - ./tools/lkl/scripts/qemu-x86_64-make-images.sh + ./tools/lkl/scripts/qemu-${{ matrix.displayTargetName }}-make-images.sh sudo chmod a+rw /dev/kvm - . tools/lkl/scripts/qemu-x86_64-start-and-set-env.sh - echo MYHOST="$HOST" >> $GITHUB_ENV + . tools/lkl/scripts/qemu-${{ matrix.displayTargetName }}-start-and-set-env.sh + echo MYHOST="$MYHOST" >> $GITHUB_ENV echo MYSSH="$MYSSH" >> $GITHUB_ENV echo MYSCP="$MYSCP" >> $GITHUB_ENV echo LKL_QEMU_TEST=1 >> $GITHUB_ENV diff --git a/tools/lkl/scripts/qemu-freebsd-make-images.sh b/tools/lkl/scripts/qemu-freebsd-make-images.sh new file mode 100755 index 00000000000000..03b42af26580ee --- /dev/null +++ b/tools/lkl/scripts/qemu-freebsd-make-images.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +if ! [ -e FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz ]; then + wget -q https://download.freebsd.org/releases/VM-IMAGES/14.4-RELEASE/amd64/Latest/FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz +fi +unxz -k -f FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz + +cat > cloud-freebsd.yml < Date: Wed, 3 Jun 2026 17:59:03 +0000 Subject: [PATCH 06/14] lkl tests: skip disk-vfio-pci for FreeBSD Skip building and running tests for disk-vfio-pci on FreeBSD. Signed-off-by: Octavian Purdila --- tools/lkl/Targets | 2 ++ tools/lkl/tests/disk-vfio-pci.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/lkl/Targets b/tools/lkl/Targets index 9c31b76a4fae1f..bedc64d94ea362 100644 --- a/tools/lkl/Targets +++ b/tools/lkl/Targets @@ -33,7 +33,9 @@ LDLIBS_cptofs-$(LKL_HOST_CONFIG_NEEDS_LARGP) += -largp tests-priv-y := tests/tests-common tests-y := tests/disk tests-y += tests/boot +ifneq ($(LKL_HOST_CONFIG_BSD),y) tests-y += tests/disk-vfio-pci +endif tests-y += tests/net-test tests-y += tests/config ifneq ($(LKL_HOST_CONFIG_BSD),y) diff --git a/tools/lkl/tests/disk-vfio-pci.sh b/tools/lkl/tests/disk-vfio-pci.sh index 62e6ed85f50c9b..ab6c798839cb3b 100755 --- a/tools/lkl/tests/disk-vfio-pci.sh +++ b/tools/lkl/tests/disk-vfio-pci.sh @@ -40,7 +40,7 @@ function cleanup() sudo tee /sys/bus/pci/drivers/vfio-pci/unbind'" } -if [ -z "$LKL_QEMU_TEST" ]; then +if [ -z "$LKL_QEMU_TEST" ] || ! [ -e $script_dir/disk-vfio-pci ] ; then lkl_test_plan 0 "disk-vfio-pci" echo "vfio not supported" else From 9900d3cdbfa0219bb4db6b22aca2e59eba5f027d Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Wed, 3 Jun 2026 18:11:47 +0000 Subject: [PATCH 07/14] lkl tests: add filesystem image setup and cleanup helpers Add filesystem image setup and cleanup helpers and use them to avoid code duplication between the disk and lklfuse tests. Signed-off-by: Octavian Purdila --- tools/lkl/tests/disk.sh | 46 +++-------------------------------- tools/lkl/tests/fs.sh | 50 ++++++++++++++++++++++++++++++++++++++ tools/lkl/tests/lklfuse.sh | 22 +++++------------ 3 files changed, 59 insertions(+), 59 deletions(-) create mode 100644 tools/lkl/tests/fs.sh diff --git a/tools/lkl/tests/disk.sh b/tools/lkl/tests/disk.sh index b7b431a5650886..277a2be5c3ad63 100755 --- a/tools/lkl/tests/disk.sh +++ b/tools/lkl/tests/disk.sh @@ -3,47 +3,7 @@ script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd) source $script_dir/test.sh - -function prepfs() -{ - set -e - - file=`mktemp disk-XXXX` - - dd if=/dev/zero of=$file bs=1048576 count=300 - - yes | mkfs.$1 $file - - if ! [ -z $ANDROID_WDIR ]; then - adb shell mkdir -p $ANDROID_WDIR - adb push $file $ANDROID_WDIR - rm $file - file=$ANDROID_WDIR/$(basename $file) - fi - if ! [ -z $BSD_WDIR ]; then - $MYSSH mkdir -p $BSD_WDIR - ssh_copy $file $BSD_WDIR - rm $file - file=$BSD_WDIR/$(basename $file) - fi - - export_vars file -} - -function cleanfs() -{ - set -e - - if ! [ -z $ANDROID_WDIR ]; then - adb shell rm $file - adb shell rm $ANDROID_WDIR/disk - elif ! [ -z $BSD_WDIR ]; then - $MYSSH rm $file - $MYSSH rm $BSD_WDIR/disk - else - rm $file - fi -} +source $script_dir/fs.sh if [ "$1" = "-t" ]; then shift @@ -62,8 +22,8 @@ if [ -z $(which mkfs.$fstype) ]; then fi lkl_test_plan 1 "disk $fstype" -lkl_test_run 1 prepfs $fstype +lkl_test_run 1 prepfsimg $fstype lkl_test_exec $script_dir/disk -d $file -t $fstype $@ lkl_test_plan 1 "disk $fstype" -lkl_test_run 1 cleanfs +lkl_test_run 1 cleanfsimg diff --git a/tools/lkl/tests/fs.sh b/tools/lkl/tests/fs.sh new file mode 100644 index 00000000000000..630b31fb64ca5c --- /dev/null +++ b/tools/lkl/tests/fs.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0 + +prepfsimg() +{ + set -e + + file=`mktemp disk-XXXX` + + size_mb=10 + if [ $1 == "xfs" ]; then + size_mb=300 + elif [ $1 == "btrfs" ]; then + size_mb=115 + fi + + dd if=/dev/zero of=$file bs=1048576 count=$size_mb + + yes | mkfs.$1 $file + + if ! [ -z $ANDROID_WDIR ]; then + adb shell mkdir -p $ANDROID_WDIR + adb push $file $ANDROID_WDIR + rm $file + file=$ANDROID_WDIR/$(basename $file) + fi + if ! [ -z $BSD_WDIR ]; then + $MYSSH mkdir -p $BSD_WDIR + $MYSCP $file $MYHOST:$BSD_WDIR + rm $file + file=$BSD_WDIR/$(basename $file) + fi + + export_vars file +} + +cleanfsimg() +{ + set -e + + if ! [ -z $ANDROID_WDIR ]; then + adb shell rm -f $file + adb shell rm -f $ANDROID_WDIR/disk + elif ! [ -z $BSD_WDIR ]; then + $MYSSH rm -f $file + $MYSSH rm -f $BSD_WDIR/disk + else + rm -f $file + fi +} diff --git a/tools/lkl/tests/lklfuse.sh b/tools/lkl/tests/lklfuse.sh index df160279792b89..ad90a93825b18b 100755 --- a/tools/lkl/tests/lklfuse.sh +++ b/tools/lkl/tests/lklfuse.sh @@ -3,6 +3,7 @@ script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd) source $script_dir/test.sh +source $script_dir/fs.sh cleanup() { @@ -13,24 +14,14 @@ cleanup() else fusermount -u $dir fi - rm $file + cleanfsimg rmdir $dir } -# $1 - fstype -function prepfs() -{ - set -e - - dd if=/dev/zero of=$file bs=1048576 count=300 - - yes | mkfs.$1 $file -} - # $1 - filesystem type lklfuse_mount() { - ${script_dir}/../lklfuse $file $dir -o type=$1,lock=$lock_file + ${script_dir}/../lklfuse $file $dir -o type=$1,lock=$file } lklfuse_basic() @@ -108,15 +99,14 @@ if [ -z $(which mkfs.$fstype) ]; then exit 0 fi -file=`mktemp` -dir=`mktemp -d` -lock_file="$file" +dir=`mktemp -d mnt-XXXX` +export_vars dir trap cleanup EXIT lkl_test_plan 5 "lklfuse $fstype" -lkl_test_run 1 prepfs $fstype +lkl_test_run 1 prepfsimg $fstype lkl_test_run 2 lklfuse_mount $fstype lkl_test_run 3 lklfuse_basic # stress-ng returns 2 with no apparent failures so skip it for now From e4253c9f263e3ece38767f07f0326e9bf7569758 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Wed, 3 Jun 2026 23:45:04 +0000 Subject: [PATCH 08/14] lkl tests: convert lklfuse test for remote execution To avoid "file text busy" error when running the lklfuse_lock_conflict test use lkl_test_cmd instead of lkl_test_exec for BSD test runs. This will avoid copying the binary again. Signed-off-by: Octavian Purdila --- tools/lkl/tests/lklfuse.sh | 43 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/tools/lkl/tests/lklfuse.sh b/tools/lkl/tests/lklfuse.sh index ad90a93825b18b..b53c07d72c1f33 100755 --- a/tools/lkl/tests/lklfuse.sh +++ b/tools/lkl/tests/lklfuse.sh @@ -7,34 +7,34 @@ source $script_dir/fs.sh cleanup() { - set -e - - if type -P fusermount3 > /dev/null; then - fusermount3 -u $dir + umount_cmd=$(lkl_test_cmd 'which fusermount3 || which fusermount') + if [ -n "$umount_cmd" ]; then + lkl_test_cmd $umount_cmd -u $dir else - fusermount -u $dir + lkl_test_cmd umount $dir fi cleanfsimg - rmdir $dir + lkl_test_cmd rmdir $dir } # $1 - filesystem type lklfuse_mount() { - ${script_dir}/../lklfuse $file $dir -o type=$1,lock=$file + dir=$(lkl_test_cmd mktemp -d mnt-XXXX) + export_vars dir + lkl_test_exec ${script_dir}/../lklfuse $file $dir -o type=$1,lock=$file } lklfuse_basic() { set -e - cd $dir - touch a - if ! [ -e ]; then exit 1; fi - rm a - mkdir a - if ! [ -d ]; then exit 1; fi - rmdir a + lkl_test_cmd touch $dir/a + lkl_test_cmd test -e $dir/a + lkl_test_cmd rm $dir/a + lkl_test_cmd mkdir $dir/a + lkl_test_cmd test -d $dir/a + lkl_test_cmd rmdir $dir/a } # $1 - filesystem type @@ -61,13 +61,17 @@ lklfuse_stressng() # $1 - filesystem type lklfuse_lock_conflict() { - local ret=$TEST_FAILURE unused_mnt=`mktemp -d` + local ret=$TEST_FAILURE unused_mnt=$(lkl_test_cmd mktemp -d) set +e # assume lklfuse already running with same lock file, causing lock conflict - ${script_dir}/../lklfuse -f $file $unused_mnt -o type=$1,lock=$lock_file + if [ -n "$BSD_WDIR" ]; then + lkl_test_cmd $BSD_WDIR/lklfuse -f $file $unused_mnt -o type=$1,lock=$file + else + lkl_test_exec ${script_dir}/../lklfuse -f $file $unused_mnt -o type=$1,lock=$file + fi [ $? -eq 2 ] && ret=$TEST_SUCCESS - rmdir "$unused_mnt" + lkl_test_cmd rmdir "$unused_mnt" return $ret } @@ -87,7 +91,7 @@ if [ "$LKL_HOST_CONFIG_FUSE" != "y" ]; then exit 0 fi -if ! [ -e /dev/fuse ]; then +if ! QUIET=1 lkl_test_cmd test -e /dev/fuse; then lkl_test_plan 0 "lklfuse.sh $fstype" echo "/dev/fuse not available" exit 0 @@ -99,9 +103,6 @@ if [ -z $(which mkfs.$fstype) ]; then exit 0 fi -dir=`mktemp -d mnt-XXXX` -export_vars dir - trap cleanup EXIT lkl_test_plan 5 "lklfuse $fstype" From 577480ddb8ad08ffdc87fa618c63a1c284800b84 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 4 Jun 2026 00:10:15 +0000 Subject: [PATCH 09/14] lkl tests: cleanup test.sh Make the output quiet and remove unused ssh_push. Signed-off-by: Octavian Purdila --- tools/lkl/tests/test.sh | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/tools/lkl/tests/test.sh b/tools/lkl/tests/test.sh index c81bbe3ca75685..03946da5f3ae0b 100644 --- a/tools/lkl/tests/test.sh +++ b/tools/lkl/tests/test.sh @@ -97,7 +97,7 @@ lkl_test_exec() file=$file.exe fi - if file $file | grep "interpreter /system/bin/linker" ; then + if file $file | grep -q "interpreter /system/bin/linker"; then adb push "$file" $ANDROID_WDIR if [ -n "$SUDO" ]; then ANDROID_USER=root @@ -110,13 +110,13 @@ lkl_test_exec() fi WRAPPER="adb shell $SU" file=$ANDROID_WDIR/$(basename $file) - elif file $file | grep PE32; then - if uname -s | grep Linux; then + elif file $file | grep -q PE32; then + if uname -s | grep -q Linux; then WRAPPER="wine" - fi - elif file $file | grep ARM; then + fi + elif file $file | grep -q ARM; then WRAPPER="qemu-arm-static" - elif file $file | grep "FreeBSD" ; then + elif file $file | grep -q "FreeBSD"; then ssh_copy "$file" $BSD_WDIR if [ -n "$SUDO" ]; then SUDO="" @@ -190,29 +190,6 @@ adb_push() done } -# XXX: $MYSSH and $MYSCP are defined in a circleci docker image. -# see the definitions in lkl/lkl-docker:circleci/freebsd11/Dockerfile -ssh_push() -{ - while [ -n "$1" ]; do - if [[ "$1" = *.sh ]]; then - type="script" - else - type="file" - fi - - dir=$(dirname $1) - $MYSSH mkdir -p $BSD_WDIR/$dir - - $MYSCP -P 7722 -r $basedir/$1 root@localhost:$BSD_WDIR/$dir - if [ "$type" = "script" ]; then - $MYSSH chmod a+x $BSD_WDIR/$1 - fi - - shift - done -} - ssh_copy() { $MYSCP -P 7722 -r $1 root@localhost:$2 From d8c5d92916cfd186cf472f29a33412c5808351df Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 4 Jun 2026 00:15:42 +0000 Subject: [PATCH 10/14] lkl/ci: enable FreeBSD tests on github Switch running the FreeBSD tests to github and remove the circleci FreeBSD steps. Doing so requires minor changes in the test infrastructure. Signed-off-by: Octavian Purdila --- .circleci/config.yml | 15 --------------- .github/workflows/ci.yml | 1 - tools/lkl/tests/test.sh | 17 +++++------------ 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 10fb5046c74c27..bae425bc04a192 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -56,8 +56,6 @@ do_steps: &do_steps command: | if [[ $CROSS_COMPILE == *android* ]]; then emulator -avd Nexus5_API24 -no-window -no-audio -no-boot-anim; - elif [[ $CROSS_COMPILE == *freebsd* ]] || [[ -n "$LKL_QEMU_TEST" ]]; then - cd /home/ubuntu && eval $QEMU fi background: true - run: cd tools/lkl && make -j8 ${MKARG} @@ -71,11 +69,6 @@ do_steps: &do_steps command: | if [[ $CROSS_COMPILE == *android* ]]; then /home/ubuntu/circle-android.sh wait-for-boot; - elif [[ $CROSS_COMPILE == *freebsd* ]] || [[ -n "$LKL_QEMU_TEST" ]]; then - while ! $MYSSH -o ConnectTimeout=1 exit 2> /dev/null - do - sleep 5 - done fi - run: name: run tests @@ -116,13 +109,6 @@ jobs: ANDROID_SDK_ROOT: /home/ubuntu/android-sdk <<: *do_steps - freebsd11_x86_64: - docker: - - image: lkldocker/circleci-freebsd11-x86_64:v1.4 - environment: - CROSS_COMPILE: "x86_64-pc-freebsd11-" - <<: *do_steps - x86_64_valgrind: docker: - image: lkldocker/circleci-x86_64:v1.4 @@ -137,7 +123,6 @@ workflows: build: jobs: - android-aarch64 - - freebsd11_x86_64 - i386 nightly: triggers: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbf26e5c8bda47..85f0524a948601 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -165,7 +165,6 @@ jobs: run: | make -j4 -C tools/lkl ${{ matrix.build_options }} - name: Tests - if: matrix.displayTargetName != 'freebsd' run: mkdir junit && make -C tools/lkl run-tests tests="--junit-dir ../../junit" - name: Save test results uses: actions/upload-artifact@v5 diff --git a/tools/lkl/tests/test.sh b/tools/lkl/tests/test.sh index 03946da5f3ae0b..42a99cc5518f1e 100644 --- a/tools/lkl/tests/test.sh +++ b/tools/lkl/tests/test.sh @@ -117,11 +117,8 @@ lkl_test_exec() elif file $file | grep -q ARM; then WRAPPER="qemu-arm-static" elif file $file | grep -q "FreeBSD"; then - ssh_copy "$file" $BSD_WDIR - if [ -n "$SUDO" ]; then - SUDO="" - fi - WRAPPER="$MYSSH $SU" + $MYSCP $file $MYHOST:$BSD_WDIR + WRAPPER="$MYSSH $SUDO" # ssh will mess up with pipes ('|') so, escape the pipe char. args="${@//\|/\\\|}" set - $BSD_WDIR/$(basename $file) $args @@ -160,7 +157,8 @@ lkl_test_cmd() fi WRAPPER="adb shell $SU" elif [ -n "$LKL_HOST_CONFIG_BSD" ]; then - WRAPPER="$MYSSH $SU" + WRAPPER="$MYSSH" + USER=lkl fi echo "$@" | $WRAPPER sh $SHOPTS @@ -190,11 +188,6 @@ adb_push() done } -ssh_copy() -{ - $MYSCP -P 7722 -r $1 root@localhost:$2 -} - lkl_test_android_cleanup() { adb shell rm -rf $ANDROID_WDIR @@ -213,6 +206,6 @@ fi if [ -n "$LKL_HOST_CONFIG_BSD" ]; then trap lkl_test_bsd_cleanup EXIT - export BSD_WDIR=/root/lkl + export BSD_WDIR=lkl $MYSSH mkdir -p $BSD_WDIR fi From b83c450acb639743a928aef0cffaac1cff032253 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 4 Jun 2026 16:34:47 +0000 Subject: [PATCH 11/14] lkl/ci: update ccache key to per matrix entry Now that we have many builds for the same OS (gcc, clang, freebsd) a common ccache for all these builds is not working anymore. Use separate ccache instances for each build variant. Signed-off-by: Octavian Purdila --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85f0524a948601..273199f7ec97a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,8 +111,8 @@ jobs: - uses: actions/cache@v4 with: path: ${{ env.CCACHE_DIR }} - key: ${{ runner.os }}-ccache-build-${{ github.sha }} - restore-keys: ${{ runner.os }}-ccache-build- + key: ${{ matrix.displayTargetName }}-ccache-build-${{ github.sha }} + restore-keys: ${{ matrix.displayTargetName }}-ccache-build- - name: Install ccache on ubuntu-latest if: runner.os == 'Linux' run: | From d3bd158d253ad60451ea749f7c43b9c978f2f09e Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 4 Jun 2026 17:33:26 +0000 Subject: [PATCH 12/14] lkl/ci: integrate fuzzers builds in the test matrix Even though we don't actually run tests for fuzzers (yet) integrating it in the matrix test job will allow us to reuse some of the optimizations we've been using there (like ccache). Also, eventually, we will enable tests for fuzzers as well. Also remove the clang-build as we already exercise it now with both FreeBSD and fuzzers. Signed-off-by: Octavian Purdila --- .github/workflows/ci.yml | 45 ++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 273199f7ec97a7..037c7efab5c996 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,11 +34,6 @@ jobs: runs_on: windows-2022 pip_option: --break-system-packages shell: msys2 {0} - - displayTargetName: clang-build - os: unix - runs_on: ubuntu-22.04 - shell: bash - build_options: "LLVM=1 CROSS_COMPILE=x86_64-linux-gnu" - displayTargetName: freebsd os: unix runs_on: ubuntu-22.04 @@ -46,10 +41,17 @@ jobs: build_options: "LLVM=1 CROSS_COMPILE=x86_64-unknown-freebsd SYSROOT=~/freebsd-sysroot" make_sysroot: "./tools/lkl/scripts/freebsd-make-sysroot.sh" run_qemu: true + - displayTargetName: fuzzers + os: unix + runs_on: ubuntu-22.04 + shell: bash + build_options: "LKL_FUZZING=1 MMU=1 fuzzers" + timeout-minutes: 100 env: CCACHE_DIR: ${{ github.workspace }}/.ccache USE_CCACHE: 1 + PROTOBUF_MUTATOR_DIR: /tmp/libprotobuf-mutator defaults: run: @@ -117,7 +119,10 @@ jobs: if: runner.os == 'Linux' run: | sudo apt update -y - sudo apt install -y ccache libjsmn-dev libfuse3-dev clang lld llvm qemu-system-x86 qemu-utils sshpass cloud-image-utils + sudo apt install -y ccache libjsmn-dev libfuse3-dev clang lld llvm qemu-system-x86 \ + qemu-utils sshpass cloud-image-utils binutils cmake ninja-build liblzma-dev libz-dev \ + pkg-config autoconf libtool + - name: Install patched binutils for Windows if: runner.os == 'Windows' run: | @@ -161,10 +166,14 @@ jobs: - name: Make sysroot run: | ${{ matrix.make_sysroot }} + - name: Build libprotobuf-mutator + if: matrix.displayTargetName == 'fuzzers' + run: tools/lkl/scripts/libprotobuf-mutator-build.sh - name: Build run: | make -j4 -C tools/lkl ${{ matrix.build_options }} - name: Tests + if: matrix.displayTargetName != 'fuzzers' run: mkdir junit && make -C tools/lkl run-tests tests="--junit-dir ../../junit" - name: Save test results uses: actions/upload-artifact@v5 @@ -195,27 +204,3 @@ jobs: run: sudo pip install ply GitPython - name: Check coding style run: tools/lkl/scripts/checkpatch.sh - - fuzzers: - runs-on: ubuntu-22.04 - name: fuzzers - env: - PROTOBUF_MUTATOR_DIR: /tmp/libprotobuf-mutator - steps: - - name: Checkout - with: - fetch-depth: 0 - uses: actions/checkout@v4 - - name: Install clang toolchain - run: | - sudo apt update -y - sudo apt install -y clang lld llvm - - name: Install libprotobuf-mutator prerequisites - run: | - sudo apt update -y - sudo apt install -y binutils cmake ninja-build liblzma-dev libz-dev \ - pkg-config autoconf libtool - - name: Build libprotobuf-mutator - run: tools/lkl/scripts/libprotobuf-mutator-build.sh - - name: Build fuzzers - run: make -j4 -C tools/lkl LKL_FUZZING=1 MMU=1 fuzzers From 56a27a7cb00606160405b7f8920872460df80a97 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 4 Jun 2026 18:05:28 +0000 Subject: [PATCH 13/14] lkl tests: add test to wait for vm to boot Add a test that runs first and waits for the VM to boot. Alternatively this can be implemented in CI only, but implementing it this way is also useful for local testing. Signed-off-by: Octavian Purdila --- tools/lkl/tests/disk-vfio-pci.sh | 12 ------------ tools/lkl/tests/run.py | 1 + tools/lkl/tests/vm-boot.sh | 22 ++++++++++++++++++++++ 3 files changed, 23 insertions(+), 12 deletions(-) create mode 100755 tools/lkl/tests/vm-boot.sh diff --git a/tools/lkl/tests/disk-vfio-pci.sh b/tools/lkl/tests/disk-vfio-pci.sh index ab6c798839cb3b..cddc5d86cf7449 100755 --- a/tools/lkl/tests/disk-vfio-pci.sh +++ b/tools/lkl/tests/disk-vfio-pci.sh @@ -8,16 +8,6 @@ pciname="0000:00:03.0" nvme_id="8086 5845" bin_name="disk-vfio-pci" -function wait_guest() -{ - for i in `seq 300`; do - if $MYSSH exit 2> /dev/null; then - break - fi - sleep 1 - done -} - function init() { # initialize @@ -44,8 +34,6 @@ if [ -z "$LKL_QEMU_TEST" ] || ! [ -e $script_dir/disk-vfio-pci ] ; then lkl_test_plan 0 "disk-vfio-pci" echo "vfio not supported" else - lkl_test_plan 1 "disk-vfio-pci" - lkl_test_run 1 wait_guest lkl_test_plan 1 "disk-vfio-pci" lkl_test_run 1 init lkl_test_exec $MYSSH ./$bin_name -n $pciname diff --git a/tools/lkl/tests/run.py b/tools/lkl/tests/run.py index ca16f98841b51f..bdea6225df73fd 100755 --- a/tools/lkl/tests/run.py +++ b/tools/lkl/tests/run.py @@ -47,6 +47,7 @@ def end(self, obj): mydir=os.path.dirname(os.path.realpath(__file__)) tests = [ + 'vm-boot.sh', 'boot.sh', 'disk.sh -t ext4', 'disk.sh -t btrfs', diff --git a/tools/lkl/tests/vm-boot.sh b/tools/lkl/tests/vm-boot.sh new file mode 100755 index 00000000000000..3e780e5735f5b7 --- /dev/null +++ b/tools/lkl/tests/vm-boot.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0 + +script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd) +source $script_dir/test.sh + +function vm_boot() +{ + if [ -z "$LKL_QEMU_TEST" ]; then + return + fi + + for i in `seq 300`; do + if $MYSSH exit 2> /dev/null; then + break + fi + sleep 1 + done +} + +lkl_test_plan 1 "vm-boot" +lkl_test_run 1 vm_boot From bf73cae80cc5b22a11f2869afcb866497d64e1a3 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 4 Jun 2026 19:18:38 +0000 Subject: [PATCH 14/14] lkl: lib: remove dead code Remove dead code caught by LLVM. Fixes the following warnings: lib/net.c:44:20: warning: unused function 'set_sockaddr' [-Wunused-function] static inline void set_sockaddr(struct lkl_sockaddr_in *sin, unsigned int addr, lib/config.c:431:16: warning: variable 'bytes_read' set but not used [-Wunused-but-set-variable] int ret = -1, bytes_read = 0; Signed-off-by: Octavian Purdila --- tools/lkl/lib/config.c | 4 ++-- tools/lkl/lib/net.c | 8 -------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/tools/lkl/lib/config.c b/tools/lkl/lib/config.c index 1488aace128708..03be99d97a96d2 100644 --- a/tools/lkl/lib/config.c +++ b/tools/lkl/lib/config.c @@ -428,7 +428,7 @@ static void add_neighbor(int ifindex, char *entries) */ static int dump_file(char *path) { - int ret = -1, bytes_read = 0; + int ret = -1; char str[1024] = { 0 }; int fd; @@ -443,7 +443,7 @@ static int dump_file(char *path) /* Need to print this out in order to make sense of the output */ lkl_printf("Reading from %s:\n==========\n", path); while ((ret = lkl_sys_read(fd, str, sizeof(str) - 1)) > 0) - bytes_read += lkl_printf("%s", str); + lkl_printf("%s", str); lkl_printf("==========\n"); if (ret) { diff --git a/tools/lkl/lib/net.c b/tools/lkl/lib/net.c index 967e1dac5cb371..8c4f692308c5c8 100644 --- a/tools/lkl/lib/net.c +++ b/tools/lkl/lib/net.c @@ -41,14 +41,6 @@ int lkl_inet_pton(int af, const char *src, void *dst) } #endif -static inline void set_sockaddr(struct lkl_sockaddr_in *sin, unsigned int addr, - unsigned short port) -{ - sin->sin_family = LKL_AF_INET; - sin->sin_addr.lkl_s_addr = addr; - sin->sin_port = port; -} - static inline int ifindex_to_name(int sock, struct lkl_ifreq *ifr, int ifindex) { ifr->lkl_ifr_ifindex = ifindex;