|
|
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.