blob: 201c08a3048961cbaadc44cd7827272359b633d8 [file] [log] [blame]
#!/bin/bash
#
#Header for BMC DUMP
#This script will create header file only for IBM systems.
#This script will generate generic IBM dump header format.
#
#Note: The dump header will be imposed on the dump file i.e
#<dump name>.tar.xz/gz only on IBM specific systems, user needs to
#separate out the header before extracting the dump.
#
#Constants
declare -rx DUMP_HEADER_ENTRY_SIZE='516'
declare -rx SIZE_4='4'
declare -rx SIZE_8='8'
declare -rx SIZE_12='12'
declare -rx SIZE_32='32'
#Dump Summary size without header
declare -rx DUMP_SUMMARY_SIZE='1024'
declare -rx HW_DUMP='00'
declare -rx HB_DUMP='20'
declare -rx SBE_DUMP='30'
declare -rx OP_DUMP="opdump"
declare -rx INVENTORY_MANAGER='xyz.openbmc_project.Inventory.Manager'
declare -rx INVENTORY_PATH='/xyz/openbmc_project/inventory/system'
declare -rx INVENTORY_ASSET_INT='xyz.openbmc_project.Inventory.Decorator.Asset'
declare -rx INVENTORY_BMC_BOARD='/xyz/openbmc_project/inventory/system/chassis/motherboard'
declare -rx PHOSPHOR_LOGGING='xyz.openbmc_project.Logging'
declare -rx PEL_ENTRY='org.open_power.Logging.PEL.Entry'
declare -rx PEL_ID_PROP='PlatformLogID'
#Variables
declare -x modelNo
modelNo=$(busctl get-property $INVENTORY_MANAGER $INVENTORY_PATH \
$INVENTORY_ASSET_INT Model | cut -d " " -f 2 | sed "s/^\(\"\)\(.*\)\1\$/\2/g")
#Variables
declare -x serialNo
serialNo=$(busctl get-property $INVENTORY_MANAGER $INVENTORY_PATH \
$INVENTORY_ASSET_INT SerialNumber | cut -d " " -f 2 | sed "s/^\(\"\)\(.*\)\1\$/\2/g")
declare -x dDay
dDay=$(date -d @"$EPOCHTIME" +'%Y%m%d%H%M%S')
declare -x bmcSerialNo
bmcSerialNo=$(busctl call $INVENTORY_MANAGER $INVENTORY_BMC_BOARD \
org.freedesktop.DBus.Properties Get ss $INVENTORY_ASSET_INT \
SerialNumber | cut -d " " -f 3 | sed "s/^\(\"\)\(.*\)\1\$/\2/g")
#Function to add NULL
function add_null() {
local a=$1
printf '%*s' $a | tr ' ' "\0" >> $FILE
}
#Function to is to convert the EPOCHTIME collected
#from dreport into hex values and write the same in
#header.
function dump_time() {
x=${#dDay}
msize=`expr $x / 2`
msize=`expr $SIZE_8 - $msize`
for ((i=0;i<$x;i+=2));
do
printf \\x${dDay:$i:2} >> $FILE
done
add_null $msize
}
#Function to fetch the size of the dump
function dump_size() {
#Adding 516 bytes as the total dump size is dump tar size
#plus the dump header entry in this case
#dump_header and dump_entry
# shellcheck disable=SC2154 # name_dir comes from elsewhere.
dumpSize=$(stat -c %s "$name_dir.bin")
sizeDump=$(( dumpSize + DUMP_HEADER_ENTRY_SIZE ))
printf -v hex "%x" "$sizeDump"
x=${#hex}
if [ $(($x % 2)) -eq 1 ]; then
hex=0$hex
x=${#hex}
fi
msize=`expr $x / 2`
msize=`expr $SIZE_8 - $msize`
add_null $msize
for ((i=0;i<$x;i+=2));
do
printf \\x${hex:$i:2} >> $FILE
done
}
#Function to set dump id to 8 bytes format
function get_dump_id() {
# shellcheck disable=SC2154
size=${#dump_id}
if [ "$1" == "$OP_DUMP" ]; then
nulltoadd=$(( SIZE_4 - size / 2 - size % 2 ))
add_null "$nulltoadd"
for ((i=0;i<size;i+=2));
do
# shellcheck disable=SC2059
printf "\\x${dump_id:$i:2}" >> "$FILE"
done
else
nulltoadd=$(( SIZE_8 - size ))
printf '%*s' "$nulltoadd" | tr ' ' "0" >> "$FILE"
printf "%s" "$dump_id" >> "$FILE"
fi
}
#Function to get the bmc serial number
function getbmc_serial() {
x=${#bmcSerialNo}
nulltoadd=`expr $SIZE_12 - $x`
printf $bmcSerialNo >> $FILE
printf '%*s' $nulltoadd | tr ' ' "0" >> $FILE
}
#Function to fetch the hostname
function system_name() {
name=$(hostname)
len=${#name}
nulltoadd=$(( SIZE_32 - len ))
printf "%s" "$name" >> "$FILE"
add_null "$nulltoadd"
}
#Function to get the errorlog ID
function get_eid() {
# shellcheck disable=SC2154 # dump_type comes from elsewhere
if [ "$dump_type" = "$OP_DUMP" ]; then
# shellcheck disable=SC2154 # elog_id comes from elsewhere
x=${#elog_id}
if [ "$x" = 8 ]; then
msize=$(( x / 2 ))
msize=$(( SIZE_4 - msize ))
for ((i=0;i<x;i+=2));
do
printf "\\x${elog_id:$i:2}" >> "$FILE"
done
add_null "$msize"
else
add_null 4
fi
else
if ! { [[ $dump_type = "$TYPE_ELOG" ]] || \
[[ $dump_type = "$TYPE_CHECKSTOP" ]]; }; then
x=${#elog_id}
if [ "$x" = 8 ]; then
for ((i=0;i<x;i+=2));
do
printf "\\x${elog_id:$i:2}" >> "$FILE"
done
else
add_null 4
fi
else
strpelid=$(busctl get-property $PHOSPHOR_LOGGING \
$optional_path $PEL_ENTRY $PEL_ID_PROP | cut -d " " -f 2)
decpelid=$(expr "$strpelid" + 0)
hexpelid=$(printf "%x" "$decpelid")
x=${#hexpelid}
if [ "$x" = 8 ]; then
for ((i=0;i<x;i+=2));
do
printf "\\x${hexpelid:$i:2}" >> "$FILE"
done
else
add_null 4
fi
fi
fi
}
#Function to get the tar size of the dump
function tar_size() {
printf -v hex "%x" "$size_dump"
x=${#hex}
if [ $((x % 2)) -eq 1 ]; then
hex=0$hex
x=${#hex}
fi
msize=$(( x / 2 ))
msize=$(( SIZE_4 - msize ))
add_null "$msize"
for ((i=0;i<x;i+=2));
do
# shellcheck disable=SC2059 # using 'hex' as a variable is safe here.
printf "\\x${hex:$i:2}" >> "$FILE"
done
}
#Function will get the total size of the dump without header
# i.e. Dump summary size i.e. 1024 bytes + the tar file size
function total_size() {
size_dump=$(( size_dump + DUMP_SUMMARY_SIZE ))
printf -v hex "%x" "$size_dump"
x=${#hex}
if [ $((x % 2)) -eq 1 ]; then
hex=0$hex
x=${#hex}
fi
msize=$(( x / 2 ))
msize=$(( SIZE_8 - msize ))
add_null "$msize"
for ((i=0;i<x;i+=2));
do
# shellcheck disable=SC2059 # using 'hex' as a variable is safe here.
printf "\\x${hex:$i:2}" >> "$FILE"
done
}
#Function to populate content type based on dump type
function content_type() {
type="00000000"
# content type:
# Hostboot dump = "20"
# Hardware dump = "00"
# SBE dump = "30"
if [ "$dump_content_type" = "$HB_DUMP" ]; then
type="00000200"
elif [ "$dump_content_type" = "$HW_DUMP" ]; then
type="40000000"
elif [ "$dump_content_type" = "$SBE_DUMP" ]; then
type="02000000"
fi
x=${#type}
for ((i=0;i<$x;i+=2));
do
# shellcheck disable=SC2059 # using 'type' as a variable is safe here.
printf "\\x${type:$i:2}" >> "$FILE"
done
}
# @brief Fetching model number and serial number property from inventory
# If the busctl command fails, populating the model and serial number
# with default value i.e. 0
function get_bmc_model_serial_number() {
modelNo=$(busctl get-property $INVENTORY_MANAGER $INVENTORY_PATH \
$INVENTORY_ASSET_INT Model | cut -d " " -f 2 | sed "s/^\(\"\)\(.*\)\1\$/\2/g")
if [ -z "$modelNo" ]; then
modelNo="00000000"
fi
bmcSerialNo=$(busctl call $INVENTORY_MANAGER $INVENTORY_BMC_BOARD \
org.freedesktop.DBus.Properties Get ss $INVENTORY_ASSET_INT \
SerialNumber | cut -d " " -f 3 | sed "s/^\(\"\)\(.*\)\1\$/\2/g")
if [ -z "$bmcSerialNo" ]; then
bmcSerialNo="000000000000"
fi
}
#Function to add virtual file directory entry, consists of below entries
####################FORMAT################
#Name Size(bytes) Value
#Entry Header 8 FILE
#Entry Size 2 0x0040
#Reserved 10 NULL
#Entry Type 2 0x0001
#File Name Prefix 2 0x000F
#Dump File Type 7 BMCDUMP/SYSDUMP/NAGDUMP
#Separator 1 .
#System Serial No 7 System serial number fetched from system
#Dump Identifier 8 Dump Identifier value fetched from dump
#Separator 1 .
#Time stamp 14 Form should be yyyymmddhhmmss
#Null Terminator 1 0x00
function dump_file_entry() {
printf "FILE " >> $FILE
add_null 1
printf '\x40' >> $FILE #Virtual file directory entry size
add_null 11
printf '\x01' >> $FILE
add_null 1
printf '\x0F' >> "$FILE"
if [ "$dump_type" = "$OP_DUMP" ]; then
printf "SYSDUMP.%s." "$serialNo" >> "$FILE"
else
printf "%s.%s." "$header_dump_name" "$serialNo" >> "$FILE"
fi
get_dump_id
printf "." >> $FILE
printf $dDay >> $FILE #UTC time stamp
add_null 1
}
#Function section directory entry, consists of below entries
####################FORMAT################
#Name Size(bytes) Value
#Entry Header 8 SECTION
#Entry Size 2 0x0030
#Section Priority 2 0x0000
#Reserved 4 NULL
#Entry Flags 4 0x00000001
#Entry Types 2 0x0002
#Reserved 2 NULL
#Dump Size 8 Dump size in hex + dump header
#Optional Section 16 BMCDUMP/NAGDUMP/DUMP SUMMARY
function dump_section_entry() {
printf "SECTION " >> $FILE
add_null 1
printf '\x30' >> "$FILE" #Section entry size
add_null 9
if [ "$dump_type" = "$OP_DUMP" ]; then
add_null 1
else
printf '\x01' >> "$FILE"
fi
add_null 1
printf '\x02' >> "$FILE"
add_null 2
if [ "$dump_type" = "$OP_DUMP" ]; then
add_null 6
printf '\x04' >> "$FILE"
add_null 1
printf "DUMP SUMMARY" >> "$FILE"
add_null 4
else
dump_size #Dump size
printf "%s" "$header_dump_name" >> "$FILE"
add_null 9
fi
}
#Function to add dump header, consists of below entries
####################FORMAT################
#Name Size(bytes) Value
#Dump type 8 BMC/NAG DUMP
#Dump Request time 8 Dump request time stamp (in BCD)
#Dump Identifier 4 Dump identifier fetched from dump
#Dump version 2 0x0210
#Dump header 2 0x200
#Total dump size 8 Dump size + dump header
#Panel function 32 System model, feature, type and IPL mode
#System Name 32 System Name (in ASCII)
#Serial number 7 System serial number
#Reserved 1 NULL
#PLID 4 Comes from errorlog
#File Header Size 2 0x70
#Dump SRC Size 2 Dump SRC Size. Currently NULL
#DUMP SRC 320 DUMP SRC. Currently NULL
#Dump Req Type 4 Dump requester user interface type.
#Dump Req ID 32 Dump requester user interface ID
#Dump Req user ID 32 Dump requester user ID.
#
#TODO: Github issue #2639, to populate the unpopulated elements.
#Note: Unpopulated elements are listed below are set as NULL
#PLID
#SRC size
#SRC dump
#Dump requester type
#Dump Req ID
#Dump Req user ID
function dump_header() {
if [ $dump_type = "$TYPE_FAULTDATA" ]; then
printf "FLT DUMP" >> $FILE
else
printf "BMC DUMP" >> $FILE
fi
dump_time
add_null 4 #Dump Identifier
printf '\x02' >> $FILE #Dump version 0x0210
printf '\x10' >> $FILE
printf '\x02' >> $FILE #Dump header size 0x0200
add_null 1
dump_size #dump size
printf "$modelNo" >> "$FILE"
add_null 24
printf "Server-%s-SN%s" "$modelNo" "$serialNo" >> "$FILE"
add_null 7
printf "$serialNo" >> "$FILE"
add_null 1
get_eid
add_null 1
printf '\x70' >> "$FILE" #File header size
add_null 2 # SRC size
add_null 320 # SRC dump
getbmc_serial
add_null 68 # Dump requester details
}
#Function to add Dump entry, consists of below entries
####################FORMAT################
#Name Size(bytes) Value
#Dump Entry Version 1 0x01
#BMC Dump Valid 1 0x01
#No of Dump Entry 2 Number of Dump Entry
#
function dump_entry() {
printf '\x01' >> $FILE #Dump entry version
printf '\x01' >> $FILE #Dump valid
add_null 1
printf '\x10' >> $FILE #Dump entry
}
#Function to Hardware Dump Section
####################FORMAT##################
#Name Size(bytes) Value
#HWDumpHeader 8 SECTION
#HWDumpEntrySize 2 0x0030
#HWDumpPriority 2 0x02
#reserve6 4 NULL
#HWDumpEntryFlag 4 0x0001
#HWDumpEntryType 2 0x02
#reserve7 2 NULL
#reserve7a 4 NULL
#HWDumpSize 4 NULL
#HWDumpName[16] 16 HARDWARE DATA
function hw_dump_section() {
printf "SECTION " >> "$FILE"
add_null 1
printf '\x30' >> "$FILE" #Section entry size
add_null 1
printf '\x02' >> "$FILE"
add_null 7
printf '\x00' >> "$FILE"
add_null 1
printf '\x02' >> "$FILE"
add_null 6
tar_size
printf "HARDWARE DATA" >> "$FILE"
add_null 3
}
#Function to Mainstore Dump Section
######################FORMAT###################
#Name Size(in bytes) Value
#MainstoreHeader 8 SECTION
#MainstoreEntrySize 2 0x30
#MainstorePriority 2 0x02
#reserve8 4 NULL
#MainstoreEntryFlag 4 NULL
#MainstoreEntryType 2 0x01
#reserve9 2 NULL
#MainstoreSize 8 NULL
#MainstoreName 16 HYPERVISOR DATA
function mainstore_dump_section() {
printf "SECTION " >> "$FILE"
add_null 1
printf '\x30' >> "$FILE" #Section entry size
add_null 1
printf '\x02' >> "$FILE"
add_null 7
printf '\x01' >> "$FILE"
add_null 1
printf '\x02' >> "$FILE"
add_null 10
printf "HYPERVISOR DATA" >> "$FILE"
add_null 1
}
#Function for platform system dump header
######################FORMAT##################
#Name Size(in bytes) Value
#eyeCatcher 8 SYS DUMP
#requestTimestamp 8 BCD time
#dumpIdentifier 4
#dumpVersion 2
#headerSize 2
#totalDumpSize 8
#machineInfo 32
#systemName 32
#systemSerialNumber 7
#Dump Creator BMC 1
#eventLogId 4
#fileHeaderSize 2
####################DATA NOT AVAILABLE##########
#srcSize 2
#dumpSrc 332
#toolType 4
#clientId 32
#userId 32
#systemDumpFlags 2
#hardwareErrorFlags 2
#processorChipEcid 2
#hardwareObjectModel 1
#chUnused 1
#cecMemoryErrorFlags 8
#memoryDumpStartTime 8
#memoryDumpCompleteTime 8
#hypVerRelMod 8
#Reserved4HysrInfo 2
#hypMode 1
#hypDumpContentPolicy 1
#Reserved4HWDInfo 2
#hardwareNodalCount 2
#hardwareDumpTableSize 4
#hardwareDumpDataSize 4
#totalHardwareDumpDataSize 4
#mdrtTableSize 4
#mdrtTableAddress 8
#memoryDumpDataSize 8
#hypModLoadMapTime 8
#hardwareCollectionEndTime 8
#contentType 4
#failingUnitId 4
#failingCappChipId 2
#failingCappUnitId 1
#reserve02 5
#hypHRMOR 8
#hypNACAAddress 8
#hardwareCollectionStartTime 8
#mdstTableSize 4
#payloadState 4
#creator BMC 1
#reservedForCreator 169
function plat_dump_header() {
printf "SYS DUMP" >> "$FILE"
dump_time
get_dump_id "$OP_DUMP" #Dump identifier
printf '\x02' >> "$FILE"
printf '\x21' >> "$FILE" #Need to cross check
printf '\x04' >> "$FILE" #Dump header size 0x0400
add_null 1
total_size
printf "%s" "$modelNo" >> "$FILE"
add_null 24
system_name
printf "%s" "$serialNo" >> "$FILE"
printf '\x01' >> "$FILE" #Dump Creator BMC
get_eid
add_null 1
printf '\xd0' >> "$FILE" #File Header size
add_null 498
content_type # 4 bytes
add_null 44
printf '\x01' >> "$FILE" # BMC indicator
add_null 367
}
#main function
function gen_header_package() {
dump_file_entry
dump_section_entry
if [ "$dump_type" = "$OP_DUMP" ]; then
hw_dump_section
mainstore_dump_section
plat_dump_header
else
dump_header
dump_entry
fi
}
get_bmc_model_serial_number
#Run gen_header_package
gen_header_package