merge in vnodes
[unix-history] / usr / src / sys / kern / kern_acct.c
index 0ed5b62..6145e7a 100644 (file)
 /*
 /*
- * 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 Regents of the University of California.
+ * All rights reserved.
  *
  *
- *     @(#)kern_acct.c 7.1 (Berkeley) %G%
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)kern_acct.c 7.5 (Berkeley) %G%
  */
 
 #include "param.h"
 #include "systm.h"
  */
 
 #include "param.h"
 #include "systm.h"
-#include "dir.h"
 #include "user.h"
 #include "user.h"
-#include "inode.h"
-#include "fs.h"
+#include "vnode.h"
+#include "mount.h"
 #include "kernel.h"
 #include "acct.h"
 #include "uio.h"
 #include "kernel.h"
 #include "acct.h"
 #include "uio.h"
+#include "syslog.h"
+
+/*
+ * 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 */
 
 /*
  * SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
  */
 
 /*
  * 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.
  */
 sysacct()
 {
 
 /*
  * Perform process accounting functions.
  */
 sysacct()
 {
-       register struct inode *ip;
+       register struct vnode *vp;
        register struct a {
                char    *fname;
        } *uap = (struct a *)u.u_ap;
        register struct nameidata *ndp = &u.u_nd;
        register struct a {
                char    *fname;
        } *uap = (struct a *)u.u_ap;
        register struct nameidata *ndp = &u.u_nd;
+       extern int acctwatch();
+       struct vnode *oacctp;
 
 
-       if (suser()) {
-               if (savacctp) {
-                       acctp = savacctp;
-                       savacctp = NULL;
-               }
-               if (uap->fname==NULL) {
-                       if (ip = acctp) {
-                               irele(ip);
-                               acctp = NULL;
-                       }
-                       return;
-               }
-               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;
+       if (u.u_error = suser(u.u_cred, &u.u_acflag))
+               return;
+       if (savacctp) {
+               acctp = savacctp;
+               savacctp = NULL;
+       }
+       if (uap->fname==NULL) {
+               if (vp = acctp) {
+                       acctp = NULL;
+                       vrele(vp);
+                       untimeout(acctwatch, (caddr_t)&chk);
                }
                }
-               if (acctp && (acctp->i_number != ip->i_number ||
-                   acctp->i_dev != ip->i_dev))
-                       irele(acctp);
-               acctp = ip;
-               iunlock(ip);
+               return;
+       }
+       ndp->ni_nameiop = LOOKUP | FOLLOW;
+       ndp->ni_segflg = UIO_USERSPACE;
+       ndp->ni_dirp = uap->fname;
+       if (u.u_error = namei(ndp))
+               return;
+       vp = ndp->ni_vp;
+       if (vp->v_type != VREG) {
+               u.u_error = EACCES;
+               vrele(vp);
+               return;
+       }
+       if (vp->v_mount->m_flag & M_RDONLY) {
+               u.u_error = EROFS;
+               vrele(vp);
+               return;
        }
        }
+       oacctp = acctp;
+       acctp = vp;
+       if (oacctp)
+               vrele(oacctp);
+       acctwatch(&chk);
 }
 
 }
 
-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()
+acctwatch(resettime)
+       struct timeval *resettime;
 {
 {
-       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) {
 
        if (savacctp) {
-               fs = savacctp->i_fs;
-               if (freespace(fs, fs->fs_minfree + acctresume) > 0) {
+               (void)VFS_STATFS(savacctp->v_mount, &sb);
+               if (sb.f_bavail > acctresume * sb.f_blocks / 100) {
                        acctp = savacctp;
                        savacctp = NULL;
                        acctp = savacctp;
                        savacctp = NULL;
-                       printf("Accounting resumed\n");
+                       log(LOG_NOTICE, "Accounting resumed\n");
+                       return;
                }
        }
                }
        }
-       if ((ip = acctp) == NULL)
+       if (acctp == NULL)
                return;
                return;
-       fs = acctp->i_fs;
-       if (freespace(fs, fs->fs_minfree + acctsuspend) <= 0) {
+       (void)VFS_STATFS(acctp->v_mount, &sb);
+       if (sb.f_bavail <= acctsuspend * sb.f_blocks / 100) {
                savacctp = acctp;
                acctp = NULL;
                savacctp = acctp;
                acctp = NULL;
-               printf("Accounting suspended\n");
-               return;
+               log(LOG_NOTICE, "Accounting suspended\n");
        }
        }
-       ilock(ip);
-       for (i = 0; i < sizeof (ap->ac_comm); i++)
-               ap->ac_comm[i] = u.u_comm[i];
+       timeout(acctwatch, (caddr_t)resettime, hzto(resettime));
+}
+
+/*
+ * On exit, write a record on the accounting file.
+ */
+acct()
+{
+       register struct rusage *ru;
+       struct vnode *vp;
+       struct timeval t;
+       int i;
+       struct acct acctbuf;
+       register struct acct *ap = &acctbuf;
+
+       if ((vp = acctp) == NULL)
+               return;
+       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);
        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);
@@ -128,14 +156,8 @@ acct()
        else
                ap->ac_tty = NODEV;
        ap->ac_flag = u.u_acflag;
        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);
+       u.u_error = vn_rdwr(UIO_WRITE, vp, (caddr_t)ap, sizeof (acctbuf),
+               (off_t)0, UIO_SYSSPACE, IO_UNIT|IO_APPEND, u.u_cred, (int *)0);
 }
 
 /*
 }
 
 /*