xref: /csrg-svn/sys/kern/kern_resource.c (revision 37553)
123373Smckusick /*
229093Smckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
323373Smckusick  * All rights reserved.  The Berkeley software License Agreement
423373Smckusick  * specifies the terms and conditions for redistribution.
523373Smckusick  *
6*37553Smckusick  *	@(#)kern_resource.c	7.4 (Berkeley) 04/26/89
723373Smckusick  */
87Sbill 
917092Sbloom #include "param.h"
1017092Sbloom #include "dir.h"
1117092Sbloom #include "user.h"
1217092Sbloom #include "proc.h"
137Sbill 
148176Sroot /*
158176Sroot  * Resource controls and accounting.
168176Sroot  */
178176Sroot 
188031Sroot getpriority()
198031Sroot {
208031Sroot 	register struct a {
218031Sroot 		int	which;
228031Sroot 		int	who;
238031Sroot 	} *uap = (struct a *)u.u_ap;
248031Sroot 	register struct proc *p;
2535810Smarc 	register int low = PRIO_MAX + 1;
268031Sroot 
278031Sroot 	switch (uap->which) {
288031Sroot 
298031Sroot 	case PRIO_PROCESS:
308031Sroot 		if (uap->who == 0)
318031Sroot 			p = u.u_procp;
328031Sroot 		else
338031Sroot 			p = pfind(uap->who);
348031Sroot 		if (p == 0)
3528149Skarels 			break;
3617400Skarels 		low = p->p_nice;
378031Sroot 		break;
388031Sroot 
3935810Smarc 	case PRIO_PGRP: {
4035810Smarc 		register struct pgrp *pg;
4135810Smarc 
428031Sroot 		if (uap->who == 0)
4335810Smarc 			pg = u.u_procp->p_pgrp;
4435810Smarc 		else if ((pg = pgfind(uap->who)) == NULL)
4535810Smarc 			break;
4635810Smarc 		for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
4735810Smarc 			if (p->p_nice < low)
4817400Skarels 				low = p->p_nice;
498176Sroot 		}
508031Sroot 		break;
5135810Smarc 	}
528031Sroot 
538176Sroot 	case PRIO_USER:
548176Sroot 		if (uap->who == 0)
558176Sroot 			uap->who = u.u_uid;
5616530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt) {
578176Sroot 			if (p->p_uid == uap->who &&
5817400Skarels 			    p->p_nice < low)
5917400Skarels 				low = p->p_nice;
608176Sroot 		}
618176Sroot 		break;
628176Sroot 
638031Sroot 	default:
648031Sroot 		u.u_error = EINVAL;
6517400Skarels 		return;
668031Sroot 	}
6717400Skarels 	if (low == PRIO_MAX + 1) {
6817400Skarels 		u.u_error = ESRCH;
6917400Skarels 		return;
7017400Skarels 	}
7117400Skarels 	u.u_r.r_val1 = low;
728031Sroot }
738031Sroot 
748031Sroot setpriority()
758031Sroot {
768031Sroot 	register struct a {
778031Sroot 		int	which;
788031Sroot 		int	who;
798031Sroot 		int	prio;
808031Sroot 	} *uap = (struct a *)u.u_ap;
818031Sroot 	register struct proc *p;
8217400Skarels 	int found = 0;
838031Sroot 
848031Sroot 	switch (uap->which) {
858031Sroot 
868031Sroot 	case PRIO_PROCESS:
878176Sroot 		if (uap->who == 0)
888176Sroot 			p = u.u_procp;
898176Sroot 		else
908176Sroot 			p = pfind(uap->who);
918031Sroot 		if (p == 0)
9228149Skarels 			break;
938031Sroot 		donice(p, uap->prio);
9417400Skarels 		found++;
958031Sroot 		break;
968031Sroot 
9735810Smarc 	case PRIO_PGRP: {
9835810Smarc 		register struct pgrp *pg;
9935810Smarc 
1008176Sroot 		if (uap->who == 0)
10135810Smarc 			pg = u.u_procp->p_pgrp;
10235810Smarc 		else if ((pg = pgfind(uap->who)) == NULL)
10335810Smarc 			break;
10435810Smarc 		for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
10535810Smarc 			donice(p, uap->prio);
10635810Smarc 			found++;
10735810Smarc 		}
1088031Sroot 		break;
10935810Smarc 	}
1108031Sroot 
1118176Sroot 	case PRIO_USER:
1128176Sroot 		if (uap->who == 0)
1138176Sroot 			uap->who = u.u_uid;
11416530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt)
11517400Skarels 			if (p->p_uid == uap->who) {
1168176Sroot 				donice(p, uap->prio);
11717400Skarels 				found++;
11817400Skarels 			}
1198176Sroot 		break;
1208176Sroot 
1218031Sroot 	default:
1228031Sroot 		u.u_error = EINVAL;
12317400Skarels 		return;
1248031Sroot 	}
12517400Skarels 	if (found == 0)
12617400Skarels 		u.u_error = ESRCH;
1278031Sroot }
1288031Sroot 
1298031Sroot donice(p, n)
1308031Sroot 	register struct proc *p;
1318031Sroot 	register int n;
1328031Sroot {
1338031Sroot 
1348031Sroot 	if (u.u_uid && u.u_ruid &&
1358031Sroot 	    u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
13621001Smckusick 		u.u_error = EPERM;
1378031Sroot 		return;
1388031Sroot 	}
13917400Skarels 	if (n > PRIO_MAX)
14017400Skarels 		n = PRIO_MAX;
14117400Skarels 	if (n < PRIO_MIN)
14217400Skarels 		n = PRIO_MIN;
143*37553Smckusick 	if (n < p->p_nice && suser(u.u_cred, &u.u_acflag)) {
1448176Sroot 		u.u_error = EACCES;
1458031Sroot 		return;
1468176Sroot 	}
1478031Sroot 	p->p_nice = n;
1488031Sroot 	(void) setpri(p);
1498031Sroot }
1508031Sroot 
1518100Sroot setrlimit()
1528031Sroot {
1538031Sroot 	register struct a {
1548031Sroot 		u_int	which;
1558031Sroot 		struct	rlimit *lim;
1568031Sroot 	} *uap = (struct a *)u.u_ap;
1578031Sroot 	struct rlimit alim;
1588031Sroot 	register struct rlimit *alimp;
15925257Skarels 	extern unsigned maxdmap;
1608031Sroot 
1618031Sroot 	if (uap->which >= RLIM_NLIMITS) {
1628031Sroot 		u.u_error = EINVAL;
1638031Sroot 		return;
1648031Sroot 	}
1658031Sroot 	alimp = &u.u_rlimit[uap->which];
1669997Ssam 	u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
1679997Ssam 		sizeof (struct rlimit));
1689997Ssam 	if (u.u_error)
1698031Sroot 		return;
1708031Sroot 	if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
171*37553Smckusick 		if (u.u_error = suser(u.u_cred, &u.u_acflag))
1728031Sroot 			return;
1738031Sroot 	switch (uap->which) {
1748031Sroot 
1758031Sroot 	case RLIMIT_DATA:
17618279Smckusick 		if (alim.rlim_cur > maxdmap)
17718279Smckusick 			alim.rlim_cur = maxdmap;
17818279Smckusick 		if (alim.rlim_max > maxdmap)
17918279Smckusick 			alim.rlim_max = maxdmap;
1808031Sroot 		break;
1818031Sroot 
1828031Sroot 	case RLIMIT_STACK:
18318279Smckusick 		if (alim.rlim_cur > maxdmap)
18418279Smckusick 			alim.rlim_cur = maxdmap;
18518279Smckusick 		if (alim.rlim_max > maxdmap)
18618279Smckusick 			alim.rlim_max = maxdmap;
1878031Sroot 		break;
1888031Sroot 	}
1898031Sroot 	*alimp = alim;
1908031Sroot 	if (uap->which == RLIMIT_RSS)
1918031Sroot 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
1928031Sroot }
1938031Sroot 
1948100Sroot getrlimit()
1958031Sroot {
1968031Sroot 	register struct a {
1978031Sroot 		u_int	which;
1988031Sroot 		struct	rlimit *rlp;
1998031Sroot 	} *uap = (struct a *)u.u_ap;
2008031Sroot 
2018031Sroot 	if (uap->which >= RLIM_NLIMITS) {
2028031Sroot 		u.u_error = EINVAL;
2038031Sroot 		return;
2048031Sroot 	}
2059997Ssam 	u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
2069997Ssam 	    sizeof (struct rlimit));
2078031Sroot }
2088031Sroot 
2098031Sroot getrusage()
2108031Sroot {
2118031Sroot 	register struct a {
2128031Sroot 		int	who;
2138031Sroot 		struct	rusage *rusage;
2148031Sroot 	} *uap = (struct a *)u.u_ap;
2158031Sroot 	register struct rusage *rup;
2168031Sroot 
2178031Sroot 	switch (uap->who) {
2188031Sroot 
2198031Sroot 	case RUSAGE_SELF:
2208031Sroot 		rup = &u.u_ru;
2218031Sroot 		break;
2228031Sroot 
2238031Sroot 	case RUSAGE_CHILDREN:
2248031Sroot 		rup = &u.u_cru;
2258031Sroot 		break;
2268031Sroot 
2278031Sroot 	default:
2288031Sroot 		u.u_error = EINVAL;
2298031Sroot 		return;
2308031Sroot 	}
2319997Ssam 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
2329997Ssam 	    sizeof (struct rusage));
2338031Sroot }
2348031Sroot 
2358031Sroot ruadd(ru, ru2)
2368031Sroot 	register struct rusage *ru, *ru2;
2378031Sroot {
2388666Sroot 	register long *ip, *ip2;
2398031Sroot 	register int i;
2408031Sroot 
2418031Sroot 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
2428031Sroot 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
2438031Sroot 	if (ru->ru_maxrss < ru2->ru_maxrss)
2448031Sroot 		ru->ru_maxrss = ru2->ru_maxrss;
2458031Sroot 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
2468031Sroot 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
2478031Sroot 		*ip++ += *ip2++;
2488031Sroot }
249