have to protect acct_process from acctwatch closing the vnode
[unix-history] / usr / src / sys / kern / kern_acct.c
index f3bfa66..235c2e0 100644 (file)
@@ -1,10 +1,15 @@
 /*-
 /*-
- * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
- * All rights reserved.
+ * 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%
  *
  *
  * %sccs.include.proprietary.c%
  *
- *     @(#)kern_acct.c 7.27 (Berkeley) %G%
+ *     @(#)kern_acct.c 8.6 (Berkeley) %G%
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -46,13 +51,12 @@ struct      vnode *savacctp;
  * accounting has been suspended, and freespace rises above acctresume,
  * accounting is resumed.
  */
  * accounting has been suspended, and freespace rises above acctresume,
  * accounting is resumed.
  */
-/* ARGSUSED */
-struct sysacct_args {
+struct acct_args {
        char    *fname;
 };
        char    *fname;
 };
-sysacct(p, uap, retval)
+acct(p, uap, retval)
        struct proc *p;
        struct proc *p;
-       struct sysacct_args *uap;
+       struct acct_args *uap;
        int *retval;
 {
        register struct vnode *vp;
        int *retval;
 {
        register struct vnode *vp;
@@ -94,7 +98,9 @@ sysacct(p, uap, retval)
 
 /*
  * Periodically check the file system to see if accounting
 
 /*
  * 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.
  */
 /* ARGSUSED */
 void
  */
 /* ARGSUSED */
 void
@@ -104,6 +110,11 @@ acctwatch(a)
        struct statfs sb;
 
        if (savacctp) {
        struct statfs sb;
 
        if (savacctp) {
+               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;
                (void)VFS_STATFS(savacctp->v_mount, &sb, (struct proc *)0);
                if (sb.f_bavail > acctresume * sb.f_blocks / 100) {
                        acctp = savacctp;
@@ -113,6 +124,11 @@ acctwatch(a)
        } else {
                if (acctp == NULL)
                        return;
        } 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;
                (void)VFS_STATFS(acctp->v_mount, &sb, (struct proc *)0);
                if (sb.f_bavail <= acctsuspend * sb.f_blocks / 100) {
                        savacctp = acctp;
@@ -127,24 +143,31 @@ acctwatch(a)
  * This routine calculates an accounting record for a process and,
  * if accounting is enabled, writes it to 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;
        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;
 
        struct acct acctbuf;
        register struct acct *ap = &acctbuf;
 
-       if ((vp = acctp) == NULL)
+       s = splclock();
+       if ((vp = acctp) == NULL) {
+               splx(s);
                return (0);
                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 = &p->p_stats->p_ru;
        calcru(p, &ut, &st, NULL);
        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;
        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, &p->p_stats->p_start);
        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);
@@ -159,14 +182,17 @@ acct(p)
        else
                ap->ac_mem = 0;
        ap->ac_io = compress(ru->ru_inblock + ru->ru_oublock, (long)0);
        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 = p->p_acflag;
                ap->ac_tty = p->p_session->s_ttyp->t_dev;
        else
                ap->ac_tty = NODEV;
        ap->ac_flag = p->p_acflag;
-       return (vn_rdwr(UIO_WRITE, vp, (caddr_t)ap, sizeof (acctbuf), (off_t)0,
+       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,
                UIO_SYSSPACE, IO_UNIT|IO_APPEND, p->p_ucred, (int *)0,
-               (struct proc *)0));
+               (struct proc *)0);
+       splx(s);
+       return (error);
 }
 
 /*
 }
 
 /*