xref: /freebsd/tools/test/stress2/tools/vmstat.sh (revision 9768746b)
1#!/bin/sh
2
3#
4# Copyright (c) 2015 EMC Corp.
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28
29# Memory leak detector: run vmstat -m & -z in a loop.
30
31export LANG=en_US.ISO8859-1
32while getopts dmz flag; do
33        case "$flag" in
34        d) debug="-v debug=1" ;;
35        m) optz=n ;;
36        z) optm=n ;;
37        *) echo "Usage $0 [-d] [-m] [-z]"
38           return 1 ;;
39        esac
40done
41
42pages=`sysctl -n vm.stats.vm.v_page_count`
43start=`date '+%s'`
44OIFS=$IFS
45while true; do
46	#          Type InUse MemUse
47	[ -z "$optm" ] && vmstat -m | sed 1d |
48	    sed 's/\(.* \)\([0-9][0-9]*\)  *\(.*\)K .*/\1:\2:\3/' |
49	    while IFS=: read -r p1 p2 p3; do
50		name=`echo $p1 | sed 's/^ *//;s/ *$//'`
51		memuse=$p3
52		[ "$memuse" -ne 0 ] && echo "vmstat -m $name,$memuse"
53	done
54
55	# ITEM                   SIZE  LIMIT     USED
56	[ -z "$optz" ] && vmstat -z |
57	    grep -vE '(rl_entry):' |
58	    sed "1,2d;/^$/d;s/: /, /" |
59	    sed -E 's/[^[:print:]\r\t]/ /g' |
60	    while read l; do
61		IFS=','
62		set $l
63		[ $# -lt 8 ] &&
64		    { echo "# args must be >= 8, but is $# in $l" 1>&2;
65		        continue; }
66		size=$2
67		used=$4
68		[ -z "$used" -o -z "$size" ] &&
69		    { echo "used/size not set $l" 1>&2; continue; }
70		echo $used | egrep -q '^ *[0-9]{1,10}$' ||
71		    { echo "Bad used: $used. l=$l" 1>&2; continue; }
72		tot=$((((size * used) + 1023) / 1024))
73		[ $tot -ne 0 ] &&
74		   echo "vmstat -z $1,$tot"
75	done
76
77	r=`sysctl -n vm.stats.vm.v_wire_count`
78	[ -n "$r" ] &&
79	echo "vm.stats.vm.v_wire_count, \
80	    $((r * 4))"
81	r=`sysctl -n vm.stats.vm.v_free_count`
82	[ -n "$r" ] &&
83	echo "pages in use, \
84	    $(((pages - r) * 4))"
85	r=`sysctl -n vm.kmem_map_size`
86	[ -n "$r" ] &&
87	echo "kmem_map_size, $r"
88	sleep 10
89done | awk $debug -F, '
90{
91# Pairs of "name, value" are passed to this awk script.
92	name=$1;
93	size=$2;
94	if (size > s[name]) {
95		if (++n[name] > 60) {
96			cmd="date '+%T'";
97			cmd | getline t;
98			close(cmd);
99			printf "%s \"%s\" %'\''dK\r\n", t,
100			    name, size;
101			n[name] = 0;
102		}
103		s[name] = size;
104		if (debug == 1 && n[name] > 1)
105			printf "%s, size %d, count %d\r\n",
106			    name, s[name], n[name] > "/dev/stderr"
107	} else if (size < s[name] && n[name] > 0)
108		n[name]--
109}' | while read l; do
110	d=$(((`date '+%s'` - start) / 86400))
111	echo "$d $l"
112done
113# Note: the %'d is used to trigger a thousands-separator character.
114