xref: /csrg-svn/sys/kern/kern_resource.c (revision 29093)
123373Smckusick /*
2*29093Smckusick  * 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*29093Smckusick  *	@(#)kern_resource.c	7.1 (Berkeley) 06/05/86
723373Smckusick  */
87Sbill 
917092Sbloom #include "param.h"
1017092Sbloom #include "systm.h"
1117092Sbloom #include "dir.h"
1217092Sbloom #include "user.h"
1317092Sbloom #include "inode.h"
1417092Sbloom #include "proc.h"
1517092Sbloom #include "seg.h"
1617092Sbloom #include "fs.h"
1717092Sbloom #include "uio.h"
1817092Sbloom #include "vm.h"
1917092Sbloom #include "kernel.h"
207Sbill 
218176Sroot /*
228176Sroot  * Resource controls and accounting.
238176Sroot  */
248176Sroot 
258031Sroot getpriority()
268031Sroot {
278031Sroot 	register struct a {
288031Sroot 		int	which;
298031Sroot 		int	who;
308031Sroot 	} *uap = (struct a *)u.u_ap;
318031Sroot 	register struct proc *p;
3217400Skarels 	int low = PRIO_MAX + 1;
338031Sroot 
348031Sroot 	switch (uap->which) {
358031Sroot 
368031Sroot 	case PRIO_PROCESS:
378031Sroot 		if (uap->who == 0)
388031Sroot 			p = u.u_procp;
398031Sroot 		else
408031Sroot 			p = pfind(uap->who);
418031Sroot 		if (p == 0)
4228149Skarels 			break;
4317400Skarels 		low = p->p_nice;
448031Sroot 		break;
458031Sroot 
468031Sroot 	case PRIO_PGRP:
478031Sroot 		if (uap->who == 0)
488031Sroot 			uap->who = u.u_procp->p_pgrp;
4916530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt) {
508031Sroot 			if (p->p_pgrp == uap->who &&
5117400Skarels 			    p->p_nice < low)
5217400Skarels 				low = p->p_nice;
538176Sroot 		}
548031Sroot 		break;
558031Sroot 
568176Sroot 	case PRIO_USER:
578176Sroot 		if (uap->who == 0)
588176Sroot 			uap->who = u.u_uid;
5916530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt) {
608176Sroot 			if (p->p_uid == uap->who &&
6117400Skarels 			    p->p_nice < low)
6217400Skarels 				low = p->p_nice;
638176Sroot 		}
648176Sroot 		break;
658176Sroot 
668031Sroot 	default:
678031Sroot 		u.u_error = EINVAL;
6817400Skarels 		return;
698031Sroot 	}
7017400Skarels 	if (low == PRIO_MAX + 1) {
7117400Skarels 		u.u_error = ESRCH;
7217400Skarels 		return;
7317400Skarels 	}
7417400Skarels 	u.u_r.r_val1 = low;
758031Sroot }
768031Sroot 
778031Sroot setpriority()
788031Sroot {
798031Sroot 	register struct a {
808031Sroot 		int	which;
818031Sroot 		int	who;
828031Sroot 		int	prio;
838031Sroot 	} *uap = (struct a *)u.u_ap;
848031Sroot 	register struct proc *p;
8517400Skarels 	int found = 0;
868031Sroot 
878031Sroot 	switch (uap->which) {
888031Sroot 
898031Sroot 	case PRIO_PROCESS:
908176Sroot 		if (uap->who == 0)
918176Sroot 			p = u.u_procp;
928176Sroot 		else
938176Sroot 			p = pfind(uap->who);
948031Sroot 		if (p == 0)
9528149Skarels 			break;
968031Sroot 		donice(p, uap->prio);
9717400Skarels 		found++;
988031Sroot 		break;
998031Sroot 
1008031Sroot 	case PRIO_PGRP:
1018176Sroot 		if (uap->who == 0)
1028176Sroot 			uap->who = u.u_procp->p_pgrp;
10316530Skarels 		for (p = allproc; p != NULL; p = p->p_nxt)
10417400Skarels 			if (p->p_pgrp == uap->who) {
1058031Sroot 				donice(p, uap->prio);
10617400Skarels 				found++;
10717400Skarels 			}
1088031Sroot 		break;
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;
1428176Sroot 	if (n < p->p_nice && !suser()) {
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)
1708031Sroot 		if (!suser())
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;
2158031Sroot 
2168031Sroot 	switch (uap->who) {
2178031Sroot 
2188031Sroot 	case RUSAGE_SELF:
2198031Sroot 		rup = &u.u_ru;
2208031Sroot 		break;
2218031Sroot 
2228031Sroot 	case RUSAGE_CHILDREN:
2238031Sroot 		rup = &u.u_cru;
2248031Sroot 		break;
2258031Sroot 
2268031Sroot 	default:
2278031Sroot 		u.u_error = EINVAL;
2288031Sroot 		return;
2298031Sroot 	}
2309997Ssam 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
2319997Ssam 	    sizeof (struct rusage));
2328031Sroot }
2338031Sroot 
2348031Sroot ruadd(ru, ru2)
2358031Sroot 	register struct rusage *ru, *ru2;
2368031Sroot {
2378666Sroot 	register long *ip, *ip2;
2388031Sroot 	register int i;
2398031Sroot 
2408031Sroot 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
2418031Sroot 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
2428031Sroot 	if (ru->ru_maxrss < ru2->ru_maxrss)
2438031Sroot 		ru->ru_maxrss = ru2->ru_maxrss;
2448031Sroot 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
2458031Sroot 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
2468031Sroot 		*ip++ += *ip2++;
2478031Sroot }
248