Multiple fixes and improvements
OK, likely I should have split this commit in many more, to ease reviews and improve bisectability. But since I didn't, I'll at least try to summarize here what was changed by this big commit, starting with the more complex additions to the trivial ones: - Added a log submission system; for now, it doesn't submit logs to anywhere since we don't have such API well-defined. But it saves the logs locally in a tar.zst, using timestamps to define the moment of log collection and clears the old files. The naming of the log compressed tarball makes use of the Deck serial number and Steam most recent logged account (thanks @TonyP for that idea). - Still on the log submission topic: we try first pstore logs, and if we have none of them, we check kdump logs. In case we have a vmcore, we save it locally (after renaming), but for now we consider that this kind of file won't be submitted. - Since we now have makedumpfile in Holo (thanks @xexaxo), I've removed this binary from here and made this package dependent on makedumpfile. Also, adjusted the respective scripts. - Added some error messages through logger, in case we fail to load pstore/kdump or fail in the log submission script. - Changed systemd service to just do the pstore/kdump loading and call the submit_report.sh script, which is then "disowned" in order we finish as fast as possible the systemd service; boot delays due to this service wouldn't be nice. - Increased the "crashkernel" memory recommended in the documentation, since I've noticed the most recent version of the kernel requires a bit more - let's play safe! - Changed timestamps to use UTC tz - this is due kdump collection happening so early, that timezone is not set, so let's stick with UTC in all cases. - Checked scripts with shellcheck[0] and improved the README. [0] Accepted most suggestions, but some are polemic, and may introduce issues, so the scripts are not fully passing shellcheck and I don't expect them to be in the future, it's just a minor style improvement and failsafe for multiple shells. Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
This commit is contained in:
154
submit_report.sh
154
submit_report.sh
@ -4,50 +4,138 @@
|
||||
#
|
||||
# Copyright (c) 2021 Valve.
|
||||
#
|
||||
# This is currently a dummy script for kdump, but collects and clears
|
||||
# pstore saved logs for now. It aims, in the future, to submit error/crash
|
||||
# reports to Valve servers in order to do a post-mortem analysis.
|
||||
# This is part of SteamOS kdump - it is invoked by systemd on boot time
|
||||
# and should always exit graciously to avoid breaking the boot services.
|
||||
# This is the SteamOS kdump/pstore log collector and submitter; this script
|
||||
# prepares the pstore/kdump collected data and submit it to the services that
|
||||
# handle support at Valve. It considers pstore as a first alternative, if no
|
||||
# logs found (or if pstore is not mounted for some reason), tries to check
|
||||
# if kdump logs are present.
|
||||
#
|
||||
|
||||
# We do some validation to be sure KDUMP_MNT pointed path is valid...
|
||||
# That and having a valid /etc/default/kdump are essential conditions.
|
||||
if [ ! -f "/etc/default/kdump" ]; then
|
||||
logger "/etc/default/kdump not present - aborting..." || true
|
||||
exit 0
|
||||
fi
|
||||
|
||||
. /etc/default/kdump
|
||||
|
||||
# Yeah, we assume pstore is mounted by default, in this location;
|
||||
KDUMP_MAIN_FOLDER="$(cat "${KDUMP_MNT}")"
|
||||
rm -f "${KDUMP_MNT}"
|
||||
|
||||
if [ ! -d "${KDUMP_MAIN_FOLDER}" ]; then
|
||||
logger "invalid folder: ${KDUMP_MAIN_FOLDER} - aborting..." || true
|
||||
exit 0
|
||||
fi
|
||||
|
||||
LOGS_FOUND=0
|
||||
KDUMP_LOGS_FOLDER="${KDUMP_MAIN_FOLDER}/logs"
|
||||
|
||||
# Use UTC timezone to match kdump collection
|
||||
CURRENT_TSTAMP=$(date -u +"%Y%m%d%H%M")
|
||||
|
||||
# We assume pstore is mounted by default, in this location;
|
||||
# if not, we get a 0 and don't loop.
|
||||
PSTORE_CNT=$(find /sys/fs/pstore/* 2>/dev/null | grep -c ramoops)
|
||||
if [ ${PSTORE_CNT} -eq 0 ]; then
|
||||
exit 0
|
||||
if [ "${PSTORE_CNT}" -ne 0 ]; then
|
||||
|
||||
# Dump the pstore logs in the <...>/kdump/logs/pstore subfolder.
|
||||
PSTORE_FOLDER="${KDUMP_LOGS_FOLDER}/pstore"
|
||||
mkdir -p "${PSTORE_FOLDER}"
|
||||
|
||||
LOOP_CNT=0
|
||||
while [ "${PSTORE_CNT}" -gt 0 ]; do
|
||||
PSTORE_FILE="$(find /sys/fs/pstore/* | grep ramoops | sort | head -n1)"
|
||||
SAVED_FILE="${PSTORE_FOLDER}/dmesg-pstore.${CURRENT_TSTAMP}-${LOOP_CNT}"
|
||||
|
||||
cat "${PSTORE_FILE}" > "${SAVED_FILE}"
|
||||
sync "${SAVED_FILE}"
|
||||
rm -f "${PSTORE_FILE}"
|
||||
|
||||
PSTORE_CNT=$((PSTORE_CNT - 1))
|
||||
LOOP_CNT=$((LOOP_CNT + 1))
|
||||
done
|
||||
LOGS_FOUND=${LOOP_CNT}
|
||||
|
||||
# Enter the else block in case we don't have pstore logs - maybe we
|
||||
# have kdump logs then.
|
||||
else
|
||||
KDUMP_CRASH_FOLDER="${KDUMP_MAIN_FOLDER}/crash"
|
||||
KDUMP_CNT=$(find ${KDUMP_CRASH_FOLDER}/* -type d 2>/dev/null | wc -l)
|
||||
|
||||
if [ "${KDUMP_CNT}" -ne 0 ]; then
|
||||
# Dump the kdump logs in the <...>/kdump/logs/kdump subfolder.
|
||||
KD_FOLDER="${KDUMP_LOGS_FOLDER}/kdump"
|
||||
mkdir -p "${KD_FOLDER}"
|
||||
|
||||
LOOP_CNT=0
|
||||
while [ "${KDUMP_CNT}" -gt 0 ]; do
|
||||
CRASH_CURRENT=$(find ${KDUMP_CRASH_FOLDER}/* -type d 2>/dev/null | head -n1)
|
||||
CRASH_TSTAMP=$(basename "${CRASH_CURRENT}")
|
||||
|
||||
if [ -s "${CRASH_CURRENT}/dmesg.txt" ]; then
|
||||
SAVED_FILE="${KD_FOLDER}/dmesg-kdump.${CRASH_TSTAMP}"
|
||||
mv "${CRASH_CURRENT}/dmesg.txt" "${SAVED_FILE}"
|
||||
sync "${SAVED_FILE}"
|
||||
|
||||
fi
|
||||
|
||||
# We don't care about submitting a vmcore, but let's save it if such file exists.
|
||||
if [ -s "${CRASH_CURRENT}/vmcore.compressed" ]; then
|
||||
SAVED_FILE="${KDUMP_CRASH_FOLDER}/vmcore.${CRASH_TSTAMP}"
|
||||
mv "${CRASH_CURRENT}/vmcore.compressed" "${SAVED_FILE}"
|
||||
sync "${SAVED_FILE}"
|
||||
|
||||
fi
|
||||
|
||||
rm -rf "${CRASH_CURRENT}"
|
||||
KDUMP_CNT=$((KDUMP_CNT - 1))
|
||||
LOOP_CNT=$((LOOP_CNT + 1))
|
||||
|
||||
done
|
||||
LOGS_FOUND=$((LOGS_FOUND + LOOP_CNT))
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# We do some validation to be sure KDUMP_MNT pointed path is valid...
|
||||
KDUMP_CRASH_FOLDER="$(cat ${KDUMP_MNT})"
|
||||
rm -f ${KDUMP_MNT}
|
||||
# If we have pstore and/or kdump logs, let's process them in order to submit...
|
||||
if [ ${LOGS_FOUND} -ne 0 ]; then
|
||||
|
||||
if [ ! -d "${KDUMP_CRASH_FOLDER}" ]; then
|
||||
exit 0
|
||||
PNAME="$(dmidecode -s system-product-name)"
|
||||
if [ "${PNAME}" = "Jupiter" ]; then
|
||||
SN="$(dmidecode -s system-serial-number)"
|
||||
else
|
||||
SN=0
|
||||
fi
|
||||
|
||||
STEAM_ACCOUNT=0
|
||||
if [ -s "${LOGINVDF}" ]; then
|
||||
# The following awk command was borrowed from:
|
||||
# https://unix.stackexchange.com/a/663959
|
||||
NUMREG=$(grep -c AccountName "${LOGINVDF}")
|
||||
IDX=1
|
||||
while [ ${IDX} -le "${NUMREG}" ]; do
|
||||
MR=$(awk -v n=${IDX} -v RS='}' 'NR==n{gsub(/.*\{\n|\n$/,""); print}' "${LOGINVDF}" | grep "MostRecent" | cut -f4 -d\")
|
||||
if [ "$MR" -ne 1 ]; then
|
||||
IDX=$((IDX + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
STEAM_ACCOUNT=$(awk -v n=${IDX} -v RS='}' 'NR==n{gsub(/.*\{\n|\n$/,""); print}' "${LOGINVDF}" | grep "AccountName" | cut -f4 -d\")
|
||||
break
|
||||
|
||||
IDX=$((IDX + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
LOG_FNAME="steamos-${SN}-${STEAM_ACCOUNT}.${CURRENT_TSTAMP}.tar"
|
||||
LOG_FNAME="${KDUMP_MAIN_FOLDER}/${LOG_FNAME}"
|
||||
tar cf "${LOG_FNAME}" "${KDUMP_LOGS_FOLDER}" 1>/dev/null 2>&1
|
||||
|
||||
zstd < "${LOG_FNAME}" > "${LOG_FNAME}.zst"
|
||||
sync "${LOG_FNAME}.zst"
|
||||
rm -rf "${KDUMP_LOGS_FOLDER}" "${LOG_FNAME}"
|
||||
|
||||
# TODO: implement a log submission mechanism, in order to send the zstd file
|
||||
# to Valve servers through an API.
|
||||
fi
|
||||
|
||||
# If valid, then dump the pstore logs in the crash subfolder.
|
||||
KDUMP_CRASH_FOLDER="${KDUMP_CRASH_FOLDER}/crash"
|
||||
mkdir -p ${KDUMP_CRASH_FOLDER}
|
||||
|
||||
PSTORE_TSTAMP=$(date +"%Y%m%d%H%M")
|
||||
LOOP_CNT=0
|
||||
while [ ${PSTORE_CNT} -gt 0 ];
|
||||
do
|
||||
PSTORE_FILE="$(find /sys/fs/pstore/* | grep ramoops | sort | head -n1)"
|
||||
SAVED_FILE="${KDUMP_CRASH_FOLDER}/dmesg-pstore.${PSTORE_TSTAMP}-${LOOP_CNT}"
|
||||
|
||||
cat ${PSTORE_FILE} > ${SAVED_FILE}
|
||||
sync ${SAVED_FILE}
|
||||
rm -f ${PSTORE_FILE}
|
||||
|
||||
PSTORE_CNT=$((${PSTORE_CNT} - 1))
|
||||
LOOP_CNT=$((${LOOP_CNT} + 1))
|
||||
done
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user