Annotation of researchv10no/sys/os/limits.C, revision 1.1

1.1     ! root        1: /*
        !             2:  * limits routines
        !             3:  */
        !             4: 
        !             5: #include "sys/param.h"
        !             6: #include "sys/systm.h"
        !             7: #include "sys/user.h"
        !             8: #include "sys/file.h"
        !             9: #include "sys/inode.h"
        !            10: #include "sys/lnode.h"
        !            11: #include "sys/proc.h"
        !            12: #include "sys/share.h"
        !            13: 
        !            14: #ifndef        ETOOMANYU
        !            15: #define        ETOOMANYU       ENOSPC  /* Must go in errno.h or lnode.h */
        !            16: #endif
        !            17: 
        !            18: float  NiceDecays[2*NZERO];    /* Table for pre-calculated priority decays */
        !            19: float  NiceRates[2*NZERO];     /* Table for pre-calculated rate increments */
        !            20: long   NiceTicks[2*NZERO];     /* Array of costs for a cpu tick biased by p_nice */
        !            21: KL_p   lastlnode;
        !            22: 
        !            23: /*
        !            24:  * limits system call
        !            25:  *
        !            26:  * Functions
        !            27:  *
        !            28:  *     0 - L_MYLIM
        !            29:  *     9 - L_MYKN
        !            30:  *         return own limit struct
        !            31:  *         return number of processes attached to node
        !            32:  *
        !            33:  *     1 - L_OTHLIM
        !            34:  *     10- L_OTHKN
        !            35:  *         return limit struct of l_uid
        !            36:  *         return number of processes attached to node or ESRCH
        !            37:  *
        !            38:  *     2 - L_ALLLIM
        !            39:  *     11- L_ALLKN
        !            40:  *         return all active limit structs
        !            41:  *         return number of structs returned
        !            42:  *
        !            43:  *     3 - L_SETLIM super-user only
        !            44:  *         initialize limit struct for l_uid
        !            45:  *         ETOOMANYU   - no spare limit structs
        !            46:  *         ESRCH       - group not installed
        !            47:  *
        !            48:  *     4 - L_DEADLIM
        !            49:  *         wait for a dead child, return limit struct and proc entry,
        !            50:  *         and if LASTREF, remove dead limit struct from the active list.
        !            51:  *         LASTREF set for dead limit struct
        !            52:  *         ECHILD      - no children to wait for
        !            53:  *         return number of processes attached to node
        !            54:  *
        !            55:  *     5 - L_CHNGLIM super-user only
        !            56:  *         change limits for active limit struct
        !            57:  *         ESRCH       - l_uid not found
        !            58:  *
        !            59:  *     6 - L_DEADGROUP
        !            60:  *         return limit struct for a dead group and remove group
        !            61:  *         ESRCH       - no dead groups
        !            62:  *
        !            63:  *     7 - L_GETCOSTS
        !            64:  *         return share constants
        !            65:  *
        !            66:  *     8 - L_SETCOSTS  super-user only
        !            67:  *         set share constants
        !            68:  */
        !            69: limits()
        !            70: {
        !            71:        register struct a {
        !            72:                struct lnode *lp;
        !            73:                int select;
        !            74:        } *uap;
        !            75:        register KL_p ol;
        !            76:        register KL_p nl;
        !            77:        register KL_p gl;
        !            78:        register int i;
        !            79:        register struct proc *up;
        !            80:        register int size;
        !            81:        static struct kern_lnode kl;
        !            82: 
        !            83:        up = u.u_procp;
        !            84:        size = sizeof(struct kern_lnode);
        !            85: 
        !            86:        uap = (struct a *)u.u_ap;
        !            87:        switch(uap->select) {
        !            88:        case L_MYLIM:
        !            89:                if(copyout((caddr_t)&up->p_lnode->kl, (caddr_t)uap->lp, sizeof(struct lnode)))
        !            90:                        u.u_error = EFAULT;
        !            91:                u.u_r.r_val1 = up->p_lnode->kl_refcount;
        !            92:                return;
        !            93: 
        !            94:        case L_MYKN:
        !            95:                if(copyout((caddr_t)up->p_lnode, (caddr_t)uap->lp, size))
        !            96:                        u.u_error = EFAULT;
        !            97:                u.u_r.r_val1 = up->p_lnode->kl_refcount;
        !            98:                return;
        !            99: 
        !           100:        case L_OTHLIM:
        !           101:                size = sizeof(struct lnode);
        !           102:        case L_OTHKN:
        !           103:                if(copyin((caddr_t)uap->lp, (uap->select == L_OTHLIM)?(caddr_t)&kl.kl:(caddr_t)&kl, size)) {
        !           104:                        u.u_error = EFAULT;
        !           105:                        return;
        !           106:                }
        !           107:                for(ol = lnodes; ol != (KL_p)0; ol = ol->kl_next) {
        !           108:                        if(ol->kl.l_uid == kl.kl.l_uid) {
        !           109:                                if(copyout((uap->select == L_OTHLIM)?(caddr_t)&ol->kl:(caddr_t)ol, (caddr_t)uap->lp, size))
        !           110:                                        u.u_error = EFAULT;
        !           111:                                u.u_r.r_val1 = ol->kl_refcount;
        !           112:                                return;
        !           113:                        }
        !           114:                }
        !           115:                u.u_error = ESRCH;
        !           116:                return;
        !           117: 
        !           118:        case L_ALLLIM:
        !           119:                size = sizeof(struct lnode);
        !           120:        case L_ALLKN:
        !           121:                i = 0;
        !           122:                for(ol = lnodes; ol != (KL_p)0; ol = ol->kl_next) {
        !           123:                        if(copyout((uap->select == L_ALLLIM)?(caddr_t)&ol->kl:(caddr_t)ol, (caddr_t)uap->lp, size)) {
        !           124:                                u.u_error = EFAULT;
        !           125:                                return;
        !           126:                        }
        !           127:                        *(caddr_t *)&uap->lp += size;
        !           128:                        i++;
        !           129:                }
        !           130:                u.u_r.r_val1 = i;
        !           131:                return;
        !           132: 
        !           133:        case L_SETLIM:
        !           134:                if(!suser())
        !           135:                        return;
        !           136:                if(copyin((caddr_t)uap->lp, (caddr_t)&kl.kl, sizeof(struct lnode))) {
        !           137:                        u.u_error = EFAULT;
        !           138:                        return;
        !           139:                }
        !           140:                if(kl.kl.l_uid == up->p_lnode->kl.l_uid)
        !           141:                        return;
        !           142:                nl = gl = (KL_p)0;
        !           143:                for(ol = lnodes, i = 0; ol < lnodesMAXUSERS; ol++) {
        !           144:                        if(!(ol->kl.l_flags & ACTIVELNODE)) {
        !           145:                                if(nl == NULL)
        !           146:                                        nl = ol;
        !           147:                                continue;
        !           148:                        }
        !           149:                        if(ol->kl.l_uid == kl.kl.l_uid) {
        !           150:                                nl = ol;
        !           151:                                goto found;
        !           152:                        }
        !           153:                        if(!(ol->kl.l_flags & NOTSHARED) && ++i >= MAXUSERS) {
        !           154:                                u.u_error = ETOOMANYU;
        !           155:                                return;
        !           156:                        }
        !           157:                        if(ol->kl.l_uid == kl.kl.l_group)
        !           158:                                gl = ol;        /* my group */
        !           159:                }
        !           160:                if(nl == NULL) {
        !           161:                        u.u_error = ETOOMANYU;
        !           162:                        return;
        !           163:                }
        !           164:                if(gl == (KL_p)0) {
        !           165:                        u.u_error = ESRCH;      /* No group installed yet */
        !           166:                        return;
        !           167:                }
        !           168:                if(grouplevel(gl)>=MAXGROUPS) {
        !           169:                        u.u_error = ESRCH;      /* ETOODEEPFORME? */
        !           170:                        return;
        !           171:                }
        !           172:                nl->kl = kl.kl;
        !           173:                nl->kl.l_flags &= ~CHNGDLIMITS;
        !           174:                nl->kl_ghead = (KL_p)0;
        !           175:                if(nl->kl.l_flags & NOTSHARED)
        !           176:                        nl->kl_gshares = zerof;
        !           177:                else
        !           178:                        nl->kl_gshares = nl->kl.l_shares;
        !           179:                nl->kl_temp = zerof;
        !           180:                nl->kl_children = 0;
        !           181:                nl->kl_cost = 0;
        !           182:                nl->kl_refcount = 0;
        !           183:                nl->kl_muse = 0;
        !           184:                nl->kl_rate = onef;
        !           185:                splshsched();   /* Hopefully, this locks out the clock scan too */
        !           186:                addgroup(gl, nl);
        !           187:                normshares(gl, 0);
        !           188:                fixusage(nl);
        !           189:                nl->kl_prev = gl;       /* insert into active list */
        !           190:                if((nl->kl_next = gl->kl_next) == (KL_p)0)
        !           191:                        lastlnode = nl;
        !           192:                else
        !           193:                        gl->kl_next->kl_prev = nl;
        !           194:                gl->kl_next = nl;
        !           195:                spl0();
        !           196:        found:
        !           197:                nl->kl.l_flags &= ~(LASTREF|DEADGROUP);
        !           198:                nl->kl.l_flags |= ACTIVELNODE;
        !           199:                ol = up->p_lnode;
        !           200:                if(--ol->kl_refcount == 0) {
        !           201:                        if(ol->kl_children == 0)
        !           202:                                ol->kl.l_flags |= DEADGROUP;
        !           203:                }
        !           204:                nl->kl_refcount++;
        !           205:                i = up->p_dsize + up->p_ssize;
        !           206:                ol->kl_muse -= i;
        !           207:                nl->kl_muse += i;
        !           208:                up->p_lnode = nl;
        !           209:                return;
        !           210: 
        !           211: #if NOTDEF             /* unused and unpleasant */
        !           212:        case L_DEADLIM:
        !           213:                wait1(WRETLIM, NULL);   /* will call retlimits() */
        !           214:                return;
        !           215: #endif
        !           216:        case L_DEADGROUP:
        !           217:                if(!suser())
        !           218:                        return;
        !           219:                for(ol = lnodes[0].kl_next; ol != (KL_p)0; ol = ol->kl_next)
        !           220:                        if(ol->kl_refcount == 0 && ol->kl_children == 0) {
        !           221:                                remlnode(ol);
        !           222:                                if(copyout((caddr_t)&ol->kl, (caddr_t)uap->lp, sizeof(struct lnode)))
        !           223:                                        u.u_error = EFAULT;
        !           224:                                return;
        !           225:                        }
        !           226:                u.u_error = ESRCH;
        !           227:                return;
        !           228: 
        !           229:        case L_CHNGLIM:
        !           230:                if(!suser())
        !           231:                        return;
        !           232:                if(copyin((caddr_t)uap->lp, (caddr_t)&kl.kl, sizeof(struct lnode))) {
        !           233:                        u.u_error = EFAULT;
        !           234:                        return;
        !           235:                }
        !           236:                if(kl.kl.l_uid == 0) {
        !           237:                        u.u_error = EINVAL;
        !           238:                        return;
        !           239:                }
        !           240:                for(ol = lnodes, gl = (KL_p)0; ol != (KL_p)0; ol = ol->kl_next) {
        !           241:                        if(ol->kl.l_uid == kl.kl.l_uid) {
        !           242:                                if(ol->kl.l_group != kl.kl.l_group) {
        !           243:                                        if(gl==(KL_p)0)
        !           244:                                                break;  /* ESRCH */
        !           245:                                        else {
        !           246:                                                splshsched();
        !           247:                                                remgroup(ol);
        !           248:                                                ol->kl.l_group = kl.kl.l_group;
        !           249:                                                addgroup(gl, ol);
        !           250:                                        }
        !           251:                                } else if(gl==(KL_p)0)
        !           252:                                        panic("lost group");
        !           253: 
        !           254:                                if(ol->kl_norms && ol->kl_usage < MAXUSAGE)
        !           255:                                        TotUsage -= onef / ol->kl_usage;
        !           256:                                ol->kl.l_usage = kl.kl.l_usage;
        !           257: 
        !           258:                                if(ol->kl.l_shares != kl.kl.l_shares
        !           259:                                || ((ol->kl.l_flags^kl.kl.l_flags) & NOTSHARED)) {
        !           260:                                        gl->kl_gshares -= ol->kl.l_shares;
        !           261:                                        if(!(ol->kl.l_flags & NOTSHARED))
        !           262:                                                ol->kl_gshares -= ol->kl.l_shares;
        !           263:                                        ol->kl.l_shares = kl.kl.l_shares;
        !           264:                                        gl->kl_gshares += ol->kl.l_shares;
        !           265:                                        if(!(kl.kl.l_flags & NOTSHARED))
        !           266:                                                ol->kl_gshares += ol->kl.l_shares;
        !           267:                                }
        !           268:                                ol->kl.l_flags &= (ACTIVELNODE|LASTREF|DEADGROUP);
        !           269:                                ol->kl.l_flags |= (kl.kl.l_flags & ~(ACTIVELNODE|LASTREF|DEADGROUP)) | CHNGDLIMITS;
        !           270:                                normshares(gl, 0);
        !           271:                                fixusage(ol);
        !           272:                                spl0();
        !           273:                                return;
        !           274:                        } else if(ol->kl.l_uid == kl.kl.l_group)
        !           275:                                gl = ol;        /* Remember [new] group */
        !           276:                }
        !           277:                u.u_error = ESRCH;
        !           278:                return;
        !           279: 
        !           280:        case L_GETCOSTS:
        !           281:                if(copyout((caddr_t)&shconsts, (caddr_t)uap->lp, sizeof shconsts))
        !           282:                        u.u_error = EFAULT;
        !           283:                return;
        !           284: 
        !           285:        case L_SETCOSTS:
        !           286:                if(!suser())
        !           287:                        return;
        !           288:                splshsched();
        !           289:                if(copyin((caddr_t)uap->lp, (caddr_t)&shconsts, (caddr_t)&LASTPARAM - (caddr_t)&shconsts))
        !           290:                        u.u_error = EFAULT;
        !           291:                setcosts();
        !           292:                spl0();
        !           293:                return;
        !           294:                        
        !           295:        default:
        !           296:                u.u_error = EINVAL;
        !           297:                return;
        !           298:        }
        !           299: }
        !           300: 
        !           301: /*
        !           302:  * Add to group list
        !           303:  */
        !           304: 
        !           305: addgroup(gl, kl)
        !           306: register KL_p gl;
        !           307: register KL_p kl;
        !           308: {
        !           309:        kl->kl_parent = gl;
        !           310:        kl->kl_gnext = gl->kl_ghead;
        !           311:        gl->kl_ghead = kl;
        !           312:        gl->kl_children++;
        !           313:        gl->kl_gshares += kl->kl.l_shares;
        !           314:        gl->kl.l_flags &= ~DEADGROUP;
        !           315: }
        !           316: 
        !           317: #if NOTDEF
        !           318: 
        !           319: /*
        !           320:  * Return dead proc and limits to init for accounting.
        !           321:  */
        !           322: 
        !           323: retlimits(p)
        !           324: register struct proc *p;
        !           325: {
        !           326:        register KL_p lp;
        !           327:        register struct a {
        !           328:                struct retlim *rp;
        !           329:        } *uap;
        !           330: 
        !           331:        lp = p->p_lnode;
        !           332:        if(lp->kl_refcount == 0) {
        !           333:                lp->kl.l_flags |= LASTREF;
        !           334:                if(lp->kl_children == 0)
        !           335:                        remlnode(lp);
        !           336:        }
        !           337: 
        !           338:        uap = (struct a *)u.u_ap;
        !           339:        if(copyout((caddr_t)p, (caddr_t)&uap->rp->r_proc, sizeof(struct xproc))
        !           340:        || copyout((caddr_t)&lp->kl, (caddr_t)&uap->rp->r_lnode, sizeof(struct lnode)))
        !           341:                u.u_error = EFAULT;
        !           342: 
        !           343:        u.u_r.r_val1 = lp->kl_refcount;
        !           344: }
        !           345: 
        !           346: #endif
        !           347: 
        !           348: /*
        !           349:  * Remove lnode from active and group lists.
        !           350:  */
        !           351: 
        !           352: remlnode(lp)
        !           353: register KL_p lp;
        !           354: {
        !           355:        splshsched();
        !           356: 
        !           357:        if((lp->kl_prev->kl_next = lp->kl_next) == (KL_p)0)
        !           358:                lastlnode = lp->kl_prev;
        !           359:        else
        !           360:                lp->kl_next->kl_prev = lp->kl_prev;
        !           361: 
        !           362:        remgroup(lp);
        !           363: 
        !           364:        spl0();
        !           365: 
        !           366:        if(lp->kl_temp += lp->kl_cost) {
        !           367:                lp->kl.l_charge += lp->kl_temp;
        !           368:                lp->kl_parent->kl_temp += lp->kl_temp;
        !           369:                lp->kl.l_usage += lp->kl_temp;
        !           370:        }
        !           371: 
        !           372:        lp->kl.l_flags &= ~ACTIVELNODE;
        !           373: 
        !           374:        if(lp->kl_parent->kl.l_flags & DEADGROUP)
        !           375:                lp->kl.l_flags |= DEADGROUP;    /* init should pick up group */
        !           376: }
        !           377: 
        !           378: /*
        !           379:  * Remove lnode from group list.
        !           380:  */
        !           381: 
        !           382: remgroup(lp)
        !           383: register KL_p lp;
        !           384: {
        !           385:        register KL_p gl, ol;
        !           386: 
        !           387:        for(ol = lp->kl_parent, gl = ol->kl_ghead; gl != (KL_p)0; ol = gl, gl = gl->kl_gnext)
        !           388:                if(gl == lp) {
        !           389:                        /* remove from group list */
        !           390:                        if(ol == lp->kl_parent)
        !           391:                                ol->kl_ghead = lp->kl_gnext;
        !           392:                        else
        !           393:                                ol->kl_gnext = lp->kl_gnext;
        !           394:                        break;
        !           395:                }
        !           396: 
        !           397:        if(gl==(KL_p)0) panic("remgroup");
        !           398: 
        !           399:        gl = lp->kl_parent;
        !           400: 
        !           401:        if(--gl->kl_children == 0 && gl->kl_refcount == 0)
        !           402:                gl->kl.l_flags |= DEADGROUP;
        !           403: 
        !           404:        gl->kl_gshares -= lp->kl.l_shares;
        !           405:        normshares(gl, 0);
        !           406: }
        !           407: 
        !           408: /*
        !           409:  * Adjust effective shares for group.
        !           410:  */
        !           411: 
        !           412: normshares(gl, d)
        !           413: register KL_p gl;
        !           414: {
        !           415:        register KL_p lp;
        !           416:        register float es;
        !           417:        register float gs;
        !           418: 
        !           419:        if((gs = gl->kl_gshares) && !(gl->kl.l_flags & NOTSHARED)) {
        !           420:                es = gl->kl_eshare * gl->kl.l_shares;
        !           421:                es /= gs;
        !           422:                gl->kl_norms = es * es;
        !           423:        } else if(gl->kl.l_uid == 0)
        !           424:                gl->kl_norms = onef;
        !           425:        else
        !           426:                gl->kl_norms = zerof;
        !           427: 
        !           428:        for(lp = gl->kl_ghead; lp != (KL_p)0; lp = lp->kl_gnext) {
        !           429:                if(gs) {
        !           430:                        es = gl->kl_eshare * lp->kl.l_shares;
        !           431:                        es /= gs;
        !           432:                } else
        !           433:                        es = zerof;
        !           434: 
        !           435:                lp->kl_eshare = es;
        !           436: 
        !           437:                if(lp->kl_ghead) {
        !           438:                        if(d >= MAXGROUPS)
        !           439:                                printf("MAXGROUPS(%d) exceeded for group %d\n", MAXGROUPS, lp->kl.l_uid);
        !           440:                        else
        !           441:                                normshares(lp, d+1);
        !           442:                } else
        !           443:                        lp->kl_norms = es * es;
        !           444:        }
        !           445: }
        !           446: 
        !           447: /*
        !           448:  * Count group nesting
        !           449:  */
        !           450: 
        !           451: grouplevel(gl)
        !           452: register KL_p gl;
        !           453: {
        !           454:        register int i;
        !           455: 
        !           456:        for(i = 0; (gl = gl->kl_parent) != (KL_p)0; i++);
        !           457:        return i;
        !           458: }
        !           459: 
        !           460: /*
        !           461:  * Check and set cost dependent variables
        !           462:  */
        !           463: 
        !           464: setcosts()
        !           465: {
        !           466:        register int i;
        !           467:        register float f = onef;
        !           468:        register float g;
        !           469: 
        !           470:        if(MAXUSERS > lnodecnt)
        !           471:                MAXUSERS = lnodecnt;
        !           472:        if(MAXGROUPS > (lnodecnt-3))
        !           473:                MAXGROUPS = lnodecnt-3;
        !           474:        if(MAXUSHARE < f)
        !           475:                MAXUSHARE = f;
        !           476:        if(MINGSHARE > f)
        !           477:                MINGSHARE = f;
        !           478: 
        !           479:        f -= DecayRate;
        !           480:        g = PriDecay / (PriDecayBase + (2*NZERO) - 1);
        !           481:        for(i = 0; i < (2*NZERO); i++) {
        !           482:                NiceDecays[i] = g * (PriDecayBase + i);
        !           483:                NiceRates[i] = i <= NZERO ? f : (f * NZERO) / i;
        !           484:                NiceTicks[i] = (shconsts.sc_tick * ((3*NZERO) - i)) / (2*NZERO);
        !           485:        }
        !           486: 
        !           487:        if(NiceTicks[2*NZERO-1] > 0)
        !           488:                NiceTicks[2*NZERO-1] = 1;       /* nice -19 is almost free */
        !           489:        NiceRates[2*NZERO-1] = zerof;
        !           490: }
        !           491: 
        !           492: /*
        !           493:  *     Initialise lnodes
        !           494:  */
        !           495: 
        !           496: initlnodes(root)
        !           497: register KL_p root;
        !           498: {
        !           499:        lastlnode = root;
        !           500:        MAXUSERS = lnodecnt;
        !           501:        MaxSharePri = onef;
        !           502: 
        !           503:        setcosts();
        !           504: 
        !           505:        root->kl.l_shares = 1;
        !           506:        root->kl.l_flags = ACTIVELNODE|NOTSHARED;
        !           507:        root->kl_norms = onef;
        !           508:        root->kl_eshare = onef;
        !           509:        root->kl_gshares = zerof;
        !           510:        root->kl_temp = zerof;
        !           511:        root->kl_usage = onef;
        !           512:        root->kl_rate = onef;
        !           513: }
        !           514: 
        !           515: /*
        !           516:  *     Adjust usage variables for new value.
        !           517:  */
        !           518: 
        !           519: fixusage(lp)
        !           520:        register KL_p   lp;
        !           521: {
        !           522:        register float  f;
        !           523: 
        !           524:        if(f = lp->kl_norms) {
        !           525:                if((f = lp->kl.l_usage / f) < twof || (Shareflags & NOSHARE))
        !           526:                        f = twof;
        !           527:                if(f > MaxUsage && f < MAXUSAGE)
        !           528:                        MaxUsage = f;
        !           529:                TotUsage += onef / f;
        !           530:                lp->kl_usage = f;
        !           531:        } else
        !           532:                lp->kl_usage = MAXUSAGE;
        !           533: }

unix.superglobalmegacorp.com

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