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