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