Commit | Line | Data |
---|---|---|
5ff67f98 DF |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
ae1f9014 | 7 | #ifndef lint |
5ff67f98 DF |
8 | char copyright[] = |
9 | "@(#) Copyright (c) 1980 Regents of the University of California.\n\ | |
10 | All rights reserved.\n"; | |
0dc27808 | 11 | #endif /* not lint */ |
5ff67f98 DF |
12 | |
13 | #ifndef lint | |
0dc27808 KB |
14 | static char sccsid[] = "@(#)pstat.c 5.17 (Berkeley) %G%"; |
15 | #endif /* not lint */ | |
5ff67f98 | 16 | |
ceb84881 BJ |
17 | /* |
18 | * Print system stuff | |
19 | */ | |
20 | ||
ceb84881 BJ |
21 | #include <sys/param.h> |
22 | #include <sys/dir.h> | |
ae1f9014 | 23 | #define KERNEL |
ceb84881 | 24 | #include <sys/file.h> |
ae1f9014 | 25 | #undef KERNEL |
ceb84881 BJ |
26 | #include <sys/user.h> |
27 | #include <sys/proc.h> | |
28 | #include <sys/text.h> | |
29 | #include <sys/inode.h> | |
30 | #include <sys/map.h> | |
88a58f27 | 31 | #include <sys/ioctl.h> |
ceb84881 BJ |
32 | #include <sys/tty.h> |
33 | #include <sys/conf.h> | |
34 | #include <sys/vm.h> | |
35 | #include <nlist.h> | |
0bc29a7d | 36 | #include <machine/pte.h> |
9ed2dfb9 | 37 | #include <stdio.h> |
ceb84881 | 38 | |
f20270fc MK |
39 | #define mask(x) (x&0377) |
40 | #define clear(x) ((int)x &~ KERNBASE) | |
41 | ||
ceb84881 | 42 | char *fcore = "/dev/kmem"; |
aadf0902 | 43 | char *fmem = "/dev/mem"; |
ceb84881 | 44 | char *fnlist = "/vmunix"; |
aadf0902 | 45 | int fc, fm; |
ceb84881 BJ |
46 | |
47 | struct nlist nl[] = { | |
48 | #define SINODE 0 | |
49 | { "_inode" }, | |
50 | #define STEXT 1 | |
51 | { "_text" }, | |
52 | #define SPROC 2 | |
53 | { "_proc" }, | |
4242be26 | 54 | #define SCONS 3 |
ceb84881 | 55 | { "_cons" }, |
4242be26 | 56 | #define SFIL 4 |
ceb84881 | 57 | { "_file" }, |
4242be26 | 58 | #define USRPTMA 5 |
ceb84881 | 59 | { "_Usrptmap" }, |
4242be26 | 60 | #define USRPT 6 |
ceb84881 | 61 | { "_usrpt" }, |
4242be26 | 62 | #define SWAPMAP 7 |
ceb84881 | 63 | { "_swapmap" }, |
4242be26 | 64 | #define SNPROC 8 |
69d3d166 | 65 | { "_nproc" }, |
4242be26 | 66 | #define SNTEXT 9 |
69d3d166 | 67 | { "_ntext" }, |
4242be26 | 68 | #define SNFILE 10 |
69d3d166 | 69 | { "_nfile" }, |
4242be26 | 70 | #define SNINODE 11 |
69d3d166 | 71 | { "_ninode" }, |
4242be26 | 72 | #define SNSWAPMAP 12 |
69d3d166 | 73 | { "_nswapmap" }, |
4242be26 | 74 | #define SPTY 13 |
676bc34a | 75 | { "_pt_tty" }, |
4242be26 | 76 | #define SDMMIN 14 |
e79dc02e | 77 | { "_dmmin" }, |
4242be26 | 78 | #define SDMMAX 15 |
e79dc02e | 79 | { "_dmmax" }, |
4242be26 | 80 | #define SNSWDEV 16 |
e79dc02e | 81 | { "_nswdev" }, |
4242be26 | 82 | #define SSWDEVT 17 |
b94a50ef | 83 | { "_swdevt" }, |
4242be26 SL |
84 | #define SYSMAP 18 |
85 | { "_Sysmap" }, | |
86 | #define SNPTY 19 | |
87 | { "_npty" }, | |
88 | #ifdef vax | |
89 | #define SDZ (SNPTY+1) | |
90 | { "_dz_tty" }, | |
91 | #define SNDZ (SNPTY+2) | |
92 | { "_dz_cnt" }, | |
93 | #define SDMF (SNPTY+3) | |
890571d1 | 94 | { "_dmf_tty" }, |
4242be26 | 95 | #define SNDMF (SNPTY+4) |
890571d1 | 96 | { "_ndmf" }, |
4242be26 SL |
97 | #define SDH (SNPTY+5) |
98 | { "_dh11" }, | |
99 | #define SNDH (SNPTY+6) | |
100 | { "_ndh11" }, | |
101 | #define SDHU (SNPTY+7) | |
5cf6fff2 | 102 | { "_dhu_tty" }, |
4242be26 | 103 | #define SNDHU (SNPTY+8) |
5cf6fff2 | 104 | { "_ndhu" }, |
4242be26 | 105 | #define SDMZ (SNPTY+9) |
35d0530f | 106 | { "_dmz_tty" }, |
4242be26 | 107 | #define SNDMZ (SNPTY+10) |
35d0530f | 108 | { "_ndmz" }, |
bac975ad MT |
109 | #define SQD (SNPTY+11) |
110 | { "_qd_tty" }, | |
111 | #define SNQD (SNPTY+12) | |
112 | { "_nNQD" }, | |
4242be26 SL |
113 | #endif |
114 | #ifdef tahoe | |
115 | #define SVX (SNPTY+1) | |
116 | { "_vx_tty" }, | |
117 | #define SNVX (SNPTY+2) | |
118 | { "_nvx" }, | |
119 | #endif | |
b94a50ef | 120 | { "" } |
ceb84881 BJ |
121 | }; |
122 | ||
123 | int inof; | |
124 | int txtf; | |
125 | int prcf; | |
126 | int ttyf; | |
127 | int usrf; | |
128 | long ubase; | |
129 | int filf; | |
130 | int swpf; | |
131 | int totflg; | |
132 | char partab[1]; | |
133 | struct cdevsw cdevsw[1]; | |
134 | struct bdevsw bdevsw[1]; | |
135 | int allflg; | |
136 | int kflg; | |
137 | struct pte *Usrptma; | |
138 | struct pte *usrpt; | |
dc2a22f1 | 139 | u_long getword(); |
9ed2dfb9 | 140 | off_t mkphys(); |
ceb84881 BJ |
141 | |
142 | main(argc, argv) | |
0dc27808 KB |
143 | int argc; |
144 | char **argv; | |
ceb84881 | 145 | { |
0dc27808 KB |
146 | extern char *optarg; |
147 | extern int optind; | |
148 | int ch; | |
ceb84881 | 149 | |
0dc27808 KB |
150 | while ((ch = getopt(argc, argv, "Tafikptu:sx")) != EOF) |
151 | switch((char)ch) { | |
ceb84881 BJ |
152 | case 'T': |
153 | totflg++; | |
154 | break; | |
ceb84881 BJ |
155 | case 'a': |
156 | allflg++; | |
0dc27808 KB |
157 | /*FALLTHROUGH*/ |
158 | case 'p': | |
159 | prcf++; | |
160 | break; | |
161 | case 'f': | |
162 | filf++; | |
ceb84881 | 163 | break; |
ceb84881 BJ |
164 | case 'i': |
165 | inof++; | |
166 | break; | |
0dc27808 | 167 | case 'k': /* undocumented */ |
ceb84881 | 168 | kflg++; |
aadf0902 | 169 | fcore = fmem = "/vmcore"; |
ceb84881 | 170 | break; |
ceb84881 BJ |
171 | case 't': |
172 | ttyf++; | |
173 | break; | |
ceb84881 | 174 | case 'u': |
ceb84881 | 175 | usrf++; |
0dc27808 | 176 | sscanf(optarg, "%x", &ubase); |
ceb84881 BJ |
177 | break; |
178 | case 's': | |
179 | swpf++; | |
180 | break; | |
0dc27808 KB |
181 | case 'x': |
182 | txtf++; | |
183 | break; | |
184 | case '?': | |
ae1f9014 | 185 | default: |
0dc27808 | 186 | printf("usage: pstat -[Tafiptsx] [-u [ubase]] [system] [core]\n"); |
ae1f9014 | 187 | exit(1); |
ceb84881 | 188 | } |
0dc27808 KB |
189 | argc -= optind; |
190 | argv += optind; | |
191 | ||
9ed2dfb9 | 192 | if (argc>1) { |
aadf0902 | 193 | fcore = fmem = argv[1]; |
9ed2dfb9 MK |
194 | kflg++; |
195 | } | |
0dc27808 KB |
196 | if ((fc = open(fcore, O_RDONLY, 0)) < 0) { |
197 | perror(fcore); | |
ceb84881 BJ |
198 | exit(1); |
199 | } | |
0dc27808 KB |
200 | if ((fm = open(fmem, O_RDONLY, 0)) < 0) { |
201 | perror(fmem); | |
aadf0902 MK |
202 | exit(1); |
203 | } | |
ae1f9014 SL |
204 | if (argc>0) |
205 | fnlist = argv[0]; | |
ceb84881 | 206 | nlist(fnlist, nl); |
ceb84881 | 207 | if (nl[0].n_type == 0) { |
0dc27808 | 208 | printf("pstat: no namelist.\n"); |
ceb84881 BJ |
209 | exit(1); |
210 | } | |
0dc27808 KB |
211 | usrpt = (struct pte *)nl[USRPT].n_value; |
212 | Usrptma = (struct pte *)nl[USRPTMA].n_value; | |
213 | if (!(filf | totflg | inof | prcf | txtf | ttyf | usrf | swpf)) { | |
ae1f9014 SL |
214 | printf("pstat: one or more of -[aixptfsu] is required\n"); |
215 | exit(1); | |
216 | } | |
ceb84881 | 217 | if (filf||totflg) |
69d3d166 | 218 | dofile(); |
ceb84881 BJ |
219 | if (inof||totflg) |
220 | doinode(); | |
221 | if (prcf||totflg) | |
222 | doproc(); | |
223 | if (txtf||totflg) | |
224 | dotext(); | |
225 | if (ttyf) | |
226 | dotty(); | |
227 | if (usrf) | |
228 | dousr(); | |
229 | if (swpf||totflg) | |
230 | doswap(); | |
231 | } | |
232 | ||
233 | doinode() | |
234 | { | |
235 | register struct inode *ip; | |
69d3d166 BJ |
236 | struct inode *xinode, *ainode; |
237 | register int nin; | |
238 | int ninode; | |
ceb84881 BJ |
239 | |
240 | nin = 0; | |
dc2a22f1 | 241 | ninode = getword(nl[SNINODE].n_value); |
69d3d166 | 242 | xinode = (struct inode *)calloc(ninode, sizeof (struct inode)); |
dc2a22f1 | 243 | ainode = (struct inode *)getword(nl[SINODE].n_value); |
9ed2dfb9 MK |
244 | if (ninode < 0 || ninode > 10000) { |
245 | fprintf(stderr, "number of inodes is preposterous (%d)\n", | |
246 | ninode); | |
247 | return; | |
248 | } | |
249 | if (xinode == NULL) { | |
250 | fprintf(stderr, "can't allocate memory for inode table\n"); | |
251 | return; | |
252 | } | |
253 | lseek(fc, mkphys((off_t)ainode), 0); | |
69d3d166 BJ |
254 | read(fc, xinode, ninode * sizeof(struct inode)); |
255 | for (ip = xinode; ip < &xinode[ninode]; ip++) | |
ceb84881 BJ |
256 | if (ip->i_count) |
257 | nin++; | |
258 | if (totflg) { | |
69d3d166 | 259 | printf("%3d/%3d inodes\n", nin, ninode); |
ceb84881 BJ |
260 | return; |
261 | } | |
69d3d166 | 262 | printf("%d/%d active inodes\n", nin, ninode); |
ae1f9014 | 263 | printf(" LOC FLAGS CNT DEVICE RDC WRC INO MODE NLK UID SIZE/DEV\n"); |
69d3d166 | 264 | for (ip = xinode; ip < &xinode[ninode]; ip++) { |
ceb84881 BJ |
265 | if (ip->i_count == 0) |
266 | continue; | |
69d3d166 | 267 | printf("%8.1x ", ainode + (ip - xinode)); |
88a58f27 | 268 | putf(ip->i_flag&ILOCKED, 'L'); |
ceb84881 BJ |
269 | putf(ip->i_flag&IUPD, 'U'); |
270 | putf(ip->i_flag&IACC, 'A'); | |
271 | putf(ip->i_flag&IMOUNT, 'M'); | |
272 | putf(ip->i_flag&IWANT, 'W'); | |
273 | putf(ip->i_flag&ITEXT, 'T'); | |
ae1f9014 SL |
274 | putf(ip->i_flag&ICHG, 'C'); |
275 | putf(ip->i_flag&ISHLOCK, 'S'); | |
276 | putf(ip->i_flag&IEXLOCK, 'E'); | |
277 | putf(ip->i_flag&ILWAIT, 'Z'); | |
ceb84881 BJ |
278 | printf("%4d", ip->i_count&0377); |
279 | printf("%4d,%3d", major(ip->i_dev), minor(ip->i_dev)); | |
88a58f27 SL |
280 | printf("%4d", ip->i_shlockc&0377); |
281 | printf("%4d", ip->i_exlockc&0377); | |
ceb84881 BJ |
282 | printf("%6d", ip->i_number); |
283 | printf("%6x", ip->i_mode & 0xffff); | |
284 | printf("%4d", ip->i_nlink); | |
285 | printf("%4d", ip->i_uid); | |
286 | if ((ip->i_mode&IFMT)==IFBLK || (ip->i_mode&IFMT)==IFCHR) | |
a06cf6a1 | 287 | printf("%6d,%3d", major(ip->i_rdev), minor(ip->i_rdev)); |
ceb84881 BJ |
288 | else |
289 | printf("%10ld", ip->i_size); | |
290 | printf("\n"); | |
291 | } | |
69d3d166 BJ |
292 | free(xinode); |
293 | } | |
294 | ||
9ed2dfb9 | 295 | u_long |
dc2a22f1 | 296 | getword(loc) |
69d3d166 BJ |
297 | off_t loc; |
298 | { | |
9ed2dfb9 | 299 | u_long word; |
69d3d166 | 300 | |
cea9ae1e | 301 | if (kflg) |
4242be26 | 302 | loc = clear(loc); |
69d3d166 BJ |
303 | lseek(fc, loc, 0); |
304 | read(fc, &word, sizeof (word)); | |
305 | return (word); | |
ceb84881 BJ |
306 | } |
307 | ||
308 | putf(v, n) | |
309 | { | |
310 | if (v) | |
311 | printf("%c", n); | |
312 | else | |
69d3d166 | 313 | printf(" "); |
ceb84881 BJ |
314 | } |
315 | ||
316 | dotext() | |
317 | { | |
318 | register struct text *xp; | |
69d3d166 BJ |
319 | int ntext; |
320 | struct text *xtext, *atext; | |
9ed2dfb9 | 321 | int ntx, ntxca; |
ceb84881 | 322 | |
9ed2dfb9 | 323 | ntx = ntxca = 0; |
dc2a22f1 | 324 | ntext = getword(nl[SNTEXT].n_value); |
69d3d166 | 325 | xtext = (struct text *)calloc(ntext, sizeof (struct text)); |
dc2a22f1 | 326 | atext = (struct text *)getword(nl[STEXT].n_value); |
9ed2dfb9 MK |
327 | if (ntext < 0 || ntext > 10000) { |
328 | fprintf(stderr, "number of texts is preposterous (%d)\n", | |
329 | ntext); | |
330 | return; | |
331 | } | |
332 | if (xtext == NULL) { | |
333 | fprintf(stderr, "can't allocate memory for text table\n"); | |
334 | return; | |
335 | } | |
336 | lseek(fc, mkphys((off_t)atext), 0); | |
69d3d166 | 337 | read(fc, xtext, ntext * sizeof (struct text)); |
9ed2dfb9 MK |
338 | for (xp = xtext; xp < &xtext[ntext]; xp++) { |
339 | if (xp->x_iptr != NULL) | |
340 | ntxca++; | |
341 | if (xp->x_count != 0) | |
ceb84881 | 342 | ntx++; |
9ed2dfb9 | 343 | } |
ceb84881 | 344 | if (totflg) { |
9ed2dfb9 | 345 | printf("%3d/%3d texts active, %3d used\n", ntx, ntext, ntxca); |
ceb84881 BJ |
346 | return; |
347 | } | |
9ed2dfb9 MK |
348 | printf("%d/%d active texts, %d used\n", ntx, ntext, ntxca); |
349 | printf("\ | |
350 | LOC FLAGS DADDR CADDR RSS SIZE IPTR CNT CCNT FORW BACK\n"); | |
69d3d166 | 351 | for (xp = xtext; xp < &xtext[ntext]; xp++) { |
ceb84881 BJ |
352 | if (xp->x_iptr == NULL) |
353 | continue; | |
69d3d166 | 354 | printf("%8.1x", atext + (xp - xtext)); |
ceb84881 BJ |
355 | printf(" "); |
356 | putf(xp->x_flag&XPAGI, 'P'); | |
357 | putf(xp->x_flag&XTRC, 'T'); | |
358 | putf(xp->x_flag&XWRIT, 'W'); | |
359 | putf(xp->x_flag&XLOAD, 'L'); | |
360 | putf(xp->x_flag&XLOCK, 'K'); | |
361 | putf(xp->x_flag&XWANT, 'w'); | |
ceb84881 | 362 | printf("%5x", xp->x_daddr[0]); |
9ed2dfb9 | 363 | printf("%10x", xp->x_caddr); |
ceb84881 BJ |
364 | printf("%5d", xp->x_rssize); |
365 | printf("%5d", xp->x_size); | |
366 | printf("%10.1x", xp->x_iptr); | |
367 | printf("%5d", xp->x_count&0377); | |
54298f71 | 368 | printf("%5d", xp->x_ccount); |
9ed2dfb9 MK |
369 | printf("%10x", xp->x_forw); |
370 | printf("%9x", xp->x_back); | |
ceb84881 BJ |
371 | printf("\n"); |
372 | } | |
69d3d166 | 373 | free(xtext); |
ceb84881 BJ |
374 | } |
375 | ||
376 | doproc() | |
377 | { | |
69d3d166 BJ |
378 | struct proc *xproc, *aproc; |
379 | int nproc; | |
ceb84881 BJ |
380 | register struct proc *pp; |
381 | register loc, np; | |
382 | struct pte apte; | |
383 | ||
dc2a22f1 | 384 | nproc = getword(nl[SNPROC].n_value); |
69d3d166 | 385 | xproc = (struct proc *)calloc(nproc, sizeof (struct proc)); |
dc2a22f1 | 386 | aproc = (struct proc *)getword(nl[SPROC].n_value); |
9ed2dfb9 MK |
387 | if (nproc < 0 || nproc > 10000) { |
388 | fprintf(stderr, "number of procs is preposterous (%d)\n", | |
389 | nproc); | |
390 | return; | |
391 | } | |
392 | if (xproc == NULL) { | |
393 | fprintf(stderr, "can't allocate memory for proc table\n"); | |
394 | return; | |
395 | } | |
396 | lseek(fc, mkphys((off_t)aproc), 0); | |
69d3d166 | 397 | read(fc, xproc, nproc * sizeof (struct proc)); |
ceb84881 | 398 | np = 0; |
69d3d166 | 399 | for (pp=xproc; pp < &xproc[nproc]; pp++) |
ceb84881 BJ |
400 | if (pp->p_stat) |
401 | np++; | |
402 | if (totflg) { | |
69d3d166 | 403 | printf("%3d/%3d processes\n", np, nproc); |
ceb84881 BJ |
404 | return; |
405 | } | |
69d3d166 | 406 | printf("%d/%d processes\n", np, nproc); |
aadf0902 | 407 | printf(" LOC S F POIP PRI SIG UID SLP TIM CPU NI PGRP PID PPID ADDR RSS SRSS SIZE WCHAN LINK TEXTP\n"); |
69d3d166 | 408 | for (pp=xproc; pp<&xproc[nproc]; pp++) { |
ceb84881 BJ |
409 | if (pp->p_stat==0 && allflg==0) |
410 | continue; | |
69d3d166 | 411 | printf("%8x", aproc + (pp - xproc)); |
ceb84881 BJ |
412 | printf(" %2d", pp->p_stat); |
413 | printf(" %4x", pp->p_flag & 0xffff); | |
414 | printf(" %4d", pp->p_poip); | |
415 | printf(" %3d", pp->p_pri); | |
54298f71 | 416 | printf(" %8x", pp->p_sig); |
ceb84881 BJ |
417 | printf(" %4d", pp->p_uid); |
418 | printf(" %3d", pp->p_slptime); | |
419 | printf(" %3d", pp->p_time); | |
420 | printf(" %4d", pp->p_cpu&0377); | |
421 | printf(" %3d", pp->p_nice); | |
422 | printf(" %6d", pp->p_pgrp); | |
423 | printf(" %6d", pp->p_pid); | |
424 | printf(" %6d", pp->p_ppid); | |
425 | if (kflg) | |
426 | pp->p_addr = (struct pte *)clear((int)pp->p_addr); | |
aadf0902 MK |
427 | if (pp->p_flag & SLOAD) { |
428 | lseek(fc, (long)pp->p_addr, 0); | |
429 | read(fc, &apte, sizeof(apte)); | |
430 | printf(" %8x", apte.pg_pfnum); | |
431 | } else | |
432 | printf(" %8x", pp->p_swaddr); | |
ceb84881 BJ |
433 | printf(" %4x", pp->p_rssize); |
434 | printf(" %4x", pp->p_swrss); | |
435 | printf(" %5x", pp->p_dsize+pp->p_ssize); | |
436 | printf(" %7x", clear(pp->p_wchan)); | |
437 | printf(" %7x", clear(pp->p_link)); | |
438 | printf(" %7x", clear(pp->p_textp)); | |
ceb84881 BJ |
439 | printf("\n"); |
440 | } | |
9ed2dfb9 | 441 | free(xproc); |
ceb84881 BJ |
442 | } |
443 | ||
5cf6fff2 KM |
444 | static char mesg[] = |
445 | " # RAW CAN OUT MODE ADDR DEL COL STATE PGRP DISC\n"; | |
446 | static int ttyspace = 128; | |
447 | static struct tty *tty; | |
448 | ||
ceb84881 BJ |
449 | dotty() |
450 | { | |
5cf6fff2 | 451 | extern char *malloc(); |
ceb84881 | 452 | |
13562341 MK |
453 | if ((tty = (struct tty *)malloc(ttyspace * sizeof(*tty))) == 0) { |
454 | printf("pstat: out of memory\n"); | |
455 | return; | |
456 | } | |
ceb84881 | 457 | printf("1 cons\n"); |
835c8965 | 458 | if (kflg) |
4242be26 SL |
459 | nl[SCONS].n_value = clear(nl[SCONS].n_value); |
460 | lseek(fc, (long)nl[SCONS].n_value, 0); | |
13562341 | 461 | read(fc, tty, sizeof(*tty)); |
ceb84881 | 462 | printf(mesg); |
13562341 | 463 | ttyprt(&tty[0], 0); |
4242be26 | 464 | #ifdef vax |
bac975ad MT |
465 | if (nl[SNQD].n_type != 0) |
466 | doqdss(); | |
5cf6fff2 KM |
467 | if (nl[SNDZ].n_type != 0) |
468 | dottytype("dz", SDZ, SNDZ); | |
469 | if (nl[SNDH].n_type != 0) | |
470 | dottytype("dh", SDH, SNDH); | |
471 | if (nl[SNDMF].n_type != 0) | |
472 | dottytype("dmf", SDMF, SNDMF); | |
473 | if (nl[SNDHU].n_type != 0) | |
474 | dottytype("dhu", SDHU, SNDHU); | |
35d0530f JB |
475 | if (nl[SNDMZ].n_type != 0) |
476 | dottytype("dmz", SDMZ, SNDMZ); | |
4242be26 SL |
477 | #endif |
478 | #ifdef tahoe | |
479 | if (nl[SNVX].n_type != 0) | |
480 | dottytype("vx", SVX, SNVX); | |
481 | #endif | |
5cf6fff2 KM |
482 | if (nl[SNPTY].n_type != 0) |
483 | dottytype("pty", SPTY, SNPTY); | |
484 | } | |
485 | ||
bac975ad MT |
486 | /* |
487 | * Special case the qdss because there are 4 tty structs per qdss | |
488 | * and only the first of each is used as a tty. | |
489 | */ | |
490 | #ifdef vax | |
491 | doqdss() | |
492 | { | |
493 | int nqd; | |
494 | register struct tty *tp; | |
495 | ||
496 | if (kflg) { | |
497 | nl[SNQD].n_value = clear(nl[SNQD].n_value); | |
498 | nl[SQD].n_value = clear(nl[SQD].n_value); | |
499 | } | |
500 | lseek(fc, (long)nl[SNQD].n_value, 0); | |
501 | read(fc, &nqd, sizeof(nqd)); | |
502 | printf("%d qd\n", nqd); | |
503 | lseek(fc, (long)nl[SQD].n_value, 0); | |
504 | read(fc, tty, nqd * sizeof(struct tty) * 4); | |
505 | printf(mesg); | |
506 | for (tp = tty; tp < &tty[nqd * 4]; tp += 4) | |
507 | ttyprt(tp, tp - tty); | |
508 | } | |
509 | #endif | |
510 | ||
5cf6fff2 KM |
511 | dottytype(name, type, number) |
512 | char *name; | |
513 | { | |
514 | int ntty; | |
515 | register struct tty *tp; | |
516 | extern char *realloc(); | |
517 | ||
bac975ad | 518 | if (tty == (struct tty *)0) |
890571d1 | 519 | return; |
676bc34a | 520 | if (kflg) { |
5cf6fff2 KM |
521 | nl[number].n_value = clear(nl[number].n_value); |
522 | nl[type].n_value = clear(nl[type].n_value); | |
13562341 | 523 | } |
5cf6fff2 | 524 | lseek(fc, (long)nl[number].n_value, 0); |
13562341 | 525 | read(fc, &ntty, sizeof(ntty)); |
5cf6fff2 | 526 | printf("%d %s lines\n", ntty, name); |
13562341 MK |
527 | if (ntty > ttyspace) { |
528 | ttyspace = ntty; | |
529 | if ((tty = (struct tty *)realloc(tty, ttyspace * sizeof(*tty))) == 0) { | |
530 | printf("pstat: out of memory\n"); | |
531 | return; | |
532 | } | |
676bc34a | 533 | } |
5cf6fff2 KM |
534 | lseek(fc, (long)nl[type].n_value, 0); |
535 | read(fc, tty, ntty * sizeof(struct tty)); | |
8faa0fee | 536 | printf(mesg); |
13562341 MK |
537 | for (tp = tty; tp < &tty[ntty]; tp++) |
538 | ttyprt(tp, tp - tty); | |
ceb84881 BJ |
539 | } |
540 | ||
541 | ttyprt(atp, line) | |
542 | struct tty *atp; | |
543 | { | |
544 | register struct tty *tp; | |
545 | ||
546 | printf("%2d", line); | |
547 | tp = atp; | |
548 | switch (tp->t_line) { | |
549 | ||
4242be26 | 550 | #ifdef notdef |
ceb84881 BJ |
551 | case NETLDISC: |
552 | if (tp->t_rec) | |
553 | printf("%4d%4d", 0, tp->t_inbuf); | |
554 | else | |
555 | printf("%4d%4d", tp->t_inbuf, 0); | |
556 | break; | |
4242be26 | 557 | #endif |
ceb84881 BJ |
558 | |
559 | default: | |
8faa0fee | 560 | printf("%4d%4d", tp->t_rawq.c_cc, tp->t_canq.c_cc); |
ceb84881 | 561 | } |
8faa0fee EW |
562 | printf("%4d %8x %8x%4d%4d", tp->t_outq.c_cc, tp->t_flags, |
563 | tp->t_addr, tp->t_delct, tp->t_col); | |
676bc34a BJ |
564 | putf(tp->t_state&TS_TIMEOUT, 'T'); |
565 | putf(tp->t_state&TS_WOPEN, 'W'); | |
566 | putf(tp->t_state&TS_ISOPEN, 'O'); | |
8faa0fee | 567 | putf(tp->t_state&TS_FLUSH, 'F'); |
676bc34a BJ |
568 | putf(tp->t_state&TS_CARR_ON, 'C'); |
569 | putf(tp->t_state&TS_BUSY, 'B'); | |
570 | putf(tp->t_state&TS_ASLEEP, 'A'); | |
571 | putf(tp->t_state&TS_XCLUDE, 'X'); | |
8faa0fee | 572 | putf(tp->t_state&TS_TTSTOP, 'S'); |
676bc34a | 573 | putf(tp->t_state&TS_HUPCLS, 'H'); |
ceb84881 BJ |
574 | printf("%6d", tp->t_pgrp); |
575 | switch (tp->t_line) { | |
576 | ||
8faa0fee EW |
577 | case OTTYDISC: |
578 | printf("\n"); | |
579 | break; | |
580 | ||
ceb84881 | 581 | case NTTYDISC: |
8faa0fee | 582 | printf(" ntty\n"); |
ceb84881 BJ |
583 | break; |
584 | ||
585 | case NETLDISC: | |
1d994a88 | 586 | printf(" berknet\n"); |
ceb84881 | 587 | break; |
8faa0fee EW |
588 | |
589 | case TABLDISC: | |
590 | printf(" tab\n"); | |
591 | break; | |
592 | ||
399e4254 KB |
593 | case SLIPDISC: |
594 | printf(" slip\n"); | |
595 | break; | |
596 | ||
8faa0fee EW |
597 | default: |
598 | printf(" %d\n", tp->t_line); | |
ceb84881 | 599 | } |
ceb84881 BJ |
600 | } |
601 | ||
602 | dousr() | |
603 | { | |
604 | struct user U; | |
605 | register i, j, *ip; | |
a5bcb7fd | 606 | register struct nameidata *nd = &U.u_nd; |
ceb84881 | 607 | |
aadf0902 MK |
608 | /* This wins only if CLBYTES >= sizeof (struct user) */ |
609 | lseek(fm, ubase * NBPG, 0); | |
610 | read(fm, &U, sizeof(U)); | |
ceb84881 BJ |
611 | printf("pcb"); |
612 | ip = (int *)&U.u_pcb; | |
613 | while (ip < &U.u_arg[0]) { | |
614 | if ((ip - (int *)&U.u_pcb) % 4 == 0) | |
615 | printf("\t"); | |
616 | printf("%x ", *ip++); | |
617 | if ((ip - (int *)&U.u_pcb) % 4 == 0) | |
618 | printf("\n"); | |
619 | } | |
620 | if ((ip - (int *)&U.u_pcb) % 4 != 0) | |
621 | printf("\n"); | |
aadf0902 MK |
622 | printf("arg"); |
623 | for (i=0; i<sizeof(U.u_arg)/sizeof(U.u_arg[0]); i++) { | |
ceb84881 BJ |
624 | if (i%5==0) |
625 | printf("\t"); | |
aadf0902 | 626 | printf(" %.1x", U.u_arg[i]); |
ceb84881 BJ |
627 | if (i%5==4) |
628 | printf("\n"); | |
629 | } | |
630 | if (i%5) | |
631 | printf("\n"); | |
a5bcb7fd | 632 | printf("segflg\t%d\nerror %d\n", nd->ni_segflg, U.u_error); |
ceb84881 BJ |
633 | printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid); |
634 | printf("procp\t%.1x\n", U.u_procp); | |
635 | printf("ap\t%.1x\n", U.u_ap); | |
636 | printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2); | |
a5bcb7fd JB |
637 | printf("base, count, offset %.1x %.1x %ld\n", nd->ni_base, |
638 | nd->ni_count, nd->ni_offset); | |
ceb84881 | 639 | printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir); |
a5bcb7fd JB |
640 | printf("dirp %.1x\n", nd->ni_dirp); |
641 | printf("dent %d %.14s\n", nd->ni_dent.d_ino, nd->ni_dent.d_name); | |
642 | printf("pdir %.1o\n", nd->ni_pdir); | |
aadf0902 MK |
643 | printf("file"); |
644 | for (i=0; i<NOFILE; i++) { | |
645 | if (i % 8 == 0) | |
646 | printf("\t"); | |
ceb84881 | 647 | printf("%9.1x", U.u_ofile[i]); |
aadf0902 MK |
648 | if (i % 8 == 7) |
649 | printf("\n"); | |
650 | } | |
651 | if (i % 8) | |
652 | printf("\n"); | |
653 | printf("pofile"); | |
654 | for (i=0; i<NOFILE; i++) { | |
655 | if (i % 8 == 0) | |
656 | printf("\t"); | |
ceb84881 | 657 | printf("%9.1x", U.u_pofile[i]); |
aadf0902 MK |
658 | if (i % 8 == 7) |
659 | printf("\n"); | |
660 | } | |
661 | if (i % 8) | |
662 | printf("\n"); | |
88a58f27 | 663 | printf("ssave"); |
ceb84881 BJ |
664 | for (i=0; i<sizeof(label_t)/sizeof(int); i++) { |
665 | if (i%5==0) | |
666 | printf("\t"); | |
88a58f27 | 667 | printf("%9.1x", U.u_ssave.val[i]); |
ceb84881 BJ |
668 | if (i%5==4) |
669 | printf("\n"); | |
670 | } | |
671 | if (i%5) | |
672 | printf("\n"); | |
aadf0902 MK |
673 | printf("sigs"); |
674 | for (i=0; i<NSIG; i++) { | |
675 | if (i % 8 == 0) | |
676 | printf("\t"); | |
ceb84881 | 677 | printf("%.1x ", U.u_signal[i]); |
aadf0902 MK |
678 | if (i % 8 == 7) |
679 | printf("\n"); | |
680 | } | |
681 | if (i % 8) | |
682 | printf("\n"); | |
df3e00cc | 683 | printf("code\t%.1x\n", U.u_code); |
ceb84881 | 684 | printf("ar0\t%.1x\n", U.u_ar0); |
b9e98a4b | 685 | printf("prof\t%x %x %x %x\n", U.u_prof.pr_base, U.u_prof.pr_size, |
ceb84881 BJ |
686 | U.u_prof.pr_off, U.u_prof.pr_scale); |
687 | printf("\neosys\t%d\n", U.u_eosys); | |
ceb84881 BJ |
688 | printf("ttyp\t%.1x\n", U.u_ttyp); |
689 | printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd)); | |
ceb84881 | 690 | printf("comm %.14s\n", U.u_comm); |
b9e98a4b KB |
691 | printf("start\t%ld\n", U.u_start.tv_sec); |
692 | printf("acflag\t%ld\n", U.u_acflag); | |
693 | printf("cmask\t%ld\n", U.u_cmask); | |
ceb84881 | 694 | printf("sizes\t%.1x %.1x %.1x\n", U.u_tsize, U.u_dsize, U.u_ssize); |
88a58f27 SL |
695 | printf("ru\t"); |
696 | ip = (int *)&U.u_ru; | |
697 | for (i = 0; i < sizeof(U.u_ru)/sizeof(int); i++) | |
b9e98a4b | 698 | printf("%ld ", ip[i]); |
ceb84881 | 699 | printf("\n"); |
88a58f27 SL |
700 | ip = (int *)&U.u_cru; |
701 | printf("cru\t"); | |
702 | for (i = 0; i < sizeof(U.u_cru)/sizeof(int); i++) | |
b9e98a4b | 703 | printf("%ld ", ip[i]); |
ceb84881 | 704 | printf("\n"); |
4242be26 | 705 | #ifdef notdef |
ceb84881 BJ |
706 | i = U.u_stack - &U; |
707 | while (U[++i] == 0); | |
708 | i &= ~07; | |
709 | while (i < 512) { | |
710 | printf("%x ", 0140000+2*i); | |
711 | for (j=0; j<8; j++) | |
712 | printf("%9x", U[i++]); | |
713 | printf("\n"); | |
714 | } | |
4242be26 | 715 | #endif |
ceb84881 BJ |
716 | } |
717 | ||
718 | oatoi(s) | |
719 | char *s; | |
720 | { | |
721 | register v; | |
722 | ||
723 | v = 0; | |
724 | while (*s) | |
725 | v = (v<<3) + *s++ - '0'; | |
726 | return(v); | |
727 | } | |
728 | ||
69d3d166 | 729 | dofile() |
ceb84881 | 730 | { |
69d3d166 BJ |
731 | int nfile; |
732 | struct file *xfile, *afile; | |
ceb84881 BJ |
733 | register struct file *fp; |
734 | register nf; | |
735 | int loc; | |
71c73ab0 | 736 | static char *dtypes[] = { "???", "inode", "socket" }; |
ceb84881 BJ |
737 | |
738 | nf = 0; | |
dc2a22f1 | 739 | nfile = getword(nl[SNFILE].n_value); |
69d3d166 | 740 | xfile = (struct file *)calloc(nfile, sizeof (struct file)); |
dc2a22f1 | 741 | afile = (struct file *)getword(nl[SFIL].n_value); |
9ed2dfb9 MK |
742 | if (nfile < 0 || nfile > 10000) { |
743 | fprintf(stderr, "number of files is preposterous (%d)\n", | |
744 | nfile); | |
745 | return; | |
746 | } | |
747 | if (xfile == NULL) { | |
748 | fprintf(stderr, "can't allocate memory for file table\n"); | |
749 | return; | |
750 | } | |
751 | lseek(fc, mkphys((off_t)afile), 0); | |
69d3d166 BJ |
752 | read(fc, xfile, nfile * sizeof (struct file)); |
753 | for (fp=xfile; fp < &xfile[nfile]; fp++) | |
ceb84881 BJ |
754 | if (fp->f_count) |
755 | nf++; | |
756 | if (totflg) { | |
69d3d166 | 757 | printf("%3d/%3d files\n", nf, nfile); |
ceb84881 BJ |
758 | return; |
759 | } | |
69d3d166 | 760 | printf("%d/%d open files\n", nf, nfile); |
192c0cf3 | 761 | printf(" LOC TYPE FLG CNT MSG DATA OFFSET\n"); |
fd2ae9b6 | 762 | for (fp=xfile,loc=(int)afile; fp < &xfile[nfile]; fp++,loc+=sizeof(xfile[0])) { |
ceb84881 BJ |
763 | if (fp->f_count==0) |
764 | continue; | |
765 | printf("%8x ", loc); | |
71c73ab0 | 766 | if (fp->f_type <= DTYPE_SOCKET) |
ae1f9014 SL |
767 | printf("%-8.8s", dtypes[fp->f_type]); |
768 | else | |
ff8002b1 | 769 | printf("%8d", fp->f_type); |
ceb84881 BJ |
770 | putf(fp->f_flag&FREAD, 'R'); |
771 | putf(fp->f_flag&FWRITE, 'W'); | |
ae1f9014 | 772 | putf(fp->f_flag&FAPPEND, 'A'); |
192c0cf3 SL |
773 | putf(fp->f_flag&FSHLOCK, 'S'); |
774 | putf(fp->f_flag&FEXLOCK, 'X'); | |
775 | putf(fp->f_flag&FASYNC, 'I'); | |
71c73ab0 SL |
776 | printf(" %3d", mask(fp->f_count)); |
777 | printf(" %3d", mask(fp->f_msgcount)); | |
778 | printf(" %8.1x", fp->f_data); | |
779 | if (fp->f_offset < 0) | |
780 | printf(" %x\n", fp->f_offset); | |
676bc34a BJ |
781 | else |
782 | printf(" %ld\n", fp->f_offset); | |
ceb84881 | 783 | } |
9ed2dfb9 | 784 | free(xfile); |
ceb84881 BJ |
785 | } |
786 | ||
e79dc02e SL |
787 | int dmmin, dmmax, nswdev; |
788 | ||
ceb84881 BJ |
789 | doswap() |
790 | { | |
69d3d166 BJ |
791 | struct proc *proc; |
792 | int nproc; | |
793 | struct text *xtext; | |
794 | int ntext; | |
795 | struct map *swapmap; | |
796 | int nswapmap; | |
b94a50ef | 797 | struct swdevt *swdevt, *sw; |
ceb84881 | 798 | register struct proc *pp; |
e79dc02e SL |
799 | int nswap, used, tused, free, waste; |
800 | int db, sb; | |
df3e00cc | 801 | register struct mapent *me; |
ceb84881 | 802 | register struct text *xp; |
e79dc02e | 803 | int i, j; |
f85d329a | 804 | long rmalloc(); |
ceb84881 | 805 | |
dc2a22f1 KM |
806 | nproc = getword(nl[SNPROC].n_value); |
807 | ntext = getword(nl[SNTEXT].n_value); | |
9ed2dfb9 MK |
808 | if (nproc < 0 || nproc > 10000 || ntext < 0 || ntext > 10000) { |
809 | fprintf(stderr, "number of procs/texts is preposterous (%d, %d)\n", | |
810 | nproc, ntext); | |
811 | return; | |
812 | } | |
813 | proc = (struct proc *)calloc(nproc, sizeof (struct proc)); | |
814 | if (proc == NULL) { | |
815 | fprintf(stderr, "can't allocate memory for proc table\n"); | |
816 | exit(1); | |
817 | } | |
b94a50ef | 818 | xtext = (struct text *)calloc(ntext, sizeof (struct text)); |
9ed2dfb9 MK |
819 | if (xtext == NULL) { |
820 | fprintf(stderr, "can't allocate memory for text table\n"); | |
821 | exit(1); | |
822 | } | |
dc2a22f1 | 823 | nswapmap = getword(nl[SNSWAPMAP].n_value); |
69d3d166 | 824 | swapmap = (struct map *)calloc(nswapmap, sizeof (struct map)); |
9ed2dfb9 MK |
825 | if (swapmap == NULL) { |
826 | fprintf(stderr, "can't allocate memory for swapmap\n"); | |
827 | exit(1); | |
828 | } | |
dc2a22f1 | 829 | nswdev = getword(nl[SNSWDEV].n_value); |
b94a50ef | 830 | swdevt = (struct swdevt *)calloc(nswdev, sizeof (struct swdevt)); |
9ed2dfb9 MK |
831 | if (swdevt == NULL) { |
832 | fprintf(stderr, "can't allocate memory for swdevt table\n"); | |
833 | exit(1); | |
834 | } | |
835 | lseek(fc, mkphys((off_t)nl[SSWDEVT].n_value), L_SET); | |
b94a50ef | 836 | read(fc, swdevt, nswdev * sizeof (struct swdevt)); |
dc2a22f1 | 837 | lseek(fc, mkphys((off_t)getword(nl[SPROC].n_value)), 0); |
b94a50ef | 838 | read(fc, proc, nproc * sizeof (struct proc)); |
dc2a22f1 | 839 | lseek(fc, mkphys((off_t)getword(nl[STEXT].n_value)), 0); |
b94a50ef | 840 | read(fc, xtext, ntext * sizeof (struct text)); |
dc2a22f1 | 841 | lseek(fc, mkphys((off_t)getword(nl[SWAPMAP].n_value)), 0); |
69d3d166 | 842 | read(fc, swapmap, nswapmap * sizeof (struct map)); |
33b2e9da | 843 | swapmap->m_name = "swap"; |
e49b41bc | 844 | swapmap->m_limit = (struct mapent *)&swapmap[nswapmap]; |
dc2a22f1 KM |
845 | dmmin = getword(nl[SDMMIN].n_value); |
846 | dmmax = getword(nl[SDMMAX].n_value); | |
b94a50ef SL |
847 | nswap = 0; |
848 | for (sw = swdevt; sw < &swdevt[nswdev]; sw++) | |
491de191 KM |
849 | if (sw->sw_freed) |
850 | nswap += sw->sw_nblks; | |
ceb84881 | 851 | free = 0; |
df3e00cc BJ |
852 | for (me = (struct mapent *)(swapmap+1); |
853 | me < (struct mapent *)&swapmap[nswapmap]; me++) | |
854 | free += me->m_size; | |
ceb84881 | 855 | tused = 0; |
69d3d166 | 856 | for (xp = xtext; xp < &xtext[ntext]; xp++) |
b94a50ef | 857 | if (xp->x_iptr!=NULL) { |
79877ea5 | 858 | tused += ctod(clrnd(xp->x_size)); |
b94a50ef | 859 | if (xp->x_flag & XPAGI) |
79877ea5 | 860 | tused += ctod(clrnd(ctopt(xp->x_size))); |
b94a50ef | 861 | } |
ceb84881 | 862 | used = tused; |
e79dc02e | 863 | waste = 0; |
69d3d166 | 864 | for (pp = proc; pp < &proc[nproc]; pp++) { |
ceb84881 BJ |
865 | if (pp->p_stat == 0 || pp->p_stat == SZOMB) |
866 | continue; | |
867 | if (pp->p_flag & SSYS) | |
868 | continue; | |
b94a50ef SL |
869 | db = ctod(pp->p_dsize), sb = up(db); |
870 | used += sb; | |
871 | waste += sb - db; | |
872 | db = ctod(pp->p_ssize), sb = up(db); | |
873 | used += sb; | |
874 | waste += sb - db; | |
ceb84881 | 875 | if ((pp->p_flag&SLOAD) == 0) |
13562341 | 876 | used += ctod(vusize(pp)); |
ceb84881 | 877 | } |
ceb84881 | 878 | if (totflg) { |
b94a50ef SL |
879 | #define btok(x) ((x) / (1024 / DEV_BSIZE)) |
880 | printf("%3d/%3d 00k swap\n", | |
881 | btok(used/100), btok((used+free)/100)); | |
ceb84881 BJ |
882 | return; |
883 | } | |
b94a50ef SL |
884 | printf("%dk used (%dk text), %dk free, %dk wasted, %dk missing\n", |
885 | btok(used), btok(tused), btok(free), btok(waste), | |
886 | /* a dmmax/2 block goes to argmap */ | |
887 | btok(nswap - dmmax/2 - (used + free))); | |
e79dc02e SL |
888 | printf("avail: "); |
889 | for (i = dmmax; i >= dmmin; i /= 2) { | |
890 | j = 0; | |
891 | while (rmalloc(swapmap, i) != 0) | |
892 | j++; | |
b94a50ef | 893 | if (j) printf("%d*%dk ", j, btok(i)); |
e79dc02e | 894 | } |
b94a50ef SL |
895 | free = 0; |
896 | for (me = (struct mapent *)(swapmap+1); | |
897 | me < (struct mapent *)&swapmap[nswapmap]; me++) | |
898 | free += me->m_size; | |
899 | printf("%d*1k\n", btok(free)); | |
ceb84881 BJ |
900 | } |
901 | ||
902 | up(size) | |
903 | register int size; | |
904 | { | |
905 | register int i, block; | |
906 | ||
907 | i = 0; | |
e79dc02e | 908 | block = dmmin; |
ceb84881 BJ |
909 | while (i < size) { |
910 | i += block; | |
e79dc02e | 911 | if (block < dmmax) |
ceb84881 BJ |
912 | block *= 2; |
913 | } | |
914 | return (i); | |
915 | } | |
916 | ||
b94a50ef SL |
917 | /* |
918 | * Compute number of pages to be allocated to the u. area | |
919 | * and data and stack area page tables, which are stored on the | |
920 | * disk immediately after the u. area. | |
921 | */ | |
ceb84881 | 922 | vusize(p) |
b94a50ef | 923 | register struct proc *p; |
ceb84881 BJ |
924 | { |
925 | register int tsz = p->p_tsize / NPTEPG; | |
926 | ||
b94a50ef SL |
927 | /* |
928 | * We do not need page table space on the disk for page | |
929 | * table pages wholly containing text. | |
930 | */ | |
931 | return (clrnd(UPAGES + | |
932 | clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz)); | |
e79dc02e SL |
933 | } |
934 | ||
935 | /* | |
936 | * Allocate 'size' units from the given | |
937 | * map. Return the base of the allocated space. | |
938 | * In a map, the addresses are increasing and the | |
939 | * list is terminated by a 0 size. | |
940 | * | |
941 | * Algorithm is first-fit. | |
942 | * | |
943 | * This routine knows about the interleaving of the swapmap | |
944 | * and handles that. | |
945 | */ | |
946 | long | |
947 | rmalloc(mp, size) | |
948 | register struct map *mp; | |
949 | long size; | |
950 | { | |
951 | register struct mapent *ep = (struct mapent *)(mp+1); | |
952 | register int addr; | |
953 | register struct mapent *bp; | |
954 | swblk_t first, rest; | |
955 | ||
956 | if (size <= 0 || size > dmmax) | |
957 | return (0); | |
958 | /* | |
959 | * Search for a piece of the resource map which has enough | |
960 | * free space to accomodate the request. | |
961 | */ | |
962 | for (bp = ep; bp->m_size; bp++) { | |
963 | if (bp->m_size >= size) { | |
964 | /* | |
965 | * If allocating from swapmap, | |
966 | * then have to respect interleaving | |
967 | * boundaries. | |
968 | */ | |
969 | if (nswdev > 1 && | |
970 | (first = dmmax - bp->m_addr%dmmax) < bp->m_size) { | |
971 | if (bp->m_size - first < size) | |
972 | continue; | |
973 | addr = bp->m_addr + first; | |
974 | rest = bp->m_size - first - size; | |
975 | bp->m_size = first; | |
976 | if (rest) | |
977 | rmfree(mp, rest, addr+size); | |
978 | return (addr); | |
979 | } | |
980 | /* | |
981 | * Allocate from the map. | |
982 | * If there is no space left of the piece | |
983 | * we allocated from, move the rest of | |
984 | * the pieces to the left. | |
985 | */ | |
986 | addr = bp->m_addr; | |
987 | bp->m_addr += size; | |
988 | if ((bp->m_size -= size) == 0) { | |
989 | do { | |
990 | bp++; | |
991 | (bp-1)->m_addr = bp->m_addr; | |
992 | } while ((bp-1)->m_size = bp->m_size); | |
993 | } | |
994 | if (addr % CLSIZE) | |
995 | return (0); | |
996 | return (addr); | |
997 | } | |
998 | } | |
999 | return (0); | |
1000 | } | |
1001 | ||
1002 | /* | |
1003 | * Free the previously allocated space at addr | |
1004 | * of size units into the specified map. | |
1005 | * Sort addr into map and combine on | |
1006 | * one or both ends if possible. | |
1007 | */ | |
1008 | rmfree(mp, size, addr) | |
1009 | struct map *mp; | |
1010 | long size, addr; | |
1011 | { | |
1012 | struct mapent *firstbp; | |
1013 | register struct mapent *bp; | |
1014 | register int t; | |
1015 | ||
1016 | /* | |
1017 | * Both address and size must be | |
1018 | * positive, or the protocol has broken down. | |
1019 | */ | |
1020 | if (addr <= 0 || size <= 0) | |
1021 | goto badrmfree; | |
1022 | /* | |
1023 | * Locate the piece of the map which starts after the | |
1024 | * returned space (or the end of the map). | |
1025 | */ | |
1026 | firstbp = bp = (struct mapent *)(mp + 1); | |
1027 | for (; bp->m_addr <= addr && bp->m_size != 0; bp++) | |
1028 | continue; | |
1029 | /* | |
1030 | * If the piece on the left abuts us, | |
1031 | * then we should combine with it. | |
1032 | */ | |
1033 | if (bp > firstbp && (bp-1)->m_addr+(bp-1)->m_size >= addr) { | |
1034 | /* | |
1035 | * Check no overlap (internal error). | |
1036 | */ | |
1037 | if ((bp-1)->m_addr+(bp-1)->m_size > addr) | |
1038 | goto badrmfree; | |
1039 | /* | |
1040 | * Add into piece on the left by increasing its size. | |
1041 | */ | |
1042 | (bp-1)->m_size += size; | |
1043 | /* | |
1044 | * If the combined piece abuts the piece on | |
1045 | * the right now, compress it in also, | |
1046 | * by shifting the remaining pieces of the map over. | |
1047 | */ | |
1048 | if (bp->m_addr && addr+size >= bp->m_addr) { | |
1049 | if (addr+size > bp->m_addr) | |
1050 | goto badrmfree; | |
1051 | (bp-1)->m_size += bp->m_size; | |
1052 | while (bp->m_size) { | |
1053 | bp++; | |
1054 | (bp-1)->m_addr = bp->m_addr; | |
1055 | (bp-1)->m_size = bp->m_size; | |
1056 | } | |
1057 | } | |
1058 | goto done; | |
1059 | } | |
1060 | /* | |
1061 | * Don't abut on the left, check for abutting on | |
1062 | * the right. | |
1063 | */ | |
1064 | if (addr+size >= bp->m_addr && bp->m_size) { | |
1065 | if (addr+size > bp->m_addr) | |
1066 | goto badrmfree; | |
1067 | bp->m_addr -= size; | |
1068 | bp->m_size += size; | |
1069 | goto done; | |
1070 | } | |
1071 | /* | |
1072 | * Don't abut at all. Make a new entry | |
1073 | * and check for map overflow. | |
1074 | */ | |
1075 | do { | |
1076 | t = bp->m_addr; | |
1077 | bp->m_addr = addr; | |
1078 | addr = t; | |
1079 | t = bp->m_size; | |
1080 | bp->m_size = size; | |
1081 | bp++; | |
1082 | } while (size = t); | |
1083 | /* | |
1084 | * Segment at bp is to be the delimiter; | |
1085 | * If there is not room for it | |
1086 | * then the table is too full | |
1087 | * and we must discard something. | |
1088 | */ | |
1089 | if (bp+1 > mp->m_limit) { | |
1090 | /* | |
1091 | * Back bp up to last available segment. | |
1092 | * which contains a segment already and must | |
1093 | * be made into the delimiter. | |
1094 | * Discard second to last entry, | |
1095 | * since it is presumably smaller than the last | |
1096 | * and move the last entry back one. | |
1097 | */ | |
1098 | bp--; | |
1099 | printf("%s: rmap ovflo, lost [%d,%d)\n", mp->m_name, | |
1100 | (bp-1)->m_addr, (bp-1)->m_addr+(bp-1)->m_size); | |
1101 | bp[-1] = bp[0]; | |
1102 | bp[0].m_size = bp[0].m_addr = 0; | |
1103 | } | |
1104 | done: | |
1105 | return; | |
1106 | badrmfree: | |
1107 | printf("bad rmfree\n"); | |
ceb84881 | 1108 | } |
76ea98af KM |
1109 | /* |
1110 | * "addr" is a kern virt addr and does not correspond | |
1111 | * To a phys addr after zipping out the high bit.. | |
1112 | * since it was valloc'd in the kernel. | |
1113 | * | |
1114 | * We return the phys addr by simulating kernel vm (/dev/kmem) | |
1115 | * when we are reading a crash dump. | |
1116 | */ | |
9ed2dfb9 | 1117 | off_t |
76ea98af | 1118 | mkphys(addr) |
9ed2dfb9 | 1119 | off_t addr; |
76ea98af | 1120 | { |
9ed2dfb9 | 1121 | register off_t o; |
76ea98af KM |
1122 | |
1123 | if (!kflg) | |
1124 | return(addr); | |
f20270fc | 1125 | addr = clear(addr); |
76ea98af KM |
1126 | o = addr & PGOFSET; |
1127 | addr >>= PGSHIFT; | |
1128 | addr &= PG_PFNUM; | |
1129 | addr *= NBPW; | |
dc2a22f1 | 1130 | addr = getword(nl[SYSMAP].n_value + addr); |
76ea98af KM |
1131 | addr = ((addr & PG_PFNUM) << PGSHIFT) | o; |
1132 | return(addr); | |
1133 | } |