#!/usr/bin/bash

# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT

{

root_writable_only() {
	file=$1
	access=$(stat -L -c "%u %g %a" "${file}")

	[[ "$access" =~ 0\ 0\ [6,7][0-7][0-5] ]]
}

decode_base64_cl_url() {
  echo "$1==" | openssl enc -d -base64
}

KDUMP_DIR=$(grep -E '^path +.*' /etc/kdump.conf | awk '{print $2}')

if [ -z "$KDUMP_DIR" ]; then
	KDUMP_DIR="/var/crash"
fi

if [ -L "$KDUMP_DIR" ]; then
	KDUMP_DIR_PARENT=$(dirname $(cd "$KDUMP_DIR"; pwd))
	(! root_writable_only "$KDUMP_DIR_PARENT" || ! root_writable_only "$KDUMP_DIR") && exit 42
else
	! root_writable_only "$KDUMP_DIR" && exit 42
fi

dump_dirs=(${KDUMP_DIR}/*)
N_DUMP=2

for (( idx=${#dump_dirs[@]}-1 ; idx>=0 ; idx-- )) ; do
	[ ! -f "${dump_dirs[idx]}/vmcore-dmesg.txt" ] && exit 1
	if [ ! -L "${dump_dirs[idx]}/vmcore" -a -f "${dump_dirs[idx]}/vmcore" ]; then
		(( $(( N_DUMP-- )) > 0 )) && continue
		rm -f  "${dump_dirs[idx]}/vmcore"
	fi
done

MINDATE=$(date +%F-%X -d "-1 days")

DIR_PANIC=$(basename $(dirname $(ls -ltr $KDUMP_DIR/*/vmcore | tail -1 | awk '{print $9}')))
[ $? != "0" ] && exit 2
LAST_PANIC=$(echo ${DIR_PANIC} | cut -d'-' -f 2,3,4,5)

TCP_PORT=515

KEY_WORDS_DMESG=("BUG" "Oops:" "Kernel panic" "general protection fault" "kernel stack overflow")

function check_if_hungtask
{
	echo "$1" | grep -q "task .* blocked"
}

function check_if_stalls
{
	echo "$1" | grep -q "detected stalls"
}

function check_if_lockup
{
	echo "$1" | grep -q -i -E "(soft|hard) ?lockup"
}

if [[ "${LAST_PANIC}" > "${MINDATE}" ]]
then
	PANIC_PATH=$KDUMP_DIR/$DIR_PANIC
	VMLINUX_PATH=/lib/debug/lib/modules/$(uname -r)/vmlinux

	[ -L $PANIC_PATH/vmcore-dmesg.txt -o -L $PANIC_PATH/vmcore ] && exit 24

	for elem in "${KEY_WORDS_DMESG[@]}"
	do
		PANIC_TXT=$(grep -A200 -e "$elem" $PANIC_PATH/vmcore-dmesg.txt)
		[ "$?" == "0" ] && break
	done

	if rpm -q kernel-debuginfo-$(uname -r) &> /dev/null; then
		if check_if_hungtask $PANIC_TXT || check_if_stalls $PANIC_TXT || check_if_lockup $PANIC_TXT
		then
			PANIC_TXT=$(printf "$PANIC_TXT\n$(crash -s $VMLINUX_PATH $PANIC_PATH/vmcore << EOF
			foreach bt
EOF
)")
		else
			PANIC_TXT=$(printf "$PANIC_TXT\n$(crash -s $VMLINUX_PATH $PANIC_PATH/vmcore << EOF
			bt
EOF
)")
		fi
	fi

	CLIENT_ID=$(decode_base64_cl_url $(cat /etc/sysconfig/rhn/jwt.token | cut -d "." -f 2) |\
			jq -r ".client_id")
	SYSTEM_ID=$(decode_base64_cl_url $(cat /etc/sysconfig/rhn/jwt.token | cut -d "." -f 2) |\
			jq -r ".system_id")
	PANIC_TXT=$(printf "$PANIC_TXT\nclient_id: $CLIENT_ID; systemd_id: $SYSTEM_ID")

	echo "$PANIC_TXT" | nc sentrykernel.cloudlinux.com $TCP_PORT
	[ $? != "0" ] && exit 3
else
	exit 4
fi

exit 0

} &> /dev/null
