pstat.c (f6f60773dda9e5b585826fccdc8355c09d5ab309) pstat.c (eedc343625e28519e717a9867dff20efe5081a12)
1/*-
2 * Copyright (c) 1980, 1991, 1993, 1994
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

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)pstat.c 8.16 (Berkeley) 5/9/95";
43#endif
44static const char rcsid[] =
1/*-
2 * Copyright (c) 1980, 1991, 1993, 1994
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

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)pstat.c 8.16 (Berkeley) 5/9/95";
43#endif
44static const char rcsid[] =
45 "$Id: pstat.c,v 1.36 1998/07/06 20:28:05 bde Exp $";
45 "$Id: pstat.c,v 1.37 1998/08/19 01:32:28 bde Exp $";
46#endif /* not lint */
47
48#include <sys/param.h>
49#include <sys/time.h>
50#include <sys/vnode.h>
51#include <sys/ucred.h>
52#define KERNEL
53#include <sys/file.h>

--- 9 unchanged lines hidden (view full) ---

63#include <nfs/nfsproto.h>
64#include <nfs/nfs.h>
65#include <nfs/nfsnode.h>
66#include <sys/ioctl.h>
67#include <sys/ioctl_compat.h> /* XXX NTTYDISC is too well hidden */
68#include <sys/tty.h>
69#include <sys/conf.h>
70#include <sys/rlist.h>
46#endif /* not lint */
47
48#include <sys/param.h>
49#include <sys/time.h>
50#include <sys/vnode.h>
51#include <sys/ucred.h>
52#define KERNEL
53#include <sys/file.h>

--- 9 unchanged lines hidden (view full) ---

