pstat.c (c9624363a804318301bc84e588423efbfb5c68a4) pstat.c (0cbfd1a52526521694bf833c9ac84fc3cdee000d)
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

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

42static char sccsid[] = "@(#)pstat.c 8.16 (Berkeley) 5/9/95";
43#endif
44static const char rcsid[] =
45 "$FreeBSD$";
46#endif /* not lint */
47
48#include <sys/param.h>
49#include <sys/time.h>
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

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

42static char sccsid[] = "@(#)pstat.c 8.16 (Berkeley) 5/9/95";
43#endif
44static const char rcsid[] =
45 "$FreeBSD$";
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>
50#define _KERNEL
51#include <sys/file.h>
54#include <ufs/ufs/quota.h>
55#include <ufs/ufs/inode.h>
56#include <sys/mount.h>
57#include <sys/uio.h>
52#include <sys/uio.h>
58#include <sys/namei.h>
59#include <fs/unionfs/union.h>
60#undef _KERNEL
61#include <sys/stat.h>
53#undef _KERNEL
54#include <sys/stat.h>
62#include <nfs/rpcv2.h>
63#include <nfs/nfsproto.h>
64#include <nfsclient/nfs.h>
65#include <nfsclient/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/blist.h>
71
72#include <sys/user.h>
73#include <sys/sysctl.h>

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

131static int totalflag;
132static int swapflag;
133static char *nlistf = NULL;
134static char *memf = NULL;
135static kvm_t *kd;
136
137static char *usagestr;
138
55#include <sys/ioctl.h>
56#include <sys/ioctl_compat.h> /* XXX NTTYDISC is too well hidden */
57#include <sys/tty.h>
58#include <sys/conf.h>
59#include <sys/blist.h>
60
61#include <sys/user.h>
62#include <sys/sysctl.h>

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

120static int totalflag;
121static int swapflag;
122static char *nlistf = NULL;
123static char *memf = NULL;
124static kvm_t *kd;
125
126static char *usagestr;
127
139static struct {
140 int m_flag;
141 const char *m_name;
142} mnt_flags[] = {
143 { MNT_RDONLY, "rdonly" },
144 { MNT_SYNCHRONOUS, "sync" },
145 { MNT_NOEXEC, "noexec" },
146 { MNT_NOSUID, "nosuid" },
147 { MNT_NODEV, "nodev" },
148 { MNT_UNION, "union" },
149 { MNT_ASYNC, "async" },
150 { MNT_SUIDDIR, "suiddir" },
151 { MNT_SOFTDEP, "softdep" },
152 { MNT_NOSYMFOLLOW, "nosymfollow" },
153 { MNT_NOATIME, "noatime" },
154 { MNT_NOCLUSTERR, "noclusterread" },
155 { MNT_NOCLUSTERW, "noclusterwrite" },
156 { MNT_EXRDONLY, "exrdonly" },
157 { MNT_EXPORTED, "exported" },
158 { MNT_DEFEXPORTED, "defexported" },
159 { MNT_EXPORTANON, "exportanon" },
160 { MNT_EXKERB, "exkerb" },
161 { MNT_EXPUBLIC, "public" },
162 { MNT_LOCAL, "local" },
163 { MNT_QUOTA, "quota" },
164 { MNT_ROOTFS, "rootfs" },
165 { MNT_USER, "user" },
166 { MNT_IGNORE, "ignore" },
167 { MNT_UPDATE, "update" },
168 { MNT_DELEXPORT, "delexport" },
169 { MNT_RELOAD, "reload" },
170 { MNT_FORCE, "force" },
171 { MNT_SNAPSHOT, "snapshot" },
172 { 0 }
173};
174
175
176#define SVAR(var) __STRING(var) /* to force expansion */
177#define KGET(idx, var) \
178 KGET1(idx, &var, sizeof(var), SVAR(var))
179#define KGET1(idx, p, s, msg) \
180 KGET2(nl[idx].n_value, p, s, msg)
181#define KGET2(addr, p, s, msg) \
182 if (kvm_read(kd, (u_long)(addr), p, s) != s) \
183 warnx("cannot read %s: %s", msg, kvm_geterr(kd))

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

