#!/bin/sh # # Post-process endurance measurements into an overview HTML report. # This file is part of sp-endurance. # # Copyright (C) 2006-2009 by Nokia Corporation # # Contact: Eero Tamminen # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # version 2 as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA # # Changelog # 2006-11-09: # - measurement data files are now in separate directories # - if converted files exist, do not re-generate them, do not remove CSV files # 2007-02-05: # - for performance reasons endurance-report.py does now SMAPS private/dirty # diffing itself (if smaps.cap exists). Script usage tells now how to get # the full SMAPS report # 2007-02-06: # - added options for: # - giving report name # - giving from which measurement to start parsing # - giving how many measurements to skip between parsing # - whether to stop parsing at first reboot # - whether to post-process SMAPS data details (which is slow) # and usage for the options # 2007-02-16: # - added options for splitting reports at reboots and stopping # at specific report # 2007-03-01: # - rename to make Lintian happy # 2007-03-13: # - kludge around files which have been copied in FTP ASCII mode # using Windows and shells (Bash) which cannot handle carriage returns # 2007-08-30: # - smaps analysis doesn't need the intermediate CSV file anymore, # it can handle the .cap files directly # 2007-11-29: # - Handle compressed smaps files # 2008-02-21: # - Fix case when DSME stat files are empty # 2009-04-21: # - Add support for lzo compressed smaps.cap files # # TODO: # - add slabinfo diffing? script=${0##*/} # tells that tool given argument is missing from path and terminates script. # if second argument is given, tell from which package the tool comes from. path_error() { echo "ERROR: couldn't find '$1' from PATH!" if [ $2 ]; then echo "You need to install '$2' package for this tool." fi exit 1 } # shows script usage and terminates it. # if argument is given, it's printed as ERROR before this. usage() { echo "========================================================" if [ -z "$1" ]; then echo "HELP for $script" else echo "ERROR: $1" # show message fi echo echo "usage: $script [options] use-case-dir1 use-case-dir2..." echo echo "Options:" echo -e " --report=\tSet the output report file name" echo -e "\t\t\t(default='endurance-report')" echo -e " --start-at=\tStart parsing from Xth given measurement directory" echo -e "\t\t\t(> 0, default=0)" echo -e " --skip=\t\tSkip N / parse only every (N+1)th measurement" echo -e "\t\t\t(use to see resource usage changes more clearly)" echo -e "\t\t\t(> 0, default=0)" echo -e " --stop-at=\t\tStop at Nth measurement" echo -e "\t\t\t(by default all files are parsed)" echo -e " --stop-at-reboot\tStop parsing if device had rebooted next round" echo -e " --split-at-reboots\tSplit results to separate report on reboot" echo -e "\t\t\t(by default all measurements go to same report)" echo -e " --parse-smaps\t\tParse SMAPS details for all reports (slow)" echo -e "\t\t\t(by default only private data changes are shown)" echo echo "FYI: If you want more detailed SMAPS report from some specific round" echo "without using the slow '--parse-smaps' option for all rounds," echo "install 'sp-smaps-visualize' package and run this directly:" echo " gunzip /smaps.cap.gz" echo " sp_smaps_analyze /smaps.cap" echo "If the file is compressed with lzop, decompress with:" echo " lzop -d /smaps.cap.lzo" echo echo "NOTE: if you skip measurements and you have cleared syslog between" echo "them, the endurance report will miss all the syslogged errors from" echo "the skipped measurements!" echo echo "Examples:" echo " $script --report=report --start-at=3 --skip=3 \\" echo " --parse-smaps --split-at-reboots test-case/101 test-case/102..." echo echo " $script test-case/[0-9]*" echo exit 1 } if [ $# -lt 2 ]; then usage fi # measurement files sw_reboot_file=dsme/stats/sw_rst hw_reboot_file=dsme/stats/32wd_to smaps_file=smaps.cap csv_file=usage.csv # add here paths if tools are not in $PATH smapsanalyze=sp_smaps_analyze endurancereport=endurance_report.py # rest of the tools (SMAPS ones) are checked only if they are needed if [ -z $(which $endurancereport) ]; then path_error $endurancereport fi # count SW and HW resets from given dir and set (global shell) # "reboots" variable accordingly count_reboots() { if [ -f "$1/$hw_reboot_file" ]; then hw_reboots=$(cat "$1/$hw_reboot_file"|tr -d '\r') fi if [ -z "$hw_reboots" ]; then hw_reboots="0" fi if [ -f "$1/$sw_reboot_file" ]; then sw_reboots=$(cat "$1/$sw_reboot_file"|tr -d '\r') fi if [ -z "$sw_reboots" ]; then sw_reboots="0" fi reboots=$(($hw_reboots + $sw_reboots)) } # parses SMAPS data and producess the HTML reports from those # 'dirs' contains a list of directories to process parse_smaps() { if [ -z $use_smaps ]; then return fi echo "Processing SMAPS details..." for dir in $dirs; do echo "+ $dir" if [ -f "$dir/smaps.html" ]; then echo " (smaps.html report already exists, skipping conversion)" else echo " - creating the SMAPS HTML report..." if [ \! -f "$dir/$smaps_file" ]; then # assume it's compressed if [ -e "$dir/$smaps_file.gz" ]; then gunzip "$dir/$smaps_file.gz" elif [ -e "$dir/$smaps_file.lzo" ]; then lzop -d "$dir/$smaps_file.lzo" fi fi sp_smaps_analyze "$dir/$smaps_file" if [ $? -ne 0 ]; then echo "ERROR: converting 'smaps.cap' to HTML failed" exit 1 fi fi done } # parses the directories and creates endurance report # 'dirs' contains a list of directories to process create_report() { if [ $suffix ]; then saveto="$report-$suffix.html" else saveto="$report.html" fi echo "Creating the '$saveto' endurance report..." $endurancereport $dirs > "$saveto" if [ $? -ne 0 ]; then echo "ERROR: HTML report creation failed" exit 1 fi } # default/initial values report="endurance-report" # report prefix suffix="" start=0 skips=0 reboots=0 started="" stop_at=999 stop_at_reboot="" split_at_reboot="" use_smaps="" dirs="" idx=0 stop="" # parse arguments echo "Checking arguments..." for i in $*; do # option value is after first '=' character val=${i#*=} case "$i" in --report=*) if [ "${val%.htm*}" != "$val" ]; then # .html suffix is added separately $val=${val%.htm*} fi report="$val" ;; --start-at=*) if [ $val -lt 1 ]; then usage "$i value has to be > 0" fi start=$val ;; --skip=*) if [ $val -lt 1 ]; then usage "$i value has to be > 0" fi skips=$val ;; --stop-at=*) if [ $val -lt 1 ]; then usage "$i value has to be > 0" fi stop_at=$val ;; --stop-at-reboot) stop_at_reboot="yes" ;; --split-at-reboots) split_at_reboot="yes" suffix="1" ;; --parse-smaps) if [ -z $(which $smapsanalyze) ]; then path_error $smapsanalyze "sp-smaps-visualize" fi use_smaps="yes" ;; -*) # for any other options, show usage usage ;; *) # check measurement dirs dir="$i" echo "+ $dir" if [ \! -f "$dir/$csv_file" ]; then echo "ERROR: resource usage CSV file '$csv_file' missing" exit 1 fi if [ $use_smaps ] && [ \! -f "$dir/$smaps_file" ] && [ \! -f "$dir/$smaps_file.gz" ] && [ \! -f "$dir/$smaps_file.lzo" ]; then echo "ERROR: SMAPS data file '$smaps_file' missing" exit 1 fi if [ -z "$started" ]; then if [ $idx -lt $start ]; then echo " - skipped" idx=$(($idx+1)) else echo " - *start from here*" count_reboots "$dir" initial_reboots=$reboots echo " - $reboots reboots before this" started="yes" dirs="$dir" skip=0 fi else count_reboots "$dir" if [ $reboots -ne $initial_reboots ]; then echo "***REBOOT*** (bootreason = $(cat $dir/bootreason))" if [ $stop_at_reboot ]; then echo "-> stop here." stop="yes" break else if [ $split_at_reboot ]; then echo "---------- split ---------" parse_smaps create_report suffix=$(($suffix+1)) dirs="$dir" echo "+ $dir" fi initial_reboots=$reboots fi fi if [ $idx -ge $stop_at ]; then stop="yes" break fi if [ $skip -lt $skips ]; then echo " - skipped" skip=$(($skip+1)) else echo " - taken..." dirs="$dirs $dir" skip=0 fi idx=$(($idx+1)) fi ;; esac if [ $stop ]; then break fi done if [ "$dirs" ]; then # process remaining dirs parse_smaps create_report fi echo "DONE!"