X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/849cbd39568bf29e4eaab12b5974fdc2f038b78c..38a01dbeac9414d4cc0fa1a01ae498024a183078:/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 2994b17d5e..7be6272ddb 100644 --- a/usr/src/sys/kern/kern_acct.c +++ b/usr/src/sys/kern/kern_acct.c @@ -1,140 +1,172 @@ -/* - * Copyright (c) 1982, 1986 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 The Regents of the University of California. + * All rights reserved. + * + * %sccs.include.proprietary.c% * - * @(#)kern_acct.c 7.4 (Berkeley) %G% + * @(#)kern_acct.c 7.26 (Berkeley) %G% */ -#include "param.h" -#include "systm.h" -#include "dir.h" -#include "user.h" -#include "inode.h" -#include "fs.h" -#include "kernel.h" -#include "acct.h" -#include "uio.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% */ +int chk = 15; /* frequency (in seconds) to check space */ /* * SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY. */ -struct inode *acctp; -struct inode *savacctp; +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. */ -sysacct() +/* ARGSUSED */ +struct sysacct_args { + char *fname; +}; +sysacct(p, uap, retval) + struct proc *p; + struct sysacct_args *uap; + int *retval; { - register struct inode *ip; - register struct a { - char *fname; - } *uap = (struct a *)u.u_ap; - register struct nameidata *ndp = &u.u_nd; + register struct vnode *vp; + extern void acctwatch __P((void *)); + struct vnode *oacctp; + int error; + struct nameidata nd; - if (u.u_error = suser(u.u_cred, &u.u_acflag)) - return; + if (error = suser(p->p_ucred, &p->p_acflag)) + return (error); if (savacctp) { acctp = savacctp; savacctp = NULL; } - if (uap->fname==NULL) { - if (ip = acctp) { + if (uap->fname == NULL) { + if (vp = acctp) { acctp = NULL; - irele(ip); + error = vn_close(vp, FWRITE, p->p_ucred, p); + untimeout(acctwatch, NULL); } - return; + return (error); } - ndp->ni_nameiop = LOOKUP | FOLLOW; - ndp->ni_segflg = UIO_USERSPACE; - ndp->ni_dirp = uap->fname; - ip = namei(ndp); - if (ip == NULL) - return; - if ((ip->i_mode&IFMT) != IFREG) { - u.u_error = EACCES; - iput(ip); - return; - } - if (ip->i_fs->fs_ronly) { - u.u_error = EROFS; - iput(ip); - return; + NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); + if (error = vn_open(&nd, FWRITE, 0644)) + return (error); + vp = nd.ni_vp; + VOP_UNLOCK(vp); + if (vp->v_type != VREG) { + (void) vn_close(vp, FWRITE, p->p_ucred, p); + return (EACCES); } - if (acctp && (acctp->i_number != ip->i_number || - acctp->i_dev != ip->i_dev)) - irele(acctp); - acctp = ip; - iunlock(ip); + oacctp = acctp; + acctp = vp; + if (oacctp) + error = vn_close(oacctp, FWRITE, p->p_ucred, p); + acctwatch(NULL); + return (error); } -int acctsuspend = 2; /* stop accounting when < 2% free space left */ -int acctresume = 4; /* resume when free space risen to > 4% */ - -struct acct acctbuf; /* - * On exit, write a record on the accounting file. + * Periodically check the file system to see if accounting + * should be turned on or off. */ -acct() +/* ARGSUSED */ +void +acctwatch(a) + void *a; { - register int i; - register struct inode *ip; - register struct fs *fs; - register struct rusage *ru; - off_t siz; - struct timeval t; - register struct acct *ap = &acctbuf; + struct statfs sb; if (savacctp) { - fs = savacctp->i_fs; - if (freespace(fs, fs->fs_minfree + acctresume) > 0) { + (void)VFS_STATFS(savacctp->v_mount, &sb, (struct proc *)0); + if (sb.f_bavail > acctresume * sb.f_blocks / 100) { acctp = savacctp; savacctp = NULL; - printf("Accounting resumed\n"); + log(LOG_NOTICE, "Accounting resumed\n"); + return; } } - if ((ip = acctp) == NULL) + if (acctp == NULL) return; - fs = acctp->i_fs; - if (freespace(fs, fs->fs_minfree + acctsuspend) <= 0) { + (void)VFS_STATFS(acctp->v_mount, &sb, (struct proc *)0); + if (sb.f_bavail <= acctsuspend * sb.f_blocks / 100) { savacctp = acctp; acctp = NULL; - printf("Accounting suspended\n"); - return; + log(LOG_NOTICE, "Accounting suspended\n"); } - ilock(ip); - bcopy(u.u_comm, ap->ac_comm, sizeof(ap->ac_comm)); - ru = &u.u_ru; - ap->ac_utime = compress(ru->ru_utime.tv_sec, ru->ru_utime.tv_usec); - ap->ac_stime = compress(ru->ru_stime.tv_sec, ru->ru_stime.tv_usec); + timeout(acctwatch, NULL, chk * hz); +} + +/* + * This routine calculates an accounting record for a process and, + * if accounting is enabled, writes it to the accounting file. + */ +acct(p) + register struct proc *p; +{ + register struct rusage *ru; + struct vnode *vp; + struct timeval t, ut, st; + int i, s; + struct acct acctbuf; + register struct acct *ap = &acctbuf; + + if ((vp = acctp) == NULL) + return (0); + bcopy(p->p_comm, ap->ac_comm, sizeof(ap->ac_comm)); + ru = &p->p_stats->p_ru; + calcru(p, &ut, &st, NULL); + s = splclock(); t = time; - timevalsub(&t, &u.u_start); + splx(s); + ap->ac_utime = compress(ut.tv_sec, ut.tv_usec); + ap->ac_stime = compress(st.tv_sec, st.tv_usec); + 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 = u.u_ruid; - ap->ac_gid = u.u_rgid; - t = ru->ru_stime; - timevaladd(&t, &ru->ru_utime); + 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_mem >>= CLSIZELOG2; ap->ac_io = compress(ru->ru_inblock + ru->ru_oublock, (long)0); - if (u.u_ttyp) - ap->ac_tty = u.u_ttyd; + if (p->p_flag&SCTTY && 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; - siz = ip->i_size; - u.u_error = 0; /* XXX */ - u.u_error = - rdwri(UIO_WRITE, ip, (caddr_t)ap, sizeof (acctbuf), siz, - 1, (int *)0); - if (u.u_error) - itrunc(ip, (u_long)siz); - iunlock(ip); + ap->ac_flag = p->p_acflag; + return (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)); } /*