blob: 3009b80614b3227990d7cdbf49802f361aa5359d [file] [log] [blame]
Jayanth Othayoth5ce15502017-10-16 00:02:44 -05001#! /bin/bash
2
3help=$"
4 dreport creates an archive(xz compressed) consisting of the following:
5 * Configuration information
6 * Debug information
7 * A summary report
8 The type parameter controls the content of the data. The generated
9 archive is stored in the user specified location.
10
11usage: dreport [OPTION]
12
13Options:
14 -n, —-name <name> Name to be used for the archive.
15 Default name format obmcdump_<id>_<epochtime>
16 -d, —-dir <directory> Archive directory to copy the compressed report.
17 Default output directory is /tmp
18 -i, —-id <id> Dump identifier to associate with the archive.
19 Identifiers include numeric characters.
20 Default dump identifier is 0
21 -t, —-type <type> Data collection type. Valid types are
22 "user", "core", "elog".
23 Default type is "user" initiated.
24 -p, —-path <path> Optional contents to be included in the archive.
25 Valid paths are absolute file path or d-bus path
26 based on type parameter.
27 -Absolute file path for "core" type.
28 -elog d-bus object for "elog" type.
29 -s, --size <size> Maximum allowed size(in KB) of the archive.
30 Report will be truncated in case size exceeds
31 this limit. Default size is unlimited.
32 -v, —-verbose Increase logging verbosity.
33 -V, --version Output version information.
34 -q, —-quiet Only log fatal errors to stderr
35 -h, —-help Display this help and exit.
36"
37
38#CONSTANTS
39declare -rx TRUE=1
40declare -rx FALSE=0
41declare -rx UNLIMITED="unlimited"
42declare -rx SUMMARY_DUMP="summary"
43declare -rx TYPE_USER="user"
44declare -rx TYPE_CORE="core"
45declare -rx TYPE_ELOG="elog"
Marri Devender Rao0deb2872018-11-12 07:45:54 -060046declare -rx TYPE_CHECKSTOP="checkstop"
George Liuff92ffe2021-02-09 15:01:53 +080047declare -rx TYPE_RAMOOPS="ramoops"
Jayanth Othayoth5ce15502017-10-16 00:02:44 -050048declare -rx SUMMARY_LOG="summary.log"
49declare -rx DREPORT_LOG="dreport.log"
50declare -rx TMP_DIR="/tmp"
51declare -rx EPOCHTIME=$(date +"%s")
52declare -rx TIME_STAMP="date -u"
53declare -rx PLUGIN="pl_"
54declare -rx DREPORT_SOURCE="/usr/share/dreport.d"
55declare -rx DREPORT_INCLUDE="$DREPORT_SOURCE/include.d"
Jayanth Othayothaa146d62018-01-08 06:57:53 -060056declare -rx ZERO="0"
57declare -rx JOURNAL_LINE_LIMIT="500"
Chirag Sharmac237e3d2020-09-15 12:01:01 -050058declare -rx HEADER_EXTENSION="$DREPORT_INCLUDE/gendumpheader"
Jayanth Othayoth5ce15502017-10-16 00:02:44 -050059
60#Error Codes
61declare -rx SUCCESS="0"
62declare -rx INTERNAL_FAILURE="1"
63declare -rx RESOURCE_UNAVAILABLE="2"
64
65#VARIABLES
66declare -x name=""
67declare -x dump_dir="/tmp"
68declare -x dump_id="00000000"
69declare -x dump_type=$TYPE_USER
70declare -x verbose=$FALSE
71declare -x quiet=$FALSE
72declare -x dump_size="unlimited"
73declare -x name_dir=""
74declare -x optional_path=""
75declare -x dreport_log=""
76declare -x summary_log=""
77declare -x cur_dump_size=0
Jayanth Othayothaa146d62018-01-08 06:57:53 -060078declare -x pid=$ZERO
Jayanth Othayoth5ce15502017-10-16 00:02:44 -050079declare -x elog_id=""
80
81#Source dreport common functions
82. $DREPORT_INCLUDE/functions
83
84# @brief Initiate data collection based on the type.
85# @return 0 on success, error code otherwise
86function collect_data()
87{
88 case $dump_type in
89 $TYPE_USER)
90 ;;
91 $TYPE_CORE)
92 log_summary "Core: $optional_path"
93 set_core_pid
94 ;;
George Liuff92ffe2021-02-09 15:01:53 +080095 $TYPE_RAMOOPS)
96 log_summary "Ramoops: $optional_path"
97 ;;
Jayanth Othayoth5ce15502017-10-16 00:02:44 -050098 $TYPE_ELOG)
99 log_summary "ELOG: $optional_path"
100 elog_id=$(basename "$optional_path")
101 set_elog_pid
102 ;;
Marri Devender Rao0deb2872018-11-12 07:45:54 -0600103 $TYPE_CHECKSTOP)
104 log_summary "CHECKSTOP: $optional_path"
105 elog_id=$(basename "$optional_path")
106 set_elog_pid
107 ;;
Jayanth Othayoth5ce15502017-10-16 00:02:44 -0500108
109 $SUMMARY_DUMP)
110 #No data collection is required.
111 return
112 ;;
113 *) # unknown option
114 log_error "Skipping: Unknown dump type: $dump_type"
115 return
116 ;;
117 esac
118
119 plugin_path=$DREPORT_SOURCE/$PLUGIN$dump_type.d
120
121 # check plugin directory for this dump type?
122 if [ ! -d $plugin_path ]; then
123 log_error "$plugin_path does not exist, skipping dump collection"
124 return 0
125 fi
126
127 #Executes plugins based on the type.
128 for i in $plugin_path/* ; do
129 $i
130 done
131}
132
133# @brief set pid by reading information from the optional path.
134# dreport "core" type user provides core file as optional path parameter.
135# As per coredump source code systemd-coredump uses below format
136# https://github.com/systemd/systemd/blob/master/src/coredump/coredump.c
137# /var/lib/systemd/coredump/core.%s.%s." SD_ID128_FORMAT_STR “.
138# <process ID>.%s000000"
139function set_core_pid()
140{
141 #Escape bash characters in file name
142 file=$(printf %q "$optional_path")
143
144 #matching systemd-coredump core file format.
145 pid=$(echo $file | awk -F . '{ print $5}')
146}
147
148# @brief set elog pid by reading _PID information from the elog d-bus object.
149# _PID information is stored elog Additional data field
150# Data format "_PID=<pid>"
151function set_elog_pid()
152{
153 additional_data=$(busctl get-property xyz.openbmc_project.Logging \
154 $optional_path \
155 xyz.openbmc_project.Logging.Entry \
156 AdditionalData)
157
158 #read _PID data.
159 if [ ! -z "$additional_data" ]; then
160 pid=$(echo $additional_data | \
161 awk -F _PID= '{ print ($2+0)}')
162 fi
163}
164
165# @brief Initial version of the summary log
166init_summary()
167{
168 log_summary "Name: $name.tar.xz"
169 log_summary "Epochtime: $EPOCHTIME"
170 log_summary "ID: $dump_id"
171 log_summary "Type: $dump_type"
172}
173
174# @brief Check the validity of user inputs and initialize global
175# variables. Create directory for temporary data collection
176# @return 0 on success, error code otherwise
177
178function initialize()
179{
180 #Dump file name
181 if [ -z $name ]; then
182 name=$"obmcdump_"$dump_id"_$EPOCHTIME"
183 fi
184
185 #Create temporary data directory.
186 mkdir -p "$TMP_DIR/$name"
187 if [ $? -ne 0 ]; then
188 echo "Error: Failed to create the temporary directory."
189 return $RESOURCE_UNAVAILABLE;
190 fi
191
192 #name directory
193 name_dir="$TMP_DIR/$name"
194
195 #dreport log file
196 dreport_log="$name_dir/$DREPORT_LOG"
197
198 #summary log file
199 summary_log="$name_dir/$SUMMARY_LOG"
200
201 #Type
Dhruvaraj Subhashchandranfdc0c3a2020-09-14 01:38:27 -0500202 if [[ ! ($dump_type = $TYPE_USER || \
203 $dump_type = $TYPE_CORE || \
204 $dump_type = $TYPE_ELOG || \
George Liuff92ffe2021-02-09 15:01:53 +0800205 $dump_type = $TYPE_RAMOOPS || \
Dhruvaraj Subhashchandranfdc0c3a2020-09-14 01:38:27 -0500206 $dump_type = $TYPE_CHECKSTOP) ]]; then
Jayanth Othayoth5ce15502017-10-16 00:02:44 -0500207 log_error "Invalid -type, Only summary log is available"
208 dump_type=$SUMMARY_DUMP
209 fi
210
211 #Size
212 #Check the input is integer.
213 if [ "$dump_size" -eq "$dump_size" ] 2>/dev/null; then
214 #Converts in to bytes.
215 dump_size="$((dump_size * 1024))"
216 else
217 dump_size=$UNLIMITED
218 fi
219
220 return $SUCCESS
221}
222
223# @brief Packaging the dump and transferring to dump location.
224function package()
225{
226 mkdir -p "$dump_dir"
227 if [ $? -ne 0 ]; then
228 log_error "Could not create the destination directory $dump_dir"
229 dest_dir=$TMP_DIR
230 fi
231
232 #tar and compress the files.
Chirag Sharmac237e3d2020-09-15 12:01:01 -0500233 if [ -f "$HEADER_EXTENSION" ]; then
234 tar -Jcf "$name_dir.tar.xz" -C \
235 $(dirname "$name_dir") $(basename "$name_dir")
236 echo "Adding Dump Header :"$HEADER_EXTENSION
237 ("$HEADER_EXTENSION")
238 cat "$name_dir.tar.xz" | tee -a "/tmp/dumpheader_$EPOCHTIME" > /dev/null
239 mv "/tmp/dumpheader_$EPOCHTIME" "$name_dir.tar.xz"
240 else
241 tar -Jcf "$name_dir.tar.xz" -C \
242 $(dirname "$name_dir") $(basename "$name_dir")
243 fi
Jayanth Othayoth5ce15502017-10-16 00:02:44 -0500244
245 if [ $? -ne 0 ]; then
246 echo $($TIME_STAMP) "Could not create the compressed tar file"
247 rm -r "$name_dir"
248 return $INTERNAL_FAILURE
249 fi
250
251 #remove the temporary name specific directory
252 rm -r "$name_dir"
253
254 echo $($TIME_STAMP) "Report is available in $dump_dir"
255
Chirag Sharmaa63f4a62020-07-13 06:14:22 -0500256 if [ "$TMP_DIR" == "$dump_dir" ] || [ "$TMP_DIR/" == "$dump_dir" ]; then
Jayanth Othayoth5ce15502017-10-16 00:02:44 -0500257 return $SUCCESS
258 fi
259
260 #copy the compressed tar file into the destination
261 cp "$name_dir.tar.xz" "$dump_dir"
262 if [ $? -ne 0 ]; then
263 echo "Failed to copy the $name_dir.tar.xz to $dump_dir"
264 rm "$name_dir.tar.xz"
265 return $INTERNAL_FAILURE
266 fi
267
268 #Remove the temporary copy of the file
269 rm "$name_dir.tar.xz"
270}
271
272# @brief Main function
273function main()
274{
275 #initialize the global variables and
276 #create temporary storage locations
277 initialize
278 result=$?
279 if [[ ${result} -ne $SUCCESS ]]; then
280 echo $($TIME_STAMP) "Error: Failed to initialize, Exiting"
281 exit;
282 fi
283
Gunnar Mills95a72982017-10-25 17:00:14 -0500284 #Initialize the summary log
Jayanth Othayoth5ce15502017-10-16 00:02:44 -0500285 init_summary
286
287 #collect data based on the type.
288 collect_data
289
290 package #package the dump
291 result=$?
292 if [[ ${result} -ne $SUCCESS ]]; then
293 echo $($TIME_STAMP) "Error: Failed to package, Exiting"
294 else
Gunnar Mills95a72982017-10-25 17:00:14 -0500295 echo $($TIME_STAMP) "Successfully completed"
Jayanth Othayoth5ce15502017-10-16 00:02:44 -0500296 exit;
297 fi
298}
299
300TEMP=`getopt -o n:d:i:t:s:p:vVqh \
301 --long name:,dir:,dumpid:,type:,size:,path:,verbose,version,quiet,help \
302 -- "$@"`
303
304if [ $? -ne 0 ]
305then
306 echo "Error: Invalid options"
307 exit 1
308fi
309
310eval set -- "$TEMP"
311
312while [[ $# -gt 1 ]]; do
313 key="$1"
314 case $key in
315 -n|--name)
316 name=$2
317 shift 2;;
318 -d|--dir)
319 dump_dir=$2
320 shift 2;;
321 -i|--dumpid)
322 dump_id=$2
323 shift 2;;
324 -t|--type)
325 dump_type=$2
326 shift 2;;
327 -s|--size)
328 dump_size=$2
329 shift 2;;
330 -p|--path)
331 optional_path=$2
332 shift 2;;
333 -v|—-verbose)
334 verbose=$TRUE
335 shift;;
336 -V|--version)
337 shift;;
338 -q|—-quiet)
339 quiet=$TRUE
340 shift;;
341 -h|--help)
342 echo "$help"
343 exit;;
344 *) # unknown option
345 log_error "Unknown argument: $1"
346 log_info "$help"
347 exit 1;;
348 esac
349done
350
351main #main program
352exit $?