Annotation of researchv10no/cmd/worm/scsi/scsi.cpio, revision 1.1
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 ���]�&� &