swap.c revision 359754
1/*-
2 * Copyright (c) 1980, 1992, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31
32__FBSDID("$FreeBSD: stable/11/usr.bin/systat/swap.c 359754 2020-04-09 20:38:36Z kevans $");
33
34#ifdef lint
35static const char sccsid[] = "@(#)swap.c	8.3 (Berkeley) 4/29/95";
36#endif
37
38/*
39 * swapinfo - based on a program of the same name by Kevin Lahey
40 */
41
42#include <sys/param.h>
43#include <sys/ioctl.h>
44#include <sys/stat.h>
45
46#include <kvm.h>
47#include <nlist.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <unistd.h>
51#include <string.h>
52#include <err.h>
53
54#include "systat.h"
55#include "extern.h"
56
57static char *header;
58static long blocksize;
59static int dlen, odlen;
60static int hlen;
61static int ulen, oulen;
62static int pagesize;
63
64WINDOW *
65openswap(void)
66{
67	return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
68}
69
70void
71closeswap(WINDOW *w)
72{
73	if (w == NULL)
74		return;
75	wclear(w);
76	wrefresh(w);
77	delwin(w);
78}
79
80/*
81 * The meat of all the swap stuff is stolen from pstat(8)'s
82 * swapmode(), which is based on a program called swapinfo written by
83 * Kevin Lahey <kml@rokkaku.atl.ga.us>.
84 */
85
86#define NSWAP	16
87
88static struct kvm_swap kvmsw[NSWAP];
89static int kvnsw, okvnsw;
90
91static void calclens(void);
92
93#define CONVERT(v)	((int)((int64_t)(v) * pagesize / blocksize))
94
95static void
96calclens(void)
97{
98	int i, n;
99	int len;
100
101	dlen = sizeof("Disk");
102	for (i = 0; i < kvnsw; ++i) {
103		len = strlen(kvmsw[i].ksw_devname);
104		if (dlen < len)
105			dlen = len;
106	}
107
108	ulen = sizeof("Used");
109	for (n = CONVERT(kvmsw[kvnsw].ksw_used), len = 2; n /= 10; ++len);
110	if (ulen < len)
111		ulen = len;
112}
113
114int
115initswap(void)
116{
117	static int once = 0;
118
119	if (once)
120		return (1);
121
122	header = getbsize(&hlen, &blocksize);
123	pagesize = getpagesize();
124
125	if ((kvnsw = kvm_getswapinfo(kd, kvmsw, NSWAP, 0)) < 0) {
126		error("systat: kvm_getswapinfo failed");
127		return (0);
128	}
129	okvnsw = kvnsw;
130
131	calclens();
132	odlen = dlen;
133	oulen = ulen;
134
135	once = 1;
136	return (1);
137}
138
139void
140fetchswap(void)
141{
142
143	okvnsw = kvnsw;
144	if ((kvnsw = kvm_getswapinfo(kd, kvmsw, NSWAP, 0)) < 0) {
145		error("systat: kvm_getswapinfo failed");
146		return;
147	}
148
149	odlen = dlen;
150	oulen = ulen;
151	calclens();
152}
153
154void
155labelswap(void)
156{
157	const char *name;
158	int i;
159
160	fetchswap();
161
162	werase(wnd);
163
164	mvwprintw(wnd, 0, 0, "%*s%*s%*s %s",
165	    -dlen, "Disk", hlen, header, ulen, "Used",
166	    "/0%  /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
167
168	for (i = 0; i <= kvnsw; ++i) {
169		if (i == kvnsw) {
170			if (kvnsw == 1)
171				break;
172			name = "Total";
173		} else
174			name = kvmsw[i].ksw_devname;
175		mvwprintw(wnd, i + 1, 0, "%*s", -dlen, name);
176	}
177}
178
179void
180showswap(void)
181{
182	int count;
183	int i;
184
185	if (kvnsw != okvnsw || dlen != odlen || ulen != oulen)
186		labelswap();
187
188	for (i = 0; i <= kvnsw; ++i) {
189		if (i == kvnsw) {
190			if (kvnsw == 1)
191				break;
192		}
193
194		if (kvmsw[i].ksw_total == 0) {
195			mvwprintw(
196			    wnd,
197			    i + 1,
198			    dlen + hlen + ulen + 1,
199			    "(swap not configured)"
200			);
201			continue;
202		}
203
204		wmove(wnd, i + 1, dlen);
205
206		wprintw(wnd, "%*d", hlen, CONVERT(kvmsw[i].ksw_total));
207		wprintw(wnd, "%*d", ulen, CONVERT(kvmsw[i].ksw_used));
208
209		count = 50.0 * kvmsw[i].ksw_used / kvmsw[i].ksw_total + 1;
210
211		waddch(wnd, ' ');
212		while (count--)
213			waddch(wnd, 'X');
214		wclrtoeol(wnd);
215	}
216}
217