63#include <nfs/nfsproto.h>
64#include <nfs/nfs.h>
65#include <nfs/nfsnode.h>
66#include <sys/ioctl.h>
67#include <sys/ioctl_compat.h> /* XXX NTTYDISC is too well hidden */
68#include <sys/tty.h>
69#include <sys/conf.h>
70#include <sys/rlist.h>
71#include <sys/blist.h>
71
72#include <sys/user.h>
73#include <sys/sysctl.h>
74
75#include <err.h>
76#include <fcntl.h>
77#include <kvm.h>
78#include <limits.h>
79#include <nlist.h>
80#include <stdio.h>
81#include <stdlib.h>
82#include <string.h>
83#include <unistd.h>
84
85struct nlist nl[] = {
86#define VM_SWAPLIST 0
87 { "_swaplist" },/* list of free swap areas */
72
73#include <sys/user.h>
74#include <sys/sysctl.h>
75
76#include <err.h>
77#include <fcntl.h>
78#include <kvm.h>
79#include <limits.h>
80#include <nlist.h>
81#include <stdio.h>
82#include <stdlib.h>
83#include <string.h>
84#include <unistd.h>
85
86struct nlist nl[] = {
87#define VM_SWAPLIST 0
88 { "_swaplist" },/* list of free swap areas */
89#define NLMANDATORYBEG 1
88#define VM_SWDEVT 1
89 { "_swdevt" }, /* list of swap devices and sizes */
90#define VM_SWDEVT 1
91 { "_swdevt" }, /* list of swap devices and sizes */
90#define VM_NSWAP 2
91 { "_nswap" }, /* size of largest swap device */
92#define VM_NSWDEV 3
92#define VM_NSWDEV 2
93 { "_nswdev" }, /* number of swap devices */
93 { "_nswdev" }, /* number of swap devices */
94#define VM_DMMAX 4
94#define VM_DMMAX 3
95 { "_dmmax" }, /* maximum size of a swap block */
95 { "_dmmax" }, /* maximum size of a swap block */
96#define V_MOUNTLIST 5
96#define V_MOUNTLIST 4
97 { "_mountlist" }, /* address of head of mount list. */
97 { "_mountlist" }, /* address of head of mount list. */
98#define V_NUMV 6
98#define V_NUMV 5
99 { "_numvnodes" },
99 { "_numvnodes" },
100#define FNL_NFILE 7
100#define FNL_NFILE 6
101 {"_nfiles"},
101 {"_nfiles"},
102#define FNL_MAXFILE 8
102#define FNL_MAXFILE 7
103 {"_maxfiles"},
103 {"_maxfiles"},
104#define NLMANDATORY FNL_MAXFILE /* names up to here are mandatory */
105#define SCONS NLMANDATORY + 1
104#define NLMANDATORYEND FNL_MAXFILE /* names up to here are mandatory */
105#define SCONS NLMANDATORYEND + 1
106 { "_cons" },
106 { "_cons" },
107#define SPTY NLMANDATORY + 2
107#define SPTY NLMANDATORYEND + 2
108 { "_pt_tty" },
108 { "_pt_tty" },
109#define SNPTY NLMANDATORY + 3
109#define SNPTY NLMANDATORYEND + 3
110 { "_npty" },
110 { "_npty" },
111#define VM_SWAPBLIST NLMANDATORYEND + 4
112 { "_swapblist" },
111
112#ifdef hp300
113
114#ifdef hp300
113#define SDCA (SNPTY+1)
115#define SDCA (VM_SWAPBLIST+1)
114 { "_dca_tty" },
116 { "_dca_tty" },
115#define SNDCA (SNPTY+2)
117#define SNDCA (VM_SWAPBLIST+2)
116 { "_ndca" },
118 { "_ndca" },
117#define SDCM (SNPTY+3)
119#define SDCM (VM_SWAPBLIST+3)
118 { "_dcm_tty" },
120 { "_dcm_tty" },
119#define SNDCM (SNPTY+4)
121#define SNDCM (VM_SWAPBLIST+4)
120 { "_ndcm" },
122 { "_ndcm" },
121#define SDCL (SNPTY+5)
123#define SDCL (VM_SWAPBLIST+5)
122 { "_dcl_tty" },
124 { "_dcl_tty" },
123#define SNDCL (SNPTY+6)
125#define SNDCL (VM_SWAPBLIST+6)
124 { "_ndcl" },
126 { "_ndcl" },
125#define SITE (SNPTY+7)
127#define SITE (VM_SWAPBLIST+7)
126 { "_ite_tty" },
128 { "_ite_tty" },
127#define SNITE (SNPTY+8)
129#define SNITE (VM_SWAPBLIST+8)
128 { "_nite" },
129#endif
130
131#ifdef mips
130 { "_nite" },
131#endif
132
133#ifdef mips
132#define SDC (SNPTY+1)
134#define SDC (VM_SWAPBLIST+1)
133 { "_dc_tty" },
135 { "_dc_tty" },
134#define SNDC (SNPTY+2)
136#define SNDC (VM_SWAPBLIST+2)
135 { "_dc_cnt" },
136#endif
137
138#ifdef __FreeBSD__
137 { "_dc_cnt" },
138#endif
139
140#ifdef __FreeBSD__
139#define SCCONS (SNPTY+1)
141#define SCCONS (VM_SWAPBLIST+1)
140 { "_sccons" },
142 { "_sccons" },
141#define NSCCONS (SNPTY+2)
143#define NSCCONS (VM_SWAPBLIST+2)
142 { "_nsccons" },
144 { "_nsccons" },
143#define SIO (SNPTY+3)
145#define SIO (VM_SWAPBLIST+3)
144 { "_sio_tty" },
146 { "_sio_tty" },
145#define NSIO (SNPTY+4)
147#define NSIO (VM_SWAPBLIST+4)
146 { "_nsio_tty" },
148 { "_nsio_tty" },
147#define RC (SNPTY+5)
149#define RC (VM_SWAPBLIST+5)
148 { "_rc_tty" },
150 { "_rc_tty" },
149#define NRC (SNPTY+6)
151#define NRC (VM_SWAPBLIST+6)
150 { "_nrc_tty" },
152 { "_nrc_tty" },
151#define CY (SNPTY+7)
153#define CY (VM_SWAPBLIST+7)
152 { "_cy_tty" },
154 { "_cy_tty" },
153#define NCY (SNPTY+8)
155#define NCY (VM_SWAPBLIST+8)
154 { "_ncy_tty" },
156 { "_ncy_tty" },
155#define SI (SNPTY+9)
157#define SI (VM_SWAPBLIST+9)
156 { "_si_tty" },
158 { "_si_tty" },
157#define NSI (SNPTY+10)
159#define NSI (VM_SWAPBLIST+10)
158 { "_si_Nports" },
159#endif
160 { "" }
161};
162
163int usenumflag;
164int totalflag;
160 { "_si_Nports" },
161#endif
162 { "" }
163};
164
165int usenumflag;
166int totalflag;
167int swapflag;
165char *nlistf = NULL;
166char *memf = NULL;
167kvm_t *kd;
168
169char *usagestr;
170
171struct {
172 int m_flag;

--- 34 unchanged lines hidden (view full) ---

207#define SVAR(var) __STRING(var) /* to force expansion */
208#define KGET(idx, var) \
209 KGET1(idx, &var, sizeof(var), SVAR(var))
210#define KGET1(idx, p, s, msg) \
211 KGET2(nl[idx].n_value, p, s, msg)
212#define KGET2(addr, p, s, msg) \
213 if (kvm_read(kd, (u_long)(addr), p, s) != s) \
214 warnx("cannot read %s: %s", msg, kvm_geterr(kd))
168char *nlistf = NULL;
169char *memf = NULL;
170kvm_t *kd;
171
172char *usagestr;
173
174struct {
175 int m_flag;

--- 34 unchanged lines hidden (view full) ---

210#define SVAR(var) __STRING(var) /* to force expansion */
211#define KGET(idx, var) \
212 KGET1(idx, &var, sizeof(var), SVAR(var))
213#define KGET1(idx, p, s, msg) \
214 KGET2(nl[idx].n_value, p, s, msg)
215#define KGET2(addr, p, s, msg) \
216 if (kvm_read(kd, (u_long)(addr), p, s) != s) \
217 warnx("cannot read %s: %s", msg, kvm_geterr(kd))
218#define KGETN(idx, var) \
219 KGET1N(idx, &var, sizeof(var), SVAR(var))
220#define KGET1N(idx, p, s, msg) \
221 KGET2N(nl[idx].n_value, p, s, msg)
222#define KGET2N(addr, p, s, msg) \
223 ((kvm_read(kd, (u_long)(addr), p, s) == s) ? 1 : 0)
215#define KGETRET(addr, p, s, msg) \
216 if (kvm_read(kd, (u_long)(addr), p, s) != s) { \
217 warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \
218 return (0); \
219 }
220
221void filemode __P((void));
222int getfiles __P((char **, int *));

--- 20 unchanged lines hidden (view full) ---

243void vnodemode __P((void));
244
245int
246main(argc, argv)
247 int argc;
248 char *argv[];
249{
250 int ch, i, quit, ret;
224#define KGETRET(addr, p, s, msg) \
225 if (kvm_read(kd, (u_long)(addr), p, s) != s) { \
226 warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \
227 return (0); \
228 }
229
230void filemode __P((void));
231int getfiles __P((char **, int *));

--- 20 unchanged lines hidden (view full) ---

252void vnodemode __P((void));
253
254int
255main(argc, argv)
256 int argc;
257 char *argv[];
258{
259 int ch, i, quit, ret;
251 int fileflag, swapflag, ttyflag, vnodeflag;
260 int fileflag, ttyflag, vnodeflag;
252 char buf[_POSIX2_LINE_MAX],*opts;
253
254 fileflag = swapflag = ttyflag = vnodeflag = 0;
255
256 /* We will behave like good old swapinfo if thus invoked */
257 opts = strrchr(argv[0],'/');
258 if (opts)
259 opts++;

--- 21 unchanged lines hidden (view full) ---

281 break;
282 case 'N':
283 nlistf = optarg;
284 break;
285 case 'n':
286 usenumflag = 1;
287 break;
288 case 's':
261 char buf[_POSIX2_LINE_MAX],*opts;
262
263 fileflag = swapflag = ttyflag = vnodeflag = 0;
264
265 /* We will behave like good old swapinfo if thus invoked */
266 opts = strrchr(argv[0],'/');
267 if (opts)
268 opts++;

--- 21 unchanged lines hidden (view full) ---

290 break;
291 case 'N':
292 nlistf = optarg;
293 break;
294 case 'n':
295 usenumflag = 1;
296 break;
297 case 's':
289 swapflag = 1;
298 ++swapflag;
290 break;
291 case 'T':
292 totalflag = 1;
293 break;
294 case 't':
295 ttyflag = 1;
296 break;
297 case 'v':

--- 17 unchanged lines hidden (view full) ---

315 if (nlistf != NULL || memf != NULL)
316 (void)setgid(getgid());
317
318 if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == 0)
319 errx(1, "kvm_openfiles: %s", buf);
320 if ((ret = kvm_nlist(kd, nl)) != 0) {
321 if (ret == -1)
322 errx(1, "kvm_nlist: %s", kvm_geterr(kd));
299 break;
300 case 'T':
301 totalflag = 1;
302 break;
303 case 't':
304 ttyflag = 1;
305 break;
306 case 'v':

--- 17 unchanged lines hidden (view full) ---

324 if (nlistf != NULL || memf != NULL)
325 (void)setgid(getgid());
326
327 if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == 0)
328 errx(1, "kvm_openfiles: %s", buf);
329 if ((ret = kvm_nlist(kd, nl)) != 0) {
330 if (ret == -1)
331 errx(1, "kvm_nlist: %s", kvm_geterr(kd));
323 for (i = quit = 0; i <= NLMANDATORY; i++)
332 for (i = NLMANDATORYBEG, quit = 0; i <= NLMANDATORYEND; i++)
324 if (!nl[i].n_value) {
325 quit = 1;
326 warnx("undefined symbol: %s", nl[i].n_name);
327 }
328 if (quit)
329 exit(1);
330 }
331 if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag))

--- 689 unchanged lines hidden (view full) ---

1021 return (-1);
1022 }
1023 *abuf = buf;
1024 *alen = len;
1025 return (0);
1026}
1027
1028/*
333 if (!nl[i].n_value) {
334 quit = 1;
335 warnx("undefined symbol: %s", nl[i].n_name);
336 }
337 if (quit)
338 exit(1);
339 }
340 if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag))

--- 689 unchanged lines hidden (view full) ---

1030 return (-1);
1031 }
1032 *abuf = buf;
1033 *alen = len;
1034 return (0);
1035}
1036
1037/*
1038 * scanradix() - used by swapmode() to scan the swap device's new style
1039 * radix tree
1040 */
1041
1042#define TABME tab, tab, ""
1043
1044int
1045scanradix(
1046 blmeta_t *scan,
1047 daddr_t blk,
1048 daddr_t radix,
1049 daddr_t skip,
1050 daddr_t count,
1051 int dmmax,
1052 int nswdev,
1053 long *perdev,
1054 int tab
1055) {
1056 blmeta_t meta;
1057
1058 KGET2(scan, &meta, sizeof(meta), "blmeta_t");
1059
1060 /*
1061 * Terminator
1062 */
1063 if (meta.bm_bighint == (daddr_t)-1) {
1064 if (swapflag > 1) {
1065 printf("%*.*s(0x%06x,%d) Terminator\n",
1066 TABME,
1067 blk,
1068 radix
1069 );
1070 }
1071 return(-1);
1072 }
1073
1074 if (radix == BLIST_BMAP_RADIX) {
1075 /*
1076 * Leaf bitmap
1077 */
1078 int i;
1079
1080 if (swapflag > 1) {
1081 printf("%*.*s(0x%06x,%d) Bitmap %08x big=%d\n",
1082 TABME,
1083 blk,
1084 radix,
1085 (int)meta.u.bmu_bitmap,
1086 meta.bm_bighint
1087 );
1088 }
1089
1090 /*
1091 * If not all allocated, count.
1092 */
1093 if (meta.u.bmu_bitmap != 0) {
1094 for (i = 0; i < BLIST_BMAP_RADIX && i < count; ++i) {
1095 /*
1096 * A 0 bit means allocated
1097 */
1098 if ((meta.u.bmu_bitmap & (1 << i))) {
1099 int t = 0;
1100
1101 if (nswdev)
1102 t = (blk + i) / dmmax % nswdev;
1103 ++perdev[t];
1104 }
1105 }
1106 }
1107 } else if (meta.u.bmu_avail == radix) {
1108 /*
1109 * Meta node if all free
1110 */
1111 if (swapflag > 1) {
1112 printf("%*.*s(0x%06x,%d) Submap ALL-FREE {\n",
1113 TABME,
1114 blk,
1115 radix,
1116 (int)meta.u.bmu_avail,
1117 meta.bm_bighint
1118 );
1119 }
1120 /*
1121 * Note: both dmmax and radix are powers of 2. However, dmmax
1122 * may be larger then radix so use a smaller increment if
1123 * necessary.
1124 */
1125 {
1126 int t;
1127 int tinc = dmmax;
1128
1129 while (tinc > radix)
1130 tinc >>= 1;
1131
1132 for (t = blk; t < blk + radix; t += tinc) {
1133 if (nswdev)
1134 perdev[0] += tinc;
1135 else
1136 perdev[t / dmmax % nswdev] += tinc;
1137 }
1138 }
1139 } else if (meta.u.bmu_avail == 0) {
1140 /*
1141 * Meta node if all used
1142 */
1143 if (swapflag > 1) {
1144 printf("%*.*s(0x%06x,%d) Submap ALL-ALLOCATED\n",
1145 TABME,
1146 blk,
1147 radix,
1148 (int)meta.u.bmu_avail,
1149 meta.bm_bighint
1150 );
1151 }
1152 } else {
1153 /*
1154 * Meta node if not all free
1155 */
1156 int i;
1157 int next_skip;
1158
1159 radix >>= BLIST_META_RADIX_SHIFT;
1160 next_skip = skip >> BLIST_META_RADIX_SHIFT;
1161
1162 if (swapflag > 1) {
1163 printf("%*.*s(0x%06x,%d) Submap avail=%d big=%d {\n",
1164 TABME,
1165 blk,
1166 radix,
1167 (int)meta.u.bmu_avail,
1168 meta.bm_bighint
1169 );
1170 }
1171
1172 for (i = 1; i <= skip; i += next_skip) {
1173 int r;
1174 daddr_t vcount = (count > radix) ? radix : count;
1175
1176 r = scanradix(
1177 &scan[i],
1178 blk,
1179 radix,
1180 next_skip - 1,
1181 vcount,
1182 dmmax,
1183 nswdev,
1184 perdev,
1185 tab + 4
1186 );
1187 if (r < 0)
1188 break;
1189 blk += radix;
1190 }
1191 if (swapflag > 1) {
1192 printf("%*.*s}\n", TABME);
1193 }
1194 }
1195 return(0);
1196}
1197
1198
1199/*
1029 * swapmode is based on a program called swapinfo written
1030 * by Kevin Lahey <kml@rokkaku.atl.ga.us>.
1031 */
1032void
1200 * swapmode is based on a program called swapinfo written
1201 * by Kevin Lahey <kml@rokkaku.atl.ga.us>.
1202 */
1203void
1033swapmode()
1204swapmode(void)
1034{
1035 char *header, *p;
1205{
1206 char *header, *p;
1036 int hlen, nswap, nswdev, dmmax;
1037 int i, div, avail, nfree, npfree, used;
1207 int hlen, nswdev, dmmax;
1208 int i, div, mul, avail, nfree, npfree, used;
1038 struct swdevt *sw;
1039 long blocksize, *perdev;
1040 struct rlist head;
1041 struct rlisthdr swaplist;
1209 struct swdevt *sw;
1210 long blocksize, *perdev;
1211 struct rlist head;
1212 struct rlisthdr swaplist;
1042 struct rlist *swapptr;
1213 struct blist *swapblist = NULL;
1043 u_long ptr;
1044
1214 u_long ptr;
1215
1045 KGET(VM_NSWAP, nswap);
1046 KGET(VM_NSWDEV, nswdev);
1216 KGET(VM_NSWDEV, nswdev);
1047 KGET(VM_DMMAX, dmmax);
1048 KGET1(VM_SWAPLIST, &swaplist, sizeof swaplist, "swaplist");
1217 KGET(VM_DMMAX, dmmax); /* PAGE_BSIZE'd or PAGE_SIZE'd depending */
1218 if (!KGET1N(VM_SWAPLIST, &swaplist, sizeof swaplist, "swaplist")) {
1219 KGET1(VM_SWAPBLIST, &swapblist, sizeof swapblist, "swapblist");
1220 }
1221
1049 if ((sw = malloc(nswdev * sizeof(*sw))) == NULL ||
1050 (perdev = malloc(nswdev * sizeof(*perdev))) == NULL)
1051 errx(1, "malloc");
1052 KGET1(VM_SWDEVT, &ptr, sizeof ptr, "swdevt");
1053 KGET2(ptr, sw, nswdev * sizeof(*sw), "*swdevt");
1054
1055 /* Count up swap space. */
1056 nfree = 0;
1057 memset(perdev, 0, nswdev * sizeof(*perdev));
1222 if ((sw = malloc(nswdev * sizeof(*sw))) == NULL ||
1223 (perdev = malloc(nswdev * sizeof(*perdev))) == NULL)
1224 errx(1, "malloc");
1225 KGET1(VM_SWDEVT, &ptr, sizeof ptr, "swdevt");
1226 KGET2(ptr, sw, nswdev * sizeof(*sw), "*swdevt");
1227
1228 /* Count up swap space. */
1229 nfree = 0;
1230 memset(perdev, 0, nswdev * sizeof(*perdev));
1058 swapptr = swaplist.rlh_list;
1059 while (swapptr) {
1060 int top, bottom, next_block;
1061
1231
1062 KGET2(swapptr, &head, sizeof(struct rlist), "swapptr");
1232 if (swapblist) {
1233 /*
1234 * New swap radix tree (ugh!)
1235 */
1236 struct blist blcopy = { 0 };
1237 KGET2(swapblist, &blcopy, sizeof(blcopy), "*swapblist");
1238 if (swapflag > 1) {
1239 printf("radix tree: %d/%d/%d blocks, %dK wired\n",
1240 blcopy.bl_free,
1241 blcopy.bl_blocks,
1242 blcopy.bl_radix,
1243 (blcopy.bl_rootblks * sizeof(blmeta_t) + 1023)/
1244 1024
1245 );
1246 }
1247 scanradix(blcopy.bl_root, 0, blcopy.bl_radix, blcopy.bl_skip, blcopy.bl_rootblks, dmmax, nswdev, perdev, 0);
1248 } else {
1249 /*
1250 * Old swap
1251 */
1252 struct rlist *swapptr;
1063
1253
1064 top = head.rl_end;
1065 bottom = head.rl_start;
1254 swapptr = swaplist.rlh_list;
1255 while (swapptr) {
1256 int top, bottom, next_block;
1066
1257
1067 nfree += top - bottom + 1;
1258 KGET2(swapptr, &head, sizeof(struct rlist), "swapptr");
1068
1259
1069 /*
1070 * Swap space is split up among the configured disks.
1071 *
1072 * For interleaved swap devices, the first dmmax blocks
1073 * of swap space some from the first disk, the next dmmax
1074 * blocks from the next, and so on up to nswap blocks.
1075 *
1076 * The list of free space joins adjacent free blocks,
1077 * ignoring device boundries. If we want to keep track
1078 * of this information per device, we'll just have to
1079 * extract it ourselves.
1080 */
1081 while (top / dmmax != bottom / dmmax) {
1082 next_block = ((bottom + dmmax) / dmmax);
1260 top = head.rl_end;
1261 bottom = head.rl_start;
1262
1263 nfree += top - bottom + 1;
1264
1265 /*
1266 * Swap space is split up among the configured disks.
1267 *
1268 * For interleaved swap devices, the first dmmax blocks
1269 * of swap space some from the first disk, the next
1270 * dmmax blocks from the next, and so.
1271 *
1272 * The list of free space joins adjacent free blocks,
1273 * ignoring device boundries. If we want to keep track
1274 * of this information per device, we'll just have to
1275 * extract it ourselves.
1276 */
1277 while (top / dmmax != bottom / dmmax) {
1278 next_block = ((bottom + dmmax) / dmmax);
1279 perdev[(bottom / dmmax) % nswdev] +=
1280 next_block * dmmax - bottom;
1281 bottom = next_block * dmmax;
1282 }
1083 perdev[(bottom / dmmax) % nswdev] +=
1283 perdev[(bottom / dmmax) % nswdev] +=
1084 next_block * dmmax - bottom;
1085 bottom = next_block * dmmax;
1086 }
1087 perdev[(bottom / dmmax) % nswdev] +=
1088 top - bottom + 1;
1284 top - bottom + 1;
1089
1285
1090 swapptr = head.rl_next;
1286 swapptr = head.rl_next;
1287 }
1091 }
1092
1093 header = getbsize(&hlen, &blocksize);
1094 if (!totalflag)
1095 (void)printf("%-11s %*s %8s %8s %8s %s\n",
1096 "Device", hlen, header,
1097 "Used", "Avail", "Capacity", "Type");
1288 }
1289
1290 header = getbsize(&hlen, &blocksize);
1291 if (!totalflag)
1292 (void)printf("%-11s %*s %8s %8s %8s %s\n",
1293 "Device", hlen, header,
1294 "Used", "Avail", "Capacity", "Type");
1098 div = blocksize / 512;
1295
1296 mul = 1;
1297 if (swapblist) {
1298 if ((div = blocksize / PAGE_SIZE) == 0) {
1299 mul = PAGE_SIZE / blocksize;
1300 div = 1;
1301 }
1302 } else {
1303 if ((div = blocksize / DEV_BSIZE) == 0) {
1304 mul = DEV_BSIZE / blocksize;
1305 div = 1;
1306 }
1307 }
1308
1099 avail = npfree = 0;
1100 for (i = 0; i < nswdev; i++) {
1101 int xsize, xfree;
1102
1103 /*
1104 * Don't report statistics for partitions which have not
1105 * yet been activated via swapon(8).
1106 */
1107 if (!(sw[i].sw_flags & SW_FREED))
1108 continue;
1109
1110 if (!totalflag)
1111 if (sw[i].sw_dev != NODEV) {
1112 p = devname(sw[i].sw_dev, S_IFBLK);
1113 (void)printf("/dev/%-6s %*d ",
1114 p == NULL ? "??" : p,
1309 avail = npfree = 0;
1310 for (i = 0; i < nswdev; i++) {
1311 int xsize, xfree;
1312
1313 /*
1314 * Don't report statistics for partitions which have not
1315 * yet been activated via swapon(8).
1316 */
1317 if (!(sw[i].sw_flags & SW_FREED))
1318 continue;
1319
1320 if (!totalflag)
1321 if (sw[i].sw_dev != NODEV) {
1322 p = devname(sw[i].sw_dev, S_IFBLK);
1323 (void)printf("/dev/%-6s %*d ",
1324 p == NULL ? "??" : p,
1115 hlen, sw[i].sw_nblks / div);
1325 hlen, sw[i].sw_nblks * mul / div);
1116 } else
1117 (void)printf("[NFS swap] %*d ",
1326 } else
1327 (void)printf("[NFS swap] %*d ",
1118 hlen, sw[i].sw_nblks / div);
1328 hlen, sw[i].sw_nblks * mul / div);
1119
1120 /* The first dmmax is never allocated to avoid trashing of
1121 * disklabels
1122 */
1123 xsize = sw[i].sw_nblks - dmmax;
1124 xfree = perdev[i];
1125 used = xsize - xfree;
1126 npfree++;
1127 avail += xsize;
1128 if (totalflag)
1129 continue;
1130 (void)printf("%8d %8d %5.0f%% %s\n",
1329
1330 /* The first dmmax is never allocated to avoid trashing of
1331 * disklabels
1332 */
1333 xsize = sw[i].sw_nblks - dmmax;
1334 xfree = perdev[i];
1335 used = xsize - xfree;
1336 npfree++;
1337 avail += xsize;
1338 if (totalflag)
1339 continue;
1340 (void)printf("%8d %8d %5.0f%% %s\n",
1131 used / div, xfree / div,
1341 used * mul / div, xfree * mul / div,
1132 (double)used / (double)xsize * 100.0,
1133 (sw[i].sw_flags & SW_SEQUENTIAL) ?
1134 "Sequential" : "Interleaved");
1135 }
1136
1137 /*
1138 * If only one partition has been set up via swapon(8), we don't
1139 * need to bother with totals.
1140 */
1141 used = avail - nfree;
1142 free(sw);
1143 free(perdev);
1144 if (totalflag) {
1145 (void)printf("%dM/%dM swap space\n", used / 2048, avail / 2048);
1146 return;
1147 }
1148 if (npfree > 1) {
1149 (void)printf("%-11s %*d %8d %8d %5.0f%%\n",
1342 (double)used / (double)xsize * 100.0,
1343 (sw[i].sw_flags & SW_SEQUENTIAL) ?
1344 "Sequential" : "Interleaved");
1345 }
1346
1347 /*
1348 * If only one partition has been set up via swapon(8), we don't
1349 * need to bother with totals.
1350 */
1351 used = avail - nfree;
1352 free(sw);
1353 free(perdev);
1354 if (totalflag) {
1355 (void)printf("%dM/%dM swap space\n", used / 2048, avail / 2048);
1356 return;
1357 }
1358 if (npfree > 1) {
1359 (void)printf("%-11s %*d %8d %8d %5.0f%%\n",
1150 "Total", hlen, avail / div, used / div, nfree / div,
1360 "Total", hlen, avail * mul / div, used * mul / div, nfree * mul / div,
1151 (double)used / (double)avail * 100.0);
1152 }
1153}
1361 (double)used / (double)avail * 100.0);
1362 }
1363}