diff options
| author | Rod Smith <rod.smith@canonical.com> | 2016-09-01 11:38:52 -0400 |
|---|---|---|
| committer | Rod Smith <rod.smith@canonical.com> | 2016-09-01 11:38:52 -0400 |
| commit | ababaa506249728f3b0c5ad62da6eb3b2c3c4652 (patch) | |
| tree | 39d141d827c6cc4797ad328facba96da0d34356c /bin | |
| parent | da93f8eba3b84a5d91857ad8ee60cfdd85e2673b (diff) | |
Added test for CPU load imposed by disk input operations.
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/disk_cpu_load | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/bin/disk_cpu_load b/bin/disk_cpu_load new file mode 100755 index 00000000..5e0d0eb8 --- /dev/null +++ b/bin/disk_cpu_load @@ -0,0 +1,138 @@ +#!/bin/bash + +# Script to test CPU load imposed by a simple disk read operation +# +# Copyright (c) 2016 Canonical Ltd. +# +# Authors +# Rod Smith <rod.smith@canonical.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3, +# 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, see <http://www.gnu.org/licenses/>. +# +# The purpose of this script is to run disk stress tests using the +# stress-ng program. +# +# Usage: +# disk_cpu_load [ --max-load <load> ] [ --xfer <mebibytes> ] +# [ <device-filename> ] +# +# Parameters: +# --max-load <load> -- The maximum acceptable CPU load, as a percentage. +# Defaults to 30. +# --xfer <mebibytes> -- The amount of data to read from the disk, in +# mebibytes. Defaults to 4096 (4 GiB). +# <device-filename> -- This is the WHOLE-DISK device filename (with or +# without "/dev/"), e.g. "sda" or "/dev/sda". The +# script finds a filesystem on that device, mounts +# it if necessary, and runs the tests on that mounted +# filesystem. Defaults to /dev/sda. + + +set -e + + +get_params() { + disk_device="/dev/sda" + short_device="sda" + max_load=30 + xfer=4096 + while [ $# -gt 0 ] ; do + case $1 in + --max-load) max_load="$2" + shift + ;; + --xfer) xfer="$2" + shift + ;; + *) disk_device="/dev/$1" + disk_device=`echo $disk_device | sed "s/\/dev\/\/dev/\/dev/g"` + short_device=$(echo $disk_device | sed "s/\/dev//g") + if [ ! -b $disk_device ] ; then + echo "Unknown block device \"$disk_device\"" + echo "Usage: $0 [ --max-load <load> ] [ --xfer <mebibytes> ]" + echo " [ device-file ]" + exit 1 + fi + ;; + esac + shift + done +} # get_params() + + +# Find the sum of all values in an array +# Input: +# $1 - The array whose values are to be summed +# Output: +# $total - The sum of the values +sum_array() { + local array=("${@}") + total=0 + for i in ${array[@]}; do + let total+=$i + done +} # sum_array() + + +# Compute's CPU load between two points in time. +# Input: +# $1 - CPU statistics from /proc/stat from START point, in a string of numbers +# $2 - CPU statistics from /proc/stat from END point, in a string of numbers +# These values can be obtained via $(grep "cpu " /proc/stat | tr -s " " | cut -d " " -f 2-) +# Ouput: +# $cpu_load - CPU load over the two measurements, as a percentage (0-100) +compute_cpu_load() { + local start_use + local end_use + IFS=' ' read -r -a start_use <<< $1 + IFS=' ' read -r -a end_use <<< $2 + local diff_idle + let diff_idle=${end_use[3]}-${start_use[3]} + + sum_array "${start_use[@]}" + local start_total=$total + sum_array "${end_use[@]}" + local end_total=$total + + local diff_total + local diff_used + let diff_total=${end_total}-${start_total} + let diff_used=$diff_total-$diff_idle + + if [ "$diff_total" != "0" ] ; then + let cpu_load=($diff_used*100)/$diff_total + else + cpu_load=0 + fi +} # compute_cpu_load() + + +# +# Main program body.... +# + +get_params "$@" +retval=0 +echo "Testing CPU load when reading $xfer MiB from $disk_device" +echo "Maximum acceptable CPU load is $max_load" +blockdev --flushbufs $disk_device +start_load="$(grep "cpu " /proc/stat | tr -s " " | cut -d " " -f 2-)" +dd if="$disk_device" of=/dev/null bs=1048576 count="$xfer" &> /dev/null +end_load="$(grep "cpu " /proc/stat | tr -s " " | cut -d " " -f 2-)" +compute_cpu_load "$start_load" "$end_load" +echo "Detected disk read CPU load is $cpu_load" +if [ "$cpu_load" -gt "$max_load" ] ; then + retval=1 + echo "*** DISK CPU LOAD TEST HAS FAILED! ***" +fi +exit $retval |
