|
|
1.1 root 1: 0707070035050375121006660011710000040000010653710464714144700000700000003143README This is a simple extensible shell (scsish) for poking at scsi
2: devices, particularly the simpler kinds commonly called toasters.
3: it is supposed to be self-documenting in use; try the help command.
4: my use of the moran-dronek /dev/scsi library is still imperfect;
5: there is still some some debugging showing.
6:
7: To compile, you first need mk. you then have to pick a system type
8: to set some flags; currently we support research and sgi.
9: yours may differ, particularly as no one else has our ansi C compiler for the sgi.
10: the only problem i would expect is the normal header file crap you get
11: mixing ansi and non-ansi files. i recommend setting NPROC=1 while debugging hdr files.
12: if you change (header) files, try putting them in the directory inc
13: (then others may benefit). To support a new system (say sgi-gcc), just create
14: a new file sgi-gcc.mk and so on. you may be missing some devices in
15: your /dev/scsi; the script scsi/gendev may help (but check the major/minor
16: numbers and permissions).
17:
18: As for modifying/extending scsish, it has been designed to be not too hard.
19: Adding a new device means adding a new set of rules (like the other rules)
20: to mkfile and creating a new directory (say exabyte) and at least two files in it
21: (dev.c and fns.h). The wren directory is a small example you can clone.
22: Adding new functions to any device means updating a file list in mkfile,
23: updating dev.c and fns.h in the device directory. The argument syntax
24: scheme is arguably pokey, but liveable. at some future point we should probably
25: switch over to osterhout's tcl.
26:
27: as always, i invite you send extensions/fixes etc back to
28: [email protected]
29: 0707070035050375111006660011710000040000010653730457563432000000500000000565TODO | COPY drive NUMBER NUMBER drive NUMBER {/*:COPY sdrive sstart nblocks ddrive dstart:: */
30: s_copy($2, $3, $4, $5, $6);
31: }
32: | READ drive NUMBER {
33: struct scsi_ret output;
34: s_read($2, $3, 1, &output);
35: scsiodump(output.data, 1024);
36: }
37: | WRITE drive NUMBER { s_write($2, $3, 1); }
38: | WRITE drive NUMBER NUMBER { s_write($2, $3, $4); } /*:WRITE drive start n:: */
39: 0707070035050406411006660011710000040000010511250474377127600001300000002245allocate.c #define _POSIX_SOURCE
40: #include <stddef.h>
41: #include <stdlib.h>
42: #include <unistd.h>
43: #include <stdio.h>
44: #include <string.h>
45: #include <errno.h>
46: #include <time.h>
47: #include "jukeface.h"
48: #include "jukebox.h"
49:
50: allocate(Jukebox *j, char *vol_id, char *buf)
51: {
52: int drive, sh;
53: char nbuf[512];
54:
55: if(j_rdshelves(j, buf)) /* read in shelf names */
56: return(-1);
57: if(j_shstatus(j, buf)) /* get the jukebox status */
58: return(-1);
59: sh = j_shelfof(j, vol_id);
60: if(sh >= 0){
61: sprintf(buf, "there is an existing '%s' on shelf %d", vol_id, sh);
62: return(-1);
63: }
64: sh = j_shelfof(j, UNALLOCATED);
65: if(sh < 0){
66: sprintf(buf, "no unallocated disks");
67: return(-1);
68: }
69: printf("using unallocated disk from shelf %d\n", sh);
70: drive = j->nluns-1;
71: if(j_sh_to_dr(sh, SIDEB, drive, buf) < 0)
72: return(-1);
73: sprintf(nbuf, "%sb", vol_id);
74: if(j_wvolid(drive, nbuf, buf))
75: return(-1);
76: j_wrshelf = 1;
77: j->names[sh] = strdup(vol_id);
78: j->shelves[sh] = 1;
79: if(j_dr_to_sh(drive, sh, SIDEB, buf) < 0)
80: return(-1);
81: if(j_sh_to_dr(sh, SIDEA, drive, buf) < 0)
82: return(-1);
83: sprintf(nbuf, "%sa", vol_id);
84: if(j_wvolid(drive, nbuf, buf))
85: return(-1);
86: if(j_dr_to_sh(drive, sh, SIDEA, buf) < 0)
87: return(-1);
88: return(0);
89: }
90: 0707070035050550721006660011710000040000011772350474343203100000600000000761arg.h /*
91: * argument processing
92: */
93: #define ARGBEGIN for((argv0? 0: (argv0=*argv)),argv++,argc--;\
94: argv[0] && argv[0][0]=='-' && argv[0][1];\
95: argc--, argv++) {\
96: char *_args, *_argt, _argc;\
97: _args = &argv[0][1];\
98: if(_args[0]=='-' && _args[1]==0){\
99: argc--; argv++; break;\
100: }\
101: while(*_args) switch(_argc=*_args++)
102: #define ARGEND }
103: #define ARGF() (_argt=_args, _args="",\
104: (*_argt? _argt: argv[1]? (argc--, *++argv): 0))
105: #define ARGC() _argc
106: extern char *argv0;
107: 0707070035050554471006660011710000040000010651520467171415300000400000000120c.c typedef int (*fn)(struct x *);
108: extern int fn1(struct x *);
109: extern fn *fp = fn1;
110: 0707070035050421771006660011710000040000010011270477113511400000700000011124cold.c #define _POSIX_SOURCE
111: #include <stddef.h>
112: #include <stdlib.h>
113: #include <unistd.h>
114: #include <stdio.h>
115: #include <string.h>
116: #include <ctype.h>
117: #include "jukeface.h"
118: #include "jukebox.h"
119: #include "tcl.h"
120: #include "generic/fns.h"
121:
122: static sort(char *buf);
123:
124: j_cold(Jukebox *j, char *type, char *err)
125: {
126: int side;
127: int drive, sh, nsh;
128: int n;
129: char vol_id[512];
130: char *didit;
131:
132: if(j_drstatus(j, err))
133: return(-1);
134: printf("drstatus done\n");
135: if(j_shstatus(j, err))
136: return(-1);
137: printf("shstatus done\n");
138: /* first clear out nonexistent labels */
139: n = 0;
140: didit = (char *)malloc(j->nshelves*sizeof(char));
141: for(sh = 0; sh < j->nshelves; sh++){
142: if(j->shelves[sh]){
143: n++;
144: j->names[sh] = "there";
145: } else
146: j->names[sh] = 0;
147: didit[sh] = 0;
148: }
149: printf("%d disks in shelves.\n", n);
150: /* second, clear the drives */
151: for(sh = 0; sh < j->nshelves; sh++)
152: if(j->shelves[sh] == 0)
153: break;
154: for(drive = 0; drive < j->nluns; drive++){
155: if(!j->luns[drive].occupied)
156: continue; /* no disk in drive */
157: printf("clearing drive %d:\n", drive);
158: if(j->luns[drive].shelf < 0){
159: if(j_dr_to_sh(drive, sh, SIDEA, err))
160: return(-1);
161: for(sh++; sh < j->nshelves; sh++)
162: if(j->shelves[sh] == 0)
163: break;
164: n++;
165: } else
166: if(j_dr_to_sh(drive, -1, SIDEA, err))
167: return(-1);
168: }
169: if(isdigit(*type)){ /* just do one shelf */
170: sh = atol(type);
171: printf("single shelf %d reload\n", sh);
172: if(j_rdshelves(j, err))
173: return(-1);
174: if(getvol(sh, drive, vol_id, &side)){
175: strcpy(err, vol_id);
176: return(-1);
177: }
178: printf("%s@%d -> %d\n", vol_id, sh, sh);
179: if(j_dr_to_sh(drive, -1, side, err) < 0)
180: return(-1);
181: j->names[sh] = strdup(vol_id);
182: j->shelves[sh] = 1;
183: j_wrshelf = 1;
184: return(0);
185: }
186: printf("reloading %d disks.\n", n);
187: side = SIDEA;
188: drive = j->nluns-1;
189: j_wrshelf = 1;
190: for(sh = 0; sh < j->nshelves; sh++){
191: if(didit[sh])
192: continue;
193: j->names[sh] = 0;
194: if(j->shelves[sh]){
195: printf("%d: ", sh); fflush(stdout);
196: if(getvol(sh, drive, vol_id, &side)){
197: strcpy(err, vol_id);
198: return(-1);
199: }
200: j->shelves[sh] = 0;
201: switch(*type)
202: {
203: case 'c':
204: for(nsh = 0; j->shelves[nsh]; nsh++)
205: ;
206: break;
207: case 's':
208: case 'r':
209: while(j->shelves[nsh = nrand(j->nshelves)])
210: ;
211: break;
212: case 'u':
213: default:
214: nsh = sh;
215: break;
216: }
217: printf("%s@%d -> %d\n", vol_id, sh, nsh);
218: if(j_dr_to_sh(drive, nsh, side, err) < 0)
219: return(-1);
220: j->names[nsh] = strdup(vol_id);
221: j->shelves[nsh] = 1;
222: didit[nsh] = 1;
223: sleep(5);
224: }
225: }
226: printf("process any new disks.\n");
227: if(j_warm(j, err))
228: return(-1);
229: /* if(type == 's')
230: return(sort(err));
231: */
232: return(0);
233: }
234:
235: getvol(int sh, int drive, char *vol_id, int *side)
236: {
237: int i;
238: char buf[512];
239:
240: if(j_sh_to_dr(sh, SIDEA, drive, vol_id) < 0)
241: return(-1);
242: if((i = j_rvolid(drive, buf)) < 0)
243: goto softerr;
244: if(i == 0)
245: *side = SIDEA;
246: else {
247: *side = SIDEB;
248: if(j_dr_to_sh(drive, sh, SIDEA, vol_id) < 0)
249: return(-1);
250: if(j_sh_to_dr(sh, SIDEB, drive, vol_id) < 0)
251: return(-1);
252: if((i = j_rvolid(drive, buf)) < 0)
253: goto softerr;
254: }
255: if(i > 0)
256: strcpy(vol_id, UNALLOCATED);
257: else {
258: strcpy(vol_id, buf);
259: i = strlen(vol_id)-1;
260: if(i < 0){
261: sprintf(buf, "apparently good superblock but null vol_id");
262: goto softerr;
263: } else if(vol_id[i] == 'a')
264: vol_id[i] = 0;
265: else if(vol_id[i] == 'b'){
266: vol_id[i] = 0;
267: *side = !*side;
268: } else {
269: sprintf(buf, "vol_id '%s' must end in a or b", vol_id);
270: strcpy(vol_id, buf);
271: return(-1);
272: }
273: }
274: return(0);
275: softerr:
276: *side = SIDEA;
277: fprintf(stderr, "error in reading shelf %d: %s; proceeding\n", sh, buf);
278: sprintf(vol_id, "DISK_ERROR%d", sh);
279: j_reset();
280: return(0);
281: }
282: #ifdef CRAP
283: static int index[j->nshelves];
284: static
285: cmp(int *a, int *b)
286: {
287: char *sa = j->shelves[*a], *sb = j->shelves[*b];
288:
289: if((sa == 0) && (sb == 0)) return(0);
290: if(sa == 0) return(-1);
291: if(sb == 0) return(1);
292: return(strcmp(sa, sb));
293: }
294:
295: static char *disk[8];
296:
297: static
298: sd(int a, int b, char *err)
299: {
300: disk[b] = j->shelves[a];
301: return(j->shelves_to_drive(a, SIDEB, b, err));
302: }
303: static
304: ds(int a, int b, char *err)
305: {
306: j->shelves[b] = disk[a];
307: return(j_drive_to_shelf(a, b, SIDEB, err));
308: }
309:
310: static
311: sort(char *errbuf)
312: {
313: int i, j, org;
314:
315: for(i = 0; i < j->nshelves; i++)
316: index[i] = i;
317: qsort(index, j->nshelves, sizeof index[0], cmp);
318: for(i = 0; i < j->nshelves; i++){
319: if(index[i] < 0) continue;
320: if(sd(org = i, NLUN-1, errbuf) < 0)
321: return(-1);
322: j = index[i];
323: index[i] = -1;
324: while(j != org){
325: if(sd(j, NLUN-2, errbuf) < 0)
326: return(-1);
327: if(ds(NLUN-2, i, errbuf) < 0)
328: return(-1);
329: i = j;
330: if(index[i] < 0)
331: break;
332: j = index[i];
333: index[i] = -1;
334: }
335: if(ds(NLUN-1, i, errbuf) < 0)
336: return(-1);
337: }
338: return(0);
339: }
340: #endif
341: 0707070035050554431006660011710000040000010134650474362344500000500000106000core �������������� �� L����� ���� �{���������d8À � �
��� ��& �l� + 0u ���]�&� &