|
|
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: * ! 33: * @(#)kern_resource.c 7.13 (Berkeley) 5/9/91 ! 34: */ ! 35: ! 36: #include "param.h" ! 37: #include "resourcevar.h" ! 38: #include "malloc.h" ! 39: #include "proc.h" ! 40: ! 41: #include "vm/vm.h" ! 42: ! 43: /* ! 44: * Resource controls and accounting. ! 45: */ ! 46: ! 47: getpriority(curp, uap, retval) ! 48: struct proc *curp; ! 49: register struct args { ! 50: int which; ! 51: int who; ! 52: } *uap; ! 53: int *retval; ! 54: { ! 55: register struct proc *p; ! 56: register int low = PRIO_MAX + 1; ! 57: ! 58: switch (uap->which) { ! 59: ! 60: case PRIO_PROCESS: ! 61: if (uap->who == 0) ! 62: p = curp; ! 63: else ! 64: p = pfind(uap->who); ! 65: if (p == 0) ! 66: break; ! 67: low = p->p_nice; ! 68: break; ! 69: ! 70: case PRIO_PGRP: { ! 71: register struct pgrp *pg; ! 72: ! 73: if (uap->who == 0) ! 74: pg = curp->p_pgrp; ! 75: else if ((pg = pgfind(uap->who)) == NULL) ! 76: break; ! 77: for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { ! 78: if (p->p_nice < low) ! 79: low = p->p_nice; ! 80: } ! 81: break; ! 82: } ! 83: ! 84: case PRIO_USER: ! 85: if (uap->who == 0) ! 86: uap->who = curp->p_ucred->cr_uid; ! 87: for (p = allproc; p != NULL; p = p->p_nxt) { ! 88: if (p->p_ucred->cr_uid == uap->who && ! 89: p->p_nice < low) ! 90: low = p->p_nice; ! 91: } ! 92: break; ! 93: ! 94: default: ! 95: return (EINVAL); ! 96: } ! 97: if (low == PRIO_MAX + 1) ! 98: return (ESRCH); ! 99: *retval = low; ! 100: return (0); ! 101: } ! 102: ! 103: /* ARGSUSED */ ! 104: setpriority(curp, uap, retval) ! 105: struct proc *curp; ! 106: register struct args { ! 107: int which; ! 108: int who; ! 109: int prio; ! 110: } *uap; ! 111: int *retval; ! 112: { ! 113: register struct proc *p; ! 114: int found = 0, error = 0; ! 115: ! 116: switch (uap->which) { ! 117: ! 118: case PRIO_PROCESS: ! 119: if (uap->who == 0) ! 120: p = curp; ! 121: else ! 122: p = pfind(uap->who); ! 123: if (p == 0) ! 124: break; ! 125: error = donice(curp, p, uap->prio); ! 126: found++; ! 127: break; ! 128: ! 129: case PRIO_PGRP: { ! 130: register struct pgrp *pg; ! 131: ! 132: if (uap->who == 0) ! 133: pg = curp->p_pgrp; ! 134: else if ((pg = pgfind(uap->who)) == NULL) ! 135: break; ! 136: for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { ! 137: error = donice(curp, p, uap->prio); ! 138: found++; ! 139: } ! 140: break; ! 141: } ! 142: ! 143: case PRIO_USER: ! 144: if (uap->who == 0) ! 145: uap->who = curp->p_ucred->cr_uid; ! 146: for (p = allproc; p != NULL; p = p->p_nxt) ! 147: if (p->p_ucred->cr_uid == uap->who) { ! 148: error = donice(curp, p, uap->prio); ! 149: found++; ! 150: } ! 151: break; ! 152: ! 153: default: ! 154: return (EINVAL); ! 155: } ! 156: if (found == 0) ! 157: return (ESRCH); ! 158: return (0); ! 159: } ! 160: ! 161: donice(curp, chgp, n) ! 162: register struct proc *curp, *chgp; ! 163: register int n; ! 164: { ! 165: register struct pcred *pcred = curp->p_cred; ! 166: ! 167: if (pcred->pc_ucred->cr_uid && pcred->p_ruid && ! 168: pcred->pc_ucred->cr_uid != chgp->p_ucred->cr_uid && ! 169: pcred->p_ruid != chgp->p_ucred->cr_uid) ! 170: return (EPERM); ! 171: if (n > PRIO_MAX) ! 172: n = PRIO_MAX; ! 173: if (n < PRIO_MIN) ! 174: n = PRIO_MIN; ! 175: if (n < chgp->p_nice && suser(pcred->pc_ucred, &curp->p_acflag)) ! 176: return (EACCES); ! 177: chgp->p_nice = n; ! 178: (void) setpri(chgp); ! 179: return (0); ! 180: } ! 181: ! 182: /* ARGSUSED */ ! 183: setrlimit(p, uap, retval) ! 184: struct proc *p; ! 185: register struct args { ! 186: u_int which; ! 187: struct rlimit *lim; ! 188: } *uap; ! 189: int *retval; ! 190: { ! 191: struct rlimit alim; ! 192: register struct rlimit *alimp; ! 193: extern unsigned maxdmap; ! 194: int error; ! 195: ! 196: if (uap->which >= RLIM_NLIMITS) ! 197: return (EINVAL); ! 198: alimp = &p->p_rlimit[uap->which]; ! 199: if (error = ! 200: copyin((caddr_t)uap->lim, (caddr_t)&alim, sizeof (struct rlimit))) ! 201: return (error); ! 202: if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) ! 203: if (error = suser(p->p_ucred, &p->p_acflag)) ! 204: return (error); ! 205: if (p->p_limit->p_refcnt > 1 && ! 206: (p->p_limit->p_lflags & PL_SHAREMOD) == 0) { ! 207: p->p_limit->p_refcnt--; ! 208: p->p_limit = limcopy(p->p_limit); ! 209: } ! 210: ! 211: switch (uap->which) { ! 212: ! 213: case RLIMIT_DATA: ! 214: if (alim.rlim_cur > maxdmap) ! 215: alim.rlim_cur = maxdmap; ! 216: if (alim.rlim_max > maxdmap) ! 217: alim.rlim_max = maxdmap; ! 218: break; ! 219: ! 220: case RLIMIT_STACK: ! 221: if (alim.rlim_cur > maxdmap) ! 222: alim.rlim_cur = maxdmap; ! 223: if (alim.rlim_max > maxdmap) ! 224: alim.rlim_max = maxdmap; ! 225: /* ! 226: * Stack is allocated to the max at exec time with only ! 227: * "rlim_cur" bytes accessible. If stack limit is going ! 228: * up make more accessible, if going down make inaccessible. ! 229: */ ! 230: if (alim.rlim_cur != alimp->rlim_cur) { ! 231: vm_offset_t addr; ! 232: vm_size_t size; ! 233: vm_prot_t prot; ! 234: ! 235: if (alim.rlim_cur > alimp->rlim_cur) { ! 236: prot = VM_PROT_ALL; ! 237: size = alim.rlim_cur - alimp->rlim_cur; ! 238: addr = USRSTACK - alim.rlim_cur; ! 239: } else { ! 240: prot = VM_PROT_NONE; ! 241: size = alimp->rlim_cur - alim.rlim_cur; ! 242: addr = USRSTACK - alimp->rlim_cur; ! 243: } ! 244: addr = trunc_page(addr); ! 245: size = round_page(size); ! 246: (void) vm_map_protect(&p->p_vmspace->vm_map, ! 247: addr, addr+size, prot, FALSE); ! 248: } ! 249: break; ! 250: } ! 251: p->p_rlimit[uap->which] = alim; ! 252: return (0); ! 253: } ! 254: ! 255: /* ARGSUSED */ ! 256: getrlimit(p, uap, retval) ! 257: struct proc *p; ! 258: register struct args { ! 259: u_int which; ! 260: struct rlimit *rlp; ! 261: } *uap; ! 262: int *retval; ! 263: { ! 264: ! 265: if (uap->which >= RLIM_NLIMITS) ! 266: return (EINVAL); ! 267: return (copyout((caddr_t)&p->p_rlimit[uap->which], (caddr_t)uap->rlp, ! 268: sizeof (struct rlimit))); ! 269: } ! 270: ! 271: /* ARGSUSED */ ! 272: getrusage(p, uap, retval) ! 273: register struct proc *p; ! 274: register struct args { ! 275: int who; ! 276: struct rusage *rusage; ! 277: } *uap; ! 278: int *retval; ! 279: { ! 280: register struct rusage *rup; ! 281: ! 282: switch (uap->who) { ! 283: ! 284: case RUSAGE_SELF: { ! 285: int s; ! 286: ! 287: rup = &p->p_stats->p_ru; ! 288: s = splclock(); ! 289: rup->ru_stime = p->p_stime; ! 290: rup->ru_utime = p->p_utime; ! 291: splx(s); ! 292: break; ! 293: } ! 294: ! 295: case RUSAGE_CHILDREN: ! 296: rup = &p->p_stats->p_cru; ! 297: break; ! 298: ! 299: default: ! 300: return (EINVAL); ! 301: } ! 302: return (copyout((caddr_t)rup, (caddr_t)uap->rusage, ! 303: sizeof (struct rusage))); ! 304: } ! 305: ! 306: ruadd(ru, ru2) ! 307: register struct rusage *ru, *ru2; ! 308: { ! 309: register long *ip, *ip2; ! 310: register int i; ! 311: ! 312: timevaladd(&ru->ru_utime, &ru2->ru_utime); ! 313: timevaladd(&ru->ru_stime, &ru2->ru_stime); ! 314: if (ru->ru_maxrss < ru2->ru_maxrss) ! 315: ru->ru_maxrss = ru2->ru_maxrss; ! 316: ip = &ru->ru_first; ip2 = &ru2->ru_first; ! 317: for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) ! 318: *ip++ += *ip2++; ! 319: } ! 320: ! 321: /* ! 322: * Make a copy of the plimit structure. ! 323: * We share these structures copy-on-write after fork, ! 324: * and copy when a limit is changed. ! 325: */ ! 326: struct plimit * ! 327: limcopy(lim) ! 328: struct plimit *lim; ! 329: { ! 330: register struct plimit *copy; ! 331: ! 332: MALLOC(copy, struct plimit *, sizeof(struct plimit), ! 333: M_SUBPROC, M_WAITOK); ! 334: bcopy(lim->pl_rlimit, copy->pl_rlimit, ! 335: sizeof(struct rlimit) * RLIM_NLIMITS); ! 336: copy->p_lflags = 0; ! 337: copy->p_refcnt = 1; ! 338: return (copy); ! 339: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.