From f69c972ae613719c0ebc5395ba3084c408023102 Mon Sep 17 00:00:00 2001 From: Julien Olivain Date: Fri, 3 Mar 2023 23:26:58 +0100 Subject: [PATCH] support/testing/tests/package/test_kexec.py: new runtime test Signed-off-by: Julien Olivain Signed-off-by: Thomas Petazzoni --- DEVELOPERS | 2 + support/testing/tests/package/test_kexec.py | 93 +++++++++++++++++++ .../package/test_kexec/linux-kexec.fragment | 5 + 3 files changed, 100 insertions(+) create mode 100644 support/testing/tests/package/test_kexec.py create mode 100644 support/testing/tests/package/test_kexec/linux-kexec.fragment diff --git a/DEVELOPERS b/DEVELOPERS index 7733d5a04e..f6e120d92b 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -1718,6 +1718,8 @@ F: support/testing/tests/package/sample_python_spake2.py F: support/testing/tests/package/test_gnupg2.py F: support/testing/tests/package/test_highway.py F: support/testing/tests/package/test_hwloc.py +F: support/testing/tests/package/test_kexec.py +F: support/testing/tests/package/test_kexec/ F: support/testing/tests/package/test_libjxl.py F: support/testing/tests/package/test_lsof.py F: support/testing/tests/package/test_ncdu.py diff --git a/support/testing/tests/package/test_kexec.py b/support/testing/tests/package/test_kexec.py new file mode 100644 index 0000000000..77e383373e --- /dev/null +++ b/support/testing/tests/package/test_kexec.py @@ -0,0 +1,93 @@ +import os + +import infra.basetest + + +class TestKexec(infra.basetest.BRTest): + + # A specific configuration is needed for using kexec: + # - We use Aarch64 since it is well supported for kexec, + # - A kernel config fragment enables all the kexec parts, + # - The kernel Image is installed on target filesystem to be + # reloaded through kexec, + # - We use a ext4 rootfs image exposed as a virtio storage (rather + # than cpio initrd). This avoids needing to install the initrd + # inside the rootfs. + config = \ + """ + BR2_aarch64=y + BR2_TOOLCHAIN_EXTERNAL=y + BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0" + BR2_LINUX_KERNEL=y + BR2_LINUX_KERNEL_CUSTOM_VERSION=y + BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.1.15" + BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y + BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config" + BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{}" + BR2_LINUX_KERNEL_INSTALL_TARGET=y + BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y + BR2_PACKAGE_KEXEC=y + BR2_TARGET_ROOTFS_EXT2=y + BR2_TARGET_ROOTFS_EXT2_4=y + # BR2_TARGET_ROOTFS_TAR is not set + """.format( + infra.filepath("tests/package/test_kexec/linux-kexec.fragment") + ) + + def test_run(self): + hda = os.path.join(self.builddir, "images", "rootfs.ext4") + kern = os.path.join(self.builddir, "images", "Image") + # Notes: + # Sufficient memory is needed to load the kernel: having at + # least 512MB works. kexec could silently fail if not enough + # memory is present. KASLR needs to be disabled for the test: + # we pass "nokaslr" to kernel bootargs, and also pass + # "dtb-kaslr-seed=off" to qemu virt machine. + bootargs = ["root=/dev/vda console=ttyAMA0 nokaslr"] + qemu_opts = ["-M", "virt,dtb-kaslr-seed=off", "-cpu", "cortex-a57", "-m", "512M", + "-drive", f"file={hda},if=virtio,format=raw"] + self.emulator.boot(arch="aarch64", + kernel=kern, + kernel_cmdline=bootargs, + options=qemu_opts) + self.emulator.login() + + # Test the program can execute + self.assertRunOk("kexec --version") + + # Check the kexec kernel is NOT loaded: + self.assertRunOk("test \"$(cat /sys/kernel/kexec_loaded)\" -eq 0") + + # Load the Kernel: + # "--append br-test" adds a dummy kernel args we'll be able to + # check in the second executed kernel. + # We use the dtb image from /sys/firmware/fdt (since we don't + # have the dtb file in the system) + self.assertRunOk("kexec -d -l --dtb=/sys/firmware/fdt --reuse-cmdline --serial=ttyAMA0 --append=br-test /boot/Image") + + # Check the kexec kernel IS loaded: + self.assertRunOk("test \"$(cat /sys/kernel/kexec_loaded)\" -eq 1") + + # Create a marker file in tmpfs which is supposed to disappear + # after kexec kernel restart. + self.assertRunOk("touch /dev/shm/br-kexec-marker") + + # Execute the loaded kernel (i.e perform a kexec reboot) + # qemu.sendline() is used here because no exit code nor + # program return is expected, since kexec is like a + # reboot. The login is expected to be reached after the + # command is issued. + self.emulator.qemu.sendline("kexec -d -e") + + # Wait for the login, and log again + self.emulator.login() + + # Check the "br-test" dummy kernel arg is present + self.assertRunOk("grep br-test /proc/cmdline") + + # Check the test marker file is no longer here + self.assertRunOk("test ! -e /dev/shm/br-kexec-marker") + + # After restart, the kernel is not supposed to have a kexec + # loaded image: + self.assertRunOk("test \"$(cat /sys/kernel/kexec_loaded)\" -eq 0") diff --git a/support/testing/tests/package/test_kexec/linux-kexec.fragment b/support/testing/tests/package/test_kexec/linux-kexec.fragment new file mode 100644 index 0000000000..04c65f5cae --- /dev/null +++ b/support/testing/tests/package/test_kexec/linux-kexec.fragment @@ -0,0 +1,5 @@ +CONFIG_KEXEC=y +CONFIG_KEXEC_FILE=y +CONFIG_PROC_KCORE=y +CONFIG_DEBUG_KERNEL=y +CONFIG_KALLSYMS_ALL=y