Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:13.1:Update
s390-tools
s390-tools-sles11sp3-dasd-enhanced-statistics.p...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File s390-tools-sles11sp3-dasd-enhanced-statistics.patch of Package s390-tools
Subject: [PATCH] [FEAT 82722] dasdstat: Add new zconf tool dasdstat From: Stefan Weinhuber <wein@de.ibm.com> Summary: dasdstat: Add new zconf tool dasdstat Description: The dasdstat command provides easy access to the debugfs based statistics of the DASD device driver. Problem-ID: 82722 --- README | 1 zconf/Makefile | 4 zconf/dasdstat | 464 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ zconf/dasdstat.8 | 97 +++++++++++ 4 files changed, 564 insertions(+), 2 deletions(-) --- a/README +++ b/README @@ -115,6 +115,7 @@ s390-tools (1.15.0) blacklist. - lsmem: Display the online status of the available memory. - chmem: Set hotplug memory online or offline. + - dasdstat: Configure and format the debugfs based DASD statistics data. * dumpconf: Allows to configure the dump device used for system dump in case a kernel --- /dev/null +++ b/zconf/dasdstat @@ -0,0 +1,464 @@ +#!/bin/bash +# +# Copyright IBM Corp. 2011 +# +# dasdstat +# Reads dasd statistics data from debugfs and prints it as formatted table +# +# Author(s): Stefan Weinhuber <wein@de.ibm.com> +# + +function print_usage() { + cat <<-EOD +Usage: $CMD <options> [<statistic>] + +<options> ::= + -e|--enable + Enable the statistics. + -d|--disable + Disable the statistics. + -r|--reset + Reset the statistics. + -i|--directory <directory> + Specify the directory in which the statistics can be found. + -h|--help + Print this text and exit. + -l|--long + Print more detailed information, e.g differentiate between + read and write requests. + -c|--columns <number> + Format the output in a table with the given number of columns. + -w|--column-width <width> + Set the minimum width of the columns in the output table. + -V|--verbose + Print more verbose information. + -v|--version + Show tools and command version. + +<statistic> + Limit operation to one or more statistic. + EOD +} + +function print_version() +{ + echo "$CMD: version %S390_TOOLS_VERSION%" + echo "Copyright IBM Corp. 2011" +} + +function unset_known_variables() { + unset start_time + unset total_requests + unset total_sectors + unset total_pav + unset total_hpf + unset histogram_sectors + unset histogram_io_times + unset histogram_io_times_weighted + unset histogram_time_build_to_ssch + unset histogram_time_ssch_to_irq + unset histogram_time_ssch_to_irq_weighted + unset histogram_time_irq_to_end + unset histogram_ccw_queue_length + unset total_read_requests + unset total_read_sectors + unset total_read_pav + unset total_read_hpf + unset histogram_read_sectors + unset histogram_read_times + unset histogram_read_time_build_to_ssch + unset histogram_read_time_ssch_to_irq + unset histogram_read_time_irq_to_end + unset histogram_read_ccw_queue_length +} + +function print_array() +{ + local width=$1 + shift + local linebreak=$1 + shift + local i=1 + for element in $* + do + printf "%${width}s" $element + (( 0 == i++ % linebreak )) && printf "\n" + done + # add an extra line break if we do not already have one + (( 0 != (i - 1) % linebreak )) && printf "\n" +} + +function subtract_array() +{ + local -a a=( $1 ) + local -a b=( $2 ) + local -a c + local i + local cnt=${#a[@]} + for (( i = 0 ; i < cnt ; i++ )) + do + (( c[i] = a[i] - b[i] )) + done + echo -n ${c[*]} +} + +function print_line() +{ + local i + for (( i = 0 ; i < $1 ; i++ )) + do + echo -n '-' + done + echo +} + +HEADERSEXP=" __<4 ___8 __16 __32 __64 _128 _256 _512 \ + __1k __2k __4k __8k _16k _32k _64k 128k \ + _256 _512 __1M __2M __4M __8M _16M _32M \ + _64M 128M 256M 512M __1G __2G __4G _>4G" + +HEADERSLIN=" ___0 ___1 ___2 ___3 ___4 ___5 ___6 ___7 \ + ___8 ___9 __10 __11 __12 __13 __14 __15 \ + __16 __17 __18 __19 __20 __21 __22 __23 \ + __24 __25 __26 __27 __28 __29 __30 __31" + + +function print_format_standard() +{ + local converted_time=$(date -d @$start_time) + # all numbers in the histograms below are smaller or equal to the + # total_requests. So we use that number to determine the column width. + local width=${#total_requests} + (( width++ )) + (( width < 5 )) && width=5 + + if [[ -n $COLUMN_WIDTH ]] && [[ $width -lt $COLUMN_WIDTH ]] + then + width=$COLUMN_WIDTH + fi + + local linebreak=$NUMBER_COLUMNS + local statname="$1" + local tablewidth + (( tablewidth = width * linebreak )) + + # Note: This function does not print the histogram_io_times_weighted + # and histogram_time_ssch_to_irq_weighted because the interpretation + # of these histograms is not intuitive and may lead to confusion. + print_line $tablewidth + printf "statistics data for statistic: %s\n" "$statname" + printf "start time of data collection: %s\n\n" "$converted_time" + + printf "%d dasd I/O requests\n" ${total_requests[*]} + printf "with %u sectors(512B each)\n" ${total_sectors[*]} + printf "%d requests used a PAV alias device\n" ${total_pav[*]} + printf "%d requests used HPF\n" ${total_hpf[*]} + print_array $width $linebreak $HEADERSEXP + printf "Histogram of sizes (512B secs)\n" + print_array $width $linebreak ${histogram_sectors[*]} + printf "Histogram of I/O times (microseconds)\n" + print_array $width $linebreak ${histogram_io_times[*]} + printf "Histogram of I/O time till ssch\n" + print_array $width $linebreak ${histogram_time_build_to_ssch[*]} + printf "Histogram of I/O time between ssch and irq\n" + print_array $width $linebreak ${histogram_time_ssch_to_irq[*]} + printf "Histogram of I/O time between irq and end\n" + print_array $width $linebreak ${histogram_time_irq_to_end[*]} + printf "# of req in chanq at enqueuing (0..31) \n" + print_array $width $linebreak $HEADERSLIN + print_array $width $linebreak ${histogram_ccw_queue_length[*]} + + if [[ $OUTPUT == "short" ]] + then + print_line $tablewidth + return + fi + + printf "\n%d dasd I/O read requests\n" ${total_read_requests[*]} + printf "with %u sectors(512B each)\n" ${total_read_sectors[*]} + printf "%d requests used a PAV alias device\n" ${total_read_pav[*]} + printf "%d requests used HPF\n" ${total_read_hpf[*]} + print_array $width $linebreak $HEADERSEXP + printf "Histogram of sizes (512B secs)\n" + print_array $width $linebreak ${histogram_read_sectors[*]} + printf "Histogram of I/O times (microseconds)\n" + print_array $width $linebreak ${histogram_read_times[*]} + printf "Histogram of I/O time till ssch\n" + print_array $width $linebreak ${histogram_read_time_build_to_ssch[*]} + printf "Histogram of I/O time between ssch and irq\n" + print_array $width $linebreak ${histogram_read_time_ssch_to_irq[*]} + printf "Histogram of I/O time between irq and end\n" + print_array $width $linebreak ${histogram_read_time_irq_to_end[*]} + printf "# of req in chanq at enqueuing (0..31) \n" + print_array $width $linebreak $HEADERSLIN + print_array $width $linebreak ${histogram_read_ccw_queue_length[*]} + + printf "\n%d dasd I/O write requests\n" $(( total_requests[0] - total_read_requests[0] )) + printf "with %u sectors(512B each)\n" $(( total_sectors[0] - total_read_sectors[0] )) + printf "%d requests used a PAV alias device\n" $(( total_pav[0] - total_read_pav[0] )) + printf "%d requests used HPF\n" $(( total_hpf[0] - total_read_hpf[0] )) + print_array $width $linebreak $HEADERSEXP + printf "Histogram of sizes (512B secs)\n" + print_array $width $linebreak $(subtract_array "${histogram_sectors[*]}" "${histogram_read_sectors[*]}") + printf "Histogram of I/O times (microseconds)\n" + print_array $width $linebreak $(subtract_array "${histogram_io_times[*]}" "${histogram_read_times[*]}") + printf "Histogram of I/O time till ssch\n" + print_array $width $linebreak $(subtract_array "${histogram_time_build_to_ssch[*]}" "${histogram_read_time_build_to_ssch[*]}") + printf "Histogram of I/O time between ssch and irq\n" + print_array $width $linebreak $(subtract_array "${histogram_time_ssch_to_irq[*]}" "${histogram_read_time_ssch_to_irq[*]}") + printf "Histogram of I/O time between irq and end\n" + print_array $width $linebreak $(subtract_array "${histogram_time_irq_to_end[*]}" "${histogram_read_time_irq_to_end[*]}") + printf "# of req in chanq at enqueuing (0..31) \n" + print_array $width $linebreak $HEADERSLIN + print_array $width $linebreak $(subtract_array "${histogram_ccw_queue_length[*]}" "${histogram_read_ccw_queue_length[*]}") + + print_line $tablewidth +} + +function read_stat_data() { + myfile="$1" + while read -d ' ' token + do + read -a $token + done < $myfile + # differentiate I/O error from disabled statistic + if [[ -n $total_requests ]] || [[ "$token" == "disabled" ]] + then + return 0 + else + return 1 + fi +} + +function print_stat() { + myfile="$1" + if [[ ! -f "$myfile" ]] + then + print_line 80 + echo "$CMD: Statistic \"$myfile\" does not exist" >&2 + print_line 80 + echo + return + fi + unset_known_variables + if read_stat_data "$myfile" + then + if [[ -z "$total_requests" ]] + then + if [[ "$VERBOSE" == "true" ]] + then + print_line 80 + echo "statistics \"$f\" are disabled" + print_line 80 + echo + fi + else + print_format_standard $f + echo + fi + else + print_line 80 + echo "$CMD: Could not read statistic \"$myfile\" " >&2 + print_line 80 + echo + fi +} + +function enable_stat() { + myfile="$1" + if [[ ! -f "$myfile" ]] + then + echo "$CMD: Statistic \"$myfile\" does not exist" >&2 + return + fi + if echo on > "$myfile" + then + echo "enable statistic \"$myfile\"" + else + echo "$CMD: Failed to enable statistic \"$myfile\"" >&2 + fi +} + +function disable_stat() { + myfile="$1" + if [[ ! -f "$myfile" ]] + then + echo "$CMD: Statistic \"$myfile\" does not exist" >&2 + return + fi + if echo off > "$myfile" + then + echo "disable statistic \"$myfile\"" + else + echo "$CMD: Failed to disable statistic \"$myfile\"" + fi +} + +function reset_stat() { + myfile="$1" + if [[ ! -f "$myfile" ]] + then + echo "$CMD: Statistic \"$myfile\" does not exist" >&2 + return + fi + if echo reset > "$myfile" + then + echo "reset statistic \"$myfile\"" + else + echo "$CMD: Failed to reset statistic \"$myfile\"" >&2 + fi +} + +function verbose_msg() { + if [[ "$VERBOSE" == "true" ]] + then + echo "$*" + fi +} + + +# Evaluating command line options +CMD=$(basename $0) +DASD_STATISTICS_DIR="" +ALLFILES="" +VERBOSE=false +OUTPUT="short" +NUMBER_COLUMNS=16 +COLUMN_WIDTH= +ACTION="print" +while [ $# -gt 0 ]; do + case $1 in + --help|-h) + print_usage + exit 0 + ;; + --enable|-e) + ACTION="enable" + ;; + --disable|-d) + ACTION="disable" + ;; + --reset|-r) + ACTION="reset" + ;; + --directory|-i) + DASD_STATISTICS_DIR="$2" + shift + if [[ ! -d $DASD_STATISTICS_DIR ]] + then + echo "$CMD: $DASD_STATISTICS_DIR is not a directory" >&2 + exit 1 + fi + ;; + --long|-l) + OUTPUT="extended" + ;; + --columns|-c) + NUMBER_COLUMNS="$2" + if [[ ! "$NUMBER_COLUMNS" -gt 0 ]] + then + echo "$CMD: $NUMBER_COLUMNS is not a positive integer number" >&2 + exit 1 + fi + shift + ;; + --column-width|-w) + COLUMN_WIDTH="$2" + if [[ ! "$COLUMN_WIDTH" -gt 0 ]] + then + echo "$CMD: $COLUMN_WIDTH is not a positive integer number" >&2 + exit 1 + fi + shift + ;; + --verbose|-V) + VERBOSE=true + ;; + --version|-v) + print_version + exit 0 + ;; + -*) + echo "$CMD: Invalid option $1" >&2 + echo "Try '$CMD --help' for more information." >&2 + exit 1 + ;; + *) + ALLFILES="$ALLFILES $1" + ;; + esac + shift +done + +# if no directory is given on command line, find dasd directory in debugfs +if [[ "$DASD_STATISTICS_DIR" == "" ]] +then + while read -a mntentries + do + if [[ "${mntentries[2]}" == "debugfs" ]] + then + DASD_STATISTICS_DIR="${mntentries[1]}" + verbose_msg "found debugfs mount point $DASD_STATISTICS_DIR" + break; + fi + done < /etc/mtab + if [[ "$DASD_STATISTICS_DIR" == "" ]] + then + echo "$CMD: No debugfs mount point found" >&2 + exit 1 + fi + DASD_STATISTICS_DIR="$DASD_STATISTICS_DIR/dasd" + if [[ ! -d "$DASD_STATISTICS_DIR" ]] + then + echo "$CMD: Default DASD debugfs directory $DASD_STATISTICS_DIR does not exist" >&2 + exit 1 + fi +fi + +# look for directories that contain statistics +if [[ "$ALLFILES" == "" ]] +then + ALLFILES=$(ls -x $DASD_STATISTICS_DIR) + explicitstats="false" +else + explicitstats="true" +fi +ALLSTATS="" +for f in $ALLFILES +do + if [[ -f "$DASD_STATISTICS_DIR/$f/statistics" ]] + then + ALLSTATS="$ALLSTATS $f" + elif [[ $explicitstats == "true" ]] + then + echo "$CMD: No statistics found for $f" >&2 + fi +done + +verbose_msg "found the following statistics in directory $DASD_STATISTICS_DIR:" +verbose_msg "$ALLSTATS" + +# execute the required operation +for f in $ALLSTATS +do + case $ACTION in + "enable") + enable_stat "$DASD_STATISTICS_DIR/$f/statistics" + ;; + "disable") + disable_stat "$DASD_STATISTICS_DIR/$f/statistics" + ;; + "reset") + reset_stat "$DASD_STATISTICS_DIR/$f/statistics" + ;; + "print") + print_stat "$DASD_STATISTICS_DIR/$f/statistics" + ;; + *) + echo "error" + exit 1 + ;; + esac +done + + --- /dev/null +++ b/zconf/dasdstat.8 @@ -0,0 +1,97 @@ +.TH LSDASD 8 "Feb 2011" "s390-tools" + +.SH NAME +dasdstat \- read or modify the statistics of the DASD device driver. + +.SH SYNOPSIS +.TP 8 +.B dasdstat +.RB [ -h ] +.TP 8 +.B dasdstat +.RB [ -e ] +.RB [ -d ] +.RB [ -r ] +.RB [ -i ] +.RB [ -l ] +.RB [ -c ] +.RB [ -w ] +.RB [ -V ] +.RB [ -v ] +.RI [ <statistic> " [" <statistic> "] ...]]" + +.SH DESCRIPTION +The dasdstat command provides easy access to the debugfs based +statistics of the DASD device driver. + +The DASD statistics feature allows to gather statistical data for the +I/O requests processed by the DASD device driver. This data can be +collected for individual DASD CCW devices (including PAV base and +alias devices), DASD block devices, or globally for all requests +handled by the DASD device driver. + +When no other options are specified, then the default operation is to +print the statistics data in a formatted table. When no specific list +of statistics is given, then the operation will be performed on all +available statistics. + +.SH OPTIONS +.TP 8 +.BR -h | --help +Print help text. +.TP +.BR -e | --enable +Enable the statistics. +.TP +.BR -d | --disable +Disable the statistics. +.TP +.BR -r | --reset +Reset the statistics. +.TP +.BR -i | --directory +Specify the directory in which the statistics can be found. +.TP +.BR -l | --long +Print more detailed information, e.g differentiate between read and +write requests. +.TP +.BR -c | --columns " \fI<number>\fR" +Format the output in a table with the given number of columns. +.TP +.BR -w | --column-width " \fI<width>\fR" +Set the minimum width of the columns in the output table. +.TP +.BR -V | --verbose +Print more verbose information. +.TP +.BR -v | --version +Print the version of the s390-tools package and the command. +.TP +\fB<statistic>\fR = +Name of a statistic that the command should work on. + +.SH EXAMPLES +\fBdasdstat\fR +.RS +Print a statistics table for each enabled statistic. +.RE + +\fBdasdstat -e\fR +.RS +Enable all DASD statistics. +.RE + +\fBdasdstat -l dasda 0.0.1800 0.0.18fe 0.0.18ff\fR +.RS +Print a detailed statistics table for DASD block device dasda and CCW +devices 0.0.1800, 0.0.18fe and 0.0.18ff. A typical scenario for this +example would be that dasda is the block device that belongs to +PAV base device 0.0.1800, and CCW devices 0.0.18fe and 0.0.18ff are the +associated alias devices. +.RE + +.SH AUTHOR +.nf +This man-page was written by Stefan Weinhuber <wein@de.ibm.com>. +.fi --- a/zconf/Makefile +++ b/zconf/Makefile @@ -4,11 +4,11 @@ include ../common.mak SCRIPTS = lsdasd lstape lscss chccwdev lsqeth lszfcp lschp chchp lszcrypt \ - chzcrypt cio_ignore znetconf + chzcrypt cio_ignore znetconf dasdstat USRSBIN_SCRIPTS = lsmem chmem lsluns MANPAGES= lsdasd.8 lstape.8 lscss.8 chccwdev.8 lsqeth.8 lszfcp.8 lschp.8 \ chchp.8 lszcrypt.8 chzcrypt.8 lsluns.8 cio_ignore.8 znetconf.8 \ - chmem.8 lsmem.8 + chmem.8 lsmem.8 dasdstat.8 all:
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor