Annotation of researchv10no/cmd/rarepl/rarepl.c, revision 1.1

1.1     ! root        1: /*% cc -O -o rarepl %
        !             2:  *
        !             3:  * replace a bad sector on an RA disk
        !             4:  */
        !             5: 
        !             6: #include <stdio.h>
        !             7: #include <sys/param.h>
        !             8: #include <sys/udaioc.h>
        !             9: #include "rct.h"
        !            10: 
        !            11: struct ud_unit ud_unit;
        !            12: int primblk;           /* ugh */
        !            13: int notprim;           /* never primary replacement */
        !            14: 
        !            15: #define        BADRBN  (-1L)
        !            16: 
        !            17: main(argc, argv)
        !            18: int argc;
        !            19: char **argv;
        !            20: {
        !            21:        int fd;
        !            22:        int errs = 0;
        !            23: 
        !            24:        if (argc < 3) {
        !            25:                fprintf(stderr, "usage: %s dev lbn ...\n", argv[0]);
        !            26:                exit(1);
        !            27:        }
        !            28:        if ((fd = open(argv[1], 2)) < 0) {
        !            29:                perror(argv[1]);
        !            30:                exit(1);
        !            31:        }
        !            32:        online(fd);
        !            33:        if (ioctl(fd, UIOCHAR, &ud_unit) < 0) {
        !            34:                perror("unit info");
        !            35:                exit(1);
        !            36:        }
        !            37:        argc--;
        !            38:        argv++;
        !            39:        while (--argc > 0)
        !            40:                errs += repl(fd, atol(*++argv));
        !            41:        exit(errs);
        !            42: }
        !            43: 
        !            44: /*
        !            45:  * read a block from the disk,
        !            46:  * just to make the driver bring it online
        !            47:  */
        !            48: 
        !            49: online(fd)
        !            50: int fd;
        !            51: {
        !            52:        char buf[RBNSEC];
        !            53: 
        !            54:        read(fd, buf, RBNSEC);          /* ignore error; might be bad sector */
        !            55: }
        !            56: 
        !            57: /*
        !            58:  * replace a block
        !            59:  */
        !            60: 
        !            61: repl(fd, bad)
        !            62: int fd;
        !            63: daddr_t bad;
        !            64: {
        !            65:        struct ud_repl r;
        !            66:        char block[RBNSEC];
        !            67:        struct rbd rct[RBNPB];
        !            68:        daddr_t rctb;
        !            69:        int rctoff;
        !            70:        daddr_t rbn;
        !            71:        daddr_t pickrbn();
        !            72: 
        !            73:        if (bad >= ud_unit.radsize) {
        !            74:                fprintf(stderr, "%ld: out of range\n", bad);
        !            75:                return (1);
        !            76:        }
        !            77:        clrbuf(block);
        !            78:        lseek(fd, (off_t)(bad * RBNSEC), 0);
        !            79:        read(fd, block, RBNSEC);        /* ignore error on purpose */
        !            80:        if ((rbn = pickrbn(fd, bad)) == BADRBN) {
        !            81:                fprintf(stderr, "can't find replacement for %ld\n", bad);
        !            82:                return (1);
        !            83:        }
        !            84:        rctb = (rbn / RBNPB) + RCTTAB;
        !            85:        rctoff = rbn % RBNPB;
        !            86:        if (rdrct(fd, rctb, (char *)rct) == 0)
        !            87:                return (1);
        !            88:        if (rct[rctoff].rb_code) {
        !            89:                fprintf(stderr, "rbn %ld in use or bad\n", rbn);
        !            90:                return (1);
        !            91:        }
        !            92:        rct[rctoff].rb_code = primblk ? RALLOC : RALLOC | RALT;
        !            93:        rct[rctoff].rb_lbn = bad;
        !            94:        if (wrrct(fd, rctb, (char *)rct) == 0)
        !            95:                return (1);
        !            96:        r.lbn = bad;
        !            97:        r.replbn = rbn;
        !            98:        r.prim = primblk;
        !            99:        if (ioctl(fd, UIOREPL, &r) < 0) {
        !           100:                perror("replace ioctl");
        !           101:                return (1);
        !           102:        }
        !           103:        lseek(fd, (off_t)(bad * RBNSEC), 0);
        !           104:        if (write(fd, block, RBNSEC) != RBNSEC) {
        !           105:                perror("write back");
        !           106:                return (1);
        !           107:        }
        !           108:        return (0);
        !           109: }
        !           110: 
        !           111: /*
        !           112:  * find a replacement block
        !           113:  * remember in primblk whether it's the primary replacement
        !           114:  */
        !           115: 
        !           116: daddr_t
        !           117: pickrbn(fd, lbn)
        !           118: int fd;
        !           119: daddr_t lbn;
        !           120: {
        !           121:        struct rbd rct[RBNPB];
        !           122:        daddr_t bno, rbn, prbn;
        !           123:        daddr_t low, high;
        !           124:        register int i;
        !           125:        daddr_t size;
        !           126:        daddr_t rctmax(), primrbn();
        !           127: 
        !           128:        size = rctmax();
        !           129:        prbn = primrbn(lbn);
        !           130:        low = high = BADRBN;
        !           131:        for (bno = RCTTAB, rbn = 0L; bno < size; bno++) {
        !           132:                if (rdrct(fd, bno, (char *)rct) == 0) {
        !           133:                        rbn += RBNPB;
        !           134:                        continue;
        !           135:                }
        !           136:                for (i = 0; i < RBNPB; i++, rbn++) {
        !           137:                        if (rct[i].rb_code == RFREE) {
        !           138:                                if (rbn < prbn)
        !           139:                                        low = rbn;
        !           140:                                else if (high == BADRBN)
        !           141:                                        high = rbn;
        !           142:                        }
        !           143:                        else if (rct[i].rb_lbn == lbn
        !           144:                             &&  rct[i].rb_code != RNULL
        !           145:                             &&  rct[i].rb_code != RBAD) {
        !           146:                                rct[i].rb_code = RBAD;
        !           147:                                wrrct(fd, bno, (char *)rct);
        !           148:                        }
        !           149:                }
        !           150:        }
        !           151:        if (low == BADRBN && high == BADRBN)
        !           152:                return (BADRBN);
        !           153:        else if (low == BADRBN)
        !           154:                rbn = high;
        !           155:        else if (high == BADRBN)
        !           156:                rbn = low;
        !           157:        else if (prbn - low < high - prbn)
        !           158:                rbn = low;
        !           159:        else
        !           160:                rbn = high;
        !           161:        if (notprim)
        !           162:                primblk = 0;
        !           163:        else
        !           164:                primblk = (rbn == prbn);
        !           165:        return (rbn);
        !           166: }
        !           167: 
        !           168: daddr_t
        !           169: rctmax()
        !           170: {
        !           171:        register daddr_t nrbns;
        !           172: 
        !           173:        nrbns = (ud_unit.radsize / ud_unit.tracksz) * ud_unit.rbns;
        !           174:        nrbns = ((nrbns+RBNPB-1) / RBNPB) + RCTTAB;
        !           175:        if (nrbns >= ud_unit.rctsize) {
        !           176:                notprim = 1;
        !           177:                return ((daddr_t)ud_unit.rctsize);
        !           178:        }
        !           179:        return (nrbns);
        !           180: }
        !           181: 
        !           182: /*
        !           183:  * figure out the primary RBN
        !           184:  * if notprim == 0, we understand what to do
        !           185:  * otherwise it's not really the primary RBN (and we won't tell the
        !           186:  * controller so), but make a guess about a preferred RBN anyway
        !           187:  */
        !           188: daddr_t
        !           189: primrbn(lbn)
        !           190: daddr_t lbn;
        !           191: {
        !           192:        daddr_t q, csize;
        !           193: 
        !           194:        if (notprim == 0)
        !           195:                return ((lbn/ud_unit.tracksz) * ud_unit.rbns);
        !           196:        /*
        !           197:         * try for one in the same cylinder,
        !           198:         * or multiple thereof
        !           199:         */
        !           200:        q = (ud_unit.rctsize - RCTTAB)*RBNPB;   /* max possible rbns */
        !           201:        q /= ud_unit.rbns;              /* max rbn quantum */
        !           202:        q = ud_unit.radsize/q;          /* max LBNs per RBN */
        !           203:        csize = ud_unit.tracksz*ud_unit.groupsz*ud_unit.cylsz;
        !           204:        q = (q + csize - 1)/csize;      /* cylinders per RBN */
        !           205:        q *= csize;                     /* probably real LBNs per RBN */
        !           206:        return ((lbn + csize - 1)/q);
        !           207: }
        !           208: 
        !           209: rdrct(fd, bno, buf)
        !           210: int fd;
        !           211: daddr_t bno;
        !           212: char *buf;
        !           213: {
        !           214:        struct ud_rctbuf b;
        !           215: 
        !           216:        b.buf = buf;
        !           217:        b.lbn = bno;
        !           218:        if (ioctl(fd, UIORRCT, &b) < 0) {
        !           219:                perror("rrct");
        !           220:                fprintf(stderr, "can't read block %ld of rct\n", bno);
        !           221:                return (0);
        !           222:        }
        !           223:        return (1);
        !           224: }
        !           225: 
        !           226: wrrct(fd, bno, buf)
        !           227: int fd;
        !           228: daddr_t bno;
        !           229: char *buf;
        !           230: {
        !           231:        struct ud_rctbuf b;
        !           232: 
        !           233:        b.buf = buf;
        !           234:        b.lbn = bno;
        !           235:        if (ioctl(fd, UIOWRCT, &b) < 0) {
        !           236:                perror("wrct");
        !           237:                fprintf(stderr, "can't write block %ld of rct\n", bno);
        !           238:                return (0);
        !           239:        }
        !           240:        return (1);
        !           241: }
        !           242: 
        !           243: clrbuf(b)
        !           244: register char *b;
        !           245: {
        !           246:        register int i;
        !           247: 
        !           248:        for (i = 0; i < RBNSEC; i++)
        !           249:                *b++ = 0;
        !           250: }

unix.superglobalmegacorp.com

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