blob: 7fc43dbce6a743224e056cc0b0944d13607f043b [file] [log] [blame]
#!/bin/bash
# shellcheck disable=SC2034 # Variable is used elsewhere
help=$(cat << EOF
opdreport creates an archive consisting of the following:
* host dump files and header applied on top of it
The type parameter controls the content of the data. The generated
archive is stored in the user specified location.
usage: opdreport [OPTION]
Options:
-n, --name <name> Name to be used for the archive.
Default name format
SYSDUMP.<serial number>.<dump_id>.<time>
Optional parameter.
-d, --dir <directory> Archive directory to copy the compressed report.
Default output directory is current working
directory. Optional parameter.
-i, --dumpid <id> Dump identifier to associate with the archive.
Identifiers include numeric characters.
Default dump identifier is 0
-s, --size <size> Maximum allowed size (in KB) of the archive.
Report will be truncated if size exceeds
this limit. Default size is unlimited.
-f, --failingunit The id of the failed unit
-e, --eid Error log associated with the failure
-t, --type Type of the dump to be collected
1 - Hardware dump
3 - Performance dump
5 - Hostboot dump
10 - SBE Dump
-h, --help Display this help and exit.
EOF
)
# Constants
readonly OP_DUMP="opdump"
readonly DREPORT_SOURCE="/usr/share/dreport.d"
readonly TRUE=1
readonly FALSE=0
readonly TIME_STAMP="date -u"
readonly UNLIMITED="unlimited"
readonly DREPORT_INCLUDE="$DREPORT_SOURCE/include.d"
readonly INVENTORY_MANAGER='xyz.openbmc_project.Inventory.Manager'
readonly INVENTORY_PATH='/xyz/openbmc_project/inventory/system'
readonly INVENTORY_ASSET_INT='xyz.openbmc_project.Inventory.Decorator.Asset'
readonly INVENTORY_BMC_BOARD='/xyz/openbmc_project/inventory/system/chassis/motherboard'
readonly HEADER_EXTENSION="$DREPORT_INCLUDE/gendumpheader"
readonly FILE_SCRIPT="$DREPORT_SOURCE/include.d/gendumpinfo"
# Error Codes
readonly SUCCESS=0
readonly INTERNAL_FAILURE=1
readonly RESOURCE_UNAVAILABLE=2
# Variables
declare -x dump_type="$OP_DUMP"
declare -x dump_sbe_type=100
declare -x size_dump=""
declare -x elog_id="00000000"
declare -x EPOCHTIME
EPOCHTIME=$(date +"%s")
declare -x name=""
declare -x dump_dir="/tmp"
declare -x dump_id="00000000"
declare -x dump_size="unlimited"
declare -x content_path=""
declare -x name_dir=""
declare -x serialNo="0000000"
declare -x dDay
dDay=$(date -d @"$EPOCHTIME" +'%Y%m%d%H%M%S')
declare -x dump_content_type=""
declare -x FILE=""
# @brief Get serial number property from inventory
function fetch_serial_number() {
serialNo=$(busctl get-property "$INVENTORY_MANAGER" "$INVENTORY_PATH" \
"$INVENTORY_ASSET_INT" SerialNumber | cut -d " " -f 2 | \
sed 's/^"\(.*\)"$/\1/')
if [ -z "$serialNo" ]; then
serialNo="0000000"
fi
}
# @brief Check the validity of user inputs and initialize global variables
function initialize() {
# shellcheck disable=SC2154 # name comes from elsewhere
if [ -z "$name" ]; then
name="SYSDUMP"
fi
fetch_serial_number
# shellcheck disable=SC2154 # dump_id comes from elsewhere
name="${name}.${serialNo}.${dump_id}.${dDay}"
if [ -z "$dump_sbe_type" ]; then
echo "Error: Dump type is not provided."
return "$RESOURCE_UNAVAILABLE"
fi
if [ -z "$dump_dir" ]; then
dump_dir=$PWD
fi
if [[ "$dump_size" =~ ^[0-9]+$ ]]; then
dump_size=$((dump_size * 1024))
else
dump_size=$UNLIMITED
fi
return "$SUCCESS"
}
# @brief Collect the dump
function collect() {
content_path="/tmp/dump_${dump_id}_${EPOCHTIME}"
dump_outpath="$content_path/plat_dump"
if ! mkdir -p "$dump_outpath"; then
echo "Could not create the destination directory $dump_outpath"
return "$INTERNAL_FAILURE"
fi
dump-collect --type "$dump_sbe_type" --id "0x$dump_id" \
--failingunit "$failing_unit" --path "$dump_outpath"
}
# @brief Package the dump and transfer to dump location
function package() {
FILE="/tmp/dumpheader_${dump_id}_${EPOCHTIME}"
if ! mkdir -p "$dump_dir"; then
echo "Could not create the destination directory $dump_dir"
dump_dir="/tmp"
fi
cd "$content_path" || exit "$INTERNAL_FAILURE"
dump_content_type=${dump_id:0:2}
"$FILE_SCRIPT"
elog_id=$eid
if ! tar -cvzf "$name" plat_dump/*Sbe* info.yaml; then
echo "$($TIME_STAMP)" "Could not create the compressed tar file"
return "$INTERNAL_FAILURE"
fi
size_dump=$(stat -c %s "$name")
if [ "$dump_size" != "$UNLIMITED" ] && \
[ "$size_dump" -gt "$dump_size" ]; then
rm "$name"
return "$RESOURCE_UNAVAILABLE"
fi
echo "Adding Dump Header: $HEADER_EXTENSION"
"$HEADER_EXTENSION"
if ! tee -a "$FILE" < "$name" > /dev/null; then
echo "$($TIME_STAMP)" "Could not create the compressed file"
rm -rf "$name" "$FILE"
return "$INTERNAL_FAILURE"
fi
if ! mv "$FILE" "$name"; then
echo "$($TIME_STAMP)" "Could not create the compressed file"
rm -rf "$name" "$FILE"
return "$INTERNAL_FAILURE"
fi
mv "$name" "$dump_dir"
rm -rf "$content_path"
rm -rf "$FILE" "$name"
return "$SUCCESS"
}
# @brief Initiate BMC dump
function initiate_bmc_dump() {
bmcDumpPath=$(busctl call xyz.openbmc_project.Dump.Manager \
/xyz/openbmc_project/dump/bmc \
xyz.openbmc_project.Dump.Create CreateDump a\{sv\} 0)
result=$?
if [[ $result -ne $SUCCESS ]]; then
echo "Error in creating BMC dump associated with system dump"
else
echo "BMC dump initiated $bmcDumpPath"
fi
}
# @brief Main function
function main() {
initialize
result=$?
if [[ $result -ne $SUCCESS ]]; then
echo "$($TIME_STAMP)" "Error: Failed to initialize, Exiting"
return "$INTERNAL_FAILURE"
fi
collect
result=$?
if [[ $result -ne $SUCCESS ]]; then
echo "$($TIME_STAMP)" "Error: Failed to collect dump, Exiting"
return "$INTERNAL_FAILURE"
fi
package
result=$?
if [[ $result -ne $SUCCESS ]]; then
echo "$($TIME_STAMP)" "Error: Failed to package, Exiting"
return "$INTERNAL_FAILURE"
else
echo "$($TIME_STAMP)" "Successfully completed"
fi
initiate_bmc_dump
return "$SUCCESS"
}
if ! TEMP=$(getopt -o n:d:i:s:t:e:f:h \
--long name:,dir:,dumpid:,size:,type:,eid:,failingunit:,help \
-- "$@"); then
echo "Error: Invalid options"
exit 1
fi
eval set -- "$TEMP"
while [[ $# -gt 1 ]]; do
key="$1"
case $key in
-n|--name)
name=$2
shift 2 ;;
-d|--dir)
dump_dir=$2
shift 2 ;;
-i|--dumpid)
dump_id=$2
shift 2 ;;
-s|--size)
dump_size=$2
shift 2 ;;
-f|--failingunit)
failing_unit=$2
shift 2 ;;
-e|--eid)
eid=$2
shift 2 ;;
-t|--type)
dump_sbe_type=$2
shift 2 ;;
-h|--help)
echo "$help"
exit ;;
*) # unknown option
echo "Unknown argument: $1"
echo "$help"
exit 1 ;;
esac
done
main
exit $?