diff --git a/bisect.conf b/bisect.conf index 196f0f7..4439a5e 100755 --- a/bisect.conf +++ b/bisect.conf @@ -21,7 +21,7 @@ TEST_STRATEGY="panic" # REBOOT_STRATEGY: 'reboot' or 'kexec' # 'reboot': Performs a full, normal system reboot. -# 'kexec': Uses 'kexec -e' for a faster reboot (requires kexec to be configured). +# 'kexec': Uses 'systemctl kexec' for a faster reboot (requires kexec to be configured). REBOOT_STRATEGY="reboot" # === Git Repository (for INSTALL_STRATEGY="git" or auto mode) === diff --git a/criu-daemon.sh b/criu-daemon.sh index 5dba8d2..3bb4d60 100755 --- a/criu-daemon.sh +++ b/criu-daemon.sh @@ -100,7 +100,7 @@ handle_checkpoint() { rm -f "$CHECKPOINT_SIGNAL" log "Received checkpoint+panic request" - if ! grep -e sysrq-trigger -e reboot "$_cmd_file"; then + if ! grep -e sysrq-trigger -e reboot -e 'systemctl kexec' "$_cmd_file"; then return 1 fi if do_checkpoint; then diff --git a/handlers/install_handler.sh b/handlers/install_handler.sh index d0f1805..3d6792f 100755 --- a/handlers/install_handler.sh +++ b/handlers/install_handler.sh @@ -211,7 +211,7 @@ install_from_rpm() { fi done - if ! run_cmd dnf install -y "${rpms_to_install[@]}" >"/var/log/install.log" 2>&1; then do_abort "RPM install failed."; fi + if ! run_cmd dnf install -y "${rpms_to_install[@]}" ">/var/log/install.log" '2>&1'; then do_abort "RPM install failed."; fi TESTED_KERNEL="$release" [[ $_kernel_name_prefix == kernel-rt ]] && TESTED_KERNEL+=+rt } diff --git a/handlers/reboot_handler.sh b/handlers/reboot_handler.sh index 5daee2a..c7f9acc 100755 --- a/handlers/reboot_handler.sh +++ b/handlers/reboot_handler.sh @@ -33,8 +33,11 @@ do_full_reboot() { } do_kexec_reboot() { - log "Strategy: kexec not supported with CRIU checkpointing, using full reboot..." - # kexec bypasses the normal boot process, which would prevent the CRIU daemon - # from properly restoring the process. Fall back to full reboot. - do_full_reboot + log "Strategy: Performing kexec reboot (fast reboot)" + if ! kexec_load_kernel "$TESTED_KERNEL"; then + log "Falling back to full reboot" + do_full_reboot + return + fi + kab_kexec } diff --git a/lib.sh b/lib.sh index e6ff31f..aaf7a89 100644 --- a/lib.sh +++ b/lib.sh @@ -83,6 +83,8 @@ signal_checkpoint() { printf "sync\n %s" "${_reboot_cmd}" >"$CHECKPOINT_SIGNAL" elif [[ $1 == panic ]]; then printf "sync\n echo 1 > /proc/sys/kernel/sysrq\n echo c > /proc/sysrq-trigger" >"$CHECKPOINT_SIGNAL" + elif [[ $1 == kexec ]]; then + printf "sync\n systemctl kexec" >"$CHECKPOINT_SIGNAL" fi # Wait for the daemon to process our request and reboot/panic the system @@ -155,6 +157,36 @@ reboot_and_wait() { done } +kexec_load_kernel() { + local kernel_release="$1" + local vmlinuz="/boot/vmlinuz-${kernel_release}" + local initramfs="/boot/initramfs-${kernel_release}.img" + + if ! run_cmd test -f "$vmlinuz"; then + log "ERROR: Kernel not found: $vmlinuz" + return 1 + fi + if ! run_cmd test -f "$initramfs"; then + log "ERROR: Initramfs not found: $initramfs" + return 1 + fi + + log "Loading kernel ${kernel_release} into kexec" + if ! run_cmd kexec -l "$vmlinuz" --initrd="$initramfs" --reuse-cmdline; then + log "ERROR: Failed to load kernel into kexec" + return 1 + fi + log "Kernel loaded into kexec successfully" +} + +kab_kexec() { + if [[ -z $KAB_TEST_HOST ]]; then + signal_checkpoint "kexec" + else + reboot_and_wait systemctl kexec + fi +} + prepare_reboot() { # try to reboot to current EFI bootloader entry next time run_cmd command -v rstrnt-prepare-reboot &>/dev/null && run_cmd rstrnt-prepare-reboot >/dev/null @@ -421,6 +453,15 @@ END } setup_kdump() { + if [[ "$REBOOT_STRATEGY" == "kexec" ]]; then + if ! run_cmd command -v kexec &>/dev/null; then + if ! run_cmd dnf install kexec-tools -yq; then + log "Failed to install kexec-tools!" + exit 1 + fi + fi + fi + if [[ "$TEST_STRATEGY" == "panic" ]]; then if ! run_cmd command -v kdumpctl &>/dev/null; then if ! run_cmd dnf install kdump-utils -yq && ! run_cmd dnf install kexec-tools -yq; then diff --git a/tests/kab_criu/test.sh b/tests/kab_criu/test.sh index a669260..1746ffe 100755 --- a/tests/kab_criu/test.sh +++ b/tests/kab_criu/test.sh @@ -52,7 +52,7 @@ done cat <$CONF_FILE" INSTALL_STRATEGY="rpm" TEST_STRATEGY="panic" -REBOOT_STRATEGY= +REBOOT_STRATEGY="kexec" RPM_CACHE_DIR="/var/cache/kdump-bisect-rpms" BAD_COMMIT=$BAD_COMMIT REPRODUCER_SCRIPT=$TEST_SCRIPT diff --git a/tests/kab_ssh/test.sh b/tests/kab_ssh/test.sh index a98ff92..3946f70 100755 --- a/tests/kab_ssh/test.sh +++ b/tests/kab_ssh/test.sh @@ -28,7 +28,7 @@ if echo "${CLIENTS}" | grep -qi "${HOSTNAME}"; then cat <"$CONF_FILE" INSTALL_STRATEGY="rpm" TEST_STRATEGY="panic" -REBOOT_STRATEGY= +REBOOT_STRATEGY="kexec" RPM_CACHE_DIR="/var/cache/kdump-bisect-rpms" GOOD_COMMIT=$GOOD_COMMIT BAD_COMMIT=$BAD_COMMIT