#!/sbin/openrc-run

description="Execute kexec if a kernel is preloaded, otherwise do a normal reboot"
name="kexec-boot"
extra_commands="status unload load"
depend() {
	after mount-ro killprocs savecache
}

start() {
    if [ -f /sys/kernel/kexec_loaded ] && [ "$(cat /sys/kernel/kexec_loaded)" -eq 1 ]; then
        einfo "Executing kexec..."
        kexec -e
        eerror "kexec failed, proceeding with normal reboot"
        sleep 10
    fi
}

status() {
    if [ -f /sys/kernel/kexec_loaded ] && [ "$(cat /sys/kernel/kexec_loaded)" -eq 1 ]; then
        einfo "A kernel is loaded for kexec"
    else
        einfo "No kernel is loaded for kexec"
    fi
}

unload(){
    if [ -f /sys/kernel/kexec_loaded ] && [ "$(cat /sys/kernel/kexec_loaded)" -eq 1 ]; then
        einfo "Unloading kernel"
        kexec -u
        if [ -f /sys/kernel/kexec_loaded ] && [ "$(cat /sys/kernel/kexec_loaded)" -eq 0 ]; then
            eend 0 "Previous kernel unloaded"
        else
            eend 1 "Failed to unload previous kernel"
            return 1
        fi
    else
        einfo "Nothing to unload"
    fi
}

load() {
    if [ -z "$KERNEL_IMAGE" ]; then
        eerror "No kernel image specified in /etc/conf.d/${RC_SVCNAME}"
        return 1
    fi

    if [ ! -f "$KERNEL_IMAGE" ]; then
        eerror "Kernel image $KERNEL_IMAGE does not exist"
        return 1
    fi

    if [ -f /sys/kernel/kexec_loaded ] && [ "$(cat /sys/kernel/kexec_loaded)" -eq 1 ]; then
        ebegin "Unloading previously loaded kernel"
        kexec -u
        if [ -f /sys/kernel/kexec_loaded ] && [ "$(cat /sys/kernel/kexec_loaded)" -eq 0 ]; then
            eend 0 "Previous kernel unloaded"
        else
            eend 1 "Failed to unload previous kernel"
            return 1
        fi
    fi
    
    if [ ! -n "$CMDLINE_OPTS" ]; then
        CMDLINE_OPTS=""

        if [ "$CMDLINE_REUSE" = "yes" ]; then
            CMDLINE_OPTS="--reuse-cmdline"
        fi

        if [ -n "$CMDLINE_APPEND" ]; then
            CMDLINE_OPTS="$CMDLINE_OPTS --append=\"$CMDLINE_APPEND\""
        fi
    fi

    ebegin "Loading kernel: $(basename $KERNEL_IMAGE)"
    
    if [ -n "$INITRAMFS" ]; then
        if [ ! -f "$INITRAMFS" ]; then
            eerror "Initramfs $INITRAMFS does not exist"
            eend 1
            return 1
        fi
        
        einfo "Using initramfs: $(basename $INITRAMFS)"
        
        kexec -l --initrd="$INITRAMFS" $CMDLINE_OPTS "$KERNEL_IMAGE"
    else
        kexec -l $CMDLINE_OPTS "$KERNEL_IMAGE"
    fi
    
    if [ -f /sys/kernel/kexec_loaded ] && [ "$(cat /sys/kernel/kexec_loaded)" -eq 1 ]; then
        eend 0 "Kernel loaded successfully"
    else
        eend 1 "Failed to load kernel"
        return 1
    fi
}