Hoist sysct and kvm calls, and pledge stdio, rpath, vminfo. Rob
Index: pstat.c =================================================================== RCS file: /cvs/src/usr.sbin/pstat/pstat.c,v retrieving revision 1.102 diff -u -p -r1.102 pstat.c --- pstat.c 12 Apr 2016 16:53:42 -0000 1.102 +++ pstat.c 12 Apr 2016 20:20:39 -0000 @@ -82,6 +82,8 @@ struct nlist vnodenl[] = { { NULL } }; +struct itty *globalitp; +struct kinfo_file *kf; struct nlist *globalnl; struct e_vnode { @@ -89,6 +91,10 @@ struct e_vnode { struct vnode vnode; }; +int numvnodes; +int maxfile; +int nfile; +int ntty; int usenumflag; int totalflag; int kflag; @@ -111,15 +117,17 @@ kvm_t *kd = NULL; } void filemode(void); +void filemodeprep(void); struct mount * getmnt(struct mount *); struct e_vnode * - kinfo_vnodes(int *); + kinfo_vnodes(void); void mount_print(struct mount *); void nfs_header(void); int nfs_print(struct vnode *); void swapmode(void); void ttymode(void); +void ttymodeprep(void); void ttyprt(struct itty *); void tty2itty(struct tty *tp, struct itty *itp); void ufs_header(void); @@ -130,6 +138,7 @@ void usage(void); void vnode_header(void); void vnode_print(struct vnode *, struct vnode *); void vnodemode(void); +void vnodemodeprep(void); int hideroot; @@ -202,6 +211,25 @@ main(int argc, char *argv[]) O_RDONLY | (need_nlist ? 0 : KVM_NO_FILES), buf)) == 0) errx(1, "kvm_openfiles: %s", buf); + if (need_nlist) + if (kvm_nlist(kd, vnodenl) == -1) + errx(1, "kvm_nlist: %s", kvm_geterr(kd)); + + if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag || dformat)) + usage(); + + if(!dformat) { + if (fileflag || totalflag) + filemodeprep(); + if (vnodeflag || totalflag) + vnodemodeprep(); + if (ttyflag) + ttymodeprep(); + } + + if (pledge("stdio rpath vminfo", NULL) == -1) + err(1, "pledge"); + if (dformat) { struct nlist *nl; int longformat = 0, stringformat = 0, error = 0, n; @@ -314,12 +342,6 @@ main(int argc, char *argv[]) exit(error); } - if (need_nlist) - if (kvm_nlist(kd, vnodenl) == -1) - errx(1, "kvm_nlist: %s", kvm_geterr(kd)); - - if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag || dformat)) - usage(); if (fileflag || totalflag) filemode(); if (vnodeflag || totalflag) @@ -337,11 +359,10 @@ vnodemode(void) struct e_vnode *e_vnodebase, *endvnode, *evp; struct vnode *vp; struct mount *maddr, *mp = NULL; - int numvnodes; globalnl = vnodenl; - e_vnodebase = kinfo_vnodes(&numvnodes); + e_vnodebase = kinfo_vnodes(); if (totalflag) { (void)printf("%7d vnodes\n", numvnodes); return; @@ -398,6 +419,21 @@ vnodemode(void) } void +vnodemodeprep(void) +{ + int mib[2]; + size_t num; + + if (kd == 0) { + mib[0] = CTL_KERN; + mib[1] = KERN_NUMVNODES; + num = sizeof(numvnodes); + if (sysctl(mib, 2, &numvnodes, &num, NULL, 0) < 0) + err(1, "sysctl(KERN_NUMVNODES) failed"); + } +} + +void vnode_header(void) { (void)printf("%*s TYP VFLAG USE HOLD", 2 * (int)sizeof(long), "ADDR"); @@ -790,24 +826,17 @@ mount_print(struct mount *mp) * simulate what a running kernel does in kinfo_vnode */ struct e_vnode * -kinfo_vnodes(int *avnodes) +kinfo_vnodes(void) { struct mntlist kvm_mountlist; struct mount *mp, mount; struct vnode *vp, vnode; char *vbuf, *evbuf, *bp; - int mib[2], numvnodes; + int mib[2]; size_t num; - if (kd == 0) { - mib[0] = CTL_KERN; - mib[1] = KERN_NUMVNODES; - num = sizeof(numvnodes); - if (sysctl(mib, 2, &numvnodes, &num, NULL, 0) < 0) - err(1, "sysctl(KERN_NUMVNODES) failed"); - } else + if (kd != 0) KGET(V_NUMV, numvnodes); - *avnodes = numvnodes; if (totalflag) return NULL; if ((vbuf = calloc(numvnodes + 20, @@ -835,7 +864,7 @@ kinfo_vnodes(int *avnodes) num++; } } - *avnodes = num; + numvnodes = num; return ((struct e_vnode *)vbuf); } @@ -864,32 +893,18 @@ ttymode(void) { struct ttylist_head tty_head; struct tty *tp, tty; - int mib[3], ntty, i; - struct itty itty, *itp; + int mib[3], i; + struct itty itty; size_t nlen; - if (kd == 0) { - mib[0] = CTL_KERN; - mib[1] = KERN_TTYCOUNT; - nlen = sizeof(ntty); - if (sysctl(mib, 2, &ntty, &nlen, NULL, 0) < 0) - err(1, "sysctl(KERN_TTYCOUNT) failed"); - } else + if (kd != 0) KGET(TTY_NTTY, ntty); (void)printf("%d terminal device%s\n", ntty, ntty == 1 ? "" : "s"); (void)printf("%s", hdr); if (kd == 0) { - mib[0] = CTL_KERN; - mib[1] = KERN_TTY; - mib[2] = KERN_TTY_INFO; - if ((itp = reallocarray(NULL, ntty, sizeof(struct itty))) == NULL) - err(1, "malloc"); - nlen = ntty * sizeof(struct itty); - if (sysctl(mib, 3, itp, &nlen, NULL, 0) < 0) - err(1, "sysctl(KERN_TTY_INFO) failed"); for (i = 0; i < ntty; i++) - ttyprt(&itp[i]); - free(itp); + ttyprt(&globalitp[i]); + free(globalitp); } else { KGET(TTY_TTYLIST, tty_head); for (tp = TAILQ_FIRST(&tty_head); tp; @@ -901,6 +916,30 @@ ttymode(void) } } +void +ttymodeprep(void) +{ + int mib[3]; + size_t nlen; + + if (kd == 0) { + mib[0] = CTL_KERN; + mib[1] = KERN_TTYCOUNT; + nlen = sizeof(ntty); + if (sysctl(mib, 2, &ntty, &nlen, NULL, 0) < 0) + err(1, "sysctl(KERN_TTYCOUNT) failed"); + + mib[0] = CTL_KERN; + mib[1] = KERN_TTY; + mib[2] = KERN_TTY_INFO; + if ((globalitp = reallocarray(NULL, ntty, sizeof(struct itty))) == NULL) + err(1, "malloc"); + nlen = ntty * sizeof(struct itty); + if (sysctl(mib, 3, globalitp, &nlen, NULL, 0) < 0) + err(1, "sysctl(KERN_TTY_INFO) failed"); + } +} + struct { int flag; char val; @@ -974,28 +1013,12 @@ ttyprt(struct itty *tp) void filemode(void) { - struct kinfo_file *kf; char flagbuf[16], *fbp; static char *dtypes[] = { "???", "inode", "socket", "pipe", "kqueue", "???", "systrace" }; - int mib[2], maxfile, nfile; - size_t len; globalnl = vnodenl; - if (nlistf == NULL && memf == NULL) { - mib[0] = CTL_KERN; - mib[1] = KERN_MAXFILES; - len = sizeof(maxfile); - if (sysctl(mib, 2, &maxfile, &len, NULL, 0) < 0) - err(1, "sysctl(KERN_MAXFILES) failed"); - if (totalflag) { - mib[0] = CTL_KERN; - mib[1] = KERN_NFILES; - len = sizeof(nfile); - if (sysctl(mib, 2, &nfile, &len, NULL, 0) < 0) - err(1, "sysctl(KERN_NFILES) failed"); - } - } else { + if (nlistf != NULL || memf != NULL) { KGET(FNL_MAXFILE, maxfile); if (totalflag) { KGET(FNL_NFILE, nfile); @@ -1004,14 +1027,6 @@ filemode(void) } } - if (!totalflag) { - kf = kvm_getfiles(kd, KERN_FILE_BYFILE, 0, sizeof *kf, &nfile); - if (kf == NULL) { - warnx("kvm_getfiles: %s", kvm_geterr(kd)); - return; - } - } - (void)printf("%d/%d open files\n", nfile, maxfile); if (totalflag) return; @@ -1054,6 +1069,36 @@ filemode(void) } else (void)printf(" %lld\n", hideroot ? 0LL : (long long)kf->f_offset); + } +} + +void +filemodeprep(void) +{ + int mib[2]; + size_t len; + + if (nlistf == NULL && memf == NULL) { + mib[0] = CTL_KERN; + mib[1] = KERN_MAXFILES; + len = sizeof(maxfile); + if (sysctl(mib, 2, &maxfile, &len, NULL, 0) < 0) + err(1, "sysctl(KERN_MAXFILES) failed"); + if (totalflag) { + mib[0] = CTL_KERN; + mib[1] = KERN_NFILES; + len = sizeof(nfile); + if (sysctl(mib, 2, &nfile, &len, NULL, 0) < 0) + err(1, "sysctl(KERN_NFILES) failed"); + } + } + + if (!totalflag) { + kf = kvm_getfiles(kd, KERN_FILE_BYFILE, 0, sizeof *kf, &nfile); + if (kf == NULL) { + warnx("kvm_getfiles: %s", kvm_geterr(kd)); + return; + } } }