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