Change to includes. no more ../h
[unix-history] / usr / src / sys / kern / kern_acct.c
CommitLineData
94368568 1/* kern_acct.c 6.5 84/08/29 */
06138e31 2
94368568
JB
3#include "param.h"
4#include "systm.h"
5#include "dir.h"
6#include "user.h"
7#include "inode.h"
8#include "fs.h"
9#include "kernel.h"
10#include "acct.h"
11#include "uio.h"
06138e31
SL
12
13/*
14 * SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
15 */
16struct inode *acctp;
17struct inode *savacctp;
18
19/*
20 * Perform process accounting functions.
21 */
22sysacct()
23{
24 register struct inode *ip;
25 register struct a {
26 char *fname;
27 } *uap = (struct a *)u.u_ap;
715baff1 28 register struct nameidata *ndp = &u.u_nd;
06138e31
SL
29
30 if (suser()) {
31 if (savacctp) {
32 acctp = savacctp;
33 savacctp = NULL;
34 }
35 if (uap->fname==NULL) {
36 if (ip = acctp) {
37 irele(ip);
38 acctp = NULL;
39 }
40 return;
41 }
715baff1
KM
42 ndp->ni_nameiop = LOOKUP | FOLLOW;
43 ndp->ni_segflg = UIO_USERSPACE;
44 ndp->ni_dirp = uap->fname;
45 ip = namei(ndp);
06138e31
SL
46 if(ip == NULL)
47 return;
48 if((ip->i_mode & IFMT) != IFREG) {
49 u.u_error = EACCES;
50 iput(ip);
51 return;
52 }
53 if (acctp && (acctp->i_number != ip->i_number ||
54 acctp->i_dev != ip->i_dev))
55 irele(acctp);
56 acctp = ip;
57 iunlock(ip);
58 }
59}
60
61int acctsuspend = 2; /* stop accounting when < 2% free space left */
62int acctresume = 4; /* resume when free space risen to > 4% */
63
64struct acct acctbuf;
65/*
66 * On exit, write a record on the accounting file.
67 */
68acct()
69{
70 register int i;
71 register struct inode *ip;
72 register struct fs *fs;
032146e9 73 register struct rusage *ru;
06138e31 74 off_t siz;
032146e9 75 struct timeval t;
06138e31
SL
76 register struct acct *ap = &acctbuf;
77
78 if (savacctp) {
79 fs = savacctp->i_fs;
80 if (freespace(fs, fs->fs_minfree + acctresume) > 0) {
81 acctp = savacctp;
82 savacctp = NULL;
83 printf("Accounting resumed\n");
84 }
85 }
86 if ((ip = acctp) == NULL)
87 return;
88 fs = acctp->i_fs;
89 if (freespace(fs, fs->fs_minfree + acctsuspend) <= 0) {
90 savacctp = acctp;
91 acctp = NULL;
92 printf("Accounting suspended\n");
93 return;
94 }
95 ilock(ip);
96 for (i = 0; i < sizeof (ap->ac_comm); i++)
97 ap->ac_comm[i] = u.u_comm[i];
032146e9
SL
98 ru = &u.u_ru;
99 ap->ac_utime = compress(ru->ru_utime.tv_sec, ru->ru_utime.tv_usec);
100 ap->ac_stime = compress(ru->ru_stime.tv_sec, ru->ru_stime.tv_usec);
101 t = time;
102 timevalsub(&t, &u.u_start);
103 ap->ac_etime = compress(t.tv_sec, t.tv_usec);
104 ap->ac_btime = u.u_start.tv_sec;
06138e31
SL
105 ap->ac_uid = u.u_ruid;
106 ap->ac_gid = u.u_rgid;
032146e9
SL
107 t = ru->ru_stime;
108 timevaladd(&t, &ru->ru_utime);
350f5463 109 if (i = t.tv_sec * hz + t.tv_usec / tick)
032146e9
SL
110 ap->ac_mem = (ru->ru_ixrss+ru->ru_idrss+ru->ru_isrss) / i;
111 else
112 ap->ac_mem = 0;
113 ap->ac_mem >>= CLSIZELOG2;
114 ap->ac_io = compress(ru->ru_inblock + ru->ru_oublock, 0);
06138e31
SL
115 if (u.u_ttyp)
116 ap->ac_tty = u.u_ttyd;
117 else
118 ap->ac_tty = NODEV;
119 ap->ac_flag = u.u_acflag;
120 siz = ip->i_size;
121 u.u_error = 0; /* XXX */
122 u.u_error =
123 rdwri(UIO_WRITE, ip, (caddr_t)ap, sizeof (acctbuf), siz,
124 1, (int *)0);
125 if (u.u_error)
126 itrunc(ip, (u_long)siz);
127 iunlock(ip);
128}
129
130/*
131 * Produce a pseudo-floating point representation
132 * with 3 bits base-8 exponent, 13 bits fraction.
133 */
032146e9 134compress(t, ut)
06138e31 135 register long t;
032146e9 136 long ut;
06138e31
SL
137{
138 register exp = 0, round = 0;
139
032146e9
SL
140 t <<= 6;
141 if (ut)
142 t += ut / (1000000 / (1<<6));
06138e31
SL
143 while (t >= 8192) {
144 exp++;
145 round = t&04;
146 t >>= 3;
147 }
148 if (round) {
149 t++;
150 if (t >= 8192) {
151 t >>= 3;
152 exp++;
153 }
154 }
155 return ((exp<<13) + t);
156}