Blame


1 a0d146ed 2005-07-12 devnull #include <u.h>
2 a0d146ed 2005-07-12 devnull #include <libc.h>
3 a0d146ed 2005-07-12 devnull #include <venti.h>
4 a0d146ed 2005-07-12 devnull #include <libsec.h>
5 a0d146ed 2005-07-12 devnull #include <thread.h>
6 da0a205e 2009-08-21 extrudeda #include <avl.h>
7 da0a205e 2009-08-21 extrudeda #include <bin.h>
8 a0d146ed 2005-07-12 devnull
9 75d04888 2009-05-25 rsc enum
10 75d04888 2009-05-25 rsc {
11 75d04888 2009-05-25 rsc // XXX What to do here?
12 71ce470a 2012-05-29 rsc VtMaxLumpSize = 65535,
13 75d04888 2009-05-25 rsc };
14 75d04888 2009-05-25 rsc
15 a0d146ed 2005-07-12 devnull int changes;
16 a0d146ed 2005-07-12 devnull int rewrite;
17 a0d146ed 2005-07-12 devnull int ignoreerrors;
18 a0d146ed 2005-07-12 devnull int fast;
19 a0d146ed 2005-07-12 devnull int verbose;
20 da0a205e 2009-08-21 extrudeda int nskip;
21 da0a205e 2009-08-21 extrudeda int nwrite;
22 da0a205e 2009-08-21 extrudeda
23 a0d146ed 2005-07-12 devnull VtConn *zsrc, *zdst;
24 da0a205e 2009-08-21 extrudeda uchar zeroscore[VtScoreSize]; /* all zeros */
25 a0d146ed 2005-07-12 devnull
26 da0a205e 2009-08-21 extrudeda typedef struct ScoreTree ScoreTree;
27 da0a205e 2009-08-21 extrudeda struct ScoreTree
28 da0a205e 2009-08-21 extrudeda {
29 da0a205e 2009-08-21 extrudeda Avl avl;
30 da0a205e 2009-08-21 extrudeda uchar score[VtScoreSize];
31 da0a205e 2009-08-21 extrudeda int type;
32 da0a205e 2009-08-21 extrudeda };
33 da0a205e 2009-08-21 extrudeda
34 da0a205e 2009-08-21 extrudeda Avltree *scoretree;
35 da0a205e 2009-08-21 extrudeda Bin *scorebin;
36 da0a205e 2009-08-21 extrudeda
37 da0a205e 2009-08-21 extrudeda static int
38 da0a205e 2009-08-21 extrudeda scoretreecmp(Avl *va, Avl *vb)
39 da0a205e 2009-08-21 extrudeda {
40 da0a205e 2009-08-21 extrudeda ScoreTree *a, *b;
41 da0a205e 2009-08-21 extrudeda int i;
42 da0a205e 2009-08-21 extrudeda
43 da0a205e 2009-08-21 extrudeda a = (ScoreTree*)va;
44 da0a205e 2009-08-21 extrudeda b = (ScoreTree*)vb;
45 da0a205e 2009-08-21 extrudeda
46 da0a205e 2009-08-21 extrudeda i = memcmp(a->score, b->score, VtScoreSize);
47 da0a205e 2009-08-21 extrudeda if(i != 0)
48 da0a205e 2009-08-21 extrudeda return i;
49 da0a205e 2009-08-21 extrudeda return a->type - b->type;
50 da0a205e 2009-08-21 extrudeda }
51 da0a205e 2009-08-21 extrudeda
52 da0a205e 2009-08-21 extrudeda static int
53 da0a205e 2009-08-21 extrudeda havevisited(uchar score[VtScoreSize], int type)
54 da0a205e 2009-08-21 extrudeda {
55 da0a205e 2009-08-21 extrudeda ScoreTree a;
56 fa325e9b 2020-01-10 cross
57 da0a205e 2009-08-21 extrudeda if(scoretree == nil)
58 da0a205e 2009-08-21 extrudeda return 0;
59 da0a205e 2009-08-21 extrudeda memmove(a.score, score, VtScoreSize);
60 da0a205e 2009-08-21 extrudeda a.type = type;
61 da0a205e 2009-08-21 extrudeda return lookupavl(scoretree, &a.avl) != nil;
62 da0a205e 2009-08-21 extrudeda }
63 da0a205e 2009-08-21 extrudeda
64 da0a205e 2009-08-21 extrudeda static void
65 da0a205e 2009-08-21 extrudeda markvisited(uchar score[VtScoreSize], int type)
66 da0a205e 2009-08-21 extrudeda {
67 da0a205e 2009-08-21 extrudeda ScoreTree *a;
68 da0a205e 2009-08-21 extrudeda Avl *old;
69 da0a205e 2009-08-21 extrudeda
70 da0a205e 2009-08-21 extrudeda if(scoretree == nil)
71 da0a205e 2009-08-21 extrudeda return;
72 da0a205e 2009-08-21 extrudeda a = binalloc(&scorebin, sizeof *a, 1);
73 da0a205e 2009-08-21 extrudeda memmove(a->score, score, VtScoreSize);
74 da0a205e 2009-08-21 extrudeda a->type = type;
75 da0a205e 2009-08-21 extrudeda insertavl(scoretree, &a->avl, &old);
76 da0a205e 2009-08-21 extrudeda }
77 da0a205e 2009-08-21 extrudeda
78 a0d146ed 2005-07-12 devnull void
79 a0d146ed 2005-07-12 devnull usage(void)
80 a0d146ed 2005-07-12 devnull {
81 da0a205e 2009-08-21 extrudeda fprint(2, "usage: copy [-fimrVv] [-t type] srchost dsthost score\n");
82 a0d146ed 2005-07-12 devnull threadexitsall("usage");
83 a0d146ed 2005-07-12 devnull }
84 a0d146ed 2005-07-12 devnull
85 a0d146ed 2005-07-12 devnull void
86 da0a205e 2009-08-21 extrudeda walk(uchar score[VtScoreSize], uint type, int base, int depth)
87 a0d146ed 2005-07-12 devnull {
88 a0d146ed 2005-07-12 devnull int i, n;
89 a0d146ed 2005-07-12 devnull uchar *buf;
90 da0a205e 2009-08-21 extrudeda uchar nscore[VtScoreSize];
91 a0d146ed 2005-07-12 devnull VtEntry e;
92 a0d146ed 2005-07-12 devnull VtRoot root;
93 a0d146ed 2005-07-12 devnull
94 da0a205e 2009-08-21 extrudeda if(verbose){
95 da0a205e 2009-08-21 extrudeda for(i = 0; i < depth; i++)
96 da0a205e 2009-08-21 extrudeda fprint(2, " ");
97 da0a205e 2009-08-21 extrudeda fprint(2, "-> %d %d %d %V\n", depth, type, base, score);
98 da0a205e 2009-08-21 extrudeda }
99 da0a205e 2009-08-21 extrudeda
100 da0a205e 2009-08-21 extrudeda if(memcmp(score, vtzeroscore, VtScoreSize) == 0 || memcmp(score, zeroscore, VtScoreSize) == 0)
101 a0d146ed 2005-07-12 devnull return;
102 fa325e9b 2020-01-10 cross
103 da0a205e 2009-08-21 extrudeda if(havevisited(score, type)){
104 da0a205e 2009-08-21 extrudeda nskip++;
105 da0a205e 2009-08-21 extrudeda return;
106 da0a205e 2009-08-21 extrudeda }
107 a0d146ed 2005-07-12 devnull
108 a0d146ed 2005-07-12 devnull buf = vtmallocz(VtMaxLumpSize);
109 a0d146ed 2005-07-12 devnull if(fast && vtread(zdst, score, type, buf, VtMaxLumpSize) >= 0){
110 a0d146ed 2005-07-12 devnull if(verbose)
111 a0d146ed 2005-07-12 devnull fprint(2, "skip %V\n", score);
112 a0d146ed 2005-07-12 devnull free(buf);
113 a0d146ed 2005-07-12 devnull return;
114 a0d146ed 2005-07-12 devnull }
115 a0d146ed 2005-07-12 devnull
116 a0d146ed 2005-07-12 devnull n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
117 a0d146ed 2005-07-12 devnull if(n < 0){
118 a0d146ed 2005-07-12 devnull if(rewrite){
119 a0d146ed 2005-07-12 devnull changes++;
120 a0d146ed 2005-07-12 devnull memmove(score, vtzeroscore, VtScoreSize);
121 a0d146ed 2005-07-12 devnull }else if(!ignoreerrors)
122 4dde6329 2005-10-29 devnull sysfatal("reading block %V (type %d): %r", score, type);
123 a0d146ed 2005-07-12 devnull return;
124 a0d146ed 2005-07-12 devnull }
125 a0d146ed 2005-07-12 devnull
126 a0d146ed 2005-07-12 devnull switch(type){
127 a0d146ed 2005-07-12 devnull case VtRootType:
128 a0d146ed 2005-07-12 devnull if(vtrootunpack(&root, buf) < 0){
129 a0d146ed 2005-07-12 devnull fprint(2, "warning: could not unpack root in %V %d\n", score, type);
130 a0d146ed 2005-07-12 devnull break;
131 a0d146ed 2005-07-12 devnull }
132 da0a205e 2009-08-21 extrudeda walk(root.prev, VtRootType, 0, depth+1);
133 da0a205e 2009-08-21 extrudeda walk(root.score, VtDirType, 0, depth+1);
134 fd0a0b2a 2009-02-05 rsc if(rewrite)
135 fd0a0b2a 2009-02-05 rsc vtrootpack(&root, buf); /* walk might have changed score */
136 a0d146ed 2005-07-12 devnull break;
137 a0d146ed 2005-07-12 devnull
138 a0d146ed 2005-07-12 devnull case VtDirType:
139 2763a6d8 2014-10-21 rsc for(i=0; i*VtEntrySize < n; i++){
140 a0d146ed 2005-07-12 devnull if(vtentryunpack(&e, buf, i) < 0){
141 a0d146ed 2005-07-12 devnull fprint(2, "warning: could not unpack entry #%d in %V %d\n", i, score, type);
142 a0d146ed 2005-07-12 devnull continue;
143 a0d146ed 2005-07-12 devnull }
144 a0d146ed 2005-07-12 devnull if(!(e.flags & VtEntryActive))
145 a0d146ed 2005-07-12 devnull continue;
146 da0a205e 2009-08-21 extrudeda walk(e.score, e.type, e.type&VtTypeBaseMask, depth+1);
147 da0a205e 2009-08-21 extrudeda /*
148 fa325e9b 2020-01-10 cross * Don't repack unless we're rewriting -- some old
149 da0a205e 2009-08-21 extrudeda * vac files have psize==0 and dsize==0, and these
150 da0a205e 2009-08-21 extrudeda * get rewritten by vtentryunpack to have less strange
151 da0a205e 2009-08-21 extrudeda * block sizes. So vtentryunpack; vtentrypack does not
152 da0a205e 2009-08-21 extrudeda * guarantee to preserve the exact bytes in buf.
153 da0a205e 2009-08-21 extrudeda */
154 fd0a0b2a 2009-02-05 rsc if(rewrite)
155 fd0a0b2a 2009-02-05 rsc vtentrypack(&e, buf, i);
156 a0d146ed 2005-07-12 devnull }
157 a0d146ed 2005-07-12 devnull break;
158 a0d146ed 2005-07-12 devnull
159 a0d146ed 2005-07-12 devnull case VtDataType:
160 a0d146ed 2005-07-12 devnull break;
161 a0d146ed 2005-07-12 devnull
162 a0d146ed 2005-07-12 devnull default: /* pointers */
163 a0d146ed 2005-07-12 devnull for(i=0; i<n; i+=VtScoreSize)
164 a0d146ed 2005-07-12 devnull if(memcmp(buf+i, vtzeroscore, VtScoreSize) != 0)
165 da0a205e 2009-08-21 extrudeda walk(buf+i, type-1, base, depth+1);
166 a0d146ed 2005-07-12 devnull break;
167 a0d146ed 2005-07-12 devnull }
168 a0d146ed 2005-07-12 devnull
169 da0a205e 2009-08-21 extrudeda nwrite++;
170 da0a205e 2009-08-21 extrudeda if(vtwrite(zdst, nscore, type, buf, n) < 0){
171 a0d146ed 2005-07-12 devnull /* figure out score for better error message */
172 a0d146ed 2005-07-12 devnull /* can't use input argument - might have changed contents */
173 a0d146ed 2005-07-12 devnull n = vtzerotruncate(type, buf, n);
174 a0d146ed 2005-07-12 devnull sha1(buf, n, score, nil);
175 a0d146ed 2005-07-12 devnull sysfatal("writing block %V (type %d): %r", score, type);
176 a0d146ed 2005-07-12 devnull }
177 da0a205e 2009-08-21 extrudeda if(!rewrite && memcmp(score, nscore, VtScoreSize) != 0)
178 fa325e9b 2020-01-10 cross sysfatal("not rewriting: wrote %V got %V", score, nscore);
179 da0a205e 2009-08-21 extrudeda
180 da0a205e 2009-08-21 extrudeda if((type !=0 || base !=0) && verbose){
181 da0a205e 2009-08-21 extrudeda n = vtzerotruncate(type, buf, n);
182 da0a205e 2009-08-21 extrudeda sha1(buf, n, score, nil);
183 da0a205e 2009-08-21 extrudeda
184 da0a205e 2009-08-21 extrudeda for(i = 0; i < depth; i++)
185 da0a205e 2009-08-21 extrudeda fprint(2, " ");
186 da0a205e 2009-08-21 extrudeda fprint(2, "<- %V\n", score);
187 da0a205e 2009-08-21 extrudeda }
188 fa325e9b 2020-01-10 cross
189 da0a205e 2009-08-21 extrudeda markvisited(score, type);
190 a0d146ed 2005-07-12 devnull free(buf);
191 a0d146ed 2005-07-12 devnull }
192 a0d146ed 2005-07-12 devnull
193 a0d146ed 2005-07-12 devnull void
194 a0d146ed 2005-07-12 devnull threadmain(int argc, char *argv[])
195 a0d146ed 2005-07-12 devnull {
196 a0d146ed 2005-07-12 devnull int type, n;
197 a0d146ed 2005-07-12 devnull uchar score[VtScoreSize];
198 a0d146ed 2005-07-12 devnull uchar *buf;
199 a0d146ed 2005-07-12 devnull char *prefix;
200 a0d146ed 2005-07-12 devnull
201 a0d146ed 2005-07-12 devnull fmtinstall('F', vtfcallfmt);
202 a0d146ed 2005-07-12 devnull fmtinstall('V', vtscorefmt);
203 a0d146ed 2005-07-12 devnull
204 a0d146ed 2005-07-12 devnull type = -1;
205 a0d146ed 2005-07-12 devnull ARGBEGIN{
206 da0a205e 2009-08-21 extrudeda case 'V':
207 da0a205e 2009-08-21 extrudeda chattyventi++;
208 da0a205e 2009-08-21 extrudeda break;
209 a0d146ed 2005-07-12 devnull case 'f':
210 a0d146ed 2005-07-12 devnull fast = 1;
211 a0d146ed 2005-07-12 devnull break;
212 a0d146ed 2005-07-12 devnull case 'i':
213 a0d146ed 2005-07-12 devnull if(rewrite)
214 a0d146ed 2005-07-12 devnull usage();
215 a0d146ed 2005-07-12 devnull ignoreerrors = 1;
216 a0d146ed 2005-07-12 devnull break;
217 da0a205e 2009-08-21 extrudeda case 'm':
218 da0a205e 2009-08-21 extrudeda scoretree = mkavltree(scoretreecmp);
219 da0a205e 2009-08-21 extrudeda break;
220 a0d146ed 2005-07-12 devnull case 'r':
221 a0d146ed 2005-07-12 devnull if(ignoreerrors)
222 a0d146ed 2005-07-12 devnull usage();
223 a0d146ed 2005-07-12 devnull rewrite = 1;
224 a0d146ed 2005-07-12 devnull break;
225 a0d146ed 2005-07-12 devnull case 't':
226 a0d146ed 2005-07-12 devnull type = atoi(EARGF(usage()));
227 a0d146ed 2005-07-12 devnull break;
228 da0a205e 2009-08-21 extrudeda case 'v':
229 da0a205e 2009-08-21 extrudeda verbose = 1;
230 da0a205e 2009-08-21 extrudeda break;
231 a0d146ed 2005-07-12 devnull default:
232 a0d146ed 2005-07-12 devnull usage();
233 a0d146ed 2005-07-12 devnull break;
234 a0d146ed 2005-07-12 devnull }ARGEND
235 a0d146ed 2005-07-12 devnull
236 a0d146ed 2005-07-12 devnull if(argc != 3)
237 a0d146ed 2005-07-12 devnull usage();
238 a0d146ed 2005-07-12 devnull
239 a0d146ed 2005-07-12 devnull if(vtparsescore(argv[2], &prefix, score) < 0)
240 a0d146ed 2005-07-12 devnull sysfatal("could not parse score: %r");
241 a0d146ed 2005-07-12 devnull
242 a0d146ed 2005-07-12 devnull buf = vtmallocz(VtMaxLumpSize);
243 a0d146ed 2005-07-12 devnull
244 a0d146ed 2005-07-12 devnull zsrc = vtdial(argv[0]);
245 a0d146ed 2005-07-12 devnull if(zsrc == nil)
246 a0d146ed 2005-07-12 devnull sysfatal("could not dial src server: %r");
247 a0d146ed 2005-07-12 devnull if(vtconnect(zsrc) < 0)
248 a0d146ed 2005-07-12 devnull sysfatal("vtconnect src: %r");
249 a0d146ed 2005-07-12 devnull
250 a0d146ed 2005-07-12 devnull zdst = vtdial(argv[1]);
251 a0d146ed 2005-07-12 devnull if(zdst == nil)
252 a0d146ed 2005-07-12 devnull sysfatal("could not dial dst server: %r");
253 a0d146ed 2005-07-12 devnull if(vtconnect(zdst) < 0)
254 a0d146ed 2005-07-12 devnull sysfatal("vtconnect dst: %r");
255 a0d146ed 2005-07-12 devnull
256 a0d146ed 2005-07-12 devnull if(type != -1){
257 a0d146ed 2005-07-12 devnull n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
258 a0d146ed 2005-07-12 devnull if(n < 0)
259 a0d146ed 2005-07-12 devnull sysfatal("could not read block: %r");
260 a0d146ed 2005-07-12 devnull }else{
261 a0d146ed 2005-07-12 devnull for(type=0; type<VtMaxType; type++){
262 a0d146ed 2005-07-12 devnull n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
263 a0d146ed 2005-07-12 devnull if(n >= 0)
264 a0d146ed 2005-07-12 devnull break;
265 a0d146ed 2005-07-12 devnull }
266 a0d146ed 2005-07-12 devnull if(type == VtMaxType)
267 a0d146ed 2005-07-12 devnull sysfatal("could not find block %V of any type", score);
268 a0d146ed 2005-07-12 devnull }
269 a0d146ed 2005-07-12 devnull
270 da0a205e 2009-08-21 extrudeda walk(score, type, VtDirType, 0);
271 a0d146ed 2005-07-12 devnull if(changes)
272 a0d146ed 2005-07-12 devnull print("%s:%V (%d pointers rewritten)\n", prefix, score, changes);
273 a0d146ed 2005-07-12 devnull
274 da0a205e 2009-08-21 extrudeda if(verbose)
275 da0a205e 2009-08-21 extrudeda print("%d skipped, %d written\n", nskip, nwrite);
276 da0a205e 2009-08-21 extrudeda
277 a0d146ed 2005-07-12 devnull if(vtsync(zdst) < 0)
278 a0d146ed 2005-07-12 devnull sysfatal("could not sync dst server: %r");
279 a0d146ed 2005-07-12 devnull
280 a0d146ed 2005-07-12 devnull threadexitsall(0);
281 a0d146ed 2005-07-12 devnull }