xref: /csrg-svn/sys/kern/kern_resource.c (revision 7817)
1*7817Sroot /*	kern_resource.c	4.11	82/08/22	*/
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"
117499Sroot #include "../h/fs.h"
12*7817Sroot #include "../h/uio.h"
137Sbill 
143098Swnj struct	inode *acctp;
157499Sroot struct	inode *savacctp;
163098Swnj 
177499Sroot long	acctlow	= 2;		/* stop accounting when < 2% data space left */
187499Sroot long	accthigh = 4;		/* resume when space risen to > 4% */
197499Sroot 
207Sbill /*
217Sbill  * Perform process accounting functions.
227Sbill  */
237Sbill sysacct()
247Sbill {
257Sbill 	register struct inode *ip;
267Sbill 	register struct a {
277Sbill 		char	*fname;
287Sbill 	} *uap;
297Sbill 
307Sbill 	uap = (struct a *)u.u_ap;
317Sbill 	if (suser()) {
327499Sroot 		if (savacctp) {
337499Sroot 			acctp = savacctp;
347499Sroot 			savacctp = NULL;
357499Sroot 		}
367Sbill 		if (uap->fname==NULL) {
373109Swnj 			if (ip = acctp) {
387141Smckusick 				irele(ip);
397Sbill 				acctp = NULL;
407Sbill 			}
417Sbill 			return;
427Sbill 		}
435990Swnj 		ip = namei(uchar, 0, 1);
447Sbill 		if(ip == NULL)
457Sbill 			return;
467Sbill 		if((ip->i_mode & IFMT) != IFREG) {
477Sbill 			u.u_error = EACCES;
487Sbill 			iput(ip);
497Sbill 			return;
507Sbill 		}
517376Skre 		if (acctp && (acctp->i_number != ip->i_number ||
527376Skre 		    acctp->i_dev != ip->i_dev))
537376Skre 			irele(acctp);
547Sbill 		acctp = ip;
557121Smckusick 		iunlock(ip);
567Sbill 	}
577Sbill }
587Sbill 
593098Swnj struct	acct acctbuf;
607Sbill /*
617Sbill  * On exit, write a record on the accounting file.
627Sbill  */
637Sbill acct()
647Sbill {
657Sbill 	register i;
667Sbill 	register struct inode *ip;
677Sbill 	off_t siz;
683098Swnj 	register struct acct *ap = &acctbuf;
697Sbill 
707499Sroot 	if (savacctp && savacctp->i_fs->fs_cstotal.cs_nbfree >
717499Sroot 	    accthigh * savacctp->i_fs->fs_dsize / 100) {
727499Sroot 		acctp = savacctp;
737499Sroot 		savacctp = NULL;
747499Sroot 		printf("Accounting resumed\n");
757499Sroot 	}
767Sbill 	if ((ip=acctp)==NULL)
777Sbill 		return;
787499Sroot 	if (acctp->i_fs->fs_cstotal.cs_nbfree <
797499Sroot 	    acctlow * acctp->i_fs->fs_dsize / 100) {
807499Sroot 		savacctp = acctp;
817499Sroot 		acctp = NULL;
827499Sroot 		printf("Accounting suspended\n");
837499Sroot 		return;
847499Sroot 	}
854816Swnj 	ilock(ip);
863098Swnj 	for (i=0; i<sizeof(ap->ac_comm); i++)
873098Swnj 		ap->ac_comm[i] = u.u_comm[i];
883098Swnj 	ap->ac_utime = compress((long)u.u_vm.vm_utime);
893098Swnj 	ap->ac_stime = compress((long)u.u_vm.vm_stime);
903098Swnj 	ap->ac_etime = compress((long)(time - u.u_start));
913098Swnj 	ap->ac_btime = u.u_start;
923098Swnj 	ap->ac_uid = u.u_ruid;
933098Swnj 	ap->ac_gid = u.u_rgid;
943098Swnj 	ap->ac_mem = 0;
9589Sbill 	if (i = u.u_vm.vm_utime + u.u_vm.vm_stime)
963098Swnj 		ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i;
973098Swnj 	ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk));
987376Skre 	if (u.u_ttyp)
997376Skre 		ap->ac_tty = u.u_ttyd;
1007376Skre 	else
1017376Skre 		ap->ac_tty = NODEV;
1023098Swnj 	ap->ac_flag = u.u_acflag;
1037Sbill 	siz = ip->i_size;
104*7817Sroot 	u.u_error =
105*7817Sroot 	    rdwri(UIO_WRITE, ip, (caddr_t)ap, sizeof (acctbuf), siz,
106*7817Sroot 		1, (int *)0);
107*7817Sroot 	if (u.u_error)
1087Sbill 		ip->i_size = siz;
1097121Smckusick 	iunlock(ip);
1107Sbill }
1117Sbill 
1127Sbill /*
1137Sbill  * Produce a pseudo-floating point representation
1147Sbill  * with 3 bits base-8 exponent, 13 bits fraction.
1157Sbill  */
1167Sbill compress(t)
1171784Sbill register long t;
1187Sbill {
1197Sbill 	register exp = 0, round = 0;
1207Sbill 
1217Sbill 	while (t >= 8192) {
1227Sbill 		exp++;
1237Sbill 		round = t&04;
1247Sbill 		t >>= 3;
1257Sbill 	}
1267Sbill 	if (round) {
1277Sbill 		t++;
1287Sbill 		if (t >= 8192) {
1297Sbill 			t >>= 3;
1307Sbill 			exp++;
1317Sbill 		}
1327Sbill 	}
1337Sbill 	return((exp<<13) + t);
1347Sbill }
1357499Sroot 
1367499Sroot vtimes()
1377499Sroot {
1387499Sroot 	register struct a {
1397499Sroot 		struct	vtimes *par_vm;
1407499Sroot 		struct	vtimes *ch_vm;
1417499Sroot 	} *uap = (struct a *)u.u_ap;
1427499Sroot 
1437499Sroot 	if (uap->par_vm == 0)
1447499Sroot 		goto onlych;
1457499Sroot 	if (copyout((caddr_t)&u.u_vm, (caddr_t)uap->par_vm,
1467499Sroot 	    sizeof(struct vtimes)) < 0)
1477499Sroot 		u.u_error = EFAULT;
1487499Sroot onlych:
1497499Sroot 	if (uap->ch_vm == 0)
1507499Sroot 		return;
1517499Sroot 	if (copyout((caddr_t)&u.u_cvm, (caddr_t)uap->ch_vm,
1527499Sroot 	    sizeof(struct vtimes)) < 0)
1537499Sroot 		u.u_error = EFAULT;
1547499Sroot }
1557499Sroot 
1567499Sroot vmsadd(vp, wp)
1577499Sroot 	register struct vtimes *vp, *wp;
1587499Sroot {
1597499Sroot 
1607499Sroot 	vp->vm_utime += wp->vm_utime;
1617499Sroot 	vp->vm_stime += wp->vm_stime;
1627499Sroot 	vp->vm_nswap += wp->vm_nswap;
1637499Sroot 	vp->vm_idsrss += wp->vm_idsrss;
1647499Sroot 	vp->vm_ixrss += wp->vm_ixrss;
1657499Sroot 	if (vp->vm_maxrss < wp->vm_maxrss)
1667499Sroot 		vp->vm_maxrss = wp->vm_maxrss;
1677499Sroot 	vp->vm_majflt += wp->vm_majflt;
1687499Sroot 	vp->vm_minflt += wp->vm_minflt;
1697499Sroot 	vp->vm_inblk += wp->vm_inblk;
1707499Sroot 	vp->vm_oublk += wp->vm_oublk;
1717499Sroot }
172