#!/bin/bash

USAGE="$0 <check|install|remove> <package-version-release>"

if test "$1" = "-h" -o "$1" = "--help"; then
	echo "$USAGE"
	exit 0
fi
if test "$#" -lt 2; then
	echo "$USAGE" >&2
	exit 1
fi

shopt -s nullglob

check_livepatching_env()
{
	LIVEPATCH_KERNEL=auto
	. /etc/sysconfig/livepatching || :

	# We want to preserve the immutability of the system in the
	# transactional server role. To that end, we define the "auto" patch
	# deployment mode that skips the patch loading in transactional
	# updates.
	DO_PATCHING=0
	[ "$TRANSACTIONAL_UPDATE" != "true" -a "$LIVEPATCH_KERNEL" == "auto" ] && DO_PATCHING=1
	[ "$LIVEPATCH_KERNEL" == "always" ] && DO_PATCHING=1

	[ "$DO_PATCHING" -eq 0 ] && return 1
	return 0
}

do_check()
{
	if test -e /.buildenv; then
		echo "Skipping kernel live patches in buildroot"
		return 0
	fi

	check_livepatching_env || return 0

	if test "$(uname -r)" != "$KREL"; then
		return 0
	fi
	klp check >&2
}

refresh_initrd()
{
	local image

	/sbin/depmod -F "/boot/System.map-$KREL" -e "$KREL" || return
	# copied from weak-modules2
	for image in vmlinuz image vmlinux linux bzImage uImage Image ""; do
		if test -f "/boot/$image-$KREL"; then
			break
		fi
	done
	if test -z "$image"; then
		return
	fi
	if test "$1" = "--force"; then
		/sbin/mkinitrd -k "/boot/$image-$KREL" -i "/boot/initrd-$KREL"
	else
		mkdir -p /var/run/regenerate-initrd
		touch "/var/run/regenerate-initrd/$image-$KREL"
	fi
}

do_install()
{
	local mod modules err

	if test -e /.buildenv; then
		return 0
	fi

	refresh_initrd

	if test "$(uname -r)" != "$KREL"; then
		return 0
	fi

	if ! check_livepatching_env; then
		echo "[klp] Skipping installation of the kernel live patch."
		return 0
	fi

	err=0
	modules=($(grep -l '^0$' /sys/module/livepatch*/refcnt /dev/null | sed 's:/refcnt::; s:/sys/module/::'))
	for mod in "${modules[@]}"; do
		echo "[klp] Unloading $mod"
		# Can't use modprobe -r, as the modules do not exist on disk
		# anymore
		rmmod "$mod" || :
	done
	modules=($(rpm -ql "$PACKAGE" | sed -rn 's:.*/(livepatch[^/]*)\.ko(\.[gx]z)?$:\1:p'))
	for mod in "${modules[@]}"; do
		echo "[klp] Loading $mod"
		modprobe "$mod" || err=$?
	done
	return $err
}

do_remove()
{
	if test -e /.buildenv; then
		return 0
	fi

	if test "$NUM_PACKAGES" -eq 0; then
		# bnc#904867
		refresh_initrd --force
	else
		refresh_initrd
	fi
}

if test $# -ne 4; then
	echo 'WARNING: Unexpected number of parameters. Are the live patch RPM scripts compatible with this rpm-helper?' >&2
fi

cmd=$1
PACKAGE=$2
KREL=$3
NUM_PACKAGES=${4-0}
case "$cmd" in
check|install|remove)
	do_$cmd
	exit
	;;
*)
	echo "$USAGE" >&2
	exit 1
esac
