|
|
1.1 root 1: /*-
2: * Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
1.1.1.3 ! root 33: * from: @(#)kern_resource.c 7.13 (Berkeley) 5/9/91
! 34: * kern_resource.c,v 1.7 1993/07/13 22:13:25 cgd Exp
1.1 root 35: */
36:
37: #include "param.h"
1.1.1.3 ! root 38: #include "systm.h"
1.1 root 39: #include "resourcevar.h"
40: #include "malloc.h"
41: #include "proc.h"
42:
43: #include "vm/vm.h"
44:
45: /*
46: * Resource controls and accounting.
47: */
48:
1.1.1.3 ! root 49: struct getpriority_args {
! 50: int which;
! 51: int who;
! 52: };
! 53:
! 54: int
1.1 root 55: getpriority(curp, uap, retval)
56: struct proc *curp;
1.1.1.3 ! root 57: register struct getpriority_args *uap;
1.1 root 58: int *retval;
59: {
60: register struct proc *p;
61: register int low = PRIO_MAX + 1;
62:
63: switch (uap->which) {
64:
65: case PRIO_PROCESS:
66: if (uap->who == 0)
67: p = curp;
68: else
69: p = pfind(uap->who);
70: if (p == 0)
71: break;
72: low = p->p_nice;
73: break;
74:
75: case PRIO_PGRP: {
76: register struct pgrp *pg;
77:
78: if (uap->who == 0)
79: pg = curp->p_pgrp;
80: else if ((pg = pgfind(uap->who)) == NULL)
81: break;
82: for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
83: if (p->p_nice < low)
84: low = p->p_nice;
85: }
86: break;
87: }
88:
89: case PRIO_USER:
90: if (uap->who == 0)
91: uap->who = curp->p_ucred->cr_uid;
92: for (p = allproc; p != NULL; p = p->p_nxt) {
93: if (p->p_ucred->cr_uid == uap->who &&
94: p->p_nice < low)
95: low = p->p_nice;
96: }
97: break;
98:
99: default:
100: return (EINVAL);
101: }
102: if (low == PRIO_MAX + 1)
103: return (ESRCH);
104: *retval = low;
105: return (0);
106: }
107:
1.1.1.3 ! root 108: struct setpriority_args {
! 109: int which;
! 110: int who;
! 111: int prio;
! 112: };
! 113:
1.1 root 114: /* ARGSUSED */
1.1.1.3 ! root 115: int
1.1 root 116: setpriority(curp, uap, retval)
117: struct proc *curp;
1.1.1.3 ! root 118: register struct setpriority_args *uap;
1.1 root 119: int *retval;
120: {
121: register struct proc *p;
122: int found = 0, error = 0;
123:
124: switch (uap->which) {
125:
126: case PRIO_PROCESS:
127: if (uap->who == 0)
128: p = curp;
129: else
130: p = pfind(uap->who);
131: if (p == 0)
132: break;
133: error = donice(curp, p, uap->prio);
134: found++;
135: break;
136:
137: case PRIO_PGRP: {
138: register struct pgrp *pg;
139:
140: if (uap->who == 0)
141: pg = curp->p_pgrp;
142: else if ((pg = pgfind(uap->who)) == NULL)
143: break;
144: for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
145: error = donice(curp, p, uap->prio);
146: found++;
147: }
148: break;
149: }
150:
151: case PRIO_USER:
152: if (uap->who == 0)
153: uap->who = curp->p_ucred->cr_uid;
154: for (p = allproc; p != NULL; p = p->p_nxt)
155: if (p->p_ucred->cr_uid == uap->who) {
156: error = donice(curp, p, uap->prio);
157: found++;
158: }
159: break;
160:
161: default:
162: return (EINVAL);
163: }
164: if (found == 0)
165: return (ESRCH);
166: return (0);
167: }
168:
1.1.1.3 ! root 169: int
1.1 root 170: donice(curp, chgp, n)
171: register struct proc *curp, *chgp;
172: register int n;
173: {
174: register struct pcred *pcred = curp->p_cred;
175:
176: if (pcred->pc_ucred->cr_uid && pcred->p_ruid &&
177: pcred->pc_ucred->cr_uid != chgp->p_ucred->cr_uid &&
178: pcred->p_ruid != chgp->p_ucred->cr_uid)
179: return (EPERM);
180: if (n > PRIO_MAX)
181: n = PRIO_MAX;
182: if (n < PRIO_MIN)
183: n = PRIO_MIN;
184: if (n < chgp->p_nice && suser(pcred->pc_ucred, &curp->p_acflag))
185: return (EACCES);
186: chgp->p_nice = n;
187: (void) setpri(chgp);
188: return (0);
189: }
190:
1.1.1.3 ! root 191: struct setrlimit_args {
! 192: u_int which;
! 193: struct rlimit *lim;
! 194: };
! 195:
1.1 root 196: /* ARGSUSED */
1.1.1.3 ! root 197: int
1.1 root 198: setrlimit(p, uap, retval)
199: struct proc *p;
1.1.1.3 ! root 200: register struct setrlimit_args *uap;
1.1 root 201: int *retval;
202: {
203: struct rlimit alim;
204: register struct rlimit *alimp;
205: extern unsigned maxdmap;
1.1.1.3 ! root 206: extern int maxfdescs;
1.1 root 207: int error;
208:
209: if (uap->which >= RLIM_NLIMITS)
210: return (EINVAL);
211: alimp = &p->p_rlimit[uap->which];
212: if (error =
213: copyin((caddr_t)uap->lim, (caddr_t)&alim, sizeof (struct rlimit)))
214: return (error);
215: if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
216: if (error = suser(p->p_ucred, &p->p_acflag))
217: return (error);
1.1.1.3 ! root 218: if (alim.rlim_cur > alim.rlim_max)
! 219: alim.rlim_cur = alim.rlim_max;
1.1 root 220: if (p->p_limit->p_refcnt > 1 &&
221: (p->p_limit->p_lflags & PL_SHAREMOD) == 0) {
222: p->p_limit->p_refcnt--;
223: p->p_limit = limcopy(p->p_limit);
224: }
225:
226: switch (uap->which) {
227:
228: case RLIMIT_DATA:
229: if (alim.rlim_cur > maxdmap)
230: alim.rlim_cur = maxdmap;
231: if (alim.rlim_max > maxdmap)
232: alim.rlim_max = maxdmap;
233: break;
234:
1.1.1.3 ! root 235: case RLIMIT_OFILE:
! 236: if (alim.rlim_cur > maxfdescs)
! 237: alim.rlim_cur = maxfdescs;
! 238: if (alim.rlim_max > maxfdescs)
! 239: alim.rlim_max = maxfdescs;
! 240: break;
1.1 root 241: case RLIMIT_STACK:
242: if (alim.rlim_cur > maxdmap)
243: alim.rlim_cur = maxdmap;
244: if (alim.rlim_max > maxdmap)
245: alim.rlim_max = maxdmap;
246: /*
247: * Stack is allocated to the max at exec time with only
248: * "rlim_cur" bytes accessible. If stack limit is going
249: * up make more accessible, if going down make inaccessible.
250: */
251: if (alim.rlim_cur != alimp->rlim_cur) {
252: vm_offset_t addr;
253: vm_size_t size;
254: vm_prot_t prot;
255:
256: if (alim.rlim_cur > alimp->rlim_cur) {
257: prot = VM_PROT_ALL;
258: size = alim.rlim_cur - alimp->rlim_cur;
1.1.1.3 ! root 259: addr = USRSTACK - alim.rlim_cur;
1.1 root 260: } else {
261: prot = VM_PROT_NONE;
262: size = alimp->rlim_cur - alim.rlim_cur;
1.1.1.3 ! root 263: addr = USRSTACK - alimp->rlim_cur;
1.1 root 264: }
265: addr = trunc_page(addr);
266: size = round_page(size);
267: (void) vm_map_protect(&p->p_vmspace->vm_map,
268: addr, addr+size, prot, FALSE);
269: }
270: break;
271: }
272: p->p_rlimit[uap->which] = alim;
273: return (0);
274: }
275:
1.1.1.3 ! root 276: struct getrlimit_args {
! 277: u_int which;
! 278: struct rlimit *rlp;
! 279: };
! 280:
1.1 root 281: /* ARGSUSED */
1.1.1.3 ! root 282: int
1.1 root 283: getrlimit(p, uap, retval)
284: struct proc *p;
1.1.1.3 ! root 285: register struct getrlimit_args *uap;
1.1 root 286: int *retval;
287: {
288:
289: if (uap->which >= RLIM_NLIMITS)
290: return (EINVAL);
291: return (copyout((caddr_t)&p->p_rlimit[uap->which], (caddr_t)uap->rlp,
292: sizeof (struct rlimit)));
293: }
294:
1.1.1.3 ! root 295: struct getrusage_args {
! 296: int who;
! 297: struct rusage *rusage;
! 298: };
! 299:
1.1 root 300: /* ARGSUSED */
1.1.1.3 ! root 301: int
1.1 root 302: getrusage(p, uap, retval)
303: register struct proc *p;
1.1.1.3 ! root 304: register struct getrusage_args *uap;
1.1 root 305: int *retval;
306: {
307: register struct rusage *rup;
308:
309: switch (uap->who) {
310:
311: case RUSAGE_SELF: {
312: int s;
313:
314: rup = &p->p_stats->p_ru;
315: s = splclock();
316: rup->ru_stime = p->p_stime;
317: rup->ru_utime = p->p_utime;
318: splx(s);
319: break;
320: }
321:
322: case RUSAGE_CHILDREN:
323: rup = &p->p_stats->p_cru;
324: break;
325:
326: default:
327: return (EINVAL);
328: }
329: return (copyout((caddr_t)rup, (caddr_t)uap->rusage,
330: sizeof (struct rusage)));
331: }
332:
1.1.1.3 ! root 333: void
1.1 root 334: ruadd(ru, ru2)
335: register struct rusage *ru, *ru2;
336: {
337: register long *ip, *ip2;
338: register int i;
339:
340: timevaladd(&ru->ru_utime, &ru2->ru_utime);
341: timevaladd(&ru->ru_stime, &ru2->ru_stime);
342: if (ru->ru_maxrss < ru2->ru_maxrss)
343: ru->ru_maxrss = ru2->ru_maxrss;
344: ip = &ru->ru_first; ip2 = &ru2->ru_first;
1.1.1.3 ! root 345: for (i = &ru->ru_last - &ru->ru_first; i >= 0; i--)
1.1 root 346: *ip++ += *ip2++;
347: }
348:
349: /*
350: * Make a copy of the plimit structure.
351: * We share these structures copy-on-write after fork,
352: * and copy when a limit is changed.
353: */
354: struct plimit *
355: limcopy(lim)
356: struct plimit *lim;
357: {
358: register struct plimit *copy;
359:
360: MALLOC(copy, struct plimit *, sizeof(struct plimit),
361: M_SUBPROC, M_WAITOK);
362: bcopy(lim->pl_rlimit, copy->pl_rlimit,
363: sizeof(struct rlimit) * RLIM_NLIMITS);
364: copy->p_lflags = 0;
365: copy->p_refcnt = 1;
366: return (copy);
367: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.