xref: /csrg-svn/sys/kern/kern_resource.c (revision 7817)
1 /*	kern_resource.c	4.11	82/08/22	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/acct.h"
6 #include "../h/dir.h"
7 #include "../h/user.h"
8 #include "../h/inode.h"
9 #include "../h/proc.h"
10 #include "../h/seg.h"
11 #include "../h/fs.h"
12 #include "../h/uio.h"
13 
14 struct	inode *acctp;
15 struct	inode *savacctp;
16 
17 long	acctlow	= 2;		/* stop accounting when < 2% data space left */
18 long	accthigh = 4;		/* resume when space risen to > 4% */
19 
20 /*
21  * Perform process accounting functions.
22  */
23 sysacct()
24 {
25 	register struct inode *ip;
26 	register struct a {
27 		char	*fname;
28 	} *uap;
29 
30 	uap = (struct a *)u.u_ap;
31 	if (suser()) {
32 		if (savacctp) {
33 			acctp = savacctp;
34 			savacctp = NULL;
35 		}
36 		if (uap->fname==NULL) {
37 			if (ip = acctp) {
38 				irele(ip);
39 				acctp = NULL;
40 			}
41 			return;
42 		}
43 		ip = namei(uchar, 0, 1);
44 		if(ip == NULL)
45 			return;
46 		if((ip->i_mode & IFMT) != IFREG) {
47 			u.u_error = EACCES;
48 			iput(ip);
49 			return;
50 		}
51 		if (acctp && (acctp->i_number != ip->i_number ||
52 		    acctp->i_dev != ip->i_dev))
53 			irele(acctp);
54 		acctp = ip;
55 		iunlock(ip);
56 	}
57 }
58 
59 struct	acct acctbuf;
60 /*
61  * On exit, write a record on the accounting file.
62  */
63 acct()
64 {
65 	register i;
66 	register struct inode *ip;
67 	off_t siz;
68 	register struct acct *ap = &acctbuf;
69 
70 	if (savacctp && savacctp->i_fs->fs_cstotal.cs_nbfree >
71 	    accthigh * savacctp->i_fs->fs_dsize / 100) {
72 		acctp = savacctp;
73 		savacctp = NULL;
74 		printf("Accounting resumed\n");
75 	}
76 	if ((ip=acctp)==NULL)
77 		return;
78 	if (acctp->i_fs->fs_cstotal.cs_nbfree <
79 	    acctlow * acctp->i_fs->fs_dsize / 100) {
80 		savacctp = acctp;
81 		acctp = NULL;
82 		printf("Accounting suspended\n");
83 		return;
84 	}
85 	ilock(ip);
86 	for (i=0; i<sizeof(ap->ac_comm); i++)
87 		ap->ac_comm[i] = u.u_comm[i];
88 	ap->ac_utime = compress((long)u.u_vm.vm_utime);
89 	ap->ac_stime = compress((long)u.u_vm.vm_stime);
90 	ap->ac_etime = compress((long)(time - u.u_start));
91 	ap->ac_btime = u.u_start;
92 	ap->ac_uid = u.u_ruid;
93 	ap->ac_gid = u.u_rgid;
94 	ap->ac_mem = 0;
95 	if (i = u.u_vm.vm_utime + u.u_vm.vm_stime)
96 		ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i;
97 	ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk));
98 	if (u.u_ttyp)
99 		ap->ac_tty = u.u_ttyd;
100 	else
101 		ap->ac_tty = NODEV;
102 	ap->ac_flag = u.u_acflag;
103 	siz = ip->i_size;
104 	u.u_error =
105 	    rdwri(UIO_WRITE, ip, (caddr_t)ap, sizeof (acctbuf), siz,
106 		1, (int *)0);
107 	if (u.u_error)
108 		ip->i_size = siz;
109 	iunlock(ip);
110 }
111 
112 /*
113  * Produce a pseudo-floating point representation
114  * with 3 bits base-8 exponent, 13 bits fraction.
115  */
116 compress(t)
117 register long t;
118 {
119 	register exp = 0, round = 0;
120 
121 	while (t >= 8192) {
122 		exp++;
123 		round = t&04;
124 		t >>= 3;
125 	}
126 	if (round) {
127 		t++;
128 		if (t >= 8192) {
129 			t >>= 3;
130 			exp++;
131 		}
132 	}
133 	return((exp<<13) + t);
134 }
135 
136 vtimes()
137 {
138 	register struct a {
139 		struct	vtimes *par_vm;
140 		struct	vtimes *ch_vm;
141 	} *uap = (struct a *)u.u_ap;
142 
143 	if (uap->par_vm == 0)
144 		goto onlych;
145 	if (copyout((caddr_t)&u.u_vm, (caddr_t)uap->par_vm,
146 	    sizeof(struct vtimes)) < 0)
147 		u.u_error = EFAULT;
148 onlych:
149 	if (uap->ch_vm == 0)
150 		return;
151 	if (copyout((caddr_t)&u.u_cvm, (caddr_t)uap->ch_vm,
152 	    sizeof(struct vtimes)) < 0)
153 		u.u_error = EFAULT;
154 }
155 
156 vmsadd(vp, wp)
157 	register struct vtimes *vp, *wp;
158 {
159 
160 	vp->vm_utime += wp->vm_utime;
161 	vp->vm_stime += wp->vm_stime;
162 	vp->vm_nswap += wp->vm_nswap;
163 	vp->vm_idsrss += wp->vm_idsrss;
164 	vp->vm_ixrss += wp->vm_ixrss;
165 	if (vp->vm_maxrss < wp->vm_maxrss)
166 		vp->vm_maxrss = wp->vm_maxrss;
167 	vp->vm_majflt += wp->vm_majflt;
168 	vp->vm_minflt += wp->vm_minflt;
169 	vp->vm_inblk += wp->vm_inblk;
170 	vp->vm_oublk += wp->vm_oublk;
171 }
172