|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1989 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: * @(#)kern_acct.c 7.12 (Berkeley) 6/28/90 ! 7: */ ! 8: ! 9: #include "param.h" ! 10: #include "systm.h" ! 11: #include "time.h" ! 12: #include "proc.h" ! 13: #include "ioctl.h" ! 14: #include "termios.h" ! 15: #include "tty.h" ! 16: #include "user.h" ! 17: #include "vnode.h" ! 18: #include "mount.h" ! 19: #include "kernel.h" ! 20: #include "acct.h" ! 21: #include "uio.h" ! 22: #include "syslog.h" ! 23: ! 24: /* ! 25: * Values associated with enabling and disabling accounting ! 26: */ ! 27: int acctsuspend = 2; /* stop accounting when < 2% free space left */ ! 28: int acctresume = 4; /* resume when free space risen to > 4% */ ! 29: struct timeval chk = { 15, 0 };/* frequency to check space for accounting */ ! 30: ! 31: /* ! 32: * SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY. ! 33: */ ! 34: struct vnode *acctp; ! 35: struct vnode *savacctp; ! 36: ! 37: /* ! 38: * Perform process accounting functions. ! 39: */ ! 40: /* ARGSUSED */ ! 41: sysacct(p, uap, retval) ! 42: struct proc *p; ! 43: struct args { ! 44: char *fname; ! 45: } *uap; ! 46: int *retval; ! 47: { ! 48: register struct vnode *vp; ! 49: register struct nameidata *ndp = &u.u_nd; ! 50: extern int acctwatch(); ! 51: struct vnode *oacctp; ! 52: int error; ! 53: ! 54: if (error = suser(u.u_cred, &u.u_acflag)) ! 55: return (error); ! 56: if (savacctp) { ! 57: acctp = savacctp; ! 58: savacctp = NULL; ! 59: } ! 60: if (uap->fname==NULL) { ! 61: if (vp = acctp) { ! 62: acctp = NULL; ! 63: vrele(vp); ! 64: untimeout(acctwatch, (caddr_t)&chk); ! 65: } ! 66: return (0); ! 67: } ! 68: ndp->ni_nameiop = LOOKUP | FOLLOW; ! 69: ndp->ni_segflg = UIO_USERSPACE; ! 70: ndp->ni_dirp = uap->fname; ! 71: if (error = namei(ndp)) ! 72: return (error); ! 73: vp = ndp->ni_vp; ! 74: if (vp->v_type != VREG) { ! 75: vrele(vp); ! 76: return (EACCES); ! 77: } ! 78: if (vp->v_mount->mnt_flag & MNT_RDONLY) { ! 79: vrele(vp); ! 80: return (EROFS); ! 81: } ! 82: oacctp = acctp; ! 83: acctp = vp; ! 84: if (oacctp) ! 85: vrele(oacctp); ! 86: acctwatch(&chk); ! 87: return (0); ! 88: } ! 89: ! 90: /* ! 91: * Periodically check the file system to see if accounting ! 92: * should be turned on or off. ! 93: */ ! 94: acctwatch(resettime) ! 95: struct timeval *resettime; ! 96: { ! 97: struct statfs sb; ! 98: ! 99: if (savacctp) { ! 100: (void)VFS_STATFS(savacctp->v_mount, &sb); ! 101: if (sb.f_bavail > acctresume * sb.f_blocks / 100) { ! 102: acctp = savacctp; ! 103: savacctp = NULL; ! 104: log(LOG_NOTICE, "Accounting resumed\n"); ! 105: return; ! 106: } ! 107: } ! 108: if (acctp == NULL) ! 109: return; ! 110: (void)VFS_STATFS(acctp->v_mount, &sb); ! 111: if (sb.f_bavail <= acctsuspend * sb.f_blocks / 100) { ! 112: savacctp = acctp; ! 113: acctp = NULL; ! 114: log(LOG_NOTICE, "Accounting suspended\n"); ! 115: } ! 116: timeout(acctwatch, (caddr_t)resettime, hzto(resettime)); ! 117: } ! 118: ! 119: /* ! 120: * On exit, write a record on the accounting file. ! 121: */ ! 122: acct(p) ! 123: register struct proc *p; ! 124: { ! 125: register struct rusage *ru; ! 126: struct vnode *vp; ! 127: struct timeval t, ut, st; ! 128: int i, s; ! 129: struct acct acctbuf; ! 130: register struct acct *ap = &acctbuf; ! 131: ! 132: if ((vp = acctp) == NULL) ! 133: return (0); ! 134: bcopy(p->p_comm, ap->ac_comm, sizeof(ap->ac_comm)); ! 135: ru = &u.u_ru; ! 136: s = splclock(); ! 137: ut = p->p_utime; ! 138: st = p->p_stime; ! 139: t = time; ! 140: splx(s); ! 141: ap->ac_utime = compress(ut.tv_sec, ut.tv_usec); ! 142: ap->ac_stime = compress(st.tv_sec, st.tv_usec); ! 143: timevalsub(&t, &u.u_start); ! 144: ap->ac_etime = compress(t.tv_sec, t.tv_usec); ! 145: ap->ac_btime = u.u_start.tv_sec; ! 146: ap->ac_uid = p->p_ruid; ! 147: ap->ac_gid = p->p_rgid; ! 148: t = st; ! 149: timevaladd(&t, &ut); ! 150: if (i = t.tv_sec * hz + t.tv_usec / tick) ! 151: ap->ac_mem = (ru->ru_ixrss+ru->ru_idrss+ru->ru_isrss) / i; ! 152: else ! 153: ap->ac_mem = 0; ! 154: ap->ac_mem >>= CLSIZELOG2; ! 155: ap->ac_io = compress(ru->ru_inblock + ru->ru_oublock, (long)0); ! 156: if (p->p_flag&SCTTY && p->p_session->s_ttyp) ! 157: ap->ac_tty = p->p_session->s_ttyp->t_dev; ! 158: else ! 159: ap->ac_tty = NODEV; ! 160: ap->ac_flag = u.u_acflag; ! 161: return (vn_rdwr(UIO_WRITE, vp, (caddr_t)ap, sizeof (acctbuf), ! 162: (off_t)0, UIO_SYSSPACE, IO_UNIT|IO_APPEND, u.u_cred, (int *)0)); ! 163: } ! 164: ! 165: /* ! 166: * Produce a pseudo-floating point representation ! 167: * with 3 bits base-8 exponent, 13 bits fraction. ! 168: */ ! 169: compress(t, ut) ! 170: register long t; ! 171: long ut; ! 172: { ! 173: register exp = 0, round = 0; ! 174: ! 175: t = t * AHZ; /* compiler will convert only this format to a shift */ ! 176: if (ut) ! 177: t += ut / (1000000 / AHZ); ! 178: while (t >= 8192) { ! 179: exp++; ! 180: round = t&04; ! 181: t >>= 3; ! 182: } ! 183: if (round) { ! 184: t++; ! 185: if (t >= 8192) { ! 186: t >>= 3; ! 187: exp++; ! 188: } ! 189: } ! 190: return ((exp<<13) + t); ! 191: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.