Annotation of Net2/kern/kern_resource.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.