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