Annotation of researchv8dc/cmd/rarepl/rarepl.c, revision 1.1.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 ch;
                     12: int primblk;           /* ugh */
                     13: 
                     14: #define        BADRBN  (-1L)
                     15: 
                     16: main(argc, argv)
                     17: int argc;
                     18: char **argv;
                     19: {
                     20:        int fd;
                     21:        int errs = 0;
                     22: 
                     23:        if (argc < 3) {
                     24:                fprintf(stderr, "usage: %s dev lbn ...\n", argv[0]);
                     25:                exit(1);
                     26:        }
                     27:        if ((fd = open(argv[1], 2)) < 0) {
                     28:                perror(argv[1]);
                     29:                exit(1);
                     30:        }
                     31:        if (ioctl(fd, UIOCHAR, &ch) < 0) {
                     32:                perror("unit info");
                     33:                exit(1);
                     34:        }
                     35:        argc--;
                     36:        argv++;
                     37:        while (--argc > 0)
                     38:                errs += repl(fd, atol(*++argv));
                     39:        exit(errs);
                     40: }
                     41: 
                     42: /*
                     43:  * replace a block
                     44:  */
                     45: 
                     46: repl(fd, bad)
                     47: int fd;
                     48: daddr_t bad;
                     49: {
                     50:        struct ud_repl r;
                     51:        char block[RBNSEC];
                     52:        struct rbd rct[RBNPB];
                     53:        daddr_t rctb;
                     54:        int rctoff;
                     55:        daddr_t rbn;
                     56:        daddr_t pickrbn();
                     57: 
                     58:        if (bad >= ch.radsize) {
                     59:                fprintf(stderr, "%ld: out of range\n", bad);
                     60:                return (1);
                     61:        }
                     62:        clrbuf(block);
                     63:        lseek(fd, (off_t)(bad * RBNSEC), 0);
                     64:        read(fd, block, RBNSEC);        /* ignore error on purpose */
                     65:        if ((rbn = pickrbn(fd, bad)) == BADRBN) {
                     66:                fprintf(stderr, "can't find replacement for %ld\n", bad);
                     67:                return (1);
                     68:        }
                     69:        rctb = (rbn / RBNPB) + RCTTAB;
                     70:        rctoff = rbn % RBNPB;
                     71:        if (rdrct(fd, rctb, (char *)rct) == 0)
                     72:                return (1);
                     73:        if (rct[rctoff].rb_code) {
                     74:                fprintf(stderr, "rbn %ld in use or bad\n", rbn);
                     75:                return (1);
                     76:        }
                     77:        rct[rctoff].rb_code = primblk ? RALLOC : RALLOC | RALT;
                     78:        rct[rctoff].rb_lbn = bad;
                     79:        if (wrrct(fd, rctb, (char *)rct) == 0)
                     80:                return (1);
                     81:        r.lbn = bad;
                     82:        r.replbn = rbn;
                     83:        r.prim = primblk;
                     84:        if (ioctl(fd, UIOREPL, &r) < 0) {
                     85:                perror("ioctl");
                     86:                return (1);
                     87:        }
                     88:        lseek(fd, (off_t)(bad * RBNSEC), 0);
                     89:        if (write(fd, block, RBNSEC) != RBNSEC) {
                     90:                perror("write back");
                     91:                return (1);
                     92:        }
                     93:        return (0);
                     94: }
                     95: 
                     96: /*
                     97:  * find a replacement block
                     98:  * remember in primblk whether it's the primary replacement
                     99:  */
                    100: 
                    101: daddr_t
                    102: pickrbn(fd, lbn)
                    103: int fd;
                    104: daddr_t lbn;
                    105: {
                    106:        struct rbd rct[RBNPB];
                    107:        daddr_t bno, rbn, prbn;
                    108:        daddr_t low, high;
                    109:        register int i;
                    110:        daddr_t size;
                    111:        daddr_t rctmax();
                    112: 
                    113:        prbn = (lbn / ch.tracksz) * ch.rbns;
                    114:        low = high = BADRBN;
                    115:        size = rctmax();
                    116:        for (bno = RCTTAB, rbn = 0L; bno < size; bno++) {
                    117:                if (rdrct(fd, bno, (char *)rct) == 0) {
                    118:                        rbn += RBNPB;
                    119:                        continue;
                    120:                }
                    121:                for (i = 0; i < RBNPB; i++, rbn++) {
                    122:                        if (rct[i].rb_code == 0) {
                    123:                                if (rbn < prbn)
                    124:                                        low = rbn;
                    125:                                else if (high == BADRBN)
                    126:                                        high = rbn;
                    127:                        }
                    128:                        else if (rct[i].rb_lbn == lbn
                    129:                             &&  rct[i].rb_code != RBAD) {
                    130:                                rct[i].rb_code = RBAD;
                    131:                                wrrct(fd, bno, (char *)rct);
                    132:                        }
                    133:                }
                    134:        }
                    135:        if (low == BADRBN && high == BADRBN)
                    136:                return (BADRBN);
                    137:        else if (low == BADRBN)
                    138:                rbn = high;
                    139:        else if (high == BADRBN)
                    140:                rbn = low;
                    141:        else if (prbn - low < high - prbn)
                    142:                rbn = low;
                    143:        else
                    144:                rbn = high;
                    145:        primblk = (rbn == prbn);
                    146:        return (rbn);
                    147: }
                    148: 
                    149: daddr_t
                    150: rctmax()
                    151: {
                    152:        daddr_t nrbns;
                    153: 
                    154:        nrbns = (ch.radsize / ch.tracksz) * ch.rbns;
                    155:        return ((nrbns / RBNPB) + RCTTAB);
                    156: }
                    157: 
                    158: 
                    159: rdrct(fd, bno, buf)
                    160: int fd;
                    161: daddr_t bno;
                    162: char *buf;
                    163: {
                    164:        struct ud_rctbuf b;
                    165: 
                    166:        b.buf = buf;
                    167:        b.lbn = bno;
                    168:        if (ioctl(fd, UIORRCT, &b) < 0) {
                    169:                perror("rrct");
                    170:                fprintf(stderr, "can't read block %ld of rct\n", bno);
                    171:                return (0);
                    172:        }
                    173:        return (1);
                    174: }
                    175: 
                    176: wrrct(fd, bno, buf)
                    177: int fd;
                    178: daddr_t bno;
                    179: char *buf;
                    180: {
                    181:        struct ud_rctbuf b;
                    182: 
                    183:        b.buf = buf;
                    184:        b.lbn = bno;
                    185:        if (ioctl(fd, UIOWRCT, &b) < 0) {
                    186:                perror("wrct");
                    187:                fprintf(stderr, "can't write block %ld of rct\n", bno);
                    188:                return (0);
                    189:        }
                    190:        return (1);
                    191: }
                    192: 
                    193: clrbuf(b)
                    194: register char *b;
                    195: {
                    196:        register int i;
                    197: 
                    198:        for (i = 0; i < RBNSEC; i++)
                    199:                *b++ = 0;
                    200: }

unix.superglobalmegacorp.com

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