blob: 92a7ce9f28db110ddb4d1008f623cbee27c81d4d [file] [log] [blame]
Dhruvaraj Subhashchandran35714cd2024-05-16 05:54:38 -05001#!/bin/bash
2# shellcheck disable=SC2034 # Variable is used elsewhere
3
4help=$(cat << EOF
5 opdreport creates an archive consisting of the following:
6 * host dump files and header applied on top of it
7 The type parameter controls the content of the data. The generated
8 archive is stored in the user specified location.
9
10usage: opdreport [OPTION]
11
12Options:
13 -n, --name <name> Name to be used for the archive.
14 Default name format
15 SYSDUMP.<serial number>.<dump_id>.<time>
16 Optional parameter.
17 -d, --dir <directory> Archive directory to copy the compressed report.
18 Default output directory is current working
19 directory. Optional parameter.
20 -i, --dumpid <id> Dump identifier to associate with the archive.
21 Identifiers include numeric characters.
22 Default dump identifier is 0
23 -s, --size <size> Maximum allowed size (in KB) of the archive.
24 Report will be truncated if size exceeds
25 this limit. Default size is unlimited.
26 -f, --failingunit The id of the failed unit
27 -e, --eid Error log associated with the failure
28 -t, --type Type of the dump to be collected
29 1 - Hardware dump
30 3 - Performance dump
31 5 - Hostboot dump
32 10 - SBE Dump
33 -h, --help Display this help and exit.
34EOF
35)
36
37# Constants
38readonly OP_DUMP="opdump"
39readonly DREPORT_SOURCE="/usr/share/dreport.d"
40readonly TRUE=1
41readonly FALSE=0
42readonly TIME_STAMP="date -u"
43readonly UNLIMITED="unlimited"
44readonly DREPORT_INCLUDE="$DREPORT_SOURCE/include.d"
45readonly INVENTORY_MANAGER='xyz.openbmc_project.Inventory.Manager'
46readonly INVENTORY_PATH='/xyz/openbmc_project/inventory/system'
47readonly INVENTORY_ASSET_INT='xyz.openbmc_project.Inventory.Decorator.Asset'
48readonly INVENTORY_BMC_BOARD='/xyz/openbmc_project/inventory/system/chassis/motherboard'
49readonly HEADER_EXTENSION="$DREPORT_INCLUDE/gendumpheader"
50readonly FILE_SCRIPT="$DREPORT_SOURCE/include.d/gendumpinfo"
51
52# Error Codes
53readonly SUCCESS=0
54readonly INTERNAL_FAILURE=1
55readonly RESOURCE_UNAVAILABLE=2
56
57# Variables
58declare -x dump_type="$OP_DUMP"
59declare -x dump_sbe_type=100
60declare -x size_dump=""
61declare -x elog_id="00000000"
62declare -x EPOCHTIME
63EPOCHTIME=$(date +"%s")
64declare -x name=""
65declare -x dump_dir="/tmp"
66declare -x dump_id="00000000"
67declare -x dump_size="unlimited"
68declare -x content_path=""
69declare -x name_dir=""
70declare -x serialNo="0000000"
71declare -x dDay
72dDay=$(date -d @"$EPOCHTIME" +'%Y%m%d%H%M%S')
73declare -x dump_content_type=""
74declare -x FILE=""
75
Swarnendu-R-C1bee03b2024-06-13 09:21:56 -050076#Source opdreport common functions
77. $DREPORT_INCLUDE/opfunctions
78
Dhruvaraj Subhashchandran35714cd2024-05-16 05:54:38 -050079# @brief Get serial number property from inventory
80function fetch_serial_number() {
81 serialNo=$(busctl get-property "$INVENTORY_MANAGER" "$INVENTORY_PATH" \
82 "$INVENTORY_ASSET_INT" SerialNumber | cut -d " " -f 2 | \
83 sed 's/^"\(.*\)"$/\1/')
84
85 if [ -z "$serialNo" ]; then
86 serialNo="0000000"
87 fi
88}
89
90# @brief Check the validity of user inputs and initialize global variables
91function initialize() {
92 # shellcheck disable=SC2154 # name comes from elsewhere
93 if [ -z "$name" ]; then
94 name="SYSDUMP"
95 fi
96 fetch_serial_number
97 # shellcheck disable=SC2154 # dump_id comes from elsewhere
98 name="${name}.${serialNo}.${dump_id}.${dDay}"
99
100 if [ -z "$dump_sbe_type" ]; then
101 echo "Error: Dump type is not provided."
102 return "$RESOURCE_UNAVAILABLE"
103 fi
104
105 if [ -z "$dump_dir" ]; then
106 dump_dir=$PWD
107 fi
108
109 if [[ "$dump_size" =~ ^[0-9]+$ ]]; then
110 dump_size=$((dump_size * 1024))
111 else
112 dump_size=$UNLIMITED
113 fi
114
Swarnendu-R-C1bee03b2024-06-13 09:21:56 -0500115 get_originator_details "system"
116
Dhruvaraj Subhashchandran35714cd2024-05-16 05:54:38 -0500117 return "$SUCCESS"
118}
119
120# @brief Collect the dump
121function collect() {
122 content_path="/tmp/dump_${dump_id}_${EPOCHTIME}"
123 dump_outpath="$content_path/plat_dump"
124 if ! mkdir -p "$dump_outpath"; then
125 echo "Could not create the destination directory $dump_outpath"
126 return "$INTERNAL_FAILURE"
127 fi
128
129 dump-collect --type "$dump_sbe_type" --id "0x$dump_id" \
130 --failingunit "$failing_unit" --path "$dump_outpath"
131}
132
133# @brief Package the dump and transfer to dump location
134function package() {
135 FILE="/tmp/dumpheader_${dump_id}_${EPOCHTIME}"
136 if ! mkdir -p "$dump_dir"; then
137 echo "Could not create the destination directory $dump_dir"
138 dump_dir="/tmp"
139 fi
140
141 cd "$content_path" || exit "$INTERNAL_FAILURE"
142
SwethaParasac14bf2c2024-09-18 02:19:34 -0500143 dump_content_type=${dump_id:0:2}
Dhruvaraj Subhashchandran35714cd2024-05-16 05:54:38 -0500144 "$FILE_SCRIPT"
145 elog_id=$eid
146
147 if ! tar -cvzf "$name" plat_dump/*Sbe* info.yaml; then
148 echo "$($TIME_STAMP)" "Could not create the compressed tar file"
149 return "$INTERNAL_FAILURE"
150 fi
151
152 size_dump=$(stat -c %s "$name")
153
154 if [ "$dump_size" != "$UNLIMITED" ] && \
155 [ "$size_dump" -gt "$dump_size" ]; then
156 rm "$name"
157 return "$RESOURCE_UNAVAILABLE"
158 fi
159
160 echo "Adding Dump Header: $HEADER_EXTENSION"
161 "$HEADER_EXTENSION"
162
163 if ! tee -a "$FILE" < "$name" > /dev/null; then
164 echo "$($TIME_STAMP)" "Could not create the compressed file"
165 rm -rf "$name" "$FILE"
166 return "$INTERNAL_FAILURE"
167 fi
168
169 if ! mv "$FILE" "$name"; then
170 echo "$($TIME_STAMP)" "Could not create the compressed file"
171 rm -rf "$name" "$FILE"
172 return "$INTERNAL_FAILURE"
173 fi
174
175 mv "$name" "$dump_dir"
176
177 rm -rf "$content_path"
178 rm -rf "$FILE" "$name"
179
180 return "$SUCCESS"
181}
182
183# @brief Initiate BMC dump
184function initiate_bmc_dump() {
185 bmcDumpPath=$(busctl call xyz.openbmc_project.Dump.Manager \
186 /xyz/openbmc_project/dump/bmc \
187 xyz.openbmc_project.Dump.Create CreateDump a\{sv\} 0)
188 result=$?
189 if [[ $result -ne $SUCCESS ]]; then
190 echo "Error in creating BMC dump associated with system dump"
191 else
192 echo "BMC dump initiated $bmcDumpPath"
193 fi
194}
195
196# @brief Main function
197function main() {
198 initialize
199 result=$?
200 if [[ $result -ne $SUCCESS ]]; then
201 echo "$($TIME_STAMP)" "Error: Failed to initialize, Exiting"
202 return "$INTERNAL_FAILURE"
203 fi
204
205 collect
206 result=$?
207 if [[ $result -ne $SUCCESS ]]; then
208 echo "$($TIME_STAMP)" "Error: Failed to collect dump, Exiting"
209 return "$INTERNAL_FAILURE"
210 fi
211
212 package
213 result=$?
214 if [[ $result -ne $SUCCESS ]]; then
215 echo "$($TIME_STAMP)" "Error: Failed to package, Exiting"
216 return "$INTERNAL_FAILURE"
217 else
218 echo "$($TIME_STAMP)" "Successfully completed"
219 fi
220
221 initiate_bmc_dump
222 return "$SUCCESS"
223}
224
225if ! TEMP=$(getopt -o n:d:i:s:t:e:f:h \
226 --long name:,dir:,dumpid:,size:,type:,eid:,failingunit:,help \
227 -- "$@"); then
228 echo "Error: Invalid options"
229 exit 1
230fi
231
232eval set -- "$TEMP"
233
234while [[ $# -gt 1 ]]; do
235 key="$1"
236 case $key in
237 -n|--name)
238 name=$2
239 shift 2 ;;
240 -d|--dir)
241 dump_dir=$2
242 shift 2 ;;
243 -i|--dumpid)
244 dump_id=$2
245 shift 2 ;;
246 -s|--size)
247 dump_size=$2
248 shift 2 ;;
249 -f|--failingunit)
250 failing_unit=$2
251 shift 2 ;;
252 -e|--eid)
253 eid=$2
254 shift 2 ;;
255 -t|--type)
256 dump_sbe_type=$2
257 shift 2 ;;
258 -h|--help)
259 echo "$help"
260 exit ;;
261 *) # unknown option
262 echo "Unknown argument: $1"
263 echo "$help"
264 exit 1 ;;
265 esac
266done
267
268main
269exit $?