|
|
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: int NDRIVES; /* how many to use */
12:
13: char *shelf[NSHELF];
14: int wr = 0;
15:
16: main(argc, argv)
17: char **argv;
18: {
19: long t;
20:
21: (void)time(&t);
22: srand((int)t);
23: if((argc = getflags(argc, argv, "clmprsuUe:1[volid]w:1[secs]", 0)) < 0)
24: usage("[ vol_id ]");
25: if((argc <= 1) && !flag['u'] && !flag['r'] && !flag['e'] && !flag['l'] && !flag['w'] && !flag['p'])
26: flag['m'] = flagset;
27: if(flag['r'] || flag['e'] || flag['l'] || flag['p'] || flag['m'] || flag['u']){
28: if(scsiinit(1))
29: exit(1);
30: } else { /* mounting */
31: if(scsiinit(0)){
32: Fprint(1, "0\n");
33: exit(0);
34: }
35: }
36: scsiid(2);
37: NDRIVES = s_ndrives();
38: if(NDRIVES < 1){
39: fprint(2, "cannot determine the number of drives\n");
40: exit(1);
41: }
42: /*print("using %d drives\n", NDRIVES);/**/
43: jread();
44: if(flag['u'])
45: unload(0);
46: if(flag['U'])
47: unload(1);
48: if(flag['r'])
49: if(jreload()){
50: fprint(2, "reload failed\n");
51: exit(1);
52: }
53: if(flag['e'])
54: jeject(flag['e'][0]);
55: if(flag['l'])
56: jload();
57: if(flag['m'])
58: jmpr();
59: if(flag['p'])
60: jpr();
61: if(wr)
62: jwrite();
63: if(argc > 1)
64: jmount(argv[1]);
65: else {
66: if(flag['w']){
67: fprint(2, "worm mount: -w given with no vol_id\n");
68: exit(1);
69: }
70: }
71: exit(0);
72: }
73:
74: jpr()
75: {
76: int i;
77:
78: for(i = 0; i < NSHELF; i++)
79: if(shelf[i]) Fprint(1, "%2d: %s\n", i, shelf[i]);
80: Fflush(1);
81: }
82:
83: jmpr()
84: {
85: int i;
86: register unsigned char *d;
87: struct scsi_o o;
88:
89: if(s_istatus(0, &o) == 0){
90: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
91: if(*d&0x80)
92: Fprint(1, "drive %d: %s%c, %sline\n", i,
93: shelf[(*d&0x7F)/2], (*d&1)? 'b':'a',
94: (d[-2]&1)?"on":"off");
95: }
96: Fflush(1);
97: }
98:
99: jeject(s)
100: char *s;
101: {
102: int i, me, drive;
103: register unsigned char *d;
104: struct scsi_o o;
105:
106: if(s_istatus(0, &o) == 0){
107: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
108: if((*d&0x80) && (strcmp(s, shelf[me = (*d&0x7F)/2]) == 0)){
109: if(s_diskeject(i))
110: fprint(2, "worm mount: couldn't eject drive %d\n", i);
111: shelf[me] = 0;
112: wr = 1;
113: return;
114: }
115: }
116: drive = getdrive();
117: for(i = 0; i < NSHELF; i++)
118: if(strcmp(shelf[i], s) == 0){
119: if(s_diskset(i, A, drive, 1)){
120: fprint(2, "worm mount: couldn't load %s into drive 1\n", s);
121: return;
122: }
123: if(s_diskeject(1)){
124: fprint(2, "worm mount: couldn't eject %s from drive 1\n", s);
125: s_diskrelease(-1, A, drive, 1);
126: return;
127: }
128: shelf[i] = 0;
129: wr = 1;
130: return;
131: }
132: fprint(2, "worm mount: can't find %s\n", s);
133: exit(1);
134: }
135:
136: jload()
137: {
138: int i;
139: int drive, flip;
140: char s[256], *side;
141: struct scsi_o output;
142: int ndone = 0;
143:
144: drive = getdrive();
145: Fprint(1, "loading new disks\n");
146: loop:
147: if(s_diskset(127, A, drive, 0)){
148: Fprint(1, "%d new disk%s loaded\n", ndone, ndone==1? "":"s");
149: return;
150: }
151: Fprint(1, "loading... "); Fflush(1);
152: if(s_start(drive)){
153: fprint(2, "worm mount: drive %d won't start\n", drive);
154: return;
155: }
156: s_readid(drive, s);
157: side = &s[strlen(s)-1];
158: if((*s == 0) || ((*side != 'a')&&(*side != 'b'))){
159: fprint(2, "worm mount: bad name '%s' in drive %d\n", s, drive);
160: return;
161: }
162: flip = (*side =='a')? A:B;
163: *side = 0;
164: if(strcmp(s, UNLABELLED))
165: for(i = 0; i < NSHELF; i++)
166: if(strcmp(shelf[i], s) == 0){
167: fprint(2, "worm mount: %s was listed shelf %d\n", s, i);
168: shelf[i] = 0;
169: break;
170: }
171: for(i = 0; i < NSHELF; i++)
172: if(shelf[i] == 0){
173: if(s_diskrelease(i, flip, drive, 1)){
174: fprint(2, "worm mount: %s to shelf %d failed\n", s, i);
175: return;
176: }
177: shelf[i] = strdup(s);
178: print("%s loaded to shelf %d\n", s, i);
179: wr = 1;
180: ndone++;
181: goto loop;
182: }
183: fprint(2, "worm mount: no space left for %s\n", s);
184: }
185:
186: jreload()
187: {
188: int i, dest, flip, try;
189: int drive = 1;
190: char s[256], *side;
191: struct scsi_o output;
192: int todo[NSHELF];
193:
194: flag['l'] = flagset;
195: for(i = 0; i < NSHELF; i++)
196: shelf[i] = 0, todo[i] = 0;
197: drive = getdrive();
198: if(s_istatus(drive, &output))
199: return(1);
200: for(i = 0; i < NSHELF; i++)
201: if((output.data[48+i]&0x80) && (output.data[48+i]&0x60)){
202: shelf[i] = "";
203: todo[i] = 1;
204: }
205: for(i = 0, try = 0; i < NSHELF; i++, try++){
206: if(!todo[i]) continue;
207: if(s_diskset(i, A, drive, 0))
208: continue;
209: Fprint(1, "doing shelf %d: ", i); Fflush(1);
210: if(s_start(drive)){
211: fprint(2, "worm mount: drive %d won't start\n", drive);
212: exit(1);
213: }
214: s_readid(drive, s);
215: if(strcmp(s, UNLABELLED) == 0)
216: strcat(s, "a");
217: side = &s[strlen(s)-1];
218: if((*s == 0) || ((*side != 'a')&&(*side != 'b'))){
219: fprint(2, "worm mount: bad volid '%s', %s\n", s, try?"ignoring":"retrying");
220: if(try == 0){
221: s_diskrelease(i, B, drive, 1);
222: i--;
223: }
224: continue;
225: }
226: sleep(1);
227: if(flag['c']){
228: for(dest = 0; dest < i; dest++)
229: if(shelf[dest] == 0) break;
230: } else if(flag['s']){
231: while(shelf[dest = nrand(NSHELF)] && (i != dest))
232: ;
233: } else
234: dest = i;
235: flip = (*side == 'a')? A:B;
236: if(s_diskrelease(dest, flip, drive, 1)){
237: fprint(2, "worm mount: %s to shelf %d failed\n", s, dest); exit(1);
238: }
239: *side = 0;
240: Fprint(1, "%s", s);
241: if(dest != i)
242: Fprint(1, " -> shelf %d", dest);
243: Fprint(1, "\n"); Fflush(1);
244: sleep(1);
245: shelf[i] = 0;
246: shelf[dest] = strdup(s);
247: wr = 1;
248: try = -1;
249: }
250: return(0);
251: }
252:
253: #define STEP 5
254:
255: jmount(vol)
256: char *vol;
257: {
258: int limit, i, sh, flip;
259: unsigned char *d;
260: char *ss;
261: struct scsi_o o;
262:
263: ss = &vol[strlen(vol)-1];
264: if((*ss != 'a') && (*ss != 'b')){
265: fprint(2, "worm mount: mount name (%s) must end in [ab]\n", vol);
266: exit(1);
267: }
268: flip = (*ss == 'a')? A:B;
269: *ss = 0;
270: for(sh = 0; sh < NSHELF; sh++)
271: if(shelf[sh] && (strcmp(vol, shelf[sh]) == 0))
272: break;
273: if(sh == NSHELF){
274: fprint(2, "worm mount: no disk with vol_id '%s'\n", vol);
275: exit(1);
276: }
277: limit = flag['w']? atoi(flag['w'][0]) : 9999999;
278: for(; limit > -STEP; limit -= STEP, sleep(STEP)){
279: if(s_istatus(0, &o))
280: continue;
281: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
282: if((*d&0x80) && (strcmp(shelf[(*d&0x7F)/2], vol) == 0)){
283: if(((*d&1) == flip) && (d[-1] != 0x80)){
284: Fprint(1, "%d\n", i);
285: return;
286: }
287: s_diskrelease(-1, A, i, 0);
288: }
289: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
290: if((d[-2]&0x40) == 0){
291: if(s_diskset(sh, flip, i, 1))
292: exit(1);
293: /*----->*/ prompt(i);
294: Fprint(1, "%d\n", i);
295: return;
296: }
297: for(i = 0, d = &o.data[18]; i < NDRIVES; i++, d += 4)
298: if((d[-2]&1) == 0){
299: s_diskrelease(-1, A, i, 0);
300: }
301: }
302: }
303:
304: jread()
305: {
306: int fd, errs = 0;
307: int ntries;
308: register char *s, *ss;
309:
310: for(ntries = 0; ntries < 10; ntries++){
311: if((fd = open(JDIR, 0)) >= 0)
312: break;
313: if(errno != ECONC)
314: break;
315: sleep(1);
316: }
317: if(fd < 0){
318: perror(JDIR);
319: exit(1);
320: }
321: Finit(fd, (char *)0);
322: while(s = Frdline(fd)){
323: if(ss = strchr(s, ' ')){
324: *ss++ = 0;
325: shelf[atoi(s)] = strdup(ss);
326: } else {
327: Fprint(2, "bad line: '%s'\n", s);
328: errs++;
329: }
330: }
331: if(errs){
332: fprint(2, "%d errors\n", errs);
333: exit(1);
334: }
335: close(fd);
336: }
337:
338: jwrite()
339: {
340: int ntries, fd, i;
341:
342: for(ntries = 0; ntries < 10; ntries++){
343: if((fd = creat(JDIR, JMODE)) >= 0)
344: break;
345: if(errno != ECONC)
346: break;
347: sleep(1);
348: }
349: if(fd < 0){
350: perror(JDIR);
351: exit(1);
352: }
353: Finit(fd, (char *)0);
354: for(i = 0; i < NSHELF; i++)
355: if(shelf[i])
356: Fprint(fd, "%d %s\n", i, shelf[i]);
357: Fflush(fd);
358: close(fd);
359: }
360:
361: unload(force)
362: {
363: int i, ret = -1;
364: unsigned char *d;
365: struct scsi_o output;
366:
367: if(s_istatus(0, &output))
368: return(1);
369: for(i = 0; i < NDRIVES; i++){
370: d = &output.data[16+4*i];
371: if((*d&0x40) || force){
372: if(((*d&1) == 0) || force)
373: s_diskrelease(-1, A, i, 0);
374: } else
375: ret = i;
376: }
377: return(ret);
378: }
379:
380: getdrive()
381: {
382: int i;
383:
384: if((i = unload(0)) < 0)
385: i = NDRIVES;
386: return(i);
387: }
388:
389: #include <sys/types.h>
390: #include <sys/udaioc.h>
391:
392: prompt(i)
393: {
394: char buf[1024];
395: int fd;
396:
397: sprint(buf, "/dev/worm%d", i);
398: fd = open(buf, 0);
399: read(fd, buf, sizeof buf);
400: ioctl(fd, UIOSPDW);
401: close(fd);
402: sleep(1);
403: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.