#!/bin/sh
#
# kexec-load	Load kernel image with kexec
#
# chkconfig:	345 99 01
#
# description:	This tool is used to load a kernel in memory and reboot into the kernel \
#  				loaded in memory using the kexec system call.
#
# $Id$

# Source function library
. /etc/rc.d/init.d/functions

LOAD_KEXEC=yes
KERNEL_IMAGE="/boot/vmlinuz"
INITRD="/boot/initrd"
APPEND=""

# Get service config - may override defaults
[ -f /etc/sysconfig/kexec ] && . /etc/sysconfig/kexec

load() {
	if [ -z "$APPEND" ]; then
		local a
		for a in $(cat /proc/cmdline); do
			case "$a" in
				kexec_*=)
					# skip entries like:
					# kexec_jump_back_entry=0x01000201a4814e49
					;;
				*)
					APPEND="$APPEND $a"
			esac
		done
	fi

	# convert to real file for readability
	if [ -L "$KERNEL_IMAGE" ]; then
		KERNEL_IMAGE=$(readlink -f "$KERNEL_IMAGE")
	fi
	if [ -L "$INITRD" ]; then
		INITRD=$(readlink -f "$INITRD")
	fi

	if [ -z "$INITRD" ]; then
		show "Loading kernel image: %s, args [%s]" "$KERNEL_IMAGE" "$APPEND"
		kexec -l "$KERNEL_IMAGE" --append="$APPEND"
	else
		show "Loading kernel image: %s, initrd %s, args [%s]" "$KERNEL_IMAGE" "$INITRD" "$APPEND"
		kexec -l "$KERNEL_IMAGE" --initrd="$INITRD" --append="$APPEND"
	fi
	RETVAL=$?
	[ $RETVAL = 0 ] && ok || fail
}

start() {
	if [ -f /var/lock/subsys/kexec ]; then
		return
	fi
	touch /var/lock/subsys/kexec
}

stop() {
	if ! is_yes "$LOAD_KEXEC" || [ ! -f /sys/kernel/kexec_loaded ]; then
		return
	fi

	# skip if already loaded something
	if [ "$(cat /sys/kernel/kexec_loaded 2>/dev/null)" = "1" ]; then
		return
	fi

	load
	rm -f /var/lock/subsys/kexec
}

status() {
	if [ "$(cat /sys/kernel/kexec_loaded 2>/dev/null)" = "1" ]; then
		show "Kexec image loaded"; ok
	else
		show "Kexec image is not loaded"; fail
	fi
  	if [ "$(cat /sys/kernel/kexec_crash_loaded 2>/dev/null)" = 1 ]; then
		show "Kexec image for kernel crash loaded"; ok
	else
		show "Kexec image for kernel crash is not loaded"; fail
	fi

	# convert to real file for readability
	if [ -L "$KERNEL_IMAGE" ]; then
		KERNEL_IMAGE=$(readlink -f "$KERNEL_IMAGE")
	fi
	if [ -L "$INITRD" ]; then
		INITRD=$(readlink -f "$INITRD")
	fi
	INIT_COL=0 show "Configured kernel: %s" "$KERNEL_IMAGE"; echo
	if [ -n "$INITRD" ]; then
		INIT_COL=0 show "Configured initrd: %s" "$INITRD"; echo
	fi
}

RETVAL=0
# See how we were called.
case "$1" in
  start)
  	start
	;;
  stop)
  	stop
	;;
  restart)
  	stop
	start
	;;
  load)
	load
	;;
  status)
	status
	;;
  *)
	msg_usage "$0 {start|stop|load|restart|status}"
	exit 3
esac

exit $RETVAL
