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