sun
[unix-history] / usr / src / sys / kern / kern_resource.c
CommitLineData
127f7d76 1/* kern_resource.c 4.19 82/12/28 */
1b64633a
BJ
2
3#include "../h/param.h"
4#include "../h/systm.h"
1b64633a
BJ
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"
4147b3f6 10#include "../h/fs.h"
9a837405 11#include "../h/uio.h"
db1874da
BJ
12#include "../h/vm.h"
13
93cc02ac
BJ
14/*
15 * Resource controls and accounting.
16 */
17
db1874da
BJ
18getpriority()
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;
93cc02ac 38 u.u_error = 0;
db1874da
BJ
39 break;
40
41 case PRIO_PGRP:
42 if (uap->who == 0)
43 uap->who = u.u_procp->p_pgrp;
93cc02ac
BJ
44 for (p = proc; p < procNPROC; p++) {
45 if (p->p_stat == NULL)
46 continue;
db1874da
BJ
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 }
93cc02ac
BJ
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 }
db1874da
BJ
67 break;
68
69 default:
70 u.u_error = EINVAL;
71 break;
72 }
73 u.u_r.r_val1 -= NZERO;
74}
75
76setpriority()
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:
93cc02ac
BJ
89 if (uap->who == 0)
90 p = u.u_procp;
91 else
92 p = pfind(uap->who);
db1874da
BJ
93 if (p == 0)
94 return;
95 donice(p, uap->prio);
96 break;
97
98 case PRIO_PGRP:
93cc02ac
BJ
99 if (uap->who == 0)
100 uap->who = u.u_procp->p_pgrp;
db1874da
BJ
101 for (p = proc; p < procNPROC; p++)
102 if (p->p_pgrp == uap->who)
103 donice(p, uap->prio);
104 break;
105
93cc02ac
BJ
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
db1874da
BJ
114 default:
115 u.u_error = EINVAL;
116 break;
117 }
118}
119
120donice(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) {
93cc02ac 127 u.u_error = EACCES;
db1874da
BJ
128 return;
129 }
93cc02ac 130 n += NZERO;
db1874da
BJ
131 if (n >= 2*NZERO)
132 n = 2*NZERO - 1;
133 if (n < 0)
134 n = 0;
93cc02ac
BJ
135 if (n < p->p_nice && !suser()) {
136 u.u_error = EACCES;
db1874da 137 return;
93cc02ac 138 }
db1874da
BJ
139 p->p_nice = n;
140 (void) setpri(p);
141 if (u.u_error == ESRCH)
142 u.u_error = 0;
143}
144
1edb1cf8 145setrlimit()
db1874da
BJ
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];
127f7d76
SL
159 u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
160 sizeof (struct rlimit));
161 if (u.u_error)
db1874da 162 return;
db1874da
BJ
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
1edb1cf8 183getrlimit()
db1874da
BJ
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 }
127f7d76
SL
194 u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
195 sizeof (struct rlimit));
db1874da
BJ
196}
197
198getrusage()
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 }
127f7d76
SL
220 u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
221 sizeof (struct rusage));
db1874da
BJ
222}
223
224ruadd(ru, ru2)
225 register struct rusage *ru, *ru2;
226{
3fd23f5c 227 register long *ip, *ip2;
db1874da
BJ
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}
1b64633a 238
1edb1cf8
BJ
239#ifndef NOCOMPAT
240onice()
1b64633a 241{
1b64633a 242 register struct a {
1edb1cf8 243 int niceness;
93cc02ac
BJ
244 } *uap = (struct a *)u.u_ap;
245 register struct proc *p = u.u_procp;
1b64633a 246
93cc02ac 247 donice(p, (p->p_nice-NZERO)+uap->niceness);
1b64633a 248}
93cc02ac
BJ
249
250#include "../h/times.h"
1b64633a 251
1edb1cf8 252otimes()
93cc02ac
BJ
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);
127f7d76 263 u.u_error = copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms));
93cc02ac
BJ
264}
265
266scale60(tvp)
267 register struct timeval *tvp;
1b64633a 268{
1edb1cf8 269
93cc02ac 270 return (tvp->tv_sec * 60 + tvp->tv_usec / 16667);
1b64633a
BJ
271}
272
961945a8 273#include "../h/vtimes.h"
93cc02ac 274
1edb1cf8 275ovtimes()
93cc02ac
BJ
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);
127f7d76
SL
285 u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->par,
286 sizeof (avt));
287 if (u.u_error)
93cc02ac 288 return;
93cc02ac
BJ
289 }
290 if (uap->chi) {
291 getvtimes(&u.u_cru, &avt);
127f7d76
SL
292 u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->chi,
293 sizeof (avt));
294 if (u.u_error)
93cc02ac 295 return;
93cc02ac
BJ
296 }
297}
298
299getvtimes(aru, avt)
300 register struct rusage *aru;
301 register struct vtimes *avt;
1b64633a 302{
1b64633a 303
93cc02ac
BJ
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;
1b64633a 314}
4147b3f6 315
1edb1cf8 316ovlimit()
4147b3f6 317{
4147b3f6 318
93cc02ac 319 u.u_error = EACCES;
4147b3f6 320}