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