xref: /csrg-svn/sys/kern/kern_resource.c (revision 7499)
1*7499Sroot /*	kern_resource.c	4.10	82/07/24	*/
27Sbill 
37Sbill #include "../h/param.h"
47Sbill #include "../h/systm.h"
57Sbill #include "../h/acct.h"
67Sbill #include "../h/dir.h"
77Sbill #include "../h/user.h"
87Sbill #include "../h/inode.h"
97Sbill #include "../h/proc.h"
107Sbill #include "../h/seg.h"
11*7499Sroot #include "../h/fs.h"
127Sbill 
133098Swnj struct	inode *acctp;
14*7499Sroot struct	inode *savacctp;
153098Swnj 
16*7499Sroot long	acctlow	= 2;		/* stop accounting when < 2% data space left */
17*7499Sroot long	accthigh = 4;		/* resume when space risen to > 4% */
18*7499Sroot 
197Sbill /*
207Sbill  * Perform process accounting functions.
217Sbill  */
227Sbill sysacct()
237Sbill {
247Sbill 	register struct inode *ip;
257Sbill 	register struct a {
267Sbill 		char	*fname;
277Sbill 	} *uap;
287Sbill 
297Sbill 	uap = (struct a *)u.u_ap;
307Sbill 	if (suser()) {
31*7499Sroot 		if (savacctp) {
32*7499Sroot 			acctp = savacctp;
33*7499Sroot 			savacctp = NULL;
34*7499Sroot 		}
357Sbill 		if (uap->fname==NULL) {
363109Swnj 			if (ip = acctp) {
377141Smckusick 				irele(ip);
387Sbill 				acctp = NULL;
397Sbill 			}
407Sbill 			return;
417Sbill 		}
425990Swnj 		ip = namei(uchar, 0, 1);
437Sbill 		if(ip == NULL)
447Sbill 			return;
457Sbill 		if((ip->i_mode & IFMT) != IFREG) {
467Sbill 			u.u_error = EACCES;
477Sbill 			iput(ip);
487Sbill 			return;
497Sbill 		}
507376Skre 		if (acctp && (acctp->i_number != ip->i_number ||
517376Skre 		    acctp->i_dev != ip->i_dev))
527376Skre 			irele(acctp);
537Sbill 		acctp = ip;
547121Smckusick 		iunlock(ip);
557Sbill 	}
567Sbill }
577Sbill 
583098Swnj struct	acct acctbuf;
597Sbill /*
607Sbill  * On exit, write a record on the accounting file.
617Sbill  */
627Sbill acct()
637Sbill {
647Sbill 	register i;
657Sbill 	register struct inode *ip;
667Sbill 	off_t siz;
673098Swnj 	register struct acct *ap = &acctbuf;
687Sbill 
69*7499Sroot 	if (savacctp && savacctp->i_fs->fs_cstotal.cs_nbfree >
70*7499Sroot 	    accthigh * savacctp->i_fs->fs_dsize / 100) {
71*7499Sroot 		acctp = savacctp;
72*7499Sroot 		savacctp = NULL;
73*7499Sroot 		printf("Accounting resumed\n");
74*7499Sroot 	}
757Sbill 	if ((ip=acctp)==NULL)
767Sbill 		return;
77*7499Sroot 	if (acctp->i_fs->fs_cstotal.cs_nbfree <
78*7499Sroot 	    acctlow * acctp->i_fs->fs_dsize / 100) {
79*7499Sroot 		savacctp = acctp;
80*7499Sroot 		acctp = NULL;
81*7499Sroot 		printf("Accounting suspended\n");
82*7499Sroot 		return;
83*7499Sroot 	}
844816Swnj 	ilock(ip);
853098Swnj 	for (i=0; i<sizeof(ap->ac_comm); i++)
863098Swnj 		ap->ac_comm[i] = u.u_comm[i];
873098Swnj 	ap->ac_utime = compress((long)u.u_vm.vm_utime);
883098Swnj 	ap->ac_stime = compress((long)u.u_vm.vm_stime);
893098Swnj 	ap->ac_etime = compress((long)(time - u.u_start));
903098Swnj 	ap->ac_btime = u.u_start;
913098Swnj 	ap->ac_uid = u.u_ruid;
923098Swnj 	ap->ac_gid = u.u_rgid;
933098Swnj 	ap->ac_mem = 0;
9489Sbill 	if (i = u.u_vm.vm_utime + u.u_vm.vm_stime)
953098Swnj 		ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i;
963098Swnj 	ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk));
977376Skre 	if (u.u_ttyp)
987376Skre 		ap->ac_tty = u.u_ttyd;
997376Skre 	else
1007376Skre 		ap->ac_tty = NODEV;
1013098Swnj 	ap->ac_flag = u.u_acflag;
1027Sbill 	siz = ip->i_size;
1037Sbill 	u.u_offset = siz;
1043098Swnj 	u.u_base = (caddr_t)ap;
1057Sbill 	u.u_count = sizeof(acctbuf);
1067Sbill 	u.u_segflg = 1;
1077Sbill 	u.u_error = 0;
1087Sbill 	writei(ip);
1097Sbill 	if(u.u_error)
1107Sbill 		ip->i_size = siz;
1117121Smckusick 	iunlock(ip);
1127Sbill }
1137Sbill 
1147Sbill /*
1157Sbill  * Produce a pseudo-floating point representation
1167Sbill  * with 3 bits base-8 exponent, 13 bits fraction.
1177Sbill  */
1187Sbill compress(t)
1191784Sbill register long t;
1207Sbill {
1217Sbill 	register exp = 0, round = 0;
1227Sbill 
1237Sbill 	while (t >= 8192) {
1247Sbill 		exp++;
1257Sbill 		round = t&04;
1267Sbill 		t >>= 3;
1277Sbill 	}
1287Sbill 	if (round) {
1297Sbill 		t++;
1307Sbill 		if (t >= 8192) {
1317Sbill 			t >>= 3;
1327Sbill 			exp++;
1337Sbill 		}
1347Sbill 	}
1357Sbill 	return((exp<<13) + t);
1367Sbill }
137*7499Sroot 
138*7499Sroot vtimes()
139*7499Sroot {
140*7499Sroot 	register struct a {
141*7499Sroot 		struct	vtimes *par_vm;
142*7499Sroot 		struct	vtimes *ch_vm;
143*7499Sroot 	} *uap = (struct a *)u.u_ap;
144*7499Sroot 
145*7499Sroot 	if (uap->par_vm == 0)
146*7499Sroot 		goto onlych;
147*7499Sroot 	if (copyout((caddr_t)&u.u_vm, (caddr_t)uap->par_vm,
148*7499Sroot 	    sizeof(struct vtimes)) < 0)
149*7499Sroot 		u.u_error = EFAULT;
150*7499Sroot onlych:
151*7499Sroot 	if (uap->ch_vm == 0)
152*7499Sroot 		return;
153*7499Sroot 	if (copyout((caddr_t)&u.u_cvm, (caddr_t)uap->ch_vm,
154*7499Sroot 	    sizeof(struct vtimes)) < 0)
155*7499Sroot 		u.u_error = EFAULT;
156*7499Sroot }
157*7499Sroot 
158*7499Sroot vmsadd(vp, wp)
159*7499Sroot 	register struct vtimes *vp, *wp;
160*7499Sroot {
161*7499Sroot 
162*7499Sroot 	vp->vm_utime += wp->vm_utime;
163*7499Sroot 	vp->vm_stime += wp->vm_stime;
164*7499Sroot 	vp->vm_nswap += wp->vm_nswap;
165*7499Sroot 	vp->vm_idsrss += wp->vm_idsrss;
166*7499Sroot 	vp->vm_ixrss += wp->vm_ixrss;
167*7499Sroot 	if (vp->vm_maxrss < wp->vm_maxrss)
168*7499Sroot 		vp->vm_maxrss = wp->vm_maxrss;
169*7499Sroot 	vp->vm_majflt += wp->vm_majflt;
170*7499Sroot 	vp->vm_minflt += wp->vm_minflt;
171*7499Sroot 	vp->vm_inblk += wp->vm_inblk;
172*7499Sroot 	vp->vm_oublk += wp->vm_oublk;
173*7499Sroot }
174