* Copyright (c) 1980, 1992 The Regents of the University of California.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)swap.c 5.14 (Berkeley) %G%";
* swapinfo - based on a program of the same name by Kevin Lahey
extern char *devname
__P((int, int));
extern char *getbsize
__P((int *headerlenp
, long *blocksizep
));
void showspace
__P((char *header
, int hlen
, long blocksize
));
{ "_swapmap" }, /* list of free swap areas */
{ "_nswapmap" },/* size of the swap map */
{ "_swdevt" }, /* list of swap devices and sizes */
{ "_nswap" }, /* size of largest swap device */
{ "_nswdev" }, /* number of swap devices */
{ "_dmmax" }, /* maximum size of a swap block */
static int nswap
, nswdev
, dmmax
, nswapmap
;
static struct swdevt
*sw
;
static struct map
*swapmap
, *kswapmap
;
static struct mapent
*mp
;
static int nfree
, hlen
, blocksize
;
#define SVAR(var) __STRING(var) /* to force expansion */
KGET1(idx, &var, sizeof(var), SVAR(var))
#define KGET1(idx, p, s, msg) \
KGET2(syms[idx].n_value, p, s, msg)
#define KGET2(addr, p, s, msg) \
if (kvm_read(kd, addr, p, s) != s) { \
error("cannot read %s: %s", msg, kvm_geterr(kd)); \
return (subwin(stdscr
, LINES
-5-1, 0, 5, 0));
if (kvm_nlist(kd
, syms
)) {
strcpy(msgbuf
, "systat: swap: cannot find");
for (i
= 0; syms
[i
].n_name
!= NULL
; i
++) {
if (syms
[i
].n_value
== 0) {
strcat(msgbuf
, syms
[i
].n_name
);
KGET(VM_NSWAPMAP
, nswapmap
);
KGET(VM_SWAPMAP
, kswapmap
); /* kernel `swapmap' is a pointer */
if ((sw
= malloc(nswdev
* sizeof(*sw
))) == NULL
||
(perdev
= malloc(nswdev
* sizeof(*perdev
))) == NULL
||
(mp
= malloc(nswapmap
* sizeof(*mp
))) == NULL
) {
KGET1(VM_SWDEVT
, sw
, nswdev
* sizeof(*sw
), "swdevt");
s
= nswapmap
* sizeof(*mp
);
if (kvm_read(kd
, (long)kswapmap
, mp
, s
) != s
)
error("cannot read swapmap: %s", kvm_geterr(kd
));
/* first entry in map is `struct map'; rest are mapent's */
swapmap
= (struct map
*)mp
;
if (nswapmap
!= swapmap
->m_limit
- (struct mapent
*)kswapmap
)
error("panic: swap: nswapmap goof");
bzero(perdev
, nswdev
* sizeof(*perdev
));
for (mp
++; mp
->m_addr
!= 0; mp
++) {
s
= mp
->m_addr
; /* start of swap region */
e
= mp
->m_addr
+ mp
->m_size
; /* end of region */
* Swap space is split up among the configured disks.
* The first dmmax blocks of swap space some from the
* first disk, the next dmmax blocks from the next,
* and so on. The list of free space joins adjacent
* free blocks, ignoring device boundries. If we want
* to keep track of this information per device, we'll
* just have to extract it ourselves.
/* calculate first device on which this falls */
i
= (s
/ dmmax
) % nswdev
;
while (s
< e
) { /* XXX this is inefficient */
int bound
= roundup(s
+ 1, dmmax
);
wmove(wnd
, row
, 0); wclrtobot(wnd
);
header
= getbsize(&hlen
, &blocksize
);
mvwprintw(wnd
, row
++, 0, "%-5s%*s%9s %55s",
"Disk", hlen
, header
, "Used",
"/0% /10% /20% /30% /40% /50% /60% /70% /80% /90% /100%");
for (i
= 0; i
< nswdev
; i
++) {
mvwprintw(wnd
, i
+ 1, 0, "%-5s",
devname(sw
[i
].sw_dev
, S_IFBLK
));
int col
, row
, div
, i
, j
, avail
, npfree
, used
, xsize
, xfree
;
for (i
= 0; i
< nswdev
; i
++) {
mvwprintw(wnd
, i
+ 1, col
, "%*d", hlen
, sw
[i
].sw_nblks
/ div
);
* Don't report statistics for partitions which have not
* yet been activated via swapon(8).
mvwprintw(wnd
, i
+ 1, col
+ 8,
"0 *** not available for swapping ***");
mvwprintw(wnd
, i
+ 1, col
, "%9d ", used
/ div
);
for (j
= (100 * used
/ xsize
+ 1) / 2; j
> 0; j
--)
* If only one partition has been set up via swapon(8), we don't
* need to bother with totals.
mvwprintw(wnd
, i
+ 1, 0, "%-5s%*d%9d ",
"Total", hlen
, avail
/ div
, used
/ div
);
for (j
= (100 * used
/ avail
+ 1) / 2; j
> 0; j
--)