xref: /freebsd/tools/test/stress2/tools/vmstat.sh (revision 1edb7116)
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	    while read l; do
49		name=`echo $l | sed -E 's/ [0-9]+ .*//; s/^ *//'`
50		memuse=`echo $l | sed -E "s#$name##" | \
51		    awk '{print int(($2 + 1023) / 1024)}'`
52		[ "$memuse" -ne 0 ] && echo "vmstat -m $name,$memuse"
53	    done
54
55	# ITEM                   SIZE  LIMIT     USED
56	[ -z "$optz" ] && vmstat -z | sed 1d |
57	    while read l; do
58		name=`echo $l | sed 's/:.*//'`
59		l=`echo $l | sed 's/.*://'`
60		size=`echo $l | awk -F ',' '{print $1}'`
61		used=`echo $l | awk -F ',' '{print $3}'`
62		[ -z "$used" -o -z "$size" ] &&
63		    { echo "used/size not set $l" 1>&2; continue; }
64		echo $used | egrep -q '^ *[0-9]{1,10}$' ||
65		    { echo "Bad used: $used. l=$l" 1>&2; continue; }
66		tot=$((((size * used) + 1023) / 1024))
67		[ $tot -ne 0 ] &&
68		   echo "vmstat -z $name,$tot"
69	    done
70
71	r=`sysctl -n vm.stats.vm.v_wire_count`
72	[ -n "$r" ] &&
73	echo "vm.stats.vm.v_wire_count, \
74	    $((r * 4))"
75	r=`sysctl -n vm.stats.vm.v_free_count`
76	[ -n "$r" ] &&
77	echo "pages in use, \
78	    $(((pages - r) * 4))"
79	r=`sysctl -n vm.kmem_map_size`
80	[ -n "$r" ] &&
81	echo "kmem_map_size, $r"
82	sleep 10
83done | awk $debug -F, '
84{
85# Pairs of "name, value" are passed to this awk script.
86	name=$1;
87	size=$2;
88	if (size > s[name]) {
89		if (++n[name] > 60) {
90			cmd="date '+%T'";
91			cmd | getline t;
92			close(cmd);
93			printf "%s \"%s\" %'\''dK\r\n", t,
94			    name, size;
95			fflush
96			n[name] = 0;
97		}
98		s[name] = size;
99		if (debug == 1 && n[name] > 1)
100			printf "%s, size %d, count %d\r\n",
101			    name, s[name], n[name] > "/dev/stderr"
102	} else if (size < s[name] && n[name] > 0)
103		n[name]--
104}' | while read l; do
105	d=$(((`date '+%s'` - start) / 86400))
106	echo "$d $l"
107done
108# Note: the %'d is used to trigger a thousands-separator character.
109