xref: /csrg-svn/sys/kern/kern_resource.c (revision 17400)
1*17400Skarels /*	kern_resource.c	6.4	84/11/20	*/
27Sbill 
317092Sbloom #include "param.h"
417092Sbloom #include "systm.h"
517092Sbloom #include "dir.h"
617092Sbloom #include "user.h"
717092Sbloom #include "inode.h"
817092Sbloom #include "proc.h"
917092Sbloom #include "seg.h"
1017092Sbloom #include "fs.h"
1117092Sbloom #include "uio.h"
1217092Sbloom #include "vm.h"
1317092Sbloom #include "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;
26*17400Skarels 	int low = PRIO_MAX + 1;
278031Sroot 
288031Sroot 	switch (uap->which) {
298031Sroot 
308031Sroot 	case PRIO_PROCESS:
318031Sroot 		if (uap->who == 0)
328031Sroot 			p = u.u_procp;
338031Sroot 		else
348031Sroot 			p = pfind(uap->who);
358031Sroot 		if (p == 0)
368031Sroot 			return;
37*17400Skarels 		low = p->p_nice;
388031Sroot 		break;
398031Sroot 
408031Sroot 	case PRIO_PGRP:
418031Sroot 		if (uap->who == 0)
428031Sroot 			uap->who = u.u_procp->p_pgrp;
4316530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt) {
448031Sroot 			if (p->p_pgrp == uap->who &&
45*17400Skarels 			    p->p_nice < low)
46*17400Skarels 				low = p->p_nice;
478176Sroot 		}
488031Sroot 		break;
498031Sroot 
508176Sroot 	case PRIO_USER:
518176Sroot 		if (uap->who == 0)
528176Sroot 			uap->who = u.u_uid;
5316530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt) {
548176Sroot 			if (p->p_uid == uap->who &&
55*17400Skarels 			    p->p_nice < low)
56*17400Skarels 				low = p->p_nice;
578176Sroot 		}
588176Sroot 		break;
598176Sroot 
608031Sroot 	default:
618031Sroot 		u.u_error = EINVAL;
62*17400Skarels 		return;
638031Sroot 	}
64*17400Skarels 	if (low == PRIO_MAX + 1) {
65*17400Skarels 		u.u_error = ESRCH;
66*17400Skarels 		return;
67*17400Skarels 	}
68*17400Skarels 	u.u_r.r_val1 = low;
698031Sroot }
708031Sroot 
718031Sroot setpriority()
728031Sroot {
738031Sroot 	register struct a {
748031Sroot 		int	which;
758031Sroot 		int	who;
768031Sroot 		int	prio;
778031Sroot 	} *uap = (struct a *)u.u_ap;
788031Sroot 	register struct proc *p;
79*17400Skarels 	int found = 0;
808031Sroot 
818031Sroot 	switch (uap->which) {
828031Sroot 
838031Sroot 	case PRIO_PROCESS:
848176Sroot 		if (uap->who == 0)
858176Sroot 			p = u.u_procp;
868176Sroot 		else
878176Sroot 			p = pfind(uap->who);
888031Sroot 		if (p == 0)
898031Sroot 			return;
908031Sroot 		donice(p, uap->prio);
91*17400Skarels 		found++;
928031Sroot 		break;
938031Sroot 
948031Sroot 	case PRIO_PGRP:
958176Sroot 		if (uap->who == 0)
968176Sroot 			uap->who = u.u_procp->p_pgrp;
9716530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt)
98*17400Skarels 			if (p->p_pgrp == uap->who) {
998031Sroot 				donice(p, uap->prio);
100*17400Skarels 				found++;
101*17400Skarels 			}
1028031Sroot 		break;
1038031Sroot 
1048176Sroot 	case PRIO_USER:
1058176Sroot 		if (uap->who == 0)
1068176Sroot 			uap->who = u.u_uid;
10716530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt)
108*17400Skarels 			if (p->p_uid == uap->who) {
1098176Sroot 				donice(p, uap->prio);
110*17400Skarels 				found++;
111*17400Skarels 			}
1128176Sroot 		break;
1138176Sroot 
1148031Sroot 	default:
1158031Sroot 		u.u_error = EINVAL;
116*17400Skarels 		return;
1178031Sroot 	}
118*17400Skarels 	if (found == 0)
119*17400Skarels 		u.u_error = ESRCH;
1208031Sroot }
1218031Sroot 
1228031Sroot donice(p, n)
1238031Sroot 	register struct proc *p;
1248031Sroot 	register int n;
1258031Sroot {
1268031Sroot 
1278031Sroot 	if (u.u_uid && u.u_ruid &&
1288031Sroot 	    u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
1298176Sroot 		u.u_error = EACCES;
1308031Sroot 		return;
1318031Sroot 	}
132*17400Skarels 	if (n > PRIO_MAX)
133*17400Skarels 		n = PRIO_MAX;
134*17400Skarels 	if (n < PRIO_MIN)
135*17400Skarels 		n = PRIO_MIN;
1368176Sroot 	if (n < p->p_nice && !suser()) {
1378176Sroot 		u.u_error = EACCES;
1388031Sroot 		return;
1398176Sroot 	}
1408031Sroot 	p->p_nice = n;
1418031Sroot 	(void) setpri(p);
1428031Sroot }
1438031Sroot 
1448100Sroot setrlimit()
1458031Sroot {
1468031Sroot 	register struct a {
1478031Sroot 		u_int	which;
1488031Sroot 		struct	rlimit *lim;
1498031Sroot 	} *uap = (struct a *)u.u_ap;
1508031Sroot 	struct rlimit alim;
1518031Sroot 	register struct rlimit *alimp;
1528031Sroot 
1538031Sroot 	if (uap->which >= RLIM_NLIMITS) {
1548031Sroot 		u.u_error = EINVAL;
1558031Sroot 		return;
1568031Sroot 	}
1578031Sroot 	alimp = &u.u_rlimit[uap->which];
1589997Ssam 	u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
1599997Ssam 		sizeof (struct rlimit));
1609997Ssam 	if (u.u_error)
1618031Sroot 		return;
1628031Sroot 	if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
1638031Sroot 		if (!suser())
1648031Sroot 			return;
1658031Sroot 	switch (uap->which) {
1668031Sroot 
1678031Sroot 	case RLIMIT_DATA:
1688031Sroot 		if (alim.rlim_cur > ctob(MAXDSIZ))
1698031Sroot 			alim.rlim_cur = ctob(MAXDSIZ);
1708031Sroot 		break;
1718031Sroot 
1728031Sroot 	case RLIMIT_STACK:
1738031Sroot 		if (alim.rlim_cur > ctob(MAXSSIZ))
1748031Sroot 			alim.rlim_cur = ctob(MAXSSIZ);
1758031Sroot 		break;
1768031Sroot 	}
1778031Sroot 	*alimp = alim;
1788031Sroot 	if (uap->which == RLIMIT_RSS)
1798031Sroot 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
1808031Sroot }
1818031Sroot 
1828100Sroot getrlimit()
1838031Sroot {
1848031Sroot 	register struct a {
1858031Sroot 		u_int	which;
1868031Sroot 		struct	rlimit *rlp;
1878031Sroot 	} *uap = (struct a *)u.u_ap;
1888031Sroot 
1898031Sroot 	if (uap->which >= RLIM_NLIMITS) {
1908031Sroot 		u.u_error = EINVAL;
1918031Sroot 		return;
1928031Sroot 	}
1939997Ssam 	u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
1949997Ssam 	    sizeof (struct rlimit));
1958031Sroot }
1968031Sroot 
1978031Sroot getrusage()
1988031Sroot {
1998031Sroot 	register struct a {
2008031Sroot 		int	who;
2018031Sroot 		struct	rusage *rusage;
2028031Sroot 	} *uap = (struct a *)u.u_ap;
2038031Sroot 	register struct rusage *rup;
2048031Sroot 
2058031Sroot 	switch (uap->who) {
2068031Sroot 
2078031Sroot 	case RUSAGE_SELF:
2088031Sroot 		rup = &u.u_ru;
2098031Sroot 		break;
2108031Sroot 
2118031Sroot 	case RUSAGE_CHILDREN:
2128031Sroot 		rup = &u.u_cru;
2138031Sroot 		break;
2148031Sroot 
2158031Sroot 	default:
2168031Sroot 		u.u_error = EINVAL;
2178031Sroot 		return;
2188031Sroot 	}
2199997Ssam 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
2209997Ssam 	    sizeof (struct rusage));
2218031Sroot }
2228031Sroot 
2238031Sroot ruadd(ru, ru2)
2248031Sroot 	register struct rusage *ru, *ru2;
2258031Sroot {
2268666Sroot 	register long *ip, *ip2;
2278031Sroot 	register int i;
2288031Sroot 
2298031Sroot 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
2308031Sroot 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
2318031Sroot 	if (ru->ru_maxrss < ru2->ru_maxrss)
2328031Sroot 		ru->ru_maxrss = ru2->ru_maxrss;
2338031Sroot 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
2348031Sroot 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
2358031Sroot 		*ip++ += *ip2++;
2368031Sroot }
237