xref: /csrg-svn/sys/kern/kern_resource.c (revision 16530)
1*16530Skarels /*	kern_resource.c	6.2	84/05/22	*/
27Sbill 
37Sbill #include "../h/param.h"
47Sbill #include "../h/systm.h"
57Sbill #include "../h/dir.h"
67Sbill #include "../h/user.h"
77Sbill #include "../h/inode.h"
87Sbill #include "../h/proc.h"
97Sbill #include "../h/seg.h"
107499Sroot #include "../h/fs.h"
117817Sroot #include "../h/uio.h"
128031Sroot #include "../h/vm.h"
1310867Ssam #include "../h/kernel.h"
147Sbill 
158176Sroot /*
168176Sroot  * Resource controls and accounting.
178176Sroot  */
188176Sroot 
198031Sroot getpriority()
208031Sroot {
218031Sroot 	register struct a {
228031Sroot 		int	which;
238031Sroot 		int	who;
248031Sroot 	} *uap = (struct a *)u.u_ap;
258031Sroot 	register struct proc *p;
268031Sroot 
278031Sroot 	u.u_r.r_val1 = NZERO+20;
288031Sroot 	u.u_error = ESRCH;
298031Sroot 	switch (uap->which) {
308031Sroot 
318031Sroot 	case PRIO_PROCESS:
328031Sroot 		if (uap->who == 0)
338031Sroot 			p = u.u_procp;
348031Sroot 		else
358031Sroot 			p = pfind(uap->who);
368031Sroot 		if (p == 0)
378031Sroot 			return;
3812689Ssam 		u.u_r.r_val1 = p->p_nice;
398176Sroot 		u.u_error = 0;
408031Sroot 		break;
418031Sroot 
428031Sroot 	case PRIO_PGRP:
438031Sroot 		if (uap->who == 0)
448031Sroot 			uap->who = u.u_procp->p_pgrp;
45*16530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt) {
468031Sroot 			if (p->p_pgrp == uap->who &&
478031Sroot 			    p->p_nice < u.u_r.r_val1) {
488031Sroot 				u.u_r.r_val1 = p->p_nice;
498031Sroot 				u.u_error = 0;
508031Sroot 			}
518176Sroot 		}
528031Sroot 		break;
538031Sroot 
548176Sroot 	case PRIO_USER:
558176Sroot 		if (uap->who == 0)
568176Sroot 			uap->who = u.u_uid;
57*16530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt) {
588176Sroot 			if (p->p_uid == uap->who &&
598176Sroot 			    p->p_nice < u.u_r.r_val1) {
608176Sroot 				u.u_r.r_val1 = p->p_nice;
618176Sroot 				u.u_error = 0;
628176Sroot 			}
638176Sroot 		}
648176Sroot 		break;
658176Sroot 
668031Sroot 	default:
678031Sroot 		u.u_error = EINVAL;
688031Sroot 		break;
698031Sroot 	}
708031Sroot 	u.u_r.r_val1 -= NZERO;
718031Sroot }
728031Sroot 
738031Sroot setpriority()
748031Sroot {
758031Sroot 	register struct a {
768031Sroot 		int	which;
778031Sroot 		int	who;
788031Sroot 		int	prio;
798031Sroot 	} *uap = (struct a *)u.u_ap;
808031Sroot 	register struct proc *p;
818031Sroot 
828031Sroot 	u.u_error = ESRCH;
838031Sroot 	switch (uap->which) {
848031Sroot 
858031Sroot 	case PRIO_PROCESS:
868176Sroot 		if (uap->who == 0)
878176Sroot 			p = u.u_procp;
888176Sroot 		else
898176Sroot 			p = pfind(uap->who);
908031Sroot 		if (p == 0)
918031Sroot 			return;
928031Sroot 		donice(p, uap->prio);
938031Sroot 		break;
948031Sroot 
958031Sroot 	case PRIO_PGRP:
968176Sroot 		if (uap->who == 0)
978176Sroot 			uap->who = u.u_procp->p_pgrp;
98*16530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt)
998031Sroot 			if (p->p_pgrp == uap->who)
1008031Sroot 				donice(p, uap->prio);
1018031Sroot 		break;
1028031Sroot 
1038176Sroot 	case PRIO_USER:
1048176Sroot 		if (uap->who == 0)
1058176Sroot 			uap->who = u.u_uid;
106*16530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt)
1078176Sroot 			if (p->p_uid == uap->who)
1088176Sroot 				donice(p, uap->prio);
1098176Sroot 		break;
1108176Sroot 
1118031Sroot 	default:
1128031Sroot 		u.u_error = EINVAL;
1138031Sroot 		break;
1148031Sroot 	}
1158031Sroot }
1168031Sroot 
1178031Sroot donice(p, n)
1188031Sroot 	register struct proc *p;
1198031Sroot 	register int n;
1208031Sroot {
1218031Sroot 
1228031Sroot 	if (u.u_uid && u.u_ruid &&
1238031Sroot 	    u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
1248176Sroot 		u.u_error = EACCES;
1258031Sroot 		return;
1268031Sroot 	}
1278176Sroot 	n += NZERO;
1288031Sroot 	if (n >= 2*NZERO)
1298031Sroot 		n = 2*NZERO - 1;
1308031Sroot 	if (n < 0)
1318031Sroot 		n = 0;
1328176Sroot 	if (n < p->p_nice && !suser()) {
1338176Sroot 		u.u_error = EACCES;
1348031Sroot 		return;
1358176Sroot 	}
1368031Sroot 	p->p_nice = n;
1378031Sroot 	(void) setpri(p);
1388031Sroot 	if (u.u_error == ESRCH)
1398031Sroot 		u.u_error = 0;
1408031Sroot }
1418031Sroot 
1428100Sroot setrlimit()
1438031Sroot {
1448031Sroot 	register struct a {
1458031Sroot 		u_int	which;
1468031Sroot 		struct	rlimit *lim;
1478031Sroot 	} *uap = (struct a *)u.u_ap;
1488031Sroot 	struct rlimit alim;
1498031Sroot 	register struct rlimit *alimp;
1508031Sroot 
1518031Sroot 	if (uap->which >= RLIM_NLIMITS) {
1528031Sroot 		u.u_error = EINVAL;
1538031Sroot 		return;
1548031Sroot 	}
1558031Sroot 	alimp = &u.u_rlimit[uap->which];
1569997Ssam 	u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
1579997Ssam 		sizeof (struct rlimit));
1589997Ssam 	if (u.u_error)
1598031Sroot 		return;
1608031Sroot 	if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
1618031Sroot 		if (!suser())
1628031Sroot 			return;
1638031Sroot 	switch (uap->which) {
1648031Sroot 
1658031Sroot 	case RLIMIT_DATA:
1668031Sroot 		if (alim.rlim_cur > ctob(MAXDSIZ))
1678031Sroot 			alim.rlim_cur = ctob(MAXDSIZ);
1688031Sroot 		break;
1698031Sroot 
1708031Sroot 	case RLIMIT_STACK:
1718031Sroot 		if (alim.rlim_cur > ctob(MAXSSIZ))
1728031Sroot 			alim.rlim_cur = ctob(MAXSSIZ);
1738031Sroot 		break;
1748031Sroot 	}
1758031Sroot 	*alimp = alim;
1768031Sroot 	if (uap->which == RLIMIT_RSS)
1778031Sroot 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
1788031Sroot }
1798031Sroot 
1808100Sroot getrlimit()
1818031Sroot {
1828031Sroot 	register struct a {
1838031Sroot 		u_int	which;
1848031Sroot 		struct	rlimit *rlp;
1858031Sroot 	} *uap = (struct a *)u.u_ap;
1868031Sroot 
1878031Sroot 	if (uap->which >= RLIM_NLIMITS) {
1888031Sroot 		u.u_error = EINVAL;
1898031Sroot 		return;
1908031Sroot 	}
1919997Ssam 	u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
1929997Ssam 	    sizeof (struct rlimit));
1938031Sroot }
1948031Sroot 
1958031Sroot getrusage()
1968031Sroot {
1978031Sroot 	register struct a {
1988031Sroot 		int	who;
1998031Sroot 		struct	rusage *rusage;
2008031Sroot 	} *uap = (struct a *)u.u_ap;
2018031Sroot 	register struct rusage *rup;
2028031Sroot 
2038031Sroot 	switch (uap->who) {
2048031Sroot 
2058031Sroot 	case RUSAGE_SELF:
2068031Sroot 		rup = &u.u_ru;
2078031Sroot 		break;
2088031Sroot 
2098031Sroot 	case RUSAGE_CHILDREN:
2108031Sroot 		rup = &u.u_cru;
2118031Sroot 		break;
2128031Sroot 
2138031Sroot 	default:
2148031Sroot 		u.u_error = EINVAL;
2158031Sroot 		return;
2168031Sroot 	}
2179997Ssam 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
2189997Ssam 	    sizeof (struct rusage));
2198031Sroot }
2208031Sroot 
2218031Sroot ruadd(ru, ru2)
2228031Sroot 	register struct rusage *ru, *ru2;
2238031Sroot {
2248666Sroot 	register long *ip, *ip2;
2258031Sroot 	register int i;
2268031Sroot 
2278031Sroot 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
2288031Sroot 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
2298031Sroot 	if (ru->ru_maxrss < ru2->ru_maxrss)
2308031Sroot 		ru->ru_maxrss = ru2->ru_maxrss;
2318031Sroot 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
2328031Sroot 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
2338031Sroot 		*ip++ += *ip2++;
2348031Sroot }
235