xref: /csrg-svn/sys/kern/kern_resource.c (revision 40705)
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*40705Skarels  *	@(#)kern_resource.c	7.6 (Berkeley) 04/03/90
723373Smckusick  */
87Sbill 
917092Sbloom #include "param.h"
1017092Sbloom #include "user.h"
1117092Sbloom #include "proc.h"
127Sbill 
138176Sroot /*
148176Sroot  * Resource controls and accounting.
158176Sroot  */
168176Sroot 
178031Sroot getpriority()
188031Sroot {
198031Sroot 	register struct a {
208031Sroot 		int	which;
218031Sroot 		int	who;
228031Sroot 	} *uap = (struct a *)u.u_ap;
238031Sroot 	register struct proc *p;
2435810Smarc 	register int low = PRIO_MAX + 1;
258031Sroot 
268031Sroot 	switch (uap->which) {
278031Sroot 
288031Sroot 	case PRIO_PROCESS:
298031Sroot 		if (uap->who == 0)
308031Sroot 			p = u.u_procp;
318031Sroot 		else
328031Sroot 			p = pfind(uap->who);
338031Sroot 		if (p == 0)
3428149Skarels 			break;
3517400Skarels 		low = p->p_nice;
368031Sroot 		break;
378031Sroot 
3835810Smarc 	case PRIO_PGRP: {
3935810Smarc 		register struct pgrp *pg;
4035810Smarc 
418031Sroot 		if (uap->who == 0)
4235810Smarc 			pg = u.u_procp->p_pgrp;
4335810Smarc 		else if ((pg = pgfind(uap->who)) == NULL)
4435810Smarc 			break;
4535810Smarc 		for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
4635810Smarc 			if (p->p_nice < low)
4717400Skarels 				low = p->p_nice;
488176Sroot 		}
498031Sroot 		break;
5035810Smarc 	}
518031Sroot 
528176Sroot 	case PRIO_USER:
538176Sroot 		if (uap->who == 0)
548176Sroot 			uap->who = u.u_uid;
5516530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt) {
568176Sroot 			if (p->p_uid == uap->who &&
5717400Skarels 			    p->p_nice < low)
5817400Skarels 				low = p->p_nice;
598176Sroot 		}
608176Sroot 		break;
618176Sroot 
628031Sroot 	default:
638031Sroot 		u.u_error = EINVAL;
6417400Skarels 		return;
658031Sroot 	}
6617400Skarels 	if (low == PRIO_MAX + 1) {
6717400Skarels 		u.u_error = ESRCH;
6817400Skarels 		return;
6917400Skarels 	}
7017400Skarels 	u.u_r.r_val1 = low;
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;
8117400Skarels 	int found = 0;
828031Sroot 
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)
9128149Skarels 			break;
928031Sroot 		donice(p, uap->prio);
9317400Skarels 		found++;
948031Sroot 		break;
958031Sroot 
9635810Smarc 	case PRIO_PGRP: {
9735810Smarc 		register struct pgrp *pg;
9835810Smarc 
998176Sroot 		if (uap->who == 0)
10035810Smarc 			pg = u.u_procp->p_pgrp;
10135810Smarc 		else if ((pg = pgfind(uap->who)) == NULL)
10235810Smarc 			break;
10335810Smarc 		for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
10435810Smarc 			donice(p, uap->prio);
10535810Smarc 			found++;
10635810Smarc 		}
1078031Sroot 		break;
10835810Smarc 	}
1098031Sroot 
1108176Sroot 	case PRIO_USER:
1118176Sroot 		if (uap->who == 0)
1128176Sroot 			uap->who = u.u_uid;
11316530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt)
11417400Skarels 			if (p->p_uid == uap->who) {
1158176Sroot 				donice(p, uap->prio);
11617400Skarels 				found++;
11717400Skarels 			}
1188176Sroot 		break;
1198176Sroot 
1208031Sroot 	default:
1218031Sroot 		u.u_error = EINVAL;
12217400Skarels 		return;
1238031Sroot 	}
12417400Skarels 	if (found == 0)
12517400Skarels 		u.u_error = ESRCH;
1268031Sroot }
1278031Sroot 
1288031Sroot donice(p, n)
1298031Sroot 	register struct proc *p;
1308031Sroot 	register int n;
1318031Sroot {
1328031Sroot 
1338031Sroot 	if (u.u_uid && u.u_ruid &&
1348031Sroot 	    u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
13521001Smckusick 		u.u_error = EPERM;
1368031Sroot 		return;
1378031Sroot 	}
13817400Skarels 	if (n > PRIO_MAX)
13917400Skarels 		n = PRIO_MAX;
14017400Skarels 	if (n < PRIO_MIN)
14117400Skarels 		n = PRIO_MIN;
14237553Smckusick 	if (n < p->p_nice && suser(u.u_cred, &u.u_acflag)) {
1438176Sroot 		u.u_error = EACCES;
1448031Sroot 		return;
1458176Sroot 	}
1468031Sroot 	p->p_nice = n;
1478031Sroot 	(void) setpri(p);
1488031Sroot }
1498031Sroot 
1508100Sroot setrlimit()
1518031Sroot {
1528031Sroot 	register struct a {
1538031Sroot 		u_int	which;
1548031Sroot 		struct	rlimit *lim;
1558031Sroot 	} *uap = (struct a *)u.u_ap;
1568031Sroot 	struct rlimit alim;
1578031Sroot 	register struct rlimit *alimp;
15825257Skarels 	extern unsigned maxdmap;
1598031Sroot 
1608031Sroot 	if (uap->which >= RLIM_NLIMITS) {
1618031Sroot 		u.u_error = EINVAL;
1628031Sroot 		return;
1638031Sroot 	}
1648031Sroot 	alimp = &u.u_rlimit[uap->which];
1659997Ssam 	u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
1669997Ssam 		sizeof (struct rlimit));
1679997Ssam 	if (u.u_error)
1688031Sroot 		return;
1698031Sroot 	if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
17037553Smckusick 		if (u.u_error = suser(u.u_cred, &u.u_acflag))
1718031Sroot 			return;
1728031Sroot 	switch (uap->which) {
1738031Sroot 
1748031Sroot 	case RLIMIT_DATA:
17518279Smckusick 		if (alim.rlim_cur > maxdmap)
17618279Smckusick 			alim.rlim_cur = maxdmap;
17718279Smckusick 		if (alim.rlim_max > maxdmap)
17818279Smckusick 			alim.rlim_max = maxdmap;
1798031Sroot 		break;
1808031Sroot 
1818031Sroot 	case RLIMIT_STACK:
18218279Smckusick 		if (alim.rlim_cur > maxdmap)
18318279Smckusick 			alim.rlim_cur = maxdmap;
18418279Smckusick 		if (alim.rlim_max > maxdmap)
18518279Smckusick 			alim.rlim_max = maxdmap;
1868031Sroot 		break;
1878031Sroot 	}
1888031Sroot 	*alimp = alim;
1898031Sroot 	if (uap->which == RLIMIT_RSS)
1908031Sroot 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
1918031Sroot }
1928031Sroot 
1938100Sroot getrlimit()
1948031Sroot {
1958031Sroot 	register struct a {
1968031Sroot 		u_int	which;
1978031Sroot 		struct	rlimit *rlp;
1988031Sroot 	} *uap = (struct a *)u.u_ap;
1998031Sroot 
2008031Sroot 	if (uap->which >= RLIM_NLIMITS) {
2018031Sroot 		u.u_error = EINVAL;
2028031Sroot 		return;
2038031Sroot 	}
2049997Ssam 	u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
2059997Ssam 	    sizeof (struct rlimit));
2068031Sroot }
2078031Sroot 
2088031Sroot getrusage()
2098031Sroot {
2108031Sroot 	register struct a {
2118031Sroot 		int	who;
2128031Sroot 		struct	rusage *rusage;
2138031Sroot 	} *uap = (struct a *)u.u_ap;
2148031Sroot 	register struct rusage *rup;
215*40705Skarels 	struct proc *p = u.u_procp;
2168031Sroot 
2178031Sroot 	switch (uap->who) {
2188031Sroot 
219*40705Skarels 	case RUSAGE_SELF: {
220*40705Skarels 		int s;
221*40705Skarels 
2228031Sroot 		rup = &u.u_ru;
223*40705Skarels 		s = splclock();
224*40705Skarels 		rup->ru_stime = p->p_stime;
225*40705Skarels 		rup->ru_utime = p->p_utime;
226*40705Skarels 		splx(s);
2278031Sroot 		break;
228*40705Skarels 	}
2298031Sroot 
2308031Sroot 	case RUSAGE_CHILDREN:
2318031Sroot 		rup = &u.u_cru;
2328031Sroot 		break;
2338031Sroot 
2348031Sroot 	default:
2358031Sroot 		u.u_error = EINVAL;
2368031Sroot 		return;
2378031Sroot 	}
2389997Ssam 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
2399997Ssam 	    sizeof (struct rusage));
2408031Sroot }
2418031Sroot 
2428031Sroot ruadd(ru, ru2)
2438031Sroot 	register struct rusage *ru, *ru2;
2448031Sroot {
2458666Sroot 	register long *ip, *ip2;
2468031Sroot 	register int i;
2478031Sroot 
2488031Sroot 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
2498031Sroot 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
2508031Sroot 	if (ru->ru_maxrss < ru2->ru_maxrss)
2518031Sroot 		ru->ru_maxrss = ru2->ru_maxrss;
2528031Sroot 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
2538031Sroot 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
2548031Sroot 		*ip++ += *ip2++;
2558031Sroot }
256