|
|
1.1 root 1: #include <libc.h>
2: #include <fio.h>
3: #include <sys/types.h>
4: #include <sys/stat.h>
5: #include <signal.h>
6: #include "worm.h"
7:
8: long minfree = 40000;
9: int verbose = 0;
10:
11: main(argc, argv)
12: char **argv;
13: {
14: Superblock in, out;
15: char *e;
16: char buf[4096];
17: int n;
18: long lineno;
19: int c;
20: char *dev = "/dev/worm0";
21: long tfiles, tbytes;
22: int eof;
23: char first[4096];
24: extern char *optarg;
25: extern int optind;
26:
27: argout = argv[0];
28: while((c = getopt(argc, argv, "vm:f:")) != -1)
29: switch(c)
30: {
31: case 'f': dev = optarg; break;
32: case 'm': minfree = atol(optarg); break;
33: case 'v': verbose = 1; break;
34: case '?': usage();
35: }
36:
37: if(optind+3 != argc)
38: usage();
39: e = mapdev(argv[optind+1]);
40: if((out.fd = open(e, 2)) < 0){
41: perror(e);
42: exit(1);
43: }
44: if(e = openinode(&out, SPIN_DOWN)){
45: fprint(2, "%s: %s\n", *argv, e);
46: exit(1);
47: }
48: if(strcmp(out.vol_id, argv[optind+2])){
49: fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind+2], out.vol_id);
50: exit(1);
51: }
52: if(out.version != VLINK){
53: fprint(2, "%s: can't write on a b-tree disk\n", out.vol_id);
54: exit(1);
55: }
56: dev = mapdev(dev);
57: if((in.fd = open(dev, 2)) < 0){
58: perror(*argv);
59: exit(1);
60: }
61: if(e = openinode(&in, DO_INODE|SPIN_DOWN)){
62: fprint(2, "%s: %s\n", *argv, e);
63: exit(1);
64: }
65: if(strcmp(in.vol_id, argv[optind])){
66: fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], in.vol_id);
67: exit(1);
68: }
69: for(n = 1; n <= NSIG; n++)
70: signal(n, SIG_IGN);
71: eof = 0;
72: tfiles = tbytes = 0;
73: lineno = 0;
74: while(!eof){
75: /* flush seperater lines */
76: while(e = Frdline(0)){
77: lineno++;
78: if(*e)
79: break;
80: }
81: if(e == 0)
82: break;
83: ininit();
84: proc(&out, e);
85: strncpy(first, e, sizeof first);
86: if(out.nfree < minfree){
87: fprint(2, "wcopy: disk %s full before copying group '%s' line %d\n",
88: out.vol_id, first, lineno);
89: exit(1);
90: }
91: while(e = Frdline(0)){
92: lineno++;
93: if(*e == 0)
94: break;
95: proc(&out, e);
96: }
97: if(e == 0)
98: eof = 1;
99: if(bad)
100: exit(1);
101: nfiles = nbytes = 0;
102: blkdone = 0;
103: inwrite(&out, &in);
104: if(bad)
105: exit(1);
106: if(verbose)
107: fprint(1, "%s group('%s' %d files, %.6fMB) done\n",
108: timenow(), first, nfiles, nbytes/1e6);
109: tfiles += nfiles;
110: tbytes += nbytes;
111: }
112: if(verbose)
113: fprint(1, "%s total: %d files, %.6fMB\n", timenow(), tfiles, tbytes/1e6);
114: exit(0);
115: }
116:
117: usage()
118: {
119: fprint(2, "Usage: worm copy [-v] [-m minfree] [-f src_dev] src_id dest_dev dest_id < files\n");
120: exit(1);
121: }
122:
123: proc(s, file)
124: Superblock *s;
125: char *file;
126: {
127: struct stat sbuf;
128: unsigned short mode;
129: Inode i;
130: Inode *srci;
131:
132: if((srci = inodeof(file)) == 0){
133: fprint(2, "can't find file '%s'\n", file);
134: return;
135: }
136: memset((char *)&i, 0, sizeof(i));
137: i = *srci;
138: i.block = 0;
139: nbytes += i.nbytes;
140: if(inadd(s, &i))
141: bad = 1;
142: }
143:
144: writeout(dest, i, blk, src)
145: Superblock *dest, *src;
146: Inode *i;
147: long *blk;
148: {
149: char b[BIGBLOCK];
150: Inode *srci;
151: long n, len, blen;
152: char *name;
153:
154: n = (i->nbytes+dest->blocksize-1)/dest->blocksize;
155: *blk += n;
156: blkdone += n;
157: blen = sizeof b/dest->blocksize;
158: len = blen*dest->blocksize;
159: nbytes += i->nbytes;
160: nfiles++;
161: name = i->name.n;
162: srci = inodeof(name);
163: Seek(src, srci->block);
164: for(n = i->nbytes; n > len; n -= len){
165: if(Read(src, b, blen)){
166: out:
167: fprint(2, "read problem: seek=%d n=%d blen=%d len=%d; ",
168: srci->block, n, blen, len);
169: perror(name);
170: bad = 1;
171: return;
172: }
173: if(Write(dest, b, blen)){
174: fprint(2, "nb=%d, n=%d len=%d blen=%d\n", i->nbytes, n, len, blen);
175: perror("data write");
176: exit(1);
177: }
178: }
179: if(n){
180: n += dest->blocksize-1;
181: n /= dest->blocksize;
182: if(Read(src, b, n))
183: goto out;
184: if(Write(dest, b, n)){
185: perror("data write");
186: exit(1);
187: }
188: }
189: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.