1#!/bin/bash 2# 3#Header for BMC DUMP 4#This script will create header file only for IBM systems. 5#This script will generate generic IBM dump header format. 6# 7#Note: The dump header will be imposed on the dump file i.e 8#<dump name>.tar.xz/gz only on IBM specific systems, user needs to 9#separate out the header before extracting the dump. 10# 11 12#Constants 13declare -rx DUMP_HEADER_ENTRY_SIZE='516' 14declare -rx SIZE_4='4' 15declare -rx SIZE_8='8' 16declare -rx SIZE_12='12' 17declare -rx SIZE_32='32' 18#Dump Summary size without header 19declare -rx DUMP_SUMMARY_SIZE='1024' 20declare -rx HW_DUMP='00' 21declare -rx HB_DUMP='20' 22declare -rx SBE_DUMP='30' 23declare -rx OP_DUMP="opdump" 24declare -rx INVENTORY_MANAGER='xyz.openbmc_project.Inventory.Manager' 25declare -rx INVENTORY_PATH='/xyz/openbmc_project/inventory/system' 26declare -rx INVENTORY_ASSET_INT='xyz.openbmc_project.Inventory.Decorator.Asset' 27declare -rx INVENTORY_BMC_BOARD='/xyz/openbmc_project/inventory/system/chassis/motherboard' 28declare -rx PHOSPHOR_LOGGING='xyz.openbmc_project.Logging' 29declare -rx PEL_ENTRY='org.open_power.Logging.PEL.Entry' 30declare -rx PEL_ID_PROP='PlatformLogID' 31 32#Variables 33declare -x modelNo 34modelNo=$(busctl get-property $INVENTORY_MANAGER $INVENTORY_PATH \ 35 $INVENTORY_ASSET_INT Model | cut -d " " -f 2 | sed "s/^\(\"\)\(.*\)\1\$/\2/g") 36#Variables 37declare -x serialNo 38serialNo=$(busctl get-property $INVENTORY_MANAGER $INVENTORY_PATH \ 39 $INVENTORY_ASSET_INT SerialNumber | cut -d " " -f 2 | sed "s/^\(\"\)\(.*\)\1\$/\2/g") 40declare -x dDay 41dDay=$(date -d @"$EPOCHTIME" +'%Y%m%d%H%M%S') 42declare -x bmcSerialNo 43bmcSerialNo=$(busctl call $INVENTORY_MANAGER $INVENTORY_BMC_BOARD \ 44 org.freedesktop.DBus.Properties Get ss $INVENTORY_ASSET_INT \ 45 SerialNumber | cut -d " " -f 3 | sed "s/^\(\"\)\(.*\)\1\$/\2/g") 46 47#Function to add NULL 48function add_null() { 49 local a=$1 50 printf '%*s' $a | tr ' ' "\0" >> $FILE 51} 52 53#Function to is to convert the EPOCHTIME collected 54#from dreport into hex values and write the same in 55#header. 56function dump_time() { 57 x=${#dDay} 58 msize=`expr $x / 2` 59 msize=`expr $SIZE_8 - $msize` 60 for ((i=0;i<$x;i+=2)); 61 do 62 printf \\x${dDay:$i:2} >> $FILE 63 done 64 add_null $msize 65} 66 67#Function to fetch the size of the dump 68function dump_size() { 69 #Adding 516 bytes as the total dump size is dump tar size 70 #plus the dump header entry in this case 71 #dump_header and dump_entry 72 # shellcheck disable=SC2154 # name_dir comes from elsewhere. 73 dumpSize=$(stat -c %s "$name_dir.bin") 74 sizeDump=$(( dumpSize + DUMP_HEADER_ENTRY_SIZE )) 75 printf -v hex "%x" "$sizeDump" 76 x=${#hex} 77 if [ $(($x % 2)) -eq 1 ]; then 78 hex=0$hex 79 x=${#hex} 80 fi 81 msize=`expr $x / 2` 82 msize=`expr $SIZE_8 - $msize` 83 add_null $msize 84 for ((i=0;i<$x;i+=2)); 85 do 86 printf \\x${hex:$i:2} >> $FILE 87 done 88} 89 90#Function to set dump id to 8 bytes format 91function get_dump_id() { 92 # shellcheck disable=SC2154 93 size=${#dump_id} 94 if [ "$1" == "$OP_DUMP" ]; then 95 nulltoadd=$(( SIZE_4 - size / 2 - size % 2 )) 96 add_null "$nulltoadd" 97 for ((i=0;i<size;i+=2)); 98 do 99 # shellcheck disable=SC2059 100 printf "\\x${dump_id:$i:2}" >> "$FILE" 101 done 102 else 103 nulltoadd=$(( SIZE_8 - size )) 104 printf '%*s' "$nulltoadd" | tr ' ' "0" >> "$FILE" 105 printf "%s" "$dump_id" >> "$FILE" 106 fi 107} 108 109#Function to get the bmc serial number 110function getbmc_serial() { 111 x=${#bmcSerialNo} 112 nulltoadd=`expr $SIZE_12 - $x` 113 printf $bmcSerialNo >> $FILE 114 printf '%*s' $nulltoadd | tr ' ' "0" >> $FILE 115} 116 117#Function to fetch the hostname 118function system_name() { 119 name=$(hostname) 120 len=${#name} 121 nulltoadd=$(( SIZE_32 - len )) 122 printf "%s" "$name" >> "$FILE" 123 add_null "$nulltoadd" 124} 125 126#Function to get the errorlog ID 127function get_eid() { 128 # shellcheck disable=SC2154 # dump_type comes from elsewhere 129 if [ "$dump_type" = "$OP_DUMP" ]; then 130 # shellcheck disable=SC2154 # elog_id comes from elsewhere 131 x=${#elog_id} 132 if [ "$x" = 8 ]; then 133 msize=$(( x / 2 )) 134 msize=$(( SIZE_4 - msize )) 135 for ((i=0;i<x;i+=2)); 136 do 137 printf "\\x${elog_id:$i:2}" >> "$FILE" 138 done 139 add_null "$msize" 140 else 141 add_null 4 142 fi 143 else 144 if ! { [[ $dump_type = "$TYPE_ELOG" ]] || \ 145 [[ $dump_type = "$TYPE_CHECKSTOP" ]]; }; then 146 x=${#elog_id} 147 if [ "$x" = 8 ]; then 148 for ((i=0;i<x;i+=2)); 149 do 150 printf "\\x${elog_id:$i:2}" >> "$FILE" 151 done 152 else 153 add_null 4 154 fi 155 else 156 strpelid=$(busctl get-property $PHOSPHOR_LOGGING \ 157 $optional_path $PEL_ENTRY $PEL_ID_PROP | cut -d " " -f 2) 158 decpelid=$(expr "$strpelid" + 0) 159 hexpelid=$(printf "%x" "$decpelid") 160 x=${#hexpelid} 161 if [ "$x" = 8 ]; then 162 for ((i=0;i<x;i+=2)); 163 do 164 printf "\\x${hexpelid:$i:2}" >> "$FILE" 165 done 166 else 167 add_null 4 168 fi 169 fi 170 fi 171} 172 173#Function to get the tar size of the dump 174function tar_size() { 175 printf -v hex "%x" "$size_dump" 176 x=${#hex} 177 if [ $((x % 2)) -eq 1 ]; then 178 hex=0$hex 179 x=${#hex} 180 fi 181 msize=$(( x / 2 )) 182 msize=$(( SIZE_4 - msize )) 183 add_null "$msize" 184 for ((i=0;i<x;i+=2)); 185 do 186 # shellcheck disable=SC2059 # using 'hex' as a variable is safe here. 187 printf "\\x${hex:$i:2}" >> "$FILE" 188 done 189} 190 191#Function will get the total size of the dump without header 192# i.e. Dump summary size i.e. 1024 bytes + the tar file size 193function total_size() { 194 size_dump=$(( size_dump + DUMP_SUMMARY_SIZE )) 195 printf -v hex "%x" "$size_dump" 196 x=${#hex} 197 if [ $((x % 2)) -eq 1 ]; then 198 hex=0$hex 199 x=${#hex} 200 fi 201 msize=$(( x / 2 )) 202 msize=$(( SIZE_8 - msize )) 203 add_null "$msize" 204 for ((i=0;i<x;i+=2)); 205 do 206 # shellcheck disable=SC2059 # using 'hex' as a variable is safe here. 207 printf "\\x${hex:$i:2}" >> "$FILE" 208 done 209} 210 211#Function to populate content type based on dump type 212function content_type() { 213 type="00000000" 214 # content type: 215 # Hostboot dump = "20" 216 # Hardware dump = "00" 217 # SBE dump = "30" 218 if [ "$dump_content_type" = "$HB_DUMP" ]; then 219 type="00000200" 220 elif [ "$dump_content_type" = "$HW_DUMP" ]; then 221 type="40000000" 222 elif [ "$dump_content_type" = "$SBE_DUMP" ]; then 223 type="02000000" 224 fi 225 x=${#type} 226 for ((i=0;i<$x;i+=2)); 227 do 228 # shellcheck disable=SC2059 # using 'type' as a variable is safe here. 229 printf "\\x${type:$i:2}" >> "$FILE" 230 done 231} 232 233# @brief Fetching model number and serial number property from inventory 234# If the busctl command fails, populating the model and serial number 235# with default value i.e. 0 236function get_bmc_model_serial_number() { 237 modelNo=$(busctl get-property $INVENTORY_MANAGER $INVENTORY_PATH \ 238 $INVENTORY_ASSET_INT Model | cut -d " " -f 2 | sed "s/^\(\"\)\(.*\)\1\$/\2/g") 239 240 if [ -z "$modelNo" ]; then 241 modelNo="00000000" 242 fi 243 244 bmcSerialNo=$(busctl call $INVENTORY_MANAGER $INVENTORY_BMC_BOARD \ 245 org.freedesktop.DBus.Properties Get ss $INVENTORY_ASSET_INT \ 246 SerialNumber | cut -d " " -f 3 | sed "s/^\(\"\)\(.*\)\1\$/\2/g") 247 248 if [ -z "$bmcSerialNo" ]; then 249 bmcSerialNo="000000000000" 250 fi 251} 252 253#Function to add virtual file directory entry, consists of below entries 254####################FORMAT################ 255#Name Size(bytes) Value 256#Entry Header 8 FILE 257#Entry Size 2 0x0040 258#Reserved 10 NULL 259#Entry Type 2 0x0001 260#File Name Prefix 2 0x000F 261#Dump File Type 7 BMCDUMP/SYSDUMP/NAGDUMP 262#Separator 1 . 263#System Serial No 7 System serial number fetched from system 264#Dump Identifier 8 Dump Identifier value fetched from dump 265#Separator 1 . 266#Time stamp 14 Form should be yyyymmddhhmmss 267#Null Terminator 1 0x00 268function dump_file_entry() { 269 printf "FILE " >> $FILE 270 add_null 1 271 printf '\x40' >> $FILE #Virtual file directory entry size 272 add_null 11 273 printf '\x01' >> $FILE 274 add_null 1 275 printf '\x0F' >> "$FILE" 276 if [ "$dump_type" = "$OP_DUMP" ]; then 277 printf "SYSDUMP.%s." "$serialNo" >> "$FILE" 278 else 279 printf "%s.%s." "$header_dump_name" "$serialNo" >> "$FILE" 280 fi 281 get_dump_id 282 printf "." >> $FILE 283 printf $dDay >> $FILE #UTC time stamp 284 add_null 1 285} 286 287#Function section directory entry, consists of below entries 288####################FORMAT################ 289#Name Size(bytes) Value 290#Entry Header 8 SECTION 291#Entry Size 2 0x0030 292#Section Priority 2 0x0000 293#Reserved 4 NULL 294#Entry Flags 4 0x00000001 295#Entry Types 2 0x0002 296#Reserved 2 NULL 297#Dump Size 8 Dump size in hex + dump header 298#Optional Section 16 BMCDUMP/NAGDUMP/DUMP SUMMARY 299function dump_section_entry() { 300 printf "SECTION " >> $FILE 301 add_null 1 302 printf '\x30' >> "$FILE" #Section entry size 303 add_null 9 304 if [ "$dump_type" = "$OP_DUMP" ]; then 305 add_null 1 306 else 307 printf '\x01' >> "$FILE" 308 fi 309 add_null 1 310 printf '\x02' >> "$FILE" 311 add_null 2 312 if [ "$dump_type" = "$OP_DUMP" ]; then 313 add_null 6 314 printf '\x04' >> "$FILE" 315 add_null 1 316 printf "DUMP SUMMARY" >> "$FILE" 317 add_null 4 318 else 319 dump_size #Dump size 320 printf "%s" "$header_dump_name" >> "$FILE" 321 add_null 9 322 fi 323} 324 325#Function to add dump header, consists of below entries 326####################FORMAT################ 327#Name Size(bytes) Value 328#Dump type 8 BMC/NAG DUMP 329#Dump Request time 8 Dump request time stamp (in BCD) 330#Dump Identifier 4 Dump identifier fetched from dump 331#Dump version 2 0x0210 332#Dump header 2 0x200 333#Total dump size 8 Dump size + dump header 334#Panel function 32 System model, feature, type and IPL mode 335#System Name 32 System Name (in ASCII) 336#Serial number 7 System serial number 337#Reserved 1 NULL 338#PLID 4 Comes from errorlog 339#File Header Size 2 0x70 340#Dump SRC Size 2 Dump SRC Size. Currently NULL 341#DUMP SRC 320 DUMP SRC. Currently NULL 342#Dump Req Type 4 Dump requester user interface type. 343#Dump Req ID 32 Dump requester user interface ID 344#Dump Req user ID 32 Dump requester user ID. 345# 346#TODO: Github issue #2639, to populate the unpopulated elements. 347#Note: Unpopulated elements are listed below are set as NULL 348#PLID 349#SRC size 350#SRC dump 351#Dump requester type 352#Dump Req ID 353#Dump Req user ID 354function dump_header() { 355 if [ $dump_type = "$TYPE_FAULTDATA" ]; then 356 printf "FLT DUMP" >> $FILE 357 else 358 printf "BMC DUMP" >> $FILE 359 fi 360 dump_time 361 add_null 4 #Dump Identifier 362 printf '\x02' >> $FILE #Dump version 0x0210 363 printf '\x10' >> $FILE 364 printf '\x02' >> $FILE #Dump header size 0x0200 365 add_null 1 366 dump_size #dump size 367 printf "$modelNo" >> "$FILE" 368 add_null 24 369 printf "Server-%s-SN%s" "$modelNo" "$serialNo" >> "$FILE" 370 add_null 7 371 printf "$serialNo" >> "$FILE" 372 add_null 1 373 get_eid 374 add_null 1 375 printf '\x70' >> "$FILE" #File header size 376 add_null 2 # SRC size 377 add_null 320 # SRC dump 378 getbmc_serial 379 add_null 68 # Dump requester details 380} 381 382#Function to add Dump entry, consists of below entries 383####################FORMAT################ 384#Name Size(bytes) Value 385#Dump Entry Version 1 0x01 386#BMC Dump Valid 1 0x01 387#No of Dump Entry 2 Number of Dump Entry 388# 389function dump_entry() { 390 printf '\x01' >> $FILE #Dump entry version 391 printf '\x01' >> $FILE #Dump valid 392 add_null 1 393 printf '\x10' >> $FILE #Dump entry 394} 395 396#Function to Hardware Dump Section 397####################FORMAT################## 398#Name Size(bytes) Value 399#HWDumpHeader 8 SECTION 400#HWDumpEntrySize 2 0x0030 401#HWDumpPriority 2 0x02 402#reserve6 4 NULL 403#HWDumpEntryFlag 4 0x0001 404#HWDumpEntryType 2 0x02 405#reserve7 2 NULL 406#reserve7a 4 NULL 407#HWDumpSize 4 NULL 408#HWDumpName[16] 16 HARDWARE DATA 409function hw_dump_section() { 410 printf "SECTION " >> "$FILE" 411 add_null 1 412 printf '\x30' >> "$FILE" #Section entry size 413 add_null 1 414 printf '\x02' >> "$FILE" 415 add_null 7 416 printf '\x00' >> "$FILE" 417 add_null 1 418 printf '\x02' >> "$FILE" 419 add_null 6 420 tar_size 421 printf "HARDWARE DATA" >> "$FILE" 422 add_null 3 423} 424 425#Function to Mainstore Dump Section 426######################FORMAT################### 427#Name Size(in bytes) Value 428#MainstoreHeader 8 SECTION 429#MainstoreEntrySize 2 0x30 430#MainstorePriority 2 0x02 431#reserve8 4 NULL 432#MainstoreEntryFlag 4 NULL 433#MainstoreEntryType 2 0x01 434#reserve9 2 NULL 435#MainstoreSize 8 NULL 436#MainstoreName 16 HYPERVISOR DATA 437function mainstore_dump_section() { 438 printf "SECTION " >> "$FILE" 439 add_null 1 440 printf '\x30' >> "$FILE" #Section entry size 441 add_null 1 442 printf '\x02' >> "$FILE" 443 add_null 7 444 printf '\x01' >> "$FILE" 445 add_null 1 446 printf '\x02' >> "$FILE" 447 add_null 10 448 printf "HYPERVISOR DATA" >> "$FILE" 449 add_null 1 450} 451 452#Function for platform system dump header 453######################FORMAT################## 454#Name Size(in bytes) Value 455#eyeCatcher 8 SYS DUMP 456#requestTimestamp 8 BCD time 457#dumpIdentifier 4 458#dumpVersion 2 459#headerSize 2 460#totalDumpSize 8 461#machineInfo 32 462#systemName 32 463#systemSerialNumber 7 464#Dump Creator BMC 1 465#eventLogId 4 466#fileHeaderSize 2 467####################DATA NOT AVAILABLE########## 468#srcSize 2 469#dumpSrc 332 470#toolType 4 471#clientId 32 472#userId 32 473#systemDumpFlags 2 474#hardwareErrorFlags 2 475#processorChipEcid 2 476#hardwareObjectModel 1 477#chUnused 1 478#cecMemoryErrorFlags 8 479#memoryDumpStartTime 8 480#memoryDumpCompleteTime 8 481#hypVerRelMod 8 482#Reserved4HysrInfo 2 483#hypMode 1 484#hypDumpContentPolicy 1 485#Reserved4HWDInfo 2 486#hardwareNodalCount 2 487#hardwareDumpTableSize 4 488#hardwareDumpDataSize 4 489#totalHardwareDumpDataSize 4 490#mdrtTableSize 4 491#mdrtTableAddress 8 492#memoryDumpDataSize 8 493#hypModLoadMapTime 8 494#hardwareCollectionEndTime 8 495#contentType 4 496#failingUnitId 4 497#failingCappChipId 2 498#failingCappUnitId 1 499#reserve02 5 500#hypHRMOR 8 501#hypNACAAddress 8 502#hardwareCollectionStartTime 8 503#mdstTableSize 4 504#payloadState 4 505#creator BMC 1 506#reservedForCreator 169 507function plat_dump_header() { 508 printf "SYS DUMP" >> "$FILE" 509 dump_time 510 get_dump_id "$OP_DUMP" #Dump identifier 511 printf '\x02' >> "$FILE" 512 printf '\x21' >> "$FILE" #Need to cross check 513 printf '\x04' >> "$FILE" #Dump header size 0x0400 514 add_null 1 515 total_size 516 printf "%s" "$modelNo" >> "$FILE" 517 add_null 24 518 system_name 519 printf "%s" "$serialNo" >> "$FILE" 520 printf '\x01' >> "$FILE" #Dump Creator BMC 521 get_eid 522 add_null 1 523 printf '\xd0' >> "$FILE" #File Header size 524 add_null 498 525 content_type # 4 bytes 526 add_null 44 527 printf '\x01' >> "$FILE" # BMC indicator 528 add_null 367 529} 530 531 532#main function 533function gen_header_package() { 534 dump_file_entry 535 dump_section_entry 536 if [ "$dump_type" = "$OP_DUMP" ]; then 537 hw_dump_section 538 mainstore_dump_section 539 plat_dump_header 540 else 541 dump_header 542 dump_entry 543 fi 544} 545 546get_bmc_model_serial_number 547 548#Run gen_header_package 549gen_header_package