|
|
1.1 ! root 1: #include <libc.h> ! 2: #include "worm.h" ! 3: #include "sym.h" ! 4: #include <sys/types.h> ! 5: #include <sys/stat.h> ! 6: #include <pwd.h> ! 7: #include <grp.h> ! 8: ! 9: char *timenow(); ! 10: long minfree = 40000; ! 11: int verbose = 0; ! 12: static char *copy(); ! 13: ! 14: main(argc, argv) ! 15: char **argv; ! 16: { ! 17: char *e; ! 18: char *dev = "/dev/worm0"; ! 19: char *dest = 0; ! 20: Superblock in, out; ! 21: long start = 1; ! 22: long count = 1000000L; ! 23: int c; ! 24: extern char *optarg; ! 25: extern int optind; ! 26: void pr(); ! 27: ! 28: while((c = getopt(argc, argv, "vc:m:s:f:")) != -1) ! 29: switch(c) ! 30: { ! 31: case 'c': count = atol(optarg); break; ! 32: case 'f': dev = optarg; break; ! 33: case 'm': minfree = atol(optarg); break; ! 34: case 's': start = atol(optarg); break; ! 35: case 'v': verbose = 1; break; ! 36: case '?': usage(); ! 37: } ! 38: dev = mapdev(dev); ! 39: if((in.fd = open(dev, 0)) < 0){ ! 40: perror(dev); ! 41: exit(1); ! 42: } ! 43: if(optind+3 != argc) ! 44: usage(); ! 45: ! 46: if(e = openinode(&in, SPIN_DOWN)){ ! 47: fprint(2, "worm copy: %s: %s\n", dev, e); ! 48: exit(1); ! 49: } ! 50: if(strcmp(argv[optind], in.vol_id)){ ! 51: fprint(2, "src vol_id mismatch: expected %s, got %s\n", ! 52: argv[optind], in.vol_id); ! 53: exit(1); ! 54: } ! 55: dest = mapdev(argv[optind+1]); ! 56: if((out.fd = open(dest, 2)) < 0){ ! 57: perror(dest); ! 58: exit(1); ! 59: } ! 60: if(e = openinode(&out, SPIN_DOWN)){ ! 61: fprint(2, "worm copy: %s: %s\n", dest, e); ! 62: exit(1); ! 63: } ! 64: if(strcmp(argv[optind+2], out.vol_id)){ ! 65: fprint(2, "destination vol_id mismatch: expected %s, got %s\n", ! 66: argv[optind+2], out.vol_id); ! 67: exit(1); ! 68: } ! 69: if(e = copy(&in, start, count, &out)){ ! 70: fprint(2, "worm copy: %s: %s\n", dest, e); ! 71: exit(1); ! 72: } ! 73: exit(0); ! 74: } ! 75: ! 76: usage() ! 77: { ! 78: fprint(2, "Usage: worm copy [-v] [-fdevice] [-s startblk] [-c count] [-m minfree] srcvolid destdev destvolid\n"); ! 79: exit(2); ! 80: } ! 81: ! 82: static char * ! 83: copy(in, blk, count, out) ! 84: register Superblock *in, *out; ! 85: long blk, count; ! 86: { ! 87: register Inode *i; ! 88: short fd = in->fd; ! 89: char *b, *err; ! 90: long nb, ndata; ! 91: char *nameb; ! 92: Inode *inodes = 0; ! 93: Inode *iend; ! 94: long delta; ! 95: static char buf[64]; ! 96: extern char *lkwri(); ! 97: ! 98: in->blocksize = 1024; ! 99: if((b = malloc(in->blocksize)) == 0){ ! 100: sprint(buf, "couldn't malloc buffer (%d bytes)", in->blocksize); ! 101: return(buf); ! 102: } ! 103: Seek(in, blk); ! 104: if(Read(in, b, 1)){ ! 105: fprint(2, "worm copy: unexpected read error\n"); ! 106: exit(1); ! 107: } ! 108: *in = *((Superblock *)b); ! 109: in->fd = fd; ! 110: while(count-- > 0){ ! 111: if(in->magic != SMAGIC){ ! 112: fprint(2, "bad Superblock at %ld\n", blk); ! 113: exit(1); ! 114: } ! 115: if(in->ninodes){ ! 116: if(verbose) ! 117: fprint(2, "%s reading chunk %s:%ld (%.1f%%)\n", ! 118: timenow(), in->vol_id, in->myblock, ! 119: in->myblock*100./(float)in->nblocks); ! 120: if(out->nfree < minfree){ ! 121: fprint(2, "worm copy: disk %s has < %d free at input %d\n", ! 122: out->vol_id, minfree, in->myblock); ! 123: exit(1); ! 124: } ! 125: nb = (in->ninodes+(in->blocksize/sizeof(Inode))-1)/(in->blocksize/sizeof(Inode)); ! 126: inodes = (Inode *)malloc((unsigned)(in->blocksize*nb)); ! 127: if(inodes == 0){ ! 128: sprint(buf, "inode malloc(%d) fail, sbrk=%d\n", ! 129: (in->blocksize*nb), sbrk(0)); ! 130: return(buf); ! 131: } ! 132: Seek(in, in->binodes); ! 133: if(Read(in, (char *)inodes, nb)) ! 134: goto skip; ! 135: delta = out->nextffree - inodes->block; ! 136: print("%d inodes; delta=%d\n", in->ninodes, delta); ! 137: for(i = inodes, iend = inodes+in->ninodes; i < iend; i++) ! 138: if(i->block > 0) ! 139: i->block += delta; ! 140: nb = (in->ninochars+in->blocksize-1)/in->blocksize; ! 141: nameb = malloc((unsigned)(in->blocksize*nb)); ! 142: if(nameb == 0){ ! 143: sprint(buf, "name buffer malloc(%d) fail, sbrk=%d\n", ! 144: (in->blocksize*nb), sbrk(0)); ! 145: return(buf); ! 146: } ! 147: if(Read(in, nameb, nb)) ! 148: goto skip; ! 149: ndata = in->binodes - in->myblock - 1; ! 150: if(err = lkwri(out, inodes, in->ninodes, nameb, in->ninochars, ndata)){ ! 151: fprint(2, "wcopy: lkwri: %s at input %d\n", err, in->myblock); ! 152: exit(1); ! 153: } ! 154: dcopy(in, out, ndata); ! 155: } ! 156: skip: ! 157: blk = in->nextsb; ! 158: Seek(in, blk); ! 159: if(Read(in, b, 1L)) ! 160: break; ! 161: *in = *((Superblock *)b); ! 162: in->fd = fd; ! 163: if(in->myblock == 0) ! 164: in->myblock = blk; ! 165: } ! 166: free(b); ! 167: if(verbose) ! 168: fprint(2, "%s copy done, %s is %.1f%% full\n", timenow(), out->vol_id, ! 169: out->myblock*100.0/(float)out->nblocks); ! 170: return((char *)0); ! 171: } ! 172: ! 173: dcopy(in, out, n) ! 174: Superblock *in, *out; ! 175: long n; ! 176: { ! 177: char buf[BIGBLOCK]; ! 178: long bs; ! 179: ! 180: bs = BIGBLOCK/in->blocksize; ! 181: Seek(in, in->myblock+1); ! 182: Seek(out, out->myblock+1); ! 183: while(n > 0){ ! 184: if(bs > n) bs = n; ! 185: if(Read(in, buf, bs)){ ! 186: fprint(2, "wcopy: warning: data read error at %d\n", in->myblock); ! 187: } ! 188: if(Write(out, buf, bs)){ ! 189: fprint(2, "wcopy: dcopy write error\n"); ! 190: exit(1); ! 191: } ! 192: n -= bs; ! 193: } ! 194: } ! 195: ! 196: char * ! 197: timenow() ! 198: { ! 199: long tim; ! 200: char *tims; ! 201: ! 202: time(&tim); ! 203: tims = ctime(&tim); ! 204: tims[19] = 0; ! 205: return(tims); ! 206: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.