This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.sbin / swapinfo / swapinfo.c
CommitLineData
4d554349
NW
1/*
2 * swapinfo
3 *
4 * Swapinfo will provide some information about the state of the swap
5 * space for the system. It'll determine the number of swap areas,
6 * their original size, and their utilization.
7 *
8 * Kevin Lahey, February 16, 1993
9 */
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <sys/types.h>
14#include <sys/ioctl.h>
15#include <sys/termios.h>
16#include <sys/stat.h>
17#include <sys/tty.h>
18#include <sys/uio.h>
19#include <sys/buf.h>
20#include <sys/conf.h>
ab9b992f 21#include <sys/rlist.h>
4d554349
NW
22#include <nlist.h>
23
ab9b992f 24struct rlist *swapmap;
4d554349
NW
25
26static struct nlist nl[] = {{"_swapmap"}, /* list of free swap areas */
27#define VM_SWAPMAP 0
28 {"_swdevt"}, /* list of swap devices and sizes */
29#define VM_SWDEVT 1
30 {"_nswap"}, /* size of largest swap device */
31#define VM_NSWAP 2
32 {"_nswdev"}, /* number of swap devices */
33#define VM_NSWDEV 3
34 {"_dmmax"}, /* maximum size of a swap block */
35#define VM_DMMAX 4
36 {""}};
37
f9ec6cbc
NW
38char *getbsize __P((char *, int *, long *));
39void usage __P((void));
40int kflag;
4d554349
NW
41
42main (argc, argv)
43int argc;
44char **argv;
45{
46 int i, total_avail, total_free, total_partitions, *by_device,
f9ec6cbc 47 nswap, nswdev, dmmax, ch;
4d554349
NW
48 struct swdevt *swdevt;
49 struct rlist head;
4e97a0eb
NW
50 static long blocksize;
51 static int headerlen;
52 static char *header;
f9ec6cbc 53 char **save;
4d554349
NW
54
55 /* We are trying to be simple here: */
56
f9ec6cbc
NW
57 save = argv;
58 kflag = 0;
59 while ((ch = getopt(argc, argv, "k")) != EOF)
60 switch(ch) {
61 case 'k':
62 kflag = 1;
63 break;
64 case '?':
65 default:
66 usage();
67 }
68 argv += optind;
69
70 if (!*argv) {
71 argv = save;
72 argv[0] = ".";
73 argv[1] = NULL;
4e97a0eb 74 }
4d554349
NW
75
76 /* Open up /dev/kmem for reading. */
77
78 if (kvm_openfiles (NULL, NULL, NULL) == -1) {
79 fprintf (stderr, "%s: kvm_openfiles: %s\n",
80 argv [0], kvm_geterr());
81 exit (1);
82 }
83
84 /* Figure out the offset of the various structures we'll need. */
85
86 if (kvm_nlist (nl) == -1) {
87 fprintf (stderr, "%s: kvm_nlist: %s\n",
88 argv [0], kvm_geterr());
89 exit (1);
90 }
91
92 if (kvm_read (nl [VM_NSWAP].n_value, &nswap, sizeof (nswap)) !=
93 sizeof (nswap)) {
94 fprintf (stderr, "%s: didn't read all of nswap\n",
95 argv [0]);
96 exit (5);
97 }
98
99 if (kvm_read (nl [VM_NSWDEV].n_value, &nswdev, sizeof (nswdev)) !=
100 sizeof (nswdev)) {
101 fprintf (stderr, "%s: didn't read all of nswdev\n",
102 argv [0]);
103 exit (5);
104 }
105
106 if (kvm_read (nl [VM_DMMAX].n_value, &dmmax, sizeof (dmmax)) !=
107 sizeof (dmmax)) {
108 fprintf (stderr, "%s: didn't read all of dmmax\n",
109 argv [0]);
110 exit (5);
111 }
112
113 if ((swdevt = malloc (sizeof (struct swdevt) * nswdev)) == NULL ||
114 (by_device = calloc (sizeof (*by_device), nswdev)) == NULL) {
115 perror ("malloc");
116 exit (5);
117 }
118
119 if (kvm_read (nl [VM_SWDEVT].n_value, swdevt,
120 sizeof (struct swdevt) * nswdev) !=
121 sizeof (struct swdevt) * nswdev) {
122 fprintf (stderr, "%s: didn't read all of swdevt\n",
123 argv [0]);
124 exit (5);
125 }
126
127 if (kvm_read (nl [0].n_value, &swapmap, sizeof (struct rlist *)) !=
128 sizeof (struct rlist *)) {
129 fprintf (stderr, "%s: didn't read all of swapmap\n",
130 argv [0]);
131 exit (5);
132 }
133
134 /* Traverse the list of free swap space... */
135
136 total_free = 0;
137 while (swapmap) {
138 int top, bottom, next_block;
139
140 if (kvm_read ((long) swapmap, &head, sizeof (struct rlist )) !=
141 sizeof (struct rlist )) {
142 fprintf (stderr, "%s: didn't read all of head\n",
143 argv [0]);
144 exit (5);
145 }
146
147 top = head.rl_end;
148 bottom = head.rl_start;
149
150 total_free += top - bottom + 1;
151
152 /*
153 * Swap space is split up among the configured disk.
154 * The first dmmax blocks of swap space some from the
155 * first disk, the next dmmax blocks from the next,
156 * and so on. The list of free space joins adjacent
157 * free blocks, ignoring device boundries. If we want
158 * to keep track of this information per device, we'll
159 * just have to extract it ourselves.
160 */
161
162 while (top / dmmax != bottom / dmmax) {
163 next_block = ((bottom + dmmax) / dmmax);
164 by_device [(bottom / dmmax) % nswdev] +=
165 next_block * dmmax - bottom;
166 bottom = next_block * dmmax;
167 }
168
169 by_device [(bottom / dmmax) % nswdev] +=
170 top - bottom + 1;
171
172 swapmap = head.rl_next;
173 }
174
4e97a0eb 175 header = getbsize("swapinfo", &headerlen, &blocksize);
4d554349 176 printf ("%-10s %10s %10s %10s %10s\n",
4e97a0eb 177 "Device", header, "Used", "Available", "Capacity");
4d554349
NW
178 for (total_avail = total_partitions = i = 0; i < nswdev; i++) {
179 printf ("/dev/%-5s %10d ",
180 devname (swdevt [i].sw_dev, S_IFBLK),
f9ec6cbc 181 swdevt [i].sw_nblks / (blocksize/512));
4d554349
NW
182
183 /*
184 * Don't report statistics for partitions which have not
185 * yet been activated via swapon(8).
186 */
187
188 if (!swdevt [i].sw_freed) {
189 printf (" *** not available for swapping ***\n");
190 } else {
191 total_partitions++;
192 total_avail += swdevt [i].sw_nblks;
193 printf ("%10d %10d %7.0f%%\n",
f9ec6cbc
NW
194 (swdevt [i].sw_nblks - by_device [i]) / (blocksize/512),
195 by_device [i] / (blocksize/512),
4d554349
NW
196 (double) (swdevt [i].sw_nblks -
197 by_device [i]) /
198 (double) swdevt [i].sw_nblks * 100.0);
199 }
200 }
201
202 /*
203 * If only one partition has been set up via swapon(8), we don't
204 * need to bother with totals.
205 */
206
207 if (total_partitions > 1)
208 printf ("%-10s %10d %10d %10d %7.0f%%\n", "Total",
f9ec6cbc
NW
209 total_avail / (blocksize/512),
210 (total_avail - total_free) / (blocksize/512),
211 total_free / (blocksize/512),
4d554349
NW
212 (double) (total_avail - total_free) /
213 (double) total_avail * 100.0);
214
215 exit (0);
216}
f9ec6cbc
NW
217
218void
219usage()
220{
221 (void)fprintf(stderr, "usage: swapinfo [-k]\n");
222 exit(1);
223}
224
225