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