X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/deeb5f1cbad465e5b78af0d0d79706a54e69aed2..6b8f7051f2b8ef9bd16f7fb52d3226972bd3aa4f:/usr/src/sys/kern/kern_acct.c diff --git a/usr/src/sys/kern/kern_acct.c b/usr/src/sys/kern/kern_acct.c index ebe0305242..235c2e0b54 100644 --- a/usr/src/sys/kern/kern_acct.c +++ b/usr/src/sys/kern/kern_acct.c @@ -1,32 +1,38 @@ -/* - * Copyright (c) 1982, 1986, 1989 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. +/*- + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * %sccs.include.proprietary.c% * - * @(#)kern_acct.c 7.13 (Berkeley) %G% + * @(#)kern_acct.c 8.6 (Berkeley) %G% */ -#include "param.h" -#include "systm.h" -#include "time.h" -#include "proc.h" -#include "ioctl.h" -#include "termios.h" -#include "tty.h" -#include "user.h" -#include "vnode.h" -#include "mount.h" -#include "kernel.h" -#include "acct.h" -#include "uio.h" -#include "syslog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* * Values associated with enabling and disabling accounting */ int acctsuspend = 2; /* stop accounting when < 2% free space left */ int acctresume = 4; /* resume when free space risen to > 4% */ -struct timeval chk = { 15, 0 };/* frequency to check space for accounting */ +int acctchkfreq = 15; /* frequency (in seconds) to check space */ /* * SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY. @@ -35,130 +41,158 @@ struct vnode *acctp; struct vnode *savacctp; /* - * Perform process accounting functions. + * Enable or disable process accounting. + * + * If a non-null filename is given, that file is used to store accounting + * records on process exit. If a null filename is given process accounting + * is suspended. If accounting is enabled, the system checks the amount + * of freespace on the filesystem at timeval intervals. If the amount of + * freespace is below acctsuspend percent, accounting is suspended. If + * accounting has been suspended, and freespace rises above acctresume, + * accounting is resumed. */ -/* ARGSUSED */ -sysacct(p, uap, retval) +struct acct_args { + char *fname; +}; +acct(p, uap, retval) struct proc *p; - struct args { - char *fname; - } *uap; + struct acct_args *uap; int *retval; { register struct vnode *vp; - register struct nameidata *ndp = &u.u_nd; - extern int acctwatch(); + extern void acctwatch __P((void *)); struct vnode *oacctp; int error; + struct nameidata nd; - if (error = suser(u.u_cred, &u.u_acflag)) + if (error = suser(p->p_ucred, &p->p_acflag)) return (error); if (savacctp) { acctp = savacctp; savacctp = NULL; } - if (uap->fname==NULL) { + if (uap->fname == NULL) { if (vp = acctp) { acctp = NULL; - vrele(vp); - untimeout(acctwatch, (caddr_t)&chk); + error = vn_close(vp, FWRITE, p->p_ucred, p); + untimeout(acctwatch, NULL); } - return (0); + return (error); } - ndp->ni_nameiop = LOOKUP | FOLLOW; - ndp->ni_segflg = UIO_USERSPACE; - ndp->ni_dirp = uap->fname; - if (error = namei(ndp)) + NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); + if (error = vn_open(&nd, FWRITE, 0644)) return (error); - vp = ndp->ni_vp; + vp = nd.ni_vp; + VOP_UNLOCK(vp); if (vp->v_type != VREG) { - vrele(vp); + (void) vn_close(vp, FWRITE, p->p_ucred, p); return (EACCES); } - if (vp->v_mount->mnt_flag & MNT_RDONLY) { - vrele(vp); - return (EROFS); - } oacctp = acctp; acctp = vp; if (oacctp) - vrele(oacctp); - acctwatch(&chk); - return (0); + error = vn_close(oacctp, FWRITE, p->p_ucred, p); + acctwatch(NULL); + return (error); } /* * Periodically check the file system to see if accounting - * should be turned on or off. + * should be turned on or off. Beware the case where the vnode + * has been vgone()'d out from underneath us, e.g. when the file + * system containing the accounting file has been forcibly unmounted. */ -acctwatch(resettime) - struct timeval *resettime; +/* ARGSUSED */ +void +acctwatch(a) + void *a; { struct statfs sb; if (savacctp) { - (void)VFS_STATFS(savacctp->v_mount, &sb); + if (savacctp->v_type == VBAD) { + (void) vn_close(savacctp, FWRITE, NOCRED, NULL); + savacctp = NULL; + return; + } + (void)VFS_STATFS(savacctp->v_mount, &sb, (struct proc *)0); if (sb.f_bavail > acctresume * sb.f_blocks / 100) { acctp = savacctp; savacctp = NULL; log(LOG_NOTICE, "Accounting resumed\n"); + } + } else { + if (acctp == NULL) + return; + if (acctp->v_type == VBAD) { + (void) vn_close(acctp, FWRITE, NOCRED, NULL); + acctp = NULL; return; } + (void)VFS_STATFS(acctp->v_mount, &sb, (struct proc *)0); + if (sb.f_bavail <= acctsuspend * sb.f_blocks / 100) { + savacctp = acctp; + acctp = NULL; + log(LOG_NOTICE, "Accounting suspended\n"); + } } - if (acctp == NULL) - return; - (void)VFS_STATFS(acctp->v_mount, &sb); - if (sb.f_bavail <= acctsuspend * sb.f_blocks / 100) { - savacctp = acctp; - acctp = NULL; - log(LOG_NOTICE, "Accounting suspended\n"); - } - timeout(acctwatch, (caddr_t)resettime, hzto(resettime)); + timeout(acctwatch, NULL, acctchkfreq * hz); } /* - * On exit, write a record on the accounting file. + * This routine calculates an accounting record for a process and, + * if accounting is enabled, writes it to the accounting file. */ -acct(p) +acct_process(p) register struct proc *p; { register struct rusage *ru; struct vnode *vp; struct timeval t, ut, st; - int i, s; + int error, i, s; struct acct acctbuf; register struct acct *ap = &acctbuf; - if ((vp = acctp) == NULL) + s = splclock(); + if ((vp = acctp) == NULL) { + splx(s); return (0); + } + if (vp->v_type == VBAD) { + (void) vn_close(vp, FWRITE, NOCRED, NULL); + acctp = NULL; + splx(s); + return (0); + } bcopy(p->p_comm, ap->ac_comm, sizeof(ap->ac_comm)); - ru = &u.u_ru; - s = splclock(); - ut = p->p_utime; - st = p->p_stime; + ru = &p->p_stats->p_ru; + calcru(p, &ut, &st, NULL); t = time; - splx(s); ap->ac_utime = compress(ut.tv_sec, ut.tv_usec); ap->ac_stime = compress(st.tv_sec, st.tv_usec); - timevalsub(&t, &u.u_start); + timevalsub(&t, &p->p_stats->p_start); ap->ac_etime = compress(t.tv_sec, t.tv_usec); - ap->ac_btime = u.u_start.tv_sec; - ap->ac_uid = p->p_ruid; - ap->ac_gid = p->p_rgid; + ap->ac_btime = p->p_stats->p_start.tv_sec; + ap->ac_uid = p->p_cred->p_ruid; + ap->ac_gid = p->p_cred->p_rgid; t = st; timevaladd(&t, &ut); if (i = t.tv_sec * hz + t.tv_usec / tick) - ap->ac_mem = (ru->ru_ixrss+ru->ru_idrss+ru->ru_isrss) / i; + ap->ac_mem = (ru->ru_ixrss + ru->ru_idrss + ru->ru_isrss) / i; else ap->ac_mem = 0; ap->ac_io = compress(ru->ru_inblock + ru->ru_oublock, (long)0); - if (p->p_flag&SCTTY && p->p_session->s_ttyp) + if (p->p_flag & P_CONTROLT && p->p_session->s_ttyp) ap->ac_tty = p->p_session->s_ttyp->t_dev; else ap->ac_tty = NODEV; - ap->ac_flag = u.u_acflag; - return (vn_rdwr(UIO_WRITE, vp, (caddr_t)ap, sizeof (acctbuf), - (off_t)0, UIO_SYSSPACE, IO_UNIT|IO_APPEND, u.u_cred, (int *)0)); + ap->ac_flag = p->p_acflag; + VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); + error = vn_rdwr(UIO_WRITE, vp, (caddr_t)ap, sizeof (acctbuf), (off_t)0, + UIO_SYSSPACE, IO_UNIT|IO_APPEND, p->p_ucred, (int *)0, + (struct proc *)0); + splx(s); + return (error); } /*