xref: /openbmc/openpower-debug-collector/dump/tools/opdump/opdreport (revision b616b69ba0a6a8da491fceb87dae97cdee54da92)
1#!/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
38declare -rx DREPORT_SOURCE="/usr/share/dreport.d"
39declare -rx DREPORT_INCLUDE="$DREPORT_SOURCE/include.d"
40readonly OP_DUMP="opdump"
41readonly TRUE=1
42readonly FALSE=0
43readonly TIME_STAMP="date -u"
44readonly UNLIMITED="unlimited"
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
76#Source opdreport common functions
77. $DREPORT_INCLUDE/opfunctions
78
79# @brief Check the validity of user inputs and initialize global variables
80function initialize() {
81    # shellcheck disable=SC2154 # name comes from elsewhere
82    if [ -z "$name" ]; then
83        name="SYSDUMP"
84    fi
85    fetch_serial_number
86    # shellcheck disable=SC2154 # dump_id comes from elsewhere
87    name="${name}.${serialNo}.${dump_id}.${dDay}"
88
89    if [ -z "$dump_sbe_type" ]; then
90        echo "Error: Dump type is not provided."
91        return "$RESOURCE_UNAVAILABLE"
92    fi
93
94    if [ -z "$dump_dir" ]; then
95        dump_dir=$PWD
96    fi
97
98    if [[ "$dump_size" =~ ^[0-9]+$ ]]; then
99        dump_size=$((dump_size * 1024))
100    else
101        dump_size=$UNLIMITED
102    fi
103
104    get_originator_details "system"
105
106    return "$SUCCESS"
107}
108
109# @brief Collect the dump
110function collect() {
111    content_path="/tmp/dump_${dump_id}_${EPOCHTIME}"
112    dump_outpath="$content_path/plat_dump"
113    if ! mkdir -p "$dump_outpath"; then
114        echo "Could not create the destination directory $dump_outpath"
115        return "$INTERNAL_FAILURE"
116    fi
117
118    dump-collect --type "$dump_sbe_type" --id "0x$dump_id" \
119        --failingunit "$failing_unit" --path "$dump_outpath"
120}
121
122# @brief Package the dump and transfer to dump location
123function package() {
124    FILE="/tmp/dumpheader_${dump_id}_${EPOCHTIME}"
125    if ! mkdir -p "$dump_dir"; then
126        echo "Could not create the destination directory $dump_dir"
127        dump_dir="/tmp"
128    fi
129
130    cd "$content_path" || exit "$INTERNAL_FAILURE"
131
132    dump_content_type=${dump_id:0:2}
133    "$FILE_SCRIPT"
134    elog_id=$eid
135
136    if ! tar -cvzf "$name" plat_dump/*Sbe* info.yaml; then
137        echo "$($TIME_STAMP)" "Could not create the compressed tar file"
138        return "$INTERNAL_FAILURE"
139    fi
140
141    size_dump=$(stat -c %s "$name")
142
143    if [ "$dump_size" != "$UNLIMITED" ] && \
144        [ "$size_dump" -gt "$dump_size" ]; then
145        rm "$name"
146        return "$RESOURCE_UNAVAILABLE"
147    fi
148
149    echo "Adding Dump Header: $HEADER_EXTENSION"
150    "$HEADER_EXTENSION"
151
152    if ! tee -a "$FILE" < "$name" > /dev/null; then
153        echo "$($TIME_STAMP)" "Could not create the compressed file"
154        rm -rf "$name" "$FILE"
155        return "$INTERNAL_FAILURE"
156    fi
157
158    if ! mv "$FILE" "$name"; then
159        echo "$($TIME_STAMP)" "Could not create the compressed file"
160        rm -rf "$name" "$FILE"
161        return "$INTERNAL_FAILURE"
162    fi
163
164    mv "$name" "$dump_dir"
165
166    rm -rf "$content_path"
167    rm -rf "$FILE" "$name"
168
169    return "$SUCCESS"
170}
171
172# @brief Initiate BMC dump
173function initiate_bmc_dump() {
174    bmcDumpPath=$(busctl call xyz.openbmc_project.Dump.Manager \
175            /xyz/openbmc_project/dump/bmc \
176        xyz.openbmc_project.Dump.Create CreateDump a\{sv\} 0)
177    result=$?
178    if [[ $result -ne $SUCCESS ]]; then
179        echo "Error in creating BMC dump associated with system dump"
180    else
181        echo "BMC dump initiated $bmcDumpPath"
182    fi
183}
184
185# @brief Main function
186function main() {
187    initialize
188    result=$?
189    if [[ $result -ne $SUCCESS ]]; then
190        echo "$($TIME_STAMP)" "Error: Failed to initialize, Exiting"
191        return "$INTERNAL_FAILURE"
192    fi
193
194    collect
195    result=$?
196    if [[ $result -ne $SUCCESS ]]; then
197        echo "$($TIME_STAMP)" "Error: Failed to collect dump, Exiting"
198        return "$INTERNAL_FAILURE"
199    fi
200
201    package
202    result=$?
203    if [[ $result -ne $SUCCESS ]]; then
204        echo "$($TIME_STAMP)" "Error: Failed to package, Exiting"
205        return "$INTERNAL_FAILURE"
206    else
207        echo "$($TIME_STAMP)" "Successfully completed"
208    fi
209
210    initiate_bmc_dump
211    return "$SUCCESS"
212}
213
214if ! TEMP=$(getopt -o n:d:i:s:t:e:f:h \
215        --long name:,dir:,dumpid:,size:,type:,eid:,failingunit:,help \
216        -- "$@"); then
217    echo "Error: Invalid options"
218    exit 1
219fi
220
221eval set -- "$TEMP"
222
223while [[ $# -gt 1 ]]; do
224    key="$1"
225    case $key in
226        -n|--name)
227            name=$2
228            shift 2 ;;
229        -d|--dir)
230            dump_dir=$2
231            shift 2 ;;
232        -i|--dumpid)
233            dump_id=$2
234            shift 2 ;;
235        -s|--size)
236            dump_size=$2
237            shift 2 ;;
238        -f|--failingunit)
239            failing_unit=$2
240            shift 2 ;;
241        -e|--eid)
242            eid=$2
243            shift 2 ;;
244        -t|--type)
245            dump_sbe_type=$2
246            shift 2 ;;
247        -h|--help)
248            echo "$help"
249            exit ;;
250        *) # unknown option
251            echo "Unknown argument: $1"
252            echo "$help"
253            exit 1 ;;
254    esac
255done
256
257main
258exit $?
259