xref: /csrg-svn/sys/kern/kern_resource.c (revision 9997)
1*9997Ssam /*	kern_resource.c	4.19	82/12/28	*/
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 
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;
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;
388176Sroot 		u.u_error = 0;
398031Sroot 		break;
408031Sroot 
418031Sroot 	case PRIO_PGRP:
428031Sroot 		if (uap->who == 0)
438031Sroot 			uap->who = u.u_procp->p_pgrp;
448176Sroot 		for (p = proc; p < procNPROC; p++) {
458176Sroot 			if (p->p_stat == NULL)
468176Sroot 				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 			}
528176Sroot 		}
538031Sroot 		break;
548031Sroot 
558176Sroot 	case PRIO_USER:
568176Sroot 		if (uap->who == 0)
578176Sroot 			uap->who = u.u_uid;
588176Sroot 		for (p = proc; p < procNPROC; p++) {
598176Sroot 			if (p->p_stat == NULL)
608176Sroot 				continue;
618176Sroot 			if (p->p_uid == uap->who &&
628176Sroot 			    p->p_nice < u.u_r.r_val1) {
638176Sroot 				u.u_r.r_val1 = p->p_nice;
648176Sroot 				u.u_error = 0;
658176Sroot 			}
668176Sroot 		}
678176Sroot 		break;
688176Sroot 
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:
898176Sroot 		if (uap->who == 0)
908176Sroot 			p = u.u_procp;
918176Sroot 		else
928176Sroot 			p = pfind(uap->who);
938031Sroot 		if (p == 0)
948031Sroot 			return;
958031Sroot 		donice(p, uap->prio);
968031Sroot 		break;
978031Sroot 
988031Sroot 	case PRIO_PGRP:
998176Sroot 		if (uap->who == 0)
1008176Sroot 			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 
1068176Sroot 	case PRIO_USER:
1078176Sroot 		if (uap->who == 0)
1088176Sroot 			uap->who = u.u_uid;
1098176Sroot 		for (p = proc; p < procNPROC; p++)
1108176Sroot 			if (p->p_uid == uap->who)
1118176Sroot 				donice(p, uap->prio);
1128176Sroot 		break;
1138176Sroot 
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) {
1278176Sroot 		u.u_error = EACCES;
1288031Sroot 		return;
1298031Sroot 	}
1308176Sroot 	n += NZERO;
1318031Sroot 	if (n >= 2*NZERO)
1328031Sroot 		n = 2*NZERO - 1;
1338031Sroot 	if (n < 0)
1348031Sroot 		n = 0;
1358176Sroot 	if (n < p->p_nice && !suser()) {
1368176Sroot 		u.u_error = EACCES;
1378031Sroot 		return;
1388176Sroot 	}
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];
159*9997Ssam 	u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
160*9997Ssam 		sizeof (struct rlimit));
161*9997Ssam 	if (u.u_error)
1628031Sroot 		return;
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 	}
194*9997Ssam 	u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
195*9997Ssam 	    sizeof (struct rlimit));
1968031Sroot }
1978031Sroot 
1988031Sroot getrusage()
1998031Sroot {
2008031Sroot 	register struct a {
2018031Sroot 		int	who;
2028031Sroot 		struct	rusage *rusage;
2038031Sroot 	} *uap = (struct a *)u.u_ap;
2048031Sroot 	register struct rusage *rup;
2058031Sroot 
2068031Sroot 	switch (uap->who) {
2078031Sroot 
2088031Sroot 	case RUSAGE_SELF:
2098031Sroot 		rup = &u.u_ru;
2108031Sroot 		break;
2118031Sroot 
2128031Sroot 	case RUSAGE_CHILDREN:
2138031Sroot 		rup = &u.u_cru;
2148031Sroot 		break;
2158031Sroot 
2168031Sroot 	default:
2178031Sroot 		u.u_error = EINVAL;
2188031Sroot 		return;
2198031Sroot 	}
220*9997Ssam 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
221*9997Ssam 	    sizeof (struct rusage));
2228031Sroot }
2238031Sroot 
2248031Sroot ruadd(ru, ru2)
2258031Sroot 	register struct rusage *ru, *ru2;
2268031Sroot {
2278666Sroot 	register long *ip, *ip2;
2288031Sroot 	register int i;
2298031Sroot 
2308031Sroot 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
2318031Sroot 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
2328031Sroot 	if (ru->ru_maxrss < ru2->ru_maxrss)
2338031Sroot 		ru->ru_maxrss = ru2->ru_maxrss;
2348031Sroot 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
2358031Sroot 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
2368031Sroot 		*ip++ += *ip2++;
2378031Sroot }
2388031Sroot 
2398100Sroot #ifndef NOCOMPAT
2408100Sroot onice()
2417Sbill {
2427Sbill 	register struct a {
2438100Sroot 		int	niceness;
2448176Sroot 	} *uap = (struct a *)u.u_ap;
2458176Sroot 	register struct proc *p = u.u_procp;
2467Sbill 
2478176Sroot 	donice(p, (p->p_nice-NZERO)+uap->niceness);
2487Sbill }
2497Sbill 
2508176Sroot #include "../h/times.h"
2518176Sroot 
2528100Sroot otimes()
2537Sbill {
2548176Sroot 	register struct a {
2558176Sroot 		struct	tms *tmsb;
2568176Sroot 	} *uap = (struct a *)u.u_ap;
2578176Sroot 	struct tms atms;
2587Sbill 
2598176Sroot 	atms.tms_utime = scale60(&u.u_ru.ru_utime);
2608176Sroot 	atms.tms_stime = scale60(&u.u_ru.ru_stime);
2618176Sroot 	atms.tms_cutime = scale60(&u.u_cru.ru_utime);
2628176Sroot 	atms.tms_cstime = scale60(&u.u_cru.ru_stime);
263*9997Ssam 	u.u_error = copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms));
2647Sbill }
2657Sbill 
2668176Sroot scale60(tvp)
2678176Sroot 	register struct timeval *tvp;
2688176Sroot {
2698176Sroot 
2708176Sroot 	return (tvp->tv_sec * 60 + tvp->tv_usec / 16667);
2718176Sroot }
2728176Sroot 
2739754Ssam #include "../h/vtimes.h"
2748176Sroot 
2758100Sroot ovtimes()
2767Sbill {
2778176Sroot 	register struct a {
2788176Sroot 		struct	vtimes *par;
2798176Sroot 		struct	vtimes *chi;
2808176Sroot 	} *uap = (struct a *)u.u_ap;
2818176Sroot 	struct vtimes avt;
2827Sbill 
2838176Sroot 	if (uap->par) {
2848176Sroot 		getvtimes(&u.u_ru, &avt);
285*9997Ssam 		u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->par,
286*9997Ssam 			sizeof (avt));
287*9997Ssam 		if (u.u_error)
2888176Sroot 			return;
2898176Sroot 	}
2908176Sroot 	if (uap->chi) {
2918176Sroot 		getvtimes(&u.u_cru, &avt);
292*9997Ssam 		u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->chi,
293*9997Ssam 			sizeof (avt));
294*9997Ssam 		if (u.u_error)
2958176Sroot 			return;
2968176Sroot 	}
2977Sbill }
2987499Sroot 
2998176Sroot getvtimes(aru, avt)
3008176Sroot 	register struct rusage *aru;
3018176Sroot 	register struct vtimes *avt;
3028176Sroot {
3038176Sroot 
3048176Sroot 	avt->vm_utime = scale60(&aru->ru_utime);
3058176Sroot 	avt->vm_stime = scale60(&aru->ru_stime);
3068176Sroot 	avt->vm_idsrss = ((aru->ru_idrss+aru->ru_isrss) / hz) * 60;
3078176Sroot 	avt->vm_ixrss = aru->ru_ixrss / hz * 60;
3088176Sroot 	avt->vm_maxrss = aru->ru_maxrss;
3098176Sroot 	avt->vm_majflt = aru->ru_majflt;
3108176Sroot 	avt->vm_minflt = aru->ru_minflt;
3118176Sroot 	avt->vm_nswap = aru->ru_nswap;
3128176Sroot 	avt->vm_inblk = aru->ru_inblock;
3138176Sroot 	avt->vm_oublk = aru->ru_oublock;
3148176Sroot }
3158176Sroot 
3168100Sroot ovlimit()
3177499Sroot {
3187499Sroot 
3198176Sroot 	u.u_error = EACCES;
3207499Sroot }
321