xref: /csrg-svn/sys/kern/kern_resource.c (revision 8176)
1*8176Sroot /*	kern_resource.c	4.14	82/09/12	*/
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"
137Sbill 
14*8176Sroot /*
15*8176Sroot  * Resource controls and accounting.
16*8176Sroot  */
17*8176Sroot 
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;
258031Sroot 
268031Sroot 	u.u_r.r_val1 = NZERO+20;
278031Sroot 	u.u_error = ESRCH;
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;
378031Sroot 		u.u_r.r_val1 = u.u_procp->p_nice;
38*8176Sroot 		u.u_error = 0;
398031Sroot 		break;
408031Sroot 
418031Sroot 	case PRIO_PGRP:
428031Sroot 		if (uap->who == 0)
438031Sroot 			uap->who = u.u_procp->p_pgrp;
44*8176Sroot 		for (p = proc; p < procNPROC; p++) {
45*8176Sroot 			if (p->p_stat == NULL)
46*8176Sroot 				continue;
478031Sroot 			if (p->p_pgrp == uap->who &&
488031Sroot 			    p->p_nice < u.u_r.r_val1) {
498031Sroot 				u.u_r.r_val1 = p->p_nice;
508031Sroot 				u.u_error = 0;
518031Sroot 			}
52*8176Sroot 		}
538031Sroot 		break;
548031Sroot 
55*8176Sroot 	case PRIO_USER:
56*8176Sroot 		if (uap->who == 0)
57*8176Sroot 			uap->who = u.u_uid;
58*8176Sroot 		for (p = proc; p < procNPROC; p++) {
59*8176Sroot 			if (p->p_stat == NULL)
60*8176Sroot 				continue;
61*8176Sroot 			if (p->p_uid == uap->who &&
62*8176Sroot 			    p->p_nice < u.u_r.r_val1) {
63*8176Sroot 				u.u_r.r_val1 = p->p_nice;
64*8176Sroot 				u.u_error = 0;
65*8176Sroot 			}
66*8176Sroot 		}
67*8176Sroot 		break;
68*8176Sroot 
698031Sroot 	default:
708031Sroot 		u.u_error = EINVAL;
718031Sroot 		break;
728031Sroot 	}
738031Sroot 	u.u_r.r_val1 -= NZERO;
748031Sroot }
758031Sroot 
768031Sroot setpriority()
778031Sroot {
788031Sroot 	register struct a {
798031Sroot 		int	which;
808031Sroot 		int	who;
818031Sroot 		int	prio;
828031Sroot 	} *uap = (struct a *)u.u_ap;
838031Sroot 	register struct proc *p;
848031Sroot 
858031Sroot 	u.u_error = ESRCH;
868031Sroot 	switch (uap->which) {
878031Sroot 
888031Sroot 	case PRIO_PROCESS:
89*8176Sroot 		if (uap->who == 0)
90*8176Sroot 			p = u.u_procp;
91*8176Sroot 		else
92*8176Sroot 			p = pfind(uap->who);
938031Sroot 		if (p == 0)
948031Sroot 			return;
958031Sroot 		donice(p, uap->prio);
968031Sroot 		break;
978031Sroot 
988031Sroot 	case PRIO_PGRP:
99*8176Sroot 		if (uap->who == 0)
100*8176Sroot 			uap->who = u.u_procp->p_pgrp;
1018031Sroot 		for (p = proc; p < procNPROC; p++)
1028031Sroot 			if (p->p_pgrp == uap->who)
1038031Sroot 				donice(p, uap->prio);
1048031Sroot 		break;
1058031Sroot 
106*8176Sroot 	case PRIO_USER:
107*8176Sroot 		if (uap->who == 0)
108*8176Sroot 			uap->who = u.u_uid;
109*8176Sroot 		for (p = proc; p < procNPROC; p++)
110*8176Sroot 			if (p->p_uid == uap->who)
111*8176Sroot 				donice(p, uap->prio);
112*8176Sroot 		break;
113*8176Sroot 
1148031Sroot 	default:
1158031Sroot 		u.u_error = EINVAL;
1168031Sroot 		break;
1178031Sroot 	}
1188031Sroot }
1198031Sroot 
1208031Sroot donice(p, n)
1218031Sroot 	register struct proc *p;
1228031Sroot 	register int n;
1238031Sroot {
1248031Sroot 
1258031Sroot 	if (u.u_uid && u.u_ruid &&
1268031Sroot 	    u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
127*8176Sroot 		u.u_error = EACCES;
1288031Sroot 		return;
1298031Sroot 	}
130*8176Sroot 	n += NZERO;
1318031Sroot 	if (n >= 2*NZERO)
1328031Sroot 		n = 2*NZERO - 1;
1338031Sroot 	if (n < 0)
1348031Sroot 		n = 0;
135*8176Sroot 	if (n < p->p_nice && !suser()) {
136*8176Sroot 		u.u_error = EACCES;
1378031Sroot 		return;
138*8176Sroot 	}
1398031Sroot 	p->p_nice = n;
1408031Sroot 	(void) setpri(p);
1418031Sroot 	if (u.u_error == ESRCH)
1428031Sroot 		u.u_error = 0;
1438031Sroot }
1448031Sroot 
1458100Sroot setrlimit()
1468031Sroot {
1478031Sroot 	register struct a {
1488031Sroot 		u_int	which;
1498031Sroot 		struct	rlimit *lim;
1508031Sroot 	} *uap = (struct a *)u.u_ap;
1518031Sroot 	struct rlimit alim;
1528031Sroot 	register struct rlimit *alimp;
1538031Sroot 
1548031Sroot 	if (uap->which >= RLIM_NLIMITS) {
1558031Sroot 		u.u_error = EINVAL;
1568031Sroot 		return;
1578031Sroot 	}
1588031Sroot 	alimp = &u.u_rlimit[uap->which];
1598031Sroot 	if (copyin((caddr_t)uap->lim, (caddr_t)&alim, sizeof (struct rlimit))) {
1608031Sroot 		u.u_error = EFAULT;
1618031Sroot 		return;
1628031Sroot 	}
1638031Sroot 	if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
1648031Sroot 		if (!suser())
1658031Sroot 			return;
1668031Sroot 	switch (uap->which) {
1678031Sroot 
1688031Sroot 	case RLIMIT_DATA:
1698031Sroot 		if (alim.rlim_cur > ctob(MAXDSIZ))
1708031Sroot 			alim.rlim_cur = ctob(MAXDSIZ);
1718031Sroot 		break;
1728031Sroot 
1738031Sroot 	case RLIMIT_STACK:
1748031Sroot 		if (alim.rlim_cur > ctob(MAXSSIZ))
1758031Sroot 			alim.rlim_cur = ctob(MAXSSIZ);
1768031Sroot 		break;
1778031Sroot 	}
1788031Sroot 	*alimp = alim;
1798031Sroot 	if (uap->which == RLIMIT_RSS)
1808031Sroot 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
1818031Sroot }
1828031Sroot 
1838100Sroot getrlimit()
1848031Sroot {
1858031Sroot 	register struct a {
1868031Sroot 		u_int	which;
1878031Sroot 		struct	rlimit *rlp;
1888031Sroot 	} *uap = (struct a *)u.u_ap;
1898031Sroot 
1908031Sroot 	if (uap->which >= RLIM_NLIMITS) {
1918031Sroot 		u.u_error = EINVAL;
1928031Sroot 		return;
1938031Sroot 	}
1948031Sroot 	if (copyout((caddr_t)&u.u_rlimit[uap->which], uap->rlp,
1958031Sroot 	    sizeof (struct rlimit))) {
1968031Sroot 		u.u_error = EFAULT;
1978031Sroot 		return;
1988031Sroot 	}
1998031Sroot }
2008031Sroot 
2018031Sroot getrusage()
2028031Sroot {
2038031Sroot 	register struct a {
2048031Sroot 		int	who;
2058031Sroot 		struct	rusage *rusage;
2068031Sroot 	} *uap = (struct a *)u.u_ap;
2078031Sroot 	register struct rusage *rup;
2088031Sroot 
2098031Sroot 	switch (uap->who) {
2108031Sroot 
2118031Sroot 	case RUSAGE_SELF:
2128031Sroot 		rup = &u.u_ru;
2138031Sroot 		break;
2148031Sroot 
2158031Sroot 	case RUSAGE_CHILDREN:
2168031Sroot 		rup = &u.u_cru;
2178031Sroot 		break;
2188031Sroot 
2198031Sroot 	default:
2208031Sroot 		u.u_error = EINVAL;
2218031Sroot 		return;
2228031Sroot 	}
2238031Sroot 	if (copyout((caddr_t)rup, uap->rusage, sizeof (struct rusage))) {
2248031Sroot 		u.u_error = EFAULT;
2258031Sroot 		return;
2268031Sroot 	}
2278031Sroot }
2288031Sroot 
2298031Sroot ruadd(ru, ru2)
2308031Sroot 	register struct rusage *ru, *ru2;
2318031Sroot {
2328031Sroot 	register int *ip, *ip2;
2338031Sroot 	register int i;
2348031Sroot 
2358031Sroot 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
2368031Sroot 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
2378031Sroot 	if (ru->ru_maxrss < ru2->ru_maxrss)
2388031Sroot 		ru->ru_maxrss = ru2->ru_maxrss;
2398031Sroot 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
2408031Sroot 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
2418031Sroot 		*ip++ += *ip2++;
2428031Sroot }
2438031Sroot 
2448100Sroot #ifndef NOCOMPAT
2458100Sroot onice()
2467Sbill {
2477Sbill 	register struct a {
2488100Sroot 		int	niceness;
249*8176Sroot 	} *uap = (struct a *)u.u_ap;
250*8176Sroot 	register struct proc *p = u.u_procp;
2517Sbill 
252*8176Sroot 	donice(p, (p->p_nice-NZERO)+uap->niceness);
2537Sbill }
2547Sbill 
255*8176Sroot #include "../h/times.h"
256*8176Sroot 
2578100Sroot otimes()
2587Sbill {
259*8176Sroot 	register struct a {
260*8176Sroot 		struct	tms *tmsb;
261*8176Sroot 	} *uap = (struct a *)u.u_ap;
262*8176Sroot 	struct tms atms;
2637Sbill 
264*8176Sroot 	atms.tms_utime = scale60(&u.u_ru.ru_utime);
265*8176Sroot 	atms.tms_stime = scale60(&u.u_ru.ru_stime);
266*8176Sroot 	atms.tms_cutime = scale60(&u.u_cru.ru_utime);
267*8176Sroot 	atms.tms_cstime = scale60(&u.u_cru.ru_stime);
268*8176Sroot 	if (copyout((caddr_t)&atms, uap->tmsb, sizeof (atms))) {
269*8176Sroot 		u.u_error = EFAULT;
270*8176Sroot 		return;
271*8176Sroot 	}
2727Sbill }
2737Sbill 
274*8176Sroot scale60(tvp)
275*8176Sroot 	register struct timeval *tvp;
276*8176Sroot {
277*8176Sroot 
278*8176Sroot 	return (tvp->tv_sec * 60 + tvp->tv_usec / 16667);
279*8176Sroot }
280*8176Sroot 
281*8176Sroot #include <vtimes.h>
282*8176Sroot 
2838100Sroot ovtimes()
2847Sbill {
285*8176Sroot 	register struct a {
286*8176Sroot 		struct	vtimes *par;
287*8176Sroot 		struct	vtimes *chi;
288*8176Sroot 	} *uap = (struct a *)u.u_ap;
289*8176Sroot 	struct vtimes avt;
2907Sbill 
291*8176Sroot 	if (uap->par) {
292*8176Sroot 		getvtimes(&u.u_ru, &avt);
293*8176Sroot 		if (copyout((caddr_t)&avt, (caddr_t)uap->par, sizeof (avt))) {
294*8176Sroot 			u.u_error = EFAULT;
295*8176Sroot 			return;
296*8176Sroot 		}
297*8176Sroot 	}
298*8176Sroot 	if (uap->chi) {
299*8176Sroot 		getvtimes(&u.u_cru, &avt);
300*8176Sroot 		if (copyout((caddr_t)&avt, (caddr_t)uap->chi, sizeof (avt))) {
301*8176Sroot 			u.u_error = EFAULT;
302*8176Sroot 			return;
303*8176Sroot 		}
304*8176Sroot 	}
3057Sbill }
3067499Sroot 
307*8176Sroot getvtimes(aru, avt)
308*8176Sroot 	register struct rusage *aru;
309*8176Sroot 	register struct vtimes *avt;
310*8176Sroot {
311*8176Sroot 
312*8176Sroot 	avt->vm_utime = scale60(&aru->ru_utime);
313*8176Sroot 	avt->vm_stime = scale60(&aru->ru_stime);
314*8176Sroot 	avt->vm_idsrss = ((aru->ru_idrss+aru->ru_isrss) / hz) * 60;
315*8176Sroot 	avt->vm_ixrss = aru->ru_ixrss / hz * 60;
316*8176Sroot 	avt->vm_maxrss = aru->ru_maxrss;
317*8176Sroot 	avt->vm_majflt = aru->ru_majflt;
318*8176Sroot 	avt->vm_minflt = aru->ru_minflt;
319*8176Sroot 	avt->vm_nswap = aru->ru_nswap;
320*8176Sroot 	avt->vm_inblk = aru->ru_inblock;
321*8176Sroot 	avt->vm_oublk = aru->ru_oublock;
322*8176Sroot }
323*8176Sroot 
3248100Sroot ovlimit()
3257499Sroot {
3267499Sroot 
327*8176Sroot 	u.u_error = EACCES;
3287499Sroot }
329