blob: 9c92e9f81ba3319a8dc157014b50a45fa89b0c3c [file] [log] [blame]
Dhruvaraj Subhashchandran65d15fb2024-05-18 12:29:09 -05001#!/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 identifer 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 requestor 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 AVAIABLE##########
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