xref: /csrg-svn/sys/kern/kern_resource.c (revision 10867)
1 /*	kern_resource.c	4.20	83/02/10	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/dir.h"
6 #include "../h/user.h"
7 #include "../h/inode.h"
8 #include "../h/proc.h"
9 #include "../h/seg.h"
10 #include "../h/fs.h"
11 #include "../h/uio.h"
12 #include "../h/vm.h"
13 #include "../h/kernel.h"
14 
15 /*
16  * Resource controls and accounting.
17  */
18 
19 getpriority()
20 {
21 	register struct a {
22 		int	which;
23 		int	who;
24 	} *uap = (struct a *)u.u_ap;
25 	register struct proc *p;
26 
27 	u.u_r.r_val1 = NZERO+20;
28 	u.u_error = ESRCH;
29 	switch (uap->which) {
30 
31 	case PRIO_PROCESS:
32 		if (uap->who == 0)
33 			p = u.u_procp;
34 		else
35 			p = pfind(uap->who);
36 		if (p == 0)
37 			return;
38 		u.u_r.r_val1 = u.u_procp->p_nice;
39 		u.u_error = 0;
40 		break;
41 
42 	case PRIO_PGRP:
43 		if (uap->who == 0)
44 			uap->who = u.u_procp->p_pgrp;
45 		for (p = proc; p < procNPROC; p++) {
46 			if (p->p_stat == NULL)
47 				continue;
48 			if (p->p_pgrp == uap->who &&
49 			    p->p_nice < u.u_r.r_val1) {
50 				u.u_r.r_val1 = p->p_nice;
51 				u.u_error = 0;
52 			}
53 		}
54 		break;
55 
56 	case PRIO_USER:
57 		if (uap->who == 0)
58 			uap->who = u.u_uid;
59 		for (p = proc; p < procNPROC; p++) {
60 			if (p->p_stat == NULL)
61 				continue;
62 			if (p->p_uid == uap->who &&
63 			    p->p_nice < u.u_r.r_val1) {
64 				u.u_r.r_val1 = p->p_nice;
65 				u.u_error = 0;
66 			}
67 		}
68 		break;
69 
70 	default:
71 		u.u_error = EINVAL;
72 		break;
73 	}
74 	u.u_r.r_val1 -= NZERO;
75 }
76 
77 setpriority()
78 {
79 	register struct a {
80 		int	which;
81 		int	who;
82 		int	prio;
83 	} *uap = (struct a *)u.u_ap;
84 	register struct proc *p;
85 
86 	u.u_error = ESRCH;
87 	switch (uap->which) {
88 
89 	case PRIO_PROCESS:
90 		if (uap->who == 0)
91 			p = u.u_procp;
92 		else
93 			p = pfind(uap->who);
94 		if (p == 0)
95 			return;
96 		donice(p, uap->prio);
97 		break;
98 
99 	case PRIO_PGRP:
100 		if (uap->who == 0)
101 			uap->who = u.u_procp->p_pgrp;
102 		for (p = proc; p < procNPROC; p++)
103 			if (p->p_pgrp == uap->who)
104 				donice(p, uap->prio);
105 		break;
106 
107 	case PRIO_USER:
108 		if (uap->who == 0)
109 			uap->who = u.u_uid;
110 		for (p = proc; p < procNPROC; p++)
111 			if (p->p_uid == uap->who)
112 				donice(p, uap->prio);
113 		break;
114 
115 	default:
116 		u.u_error = EINVAL;
117 		break;
118 	}
119 }
120 
121 donice(p, n)
122 	register struct proc *p;
123 	register int n;
124 {
125 
126 	if (u.u_uid && u.u_ruid &&
127 	    u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
128 		u.u_error = EACCES;
129 		return;
130 	}
131 	n += NZERO;
132 	if (n >= 2*NZERO)
133 		n = 2*NZERO - 1;
134 	if (n < 0)
135 		n = 0;
136 	if (n < p->p_nice && !suser()) {
137 		u.u_error = EACCES;
138 		return;
139 	}
140 	p->p_nice = n;
141 	(void) setpri(p);
142 	if (u.u_error == ESRCH)
143 		u.u_error = 0;
144 }
145 
146 setrlimit()
147 {
148 	register struct a {
149 		u_int	which;
150 		struct	rlimit *lim;
151 	} *uap = (struct a *)u.u_ap;
152 	struct rlimit alim;
153 	register struct rlimit *alimp;
154 
155 	if (uap->which >= RLIM_NLIMITS) {
156 		u.u_error = EINVAL;
157 		return;
158 	}
159 	alimp = &u.u_rlimit[uap->which];
160 	u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
161 		sizeof (struct rlimit));
162 	if (u.u_error)
163 		return;
164 	if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
165 		if (!suser())
166 			return;
167 	switch (uap->which) {
168 
169 	case RLIMIT_DATA:
170 		if (alim.rlim_cur > ctob(MAXDSIZ))
171 			alim.rlim_cur = ctob(MAXDSIZ);
172 		break;
173 
174 	case RLIMIT_STACK:
175 		if (alim.rlim_cur > ctob(MAXSSIZ))
176 			alim.rlim_cur = ctob(MAXSSIZ);
177 		break;
178 	}
179 	*alimp = alim;
180 	if (uap->which == RLIMIT_RSS)
181 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
182 }
183 
184 getrlimit()
185 {
186 	register struct a {
187 		u_int	which;
188 		struct	rlimit *rlp;
189 	} *uap = (struct a *)u.u_ap;
190 
191 	if (uap->which >= RLIM_NLIMITS) {
192 		u.u_error = EINVAL;
193 		return;
194 	}
195 	u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
196 	    sizeof (struct rlimit));
197 }
198 
199 getrusage()
200 {
201 	register struct a {
202 		int	who;
203 		struct	rusage *rusage;
204 	} *uap = (struct a *)u.u_ap;
205 	register struct rusage *rup;
206 
207 	switch (uap->who) {
208 
209 	case RUSAGE_SELF:
210 		rup = &u.u_ru;
211 		break;
212 
213 	case RUSAGE_CHILDREN:
214 		rup = &u.u_cru;
215 		break;
216 
217 	default:
218 		u.u_error = EINVAL;
219 		return;
220 	}
221 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
222 	    sizeof (struct rusage));
223 }
224 
225 ruadd(ru, ru2)
226 	register struct rusage *ru, *ru2;
227 {
228 	register long *ip, *ip2;
229 	register int i;
230 
231 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
232 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
233 	if (ru->ru_maxrss < ru2->ru_maxrss)
234 		ru->ru_maxrss = ru2->ru_maxrss;
235 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
236 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
237 		*ip++ += *ip2++;
238 }
239 
240 #ifndef NOCOMPAT
241 onice()
242 {
243 	register struct a {
244 		int	niceness;
245 	} *uap = (struct a *)u.u_ap;
246 	register struct proc *p = u.u_procp;
247 
248 	donice(p, (p->p_nice-NZERO)+uap->niceness);
249 }
250 
251 #include "../h/times.h"
252 
253 otimes()
254 {
255 	register struct a {
256 		struct	tms *tmsb;
257 	} *uap = (struct a *)u.u_ap;
258 	struct tms atms;
259 
260 	atms.tms_utime = scale60(&u.u_ru.ru_utime);
261 	atms.tms_stime = scale60(&u.u_ru.ru_stime);
262 	atms.tms_cutime = scale60(&u.u_cru.ru_utime);
263 	atms.tms_cstime = scale60(&u.u_cru.ru_stime);
264 	u.u_error = copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms));
265 }
266 
267 scale60(tvp)
268 	register struct timeval *tvp;
269 {
270 
271 	return (tvp->tv_sec * 60 + tvp->tv_usec / 16667);
272 }
273 
274 #include "../h/vtimes.h"
275 
276 ovtimes()
277 {
278 	register struct a {
279 		struct	vtimes *par;
280 		struct	vtimes *chi;
281 	} *uap = (struct a *)u.u_ap;
282 	struct vtimes avt;
283 
284 	if (uap->par) {
285 		getvtimes(&u.u_ru, &avt);
286 		u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->par,
287 			sizeof (avt));
288 		if (u.u_error)
289 			return;
290 	}
291 	if (uap->chi) {
292 		getvtimes(&u.u_cru, &avt);
293 		u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->chi,
294 			sizeof (avt));
295 		if (u.u_error)
296 			return;
297 	}
298 }
299 
300 getvtimes(aru, avt)
301 	register struct rusage *aru;
302 	register struct vtimes *avt;
303 {
304 
305 	avt->vm_utime = scale60(&aru->ru_utime);
306 	avt->vm_stime = scale60(&aru->ru_stime);
307 	avt->vm_idsrss = ((aru->ru_idrss+aru->ru_isrss) / hz) * 60;
308 	avt->vm_ixrss = aru->ru_ixrss / hz * 60;
309 	avt->vm_maxrss = aru->ru_maxrss;
310 	avt->vm_majflt = aru->ru_majflt;
311 	avt->vm_minflt = aru->ru_minflt;
312 	avt->vm_nswap = aru->ru_nswap;
313 	avt->vm_inblk = aru->ru_inblock;
314 	avt->vm_oublk = aru->ru_oublock;
315 }
316 
317 ovlimit()
318 {
319 
320 	u.u_error = EACCES;
321 }
322