|
|
1.1 root 1: #include "scsi.h"
2: #include <getflags.h>
3: #include <string.h>
4: #include <errno.h>
5: #include <fio.h>
6:
7: #define JDIR "/usr/worm/jukedir"
8: #define JMODE 03666
9: #define NSHELF 50
10:
11: #define NDRIVES 2 /* how many to use */
12:
13: char *shelf[NSHELF];
14: int wr = 0;
15:
16: main(argc, argv)
17: char **argv;
18: {
19: if((argc = getflags(argc, argv, "pcre:1[volid]lw:1[secs]", 0)) < 0)
20: usage("[ vol_id ]");
21: if((argc <= 1) && !flag['r'] && !flag['e'] && !flag['l'] && !flag['w'])
22: flag['p'] = flagset;
23: if(flag['r'] || flag['e'] || flag['l'] || flag['p']){
24: if(scsiinit(1))
25: exit(1);
26: } else { /* mounting */
27: if(scsiinit(0)){
28: Fprint(1, "0\n");
29: exit(0);
30: }
31: }
32: scsiid(2);
33: jread();
34: if(flag['r'])
35: jreload();
36: if(flag['e'])
37: jeject(flag['e'][0]);
38: if(flag['l'])
39: jload();
40: if(flag['p'])
41: jpr();
42: if(wr)
43: jwrite();
44: if(argc > 1)
45: jmount(argv[1]);
46: else {
47: if(flag['w']){
48: fprint(2, "worm mount: -w given with no vol_id\n");
49: exit(1);
50: }
51: }
52: exit(0);
53: }
54:
55: jpr()
56: {
57: int i;
58: register unsigned char *d;
59: struct scsi_o o;
60:
61: if(s_istatus(0, &o) == 0){
62: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
63: if(*d&0x80)
64: Fprint(1, "drive %d: %s%c, %sline\n", i,
65: shelf[(*d&0x7F)/2], (*d&1)? 'b':'a',
66: (d[-2]&1)?"on":"off");
67: }
68: for(i = 0; i < NSHELF; i++)
69: if(shelf[i]) Fprint(1, "%2d: %s\n", i, shelf[i]);
70: Fflush(1);
71: }
72:
73: jeject(s)
74: char *s;
75: {
76: int i, me;
77: register unsigned char *d;
78: struct scsi_o o;
79:
80: if(s_istatus(0, &o) == 0){
81: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
82: if((*d&0x80) && (strcmp(s, shelf[me = (*d&0x7F)/2]) == 0)){
83: if(s_diskeject(i))
84: fprint(2, "worm mount: couldn't eject drive %d\n", i);
85: shelf[me] = 0;
86: wr = 1;
87: return;
88: }
89: }
90: for(i = 0; i < NSHELF; i++)
91: if(strcmp(shelf[i], s) == 0){
92: if(s_diskset(i, A, 1, 1)){
93: fprint(2, "worm mount: couldn't load %s into drive 1\n", s);
94: return;
95: }
96: if(s_diskeject(1)){
97: fprint(2, "worm mount: couldn't eject %s from drive 1\n", s);
98: s_diskrelease(-1, A, 1, 1);
99: return;
100: }
101: shelf[i] = 0;
102: wr = 1;
103: return;
104: }
105: fprint(2, "worm mount: can't find %s\n", s);
106: exit(1);
107: }
108:
109: jload()
110: {
111: int i;
112: int drive = 1, flip;
113: char s[256], *side;
114: struct scsi_o output;
115: int ndone = 0;
116:
117: Fprint(1, "loading new disks\n");
118: loop:
119: if(s_diskset(127, A, drive, 0)){
120: Fprint(1, "%d new disk%s loaded\n", ndone, ndone==1? "":"s");
121: return;
122: }
123: Fprint(1, "loading... "); Fflush(1);
124: if(s_start(drive)){
125: fprint(2, "worm mount: drive %d won't start\n", drive);
126: return;
127: }
128: if(s_read(drive, 1, 1, &output)){
129: fprint(2, "worm mount: read id failed\n", drive);
130: return;
131: }
132: strcpy(s, (char *)&output.data[42]);
133: side = &s[strlen(s)-1];
134: if((*s == 0) || ((*side != 'a')&&(*side != 'b'))){
135: fprint(2, "worm mount: bad name '%s' in drive %d\n", s, drive);
136: return;
137: }
138: flip = (*side =='a')? A:B;
139: *side = 0;
140: for(i = 0; i < NSHELF; i++)
141: if(strcmp(shelf[i], s) == 0){
142: fprint(2, "worm mount: %s was listed shelf %d\n", s, i);
143: shelf[i] = 0;
144: break;
145: }
146: for(i = 0; i < NSHELF; i++)
147: if(shelf[i] == 0){
148: if(s_diskrelease(i, flip, drive, 1)){
149: fprint(2, "worm mount: %s to shelf %d failed\n", s, i);
150: return;
151: }
152: shelf[i] = strdup(s);
153: print("%s loaded to shelf %d\n", s, i);
154: wr = 1;
155: ndone++;
156: goto loop;
157: }
158: fprint(2, "worm mount: no space left for %s\n", s);
159: }
160:
161: jreload()
162: {
163: int i, dest, flip, try;
164: int drive = 1;
165: char s[256], *side;
166: struct scsi_o output;
167:
168: flag['l'] = flagset;
169: for(i = 0; i < NSHELF; i++)
170: shelf[i] = 0;
171: for(i = 0; i < NDRIVES; i++)
172: s_diskrelease(-1, A, i, 0); /* release disks loaded */
173: for(i = 0, try = 0; i < 50; i++, try++){
174: if(s_diskset(i, A, drive, 0))
175: continue;
176: Fprint(1, "doing shelf %d: ", i); Fflush(1);
177: if(s_start(drive)){
178: fprint(2, "worm mount: drive %d won't start\n", drive);
179: exit(1);
180: }
181: if(s_read(drive, 1, 1, &output)){
182: fprint(2, "worm mount: read id failed\n", drive);
183: exit(1);
184: }
185: strcpy(s, (char *)&output.data[42]);
186: side = &s[strlen(s)-1];
187: if((*s == 0) || ((*side != 'a')&&(*side != 'b'))){
188: fprint(2, "worm mount: bad volid '%s', %s\n", s, try?"ignoring":"retrying");
189: if(try == 0){
190: s_diskrelease(i, B, drive, 1);
191: i--;
192: }
193: continue;
194: }
195: if(flag['c']){
196: for(dest = 0; dest < i; dest++)
197: if(shelf[dest] == 0) break;
198: } else
199: dest = i;
200: flip = (*side == 'a')? A:B;
201: if(s_diskrelease(dest, flip, drive, 1)){
202: fprint(2, "worm mount: %s to shelf %d failed\n", s, dest); exit(1);
203: }
204: *side = 0;
205: Fprint(1, "%s\n", s); Fflush(1);
206: shelf[dest] = strdup(s);
207: wr = 1;
208: try = -1;
209: }
210: }
211:
212: #define STEP 5
213:
214: jmount(vol)
215: char *vol;
216: {
217: int limit, i, sh, flip;
218: unsigned char *d;
219: char *ss;
220: struct scsi_o o;
221:
222: ss = &vol[strlen(vol)-1];
223: flip = (*ss == 'a')? A:B;
224: *ss = 0;
225: for(sh = 0; sh < NSHELF; sh++)
226: if(shelf[sh] && (strcmp(vol, shelf[sh]) == 0))
227: break;
228: if(sh == NSHELF){
229: fprint(2, "worm mount: no disk with vol_id '%s'\n", vol);
230: exit(1);
231: }
232: limit = flag['w']? atoi(flag['w'][0]) : 9999999;
233: for(; limit > -STEP; limit -= STEP, sleep(STEP)){
234: if(s_istatus(0, &o))
235: continue;
236: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
237: if((*d&0x80) && (strcmp(shelf[(*d&0x7F)/2], vol) == 0)){
238: if(((*d&1) == flip) && (d[-1] != 0x80)){
239: Fprint(1, "%d\n", i);
240: return;
241: }
242: s_diskrelease(-1, A, i, 0);
243: }
244: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
245: if((d[-2]&0x40) == 0){
246: if(s_diskset(sh, flip, i, 1))
247: exit(1);
248: Fprint(1, "%d\n", i);
249: return;
250: }
251: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
252: if((d[-2]&1) == 0){
253: s_diskrelease(-1, A, i, 0);
254: }
255: }
256: }
257:
258: jread()
259: {
260: int fd, errs = 0;
261: int ntries;
262: register char *s, *ss;
263:
264: for(ntries = 0; ntries < 10; ntries++){
265: if((fd = open(JDIR, 0)) >= 0)
266: break;
267: if(errno != ECONC)
268: break;
269: sleep(1);
270: }
271: if(fd < 0){
272: perror(JDIR);
273: exit(1);
274: }
275: Finit(fd, (char *)0);
276: while(s = Frdline(fd)){
277: if(ss = strchr(s, ' ')){
278: *ss++ = 0;
279: shelf[atoi(s)] = strdup(ss);
280: } else {
281: Fprint(2, "bad line: '%s'\n", s);
282: errs++;
283: }
284: }
285: if(errs){
286: fprint(2, "%d errors\n", errs);
287: exit(1);
288: }
289: close(fd);
290: }
291:
292: jwrite()
293: {
294: int ntries, fd, i;
295:
296: for(ntries = 0; ntries < 10; ntries++){
297: if((fd = creat(JDIR, JMODE)) >= 0)
298: break;
299: if(errno != ECONC)
300: break;
301: sleep(1);
302: }
303: if(fd < 0){
304: perror(JDIR);
305: exit(1);
306: }
307: Finit(fd, (char *)0);
308: for(i = 0; i < NSHELF; i++)
309: if(shelf[i])
310: Fprint(fd, "%d %s\n", i, shelf[i]);
311: Fflush(fd);
312: close(fd);
313: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.