|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.