190#define KGETRET(addr, p, s, msg) \
191 if (kvm_read(kd, (u_long)(addr), p, s) != s) { \
192 warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \
193 return (0); \
194 }
195
196static void filemode(void);
197static int getfiles(char **, int *);
128#define SVAR(var) __STRING(var) /* to force expansion */
129#define KGET(idx, var) \
130 KGET1(idx, &var, sizeof(var), SVAR(var))
131#define KGET1(idx, p, s, msg) \
132 KGET2(nl[idx].n_value, p, s, msg)
133#define KGET2(addr, p, s, msg) \
134 if (kvm_read(kd, (u_long)(addr), p, s) != s) \
135 warnx("cannot read %s: %s", msg, kvm_geterr(kd))

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

142#define KGETRET(addr, p, s, msg) \
143 if (kvm_read(kd, (u_long)(addr), p, s) != s) { \
144 warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \
145 return (0); \
146 }
147
148static void filemode(void);
149static int getfiles(char **, int *);
198static struct mount *getmnt(struct mount *);
199static struct e_vnode *kinfo_vnodes(int *);
200static struct e_vnode *loadvnodes(int *);
201static void mount_print(struct mount *);
202static void nfs_header(void);
203static int nfs_print(struct vnode *);
204static void swapmode(void);
205static void ttymode(void);
206static void ttyprt(struct tty *, int);
207static void ttytype(struct tty *, char *, int, int, int);
150static void swapmode(void);
151static void ttymode(void);
152static void ttyprt(struct tty *, int);
153static void ttytype(struct tty *, char *, int, int, int);
208static void ufs_header(void);
209static int ufs_print(struct vnode *);
210static void union_header(void);
211static int union_print(struct vnode *);
212static void usage(void);
154static void usage(void);
213static void vnode_header(void);
214static void vnode_print(struct vnode *, struct vnode *);
215static void vnodemode(void);
216
217int
218main(int argc, char *argv[])
219{
220 int ch, i, quit, ret;
155
156int
157main(int argc, char *argv[])
158{
159 int ch, i, quit, ret;
221 int fileflag, ttyflag, vnodeflag;
160 int fileflag, ttyflag;
222 char buf[_POSIX2_LINE_MAX],*opts;
223
161 char buf[_POSIX2_LINE_MAX],*opts;
162
224 fileflag = swapflag = ttyflag = vnodeflag = 0;
163 fileflag = swapflag = ttyflag = 0;
225
226 /* We will behave like good old swapinfo if thus invoked */
227 opts = strrchr(argv[0],'/');
228 if (opts)
229 opts++;
230 else
231 opts = argv[0];
232 if (!strcmp(opts,"swapinfo")) {
233 swapflag = 1;
234 opts = "kM:N:";
235 usagestr = "swapinfo [-k] [-M core] [-N system]";
236 } else {
164
165 /* We will behave like good old swapinfo if thus invoked */
166 opts = strrchr(argv[0],'/');
167 if (opts)
168 opts++;
169 else
170 opts = argv[0];
171 if (!strcmp(opts,"swapinfo")) {
172 swapflag = 1;
173 opts = "kM:N:";
174 usagestr = "swapinfo [-k] [-M core] [-N system]";
175 } else {
237 opts = "TM:N:fiknstv";
176 opts = "TM:N:fknst";
238 usagestr = "pstat [-Tfknstv] [-M core] [-N system]";
239 }
240
241 while ((ch = getopt(argc, argv, opts)) != -1)
242 switch (ch) {
243 case 'f':
244 fileflag = 1;
245 break;

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

259 ++swapflag;
260 break;
261 case 'T':
262 totalflag = 1;
263 break;
264 case 't':
265 ttyflag = 1;
266 break;
177 usagestr = "pstat [-Tfknstv] [-M core] [-N system]";
178 }
179
180 while ((ch = getopt(argc, argv, opts)) != -1)
181 switch (ch) {
182 case 'f':
183 fileflag = 1;
184 break;

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

198 ++swapflag;
199 break;
200 case 'T':
201 totalflag = 1;
202 break;
203 case 't':
204 ttyflag = 1;
205 break;
267 case 'v':
268 case 'i': /* Backward compatibility. */
269 errx(1, "vnode mode not supported");
270#if 0
271 vnodeflag = 1;
272 break;
273#endif
274 default:
275 usage();
276 }
277 argc -= optind;
278 argv += optind;
279
280 /*
281 * Discard setgid privileges if not the running kernel so that bad

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

293 for (i = NLMANDATORYBEG, quit = 0; i <= NLMANDATORYEND; i++)
294 if (!nl[i].n_value) {
295 quit = 1;
296 warnx("undefined symbol: %s", nl[i].n_name);
297 }
298 if (quit)
299 exit(1);
300 }
206 default:
207 usage();
208 }
209 argc -= optind;
210 argv += optind;
211
212 /*
213 * Discard setgid privileges if not the running kernel so that bad

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

225 for (i = NLMANDATORYBEG, quit = 0; i <= NLMANDATORYEND; i++)
226 if (!nl[i].n_value) {
227 quit = 1;
228 warnx("undefined symbol: %s", nl[i].n_name);
229 }
230 if (quit)
231 exit(1);
232 }
301 if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag))
233 if (!(fileflag | ttyflag | swapflag | totalflag))
302 usage();
303 if (fileflag || totalflag)
304 filemode();
234 usage();
235 if (fileflag || totalflag)
236 filemode();
305 if (vnodeflag)
306 vnodemode();
307 if (ttyflag)
308 ttymode();
309 if (swapflag || totalflag)
310 swapmode();
311 exit (0);
312}
313
314static void
315usage(void)
316{
317 fprintf(stderr, "usage: %s\n", usagestr);
318 exit (1);
319}
320
237 if (ttyflag)
238 ttymode();
239 if (swapflag || totalflag)
240 swapmode();
241 exit (0);
242}
243
244static void
245usage(void)
246{
247 fprintf(stderr, "usage: %s\n", usagestr);
248 exit (1);
249}
250
321struct e_vnode {
322 struct vnode *avnode;
323 struct vnode vnode;
324};
325
326static void
327vnodemode(void)
328{
329 struct e_vnode *e_vnodebase, *endvnode, *evp;
330 struct vnode *vp;
331 struct mount *maddr, *mp;
332 int numvnodes;
333
334 e_vnodebase = loadvnodes(&numvnodes);
335 if (totalflag) {
336 (void)printf("%7d vnodes\n", numvnodes);
337 return;
338 }
339 endvnode = e_vnodebase + numvnodes;
340 (void)printf("%d active vnodes\n", numvnodes);
341
342
343#define ST mp->mnt_stat
344 maddr = NULL;
345 for (evp = e_vnodebase; evp < endvnode; evp++) {
346 vp = &evp->vnode;
347 if (vp->v_mount != maddr) {
348 /*
349 * New filesystem
350 */
351 if ((mp = getmnt(vp->v_mount)) == NULL)
352 continue;
353 maddr = vp->v_mount;
354 mount_print(mp);
355 vnode_header();
356 if (!strcmp(ST.f_fstypename, "ufs"))
357 ufs_header();
358 else if (!strcmp(ST.f_fstypename, "nfs"))
359 nfs_header();
360 else if (!strcmp(ST.f_fstypename, "union"))
361 union_header();
362 (void)printf("\n");
363 }
364 vnode_print(evp->avnode, vp);
365 if (!strcmp(ST.f_fstypename, "ufs"))
366 ufs_print(vp);
367 else if (!strcmp(ST.f_fstypename, "nfs"))
368 nfs_print(vp);
369 else if (!strcmp(ST.f_fstypename, "union"))
370 union_print(vp);
371 (void)printf("\n");
372 }
373 free(e_vnodebase);
374}
375
376static void
377vnode_header(void)
378{
379 (void)printf("ADDR TYP VFLAG USE HOLD");
380}
381
382static void
383vnode_print(struct vnode *avnode, struct vnode *vp)
384{
385 char *type, flags[16];
386 char *fp = flags;
387 int flag;
388
389 /*
390 * set type
391 */
392 switch (vp->v_type) {
393 case VNON:
394 type = "non"; break;
395 case VREG:
396 type = "reg"; break;
397 case VDIR:
398 type = "dir"; break;
399 case VBLK:
400 type = "blk"; break;
401 case VCHR:
402 type = "chr"; break;
403 case VLNK:
404 type = "lnk"; break;
405 case VSOCK:
406 type = "soc"; break;
407 case VFIFO:
408 type = "fif"; break;
409 case VBAD:
410 type = "bad"; break;
411 default:
412 type = "unk"; break;
413 }
414 /*
415 * gather flags
416 */
417 flag = vp->v_flag;
418 if (flag & VROOT)
419 *fp++ = 'R';
420 if (flag & VTEXT)
421 *fp++ = 'T';
422 if (flag & VSYSTEM)
423 *fp++ = 'S';
424 if (flag & VISTTY)
425 *fp++ = 't';
426 if (flag & VXLOCK)
427 *fp++ = 'L';
428 if (flag & VXWANT)
429 *fp++ = 'W';
430 if (flag & VBWAIT)
431 *fp++ = 'B';
432 if (flag & VOBJBUF)
433 *fp++ = 'V';
434 if (flag & VCOPYONWRITE)
435 *fp++ = 'C';
436 if (flag & VAGE)
437 *fp++ = 'a';
438 if (flag & VOLOCK)
439 *fp++ = 'l';
440 if (flag & VOWANT)
441 *fp++ = 'w';
442 if (flag & VDOOMED)
443 *fp++ = 'D';
444 if (flag & VFREE)
445 *fp++ = 'F';
446 if (flag & VONWORKLST)
447 *fp++ = 'O';
448 if (flag & VMOUNT)
449 *fp++ = 'M';
450
451 if (flag == 0)
452 *fp++ = '-';
453 *fp = '\0';
454 (void)printf("%8lx %s %5s %4d %4d",
455 (u_long)(void *)avnode, type, flags, vp->v_usecount, vp->v_holdcnt);
456}
457
458static void
459ufs_header(void)
460{
461 (void)printf(" FILEID IFLAG RDEV|SZ");
462}
463
464static int
465ufs_print(struct vnode *vp)
466{
467 int flag;
468 struct inode inode, *ip = &inode;
469 char flagbuf[16], *flags = flagbuf;
470 char *name;
471 mode_t type;
472
473 KGETRET(VTOI(vp), &inode, sizeof(struct inode), "vnode's inode");
474 flag = ip->i_flag;
475 if (flag & IN_ACCESS)
476 *flags++ = 'A';
477 if (flag & IN_CHANGE)
478 *flags++ = 'C';
479 if (flag & IN_UPDATE)
480 *flags++ = 'U';
481 if (flag & IN_MODIFIED)
482 *flags++ = 'M';
483 if (flag & IN_RENAME)
484 *flags++ = 'R';
485 if (flag & IN_HASHED)
486 *flags++ = 'H';
487 if (flag & IN_LAZYMOD)
488 *flags++ = 'L';
489 if (flag == 0)
490 *flags++ = '-';
491 *flags = '\0';
492
493 (void)printf(" %6d %5s", ip->i_number, flagbuf);
494 type = ip->i_mode & S_IFMT;
495 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
496 if (usenumflag || ((name = devname(ip->i_rdev, type)) == NULL))
497 (void)printf(" %2d,%-2d",
498 major(ip->i_rdev), minor(ip->i_rdev));
499 else
500 (void)printf(" %7s", name);
501 else
502 (void)printf(" %7qd", ip->i_size);
503 return (0);
504}
505
506static void
507nfs_header(void)
508{
509 (void)printf(" FILEID NFLAG RDEV|SZ");
510}
511
512static int
513nfs_print(struct vnode *vp)
514{
515 struct nfsnode nfsnode, *np = &nfsnode;
516 char flagbuf[16], *flags = flagbuf;
517 int flag;
518 char *name;
519 mode_t type;
520
521 KGETRET(VTONFS(vp), &nfsnode, sizeof(nfsnode), "vnode's nfsnode");
522 flag = np->n_flag;
523 if (flag & NFLUSHWANT)
524 *flags++ = 'W';
525 if (flag & NFLUSHINPROG)
526 *flags++ = 'P';
527 if (flag & NMODIFIED)
528 *flags++ = 'M';
529 if (flag & NWRITEERR)
530 *flags++ = 'E';
531 if (flag & NACC)
532 *flags++ = 'A';
533 if (flag & NUPD)
534 *flags++ = 'U';
535 if (flag & NCHG)
536 *flags++ = 'C';
537 if (flag == 0)
538 *flags++ = '-';
539 *flags = '\0';
540
541#define VT np->n_vattr
542 (void)printf(" %6ld %5s", VT.va_fileid, flagbuf);
543 type = VT.va_mode & S_IFMT;
544 if (S_ISCHR(VT.va_mode) || S_ISBLK(VT.va_mode))
545 if (usenumflag || ((name = devname(VT.va_rdev, type)) == NULL))
546 (void)printf(" %2d,%-2d",
547 major(VT.va_rdev), minor(VT.va_rdev));
548 else
549 (void)printf(" %7s", name);
550 else
551 (void)printf(" %7qd", np->n_size);
552 return (0);
553}
554
555static void
556union_header(void)
557{
558 (void)printf(" UPPER LOWER");
559}
560
561static int
562union_print(struct vnode *vp)
563{
564 struct union_node unode, *up = &unode;
565
566 KGETRET(VTOUNION(vp), &unode, sizeof(unode), "vnode's unode");
567
568 (void)printf(" %8lx %8lx", (u_long)(void *)up->un_uppervp,
569 (u_long)(void *)up->un_lowervp);
570 return (0);
571}
572
573/*
574 * Given a pointer to a mount structure in kernel space,
575 * read it in and return a usable pointer to it.
576 */
577static struct mount *
578getmnt(struct mount *maddr)
579{
580 static struct mtab {
581 struct mtab *next;
582 struct mount *maddr;
583 struct mount mount;
584 } *mhead = NULL;
585 struct mtab *mt;
586
587 for (mt = mhead; mt != NULL; mt = mt->next)
588 if (maddr == mt->maddr)
589 return (&mt->mount);
590 if ((mt = malloc(sizeof(struct mtab))) == NULL)
591 errx(1, "malloc");
592 KGETRET(maddr, &mt->mount, sizeof(struct mount), "mount table");
593 mt->maddr = maddr;
594 mt->next = mhead;
595 mhead = mt;
596 return (&mt->mount);
597}
598
599static void
600mount_print(struct mount *mp)
601{
602 int flags;
603
604#define ST mp->mnt_stat
605 (void)printf("*** MOUNT %s %s on %s", ST.f_fstypename,
606 ST.f_mntfromname, ST.f_mntonname);
607 if ((flags = mp->mnt_flag)) {
608 int i;
609 const char *sep = " (";
610
611 for (i = 0; mnt_flags[i].m_flag; i++) {
612 if (flags & mnt_flags[i].m_flag) {
613 (void)printf("%s%s", sep, mnt_flags[i].m_name);
614 flags &= ~mnt_flags[i].m_flag;
615 sep = ",";
616 }
617 }
618 if (flags)
619 (void)printf("%sunknown_flags:%x", sep, flags);
620 (void)printf(")");
621 }
622 (void)printf("\n");
623#undef ST
624}
625
626static struct e_vnode *
627loadvnodes(int *avnodes)
628{
629 int mib[2];
630 size_t copysize;
631 struct e_vnode *vnodebase;
632
633 if (memf != NULL) {
634 /*
635 * do it by hand
636 */
637 return (kinfo_vnodes(avnodes));
638 }
639 mib[0] = CTL_KERN;
640 mib[1] = KERN_VNODE;
641 if (sysctl(mib, 2, NULL, &copysize, NULL, 0) == -1)
642 err(1, "sysctl: KERN_VNODE");
643 if ((vnodebase = malloc(copysize)) == NULL)
644 errx(1, "malloc");
645 if (sysctl(mib, 2, vnodebase, &copysize, NULL, 0) == -1)
646 err(1, "sysctl: KERN_VNODE");
647 if (copysize % sizeof(struct e_vnode))
648 errx(1, "vnode size mismatch");
649 *avnodes = copysize / sizeof(struct e_vnode);
650
651 return (vnodebase);
652}
653
654/*
655 * simulate what a running kernel does in in kinfo_vnode
656 */
657static struct e_vnode *
658kinfo_vnodes(int *avnodes)
659{
660 struct mntlist mountlist;
661 struct mount *mp, mount, *mp_next;
662 struct vnode *vp, vnode, *vp_next;
663 char *vbuf, *evbuf, *bp;
664 int num, numvnodes;
665
666#define VPTRSZ sizeof(struct vnode *)
667#define VNODESZ sizeof(struct vnode)
668
669 KGET(V_NUMV, numvnodes);
670 if ((vbuf = malloc((numvnodes + 20) * (VPTRSZ + VNODESZ))) == NULL)
671 errx(1, "malloc");
672 bp = vbuf;
673 evbuf = vbuf + (numvnodes + 20) * (VPTRSZ + VNODESZ);
674 KGET(V_MOUNTLIST, mountlist);
675 for (num = 0, mp = TAILQ_FIRST(&mountlist); ; mp = mp_next) {
676 KGET2(mp, &mount, sizeof(mount), "mount entry");
677 mp_next = TAILQ_NEXT(&mount, mnt_list);
678 for (vp = TAILQ_FIRST(&mount.mnt_nvnodelist);
679 vp != NULL; vp = vp_next) {
680 KGET2(vp, &vnode, sizeof(vnode), "vnode");
681 vp_next = TAILQ_NEXT(&vnode, v_nmntvnodes);
682 if ((bp + VPTRSZ + VNODESZ) > evbuf)
683 /* XXX - should realloc */
684 errx(1, "no more room for vnodes");
685 memmove(bp, &vp, VPTRSZ);
686 bp += VPTRSZ;
687 memmove(bp, &vnode, VNODESZ);
688 bp += VNODESZ;
689 num++;
690 }
691 if (mp == TAILQ_LAST(&mountlist, mntlist))
692 break;
693 }
694 *avnodes = num;
695 return ((struct e_vnode *)vbuf);
696}
697
698static const char hdr[] =
699" LINE RAW CAN OUT IHIWT ILOWT OHWT LWT COL STATE SESS PGID DISC\n";
700int ttyspace = 128;
701
702static void
703ttymode(void)
704{
705 struct tty *tty;

--- 318 unchanged lines hidden ---
251static const char hdr[] =
252" LINE RAW CAN OUT IHIWT ILOWT OHWT LWT COL STATE SESS PGID DISC\n";
253int ttyspace = 128;
254
255static void
256ttymode(void)
257{
258 struct tty *tty;

--- 318 unchanged lines hidden ---