Commit | Line | Data |
---|---|---|
77945073 WD |
1 | Added a pipe from the generator to the receiver that communicates |
2 | what basis file we used to generate the file data (if it was not | |
3 | the default name). This optimizes away the basis-file search in | |
4 | the receiver and makes future options that do more basis-file | |
5 | searching more efficient (such as the --fuzzy option and the | |
6 | support for multiple --compare-dest options). | |
7 | ||
8 | You must run "make proto" before compiling. | |
9 | ||
2aa9af10 WD |
10 | --- orig/generator.c 2004-10-06 00:12:16 |
11 | +++ generator.c 2004-10-09 04:06:49 | |
ccfe7463 | 12 | @@ -254,14 +254,15 @@ static void generate_and_send_sums(int f |
77945073 WD |
13 | * out. It might be wrong. |
14 | */ | |
15 | static void recv_generator(char *fname, struct file_struct *file, int i, | |
16 | - int f_out) | |
d6e18487 | 17 | + int f_out, int f_out_name) |
77945073 | 18 | { |
ccfe7463 | 19 | - int fd, f_copy; |
2aa9af10 | 20 | + int fd = -1, f_copy = -1; |
ccfe7463 | 21 | STRUCT_STAT st, partial_st; |
2aa9af10 WD |
22 | - struct file_struct *back_file; |
23 | + struct file_struct *back_file = NULL; | |
b952a177 | 24 | int statret, stat_errno; |
2aa9af10 WD |
25 | - char *fnamecmp, *partialptr, *backupptr; |
26 | + char *fnamecmp, *partialptr, *backupptr = NULL; | |
ccfe7463 | 27 | char fnamecmpbuf[MAXPATHLEN]; |
65021ef6 WD |
28 | + uchar fnamecmp_type; |
29 | ||
30 | if (list_only) | |
31 | return; | |
2aa9af10 | 32 | @@ -421,6 +422,7 @@ static void recv_generator(char *fname, |
65021ef6 WD |
33 | } |
34 | ||
35 | fnamecmp = fname; | |
36 | + fnamecmp_type = G2R_FNAME; | |
37 | ||
38 | if (statret == -1 && compare_dest != NULL) { | |
39 | /* try the file at compare_dest instead */ | |
2aa9af10 | 40 | @@ -437,10 +439,14 @@ static void recv_generator(char *fname, |
b952a177 WD |
41 | safe_fname(fname)); |
42 | } | |
43 | fnamecmp = fnamecmpbuf; | |
65021ef6 WD |
44 | + fnamecmp_type = 0; |
45 | } | |
b952a177 | 46 | } else |
77945073 | 47 | #endif |
65021ef6 | 48 | + { |
b952a177 | 49 | fnamecmp = fnamecmpbuf; |
65021ef6 WD |
50 | + fnamecmp_type = 0; |
51 | + } | |
b952a177 | 52 | statret = 0; |
65021ef6 WD |
53 | } |
54 | } | |
2aa9af10 | 55 | @@ -463,11 +469,9 @@ static void recv_generator(char *fname, |
77945073 WD |
56 | if (statret == -1) { |
57 | if (preserve_hard_links && hard_link_check(file, HL_SKIP)) | |
58 | return; | |
b952a177 | 59 | - if (stat_errno == ENOENT) { |
0bd6d59f | 60 | - write_int(f_out,i); |
2f5fa77e | 61 | - if (!dry_run && !read_batch) |
0bd6d59f WD |
62 | - write_sum_head(f_out, NULL); |
63 | - } else if (verbose > 1) { | |
b952a177 | 64 | + if (stat_errno == ENOENT) |
d24c084d | 65 | + goto notify_others; |
0bd6d59f | 66 | + if (verbose > 1) { |
b952a177 WD |
67 | rsyserr(FERROR, stat_errno, |
68 | "recv_generator: failed to stat %s", | |
0bd6d59f | 69 | full_fname(fname)); |
2aa9af10 | 70 | @@ -475,13 +479,13 @@ static void recv_generator(char *fname, |
b952a177 | 71 | return; |
77945073 WD |
72 | } |
73 | ||
74 | - if (opt_ignore_existing && fnamecmp == fname) { | |
65021ef6 | 75 | + if (opt_ignore_existing && fnamecmp_type == G2R_FNAME) { |
77945073 | 76 | if (verbose > 1) |
b952a177 | 77 | rprintf(FINFO, "%s exists\n", safe_fname(fname)); |
77945073 WD |
78 | return; |
79 | } | |
80 | ||
81 | - if (update_only && fnamecmp == fname | |
65021ef6 | 82 | + if (update_only && fnamecmp_type == G2R_FNAME |
77945073 WD |
83 | && cmp_modtime(st.st_mtime, file->modtime) > 0) { |
84 | if (verbose > 1) | |
b952a177 | 85 | rprintf(FINFO, "%s is newer\n", safe_fname(fname)); |
2aa9af10 | 86 | @@ -489,26 +493,23 @@ static void recv_generator(char *fname, |
77945073 WD |
87 | } |
88 | ||
ec8473c6 | 89 | if (skip_file(fnamecmp, file, &st)) { |
77945073 | 90 | - if (fnamecmp == fname) |
65021ef6 | 91 | + if (fnamecmp_type == G2R_FNAME) |
77945073 WD |
92 | set_perms(fname, file, &st, PERMS_REPORT); |
93 | return; | |
94 | } | |
95 | ||
ccfe7463 | 96 | prepare_to_open: |
2f5fa77e | 97 | - if (dry_run || read_batch) { |
0bd6d59f WD |
98 | - write_int(f_out,i); |
99 | - return; | |
100 | - } | |
101 | - | |
102 | - if (whole_file > 0) { | |
103 | - write_int(f_out,i); | |
104 | - write_sum_head(f_out, NULL); | |
105 | - return; | |
b857cf41 | 106 | + if (dry_run || whole_file > 0) { |
0bd6d59f | 107 | + statret = -1; |
d24c084d | 108 | + goto notify_others; |
77945073 | 109 | } |
0bd6d59f | 110 | + if (read_batch) |
d24c084d | 111 | + goto notify_others; |
77945073 | 112 | |
ccfe7463 WD |
113 | if (partialptr) { |
114 | st = partial_st; | |
115 | fnamecmp = partialptr; | |
116 | + fnamecmp_type = G2R_PARTIAL_DIR; | |
65021ef6 WD |
117 | } |
118 | ||
ccfe7463 | 119 | /* open the file */ |
2aa9af10 | 120 | @@ -521,9 +522,8 @@ prepare_to_open: |
77945073 WD |
121 | /* pretend the file didn't exist */ |
122 | if (preserve_hard_links && hard_link_check(file, HL_SKIP)) | |
123 | return; | |
0bd6d59f WD |
124 | - write_int(f_out,i); |
125 | - write_sum_head(f_out, NULL); | |
126 | - return; | |
127 | + statret = -1; | |
d24c084d | 128 | + goto notify_others; |
0bd6d59f WD |
129 | } |
130 | ||
ccfe7463 | 131 | if (inplace && make_backups) { |
2aa9af10 | 132 | @@ -550,10 +550,7 @@ prepare_to_open: |
ccfe7463 WD |
133 | close(fd); |
134 | return; | |
135 | } | |
2aa9af10 WD |
136 | - } else { |
137 | - backupptr = NULL; | |
138 | - back_file = NULL; | |
139 | - f_copy = -1; | |
ccfe7463 | 140 | + fnamecmp_type = G2R_BACKUP; |
2aa9af10 WD |
141 | } |
142 | ||
143 | if (verbose > 3) { | |
144 | @@ -564,22 +561,38 @@ prepare_to_open: | |
77945073 WD |
145 | if (verbose > 2) |
146 | rprintf(FINFO, "generating and sending sums for %d\n", i); | |
147 | ||
0bd6d59f | 148 | - write_int(f_out,i); |
ccfe7463 WD |
149 | - generate_and_send_sums(fd, st.st_size, f_out, f_copy); |
150 | - | |
151 | - if (f_copy >= 0) { | |
152 | - close(f_copy); | |
153 | - set_perms(backupptr, back_file, NULL, 0); | |
a6587818 WD |
154 | - if (verbose > 1) |
155 | - rprintf(FINFO, "backed up %s to %s\n", fname, backupptr); | |
ccfe7463 | 156 | - free(back_file); |
d24c084d | 157 | +notify_others: |
d6e18487 | 158 | + if (f_out_name >= 0) { |
65021ef6 | 159 | + write_byte(f_out_name, fnamecmp_type); |
d6e18487 | 160 | + io_flush(NORMAL_FLUSH); /* XXX make this more efficient! */ |
ccfe7463 | 161 | } |
2f5fa77e WD |
162 | |
163 | - close(fd); | |
ccfe7463 WD |
164 | + write_int(f_out, i); |
165 | + | |
65021ef6 WD |
166 | + if (dry_run || read_batch) |
167 | + return; | |
168 | + | |
0bd6d59f | 169 | + if (statret == 0) { |
ccfe7463 | 170 | + generate_and_send_sums(fd, st.st_size, f_out, f_copy); |
ccfe7463 WD |
171 | + |
172 | + if (f_copy >= 0) { | |
173 | + close(f_copy); | |
174 | + set_perms(backupptr, back_file, NULL, 0); | |
a6587818 WD |
175 | + if (verbose > 1) { |
176 | + rprintf(FINFO, "backed up %s to %s\n", | |
177 | + fname, backupptr); | |
178 | + } | |
ccfe7463 WD |
179 | + free(back_file); |
180 | + } | |
a6587818 WD |
181 | + |
182 | + close(fd); | |
d6e18487 | 183 | + } else |
0bd6d59f | 184 | + write_sum_head(f_out, NULL); |
77945073 WD |
185 | } |
186 | ||
187 | ||
9be39c35 WD |
188 | -void generate_files(int f_out, struct file_list *flist, char *local_name) |
189 | +void generate_files(int f_out, struct file_list *flist, char *local_name, | |
d6e18487 | 190 | + int f_out_name) |
77945073 WD |
191 | { |
192 | int i; | |
8cec1ead | 193 | int phase = 0; |
2aa9af10 | 194 | @@ -620,7 +633,7 @@ void generate_files(int f_out, struct fi |
77945073 WD |
195 | } |
196 | ||
197 | recv_generator(local_name ? local_name : f_name_to(file, fbuf), | |
9be39c35 | 198 | - file, i, f_out); |
d6e18487 | 199 | + file, i, f_out, f_out_name); |
77945073 WD |
200 | } |
201 | ||
202 | phase++; | |
2aa9af10 | 203 | @@ -637,7 +650,7 @@ void generate_files(int f_out, struct fi |
77945073 WD |
204 | while ((i = get_redo_num()) != -1) { |
205 | struct file_struct *file = flist->files[i]; | |
206 | recv_generator(local_name ? local_name : f_name_to(file, fbuf), | |
9be39c35 | 207 | - file, i, f_out); |
d6e18487 | 208 | + file, i, f_out, f_out_name); |
77945073 WD |
209 | } |
210 | ||
211 | phase++; | |
2aa9af10 | 212 | @@ -656,7 +669,7 @@ void generate_files(int f_out, struct fi |
77945073 WD |
213 | if (!file->basename || !S_ISDIR(file->mode)) |
214 | continue; | |
215 | recv_generator(local_name ? local_name : f_name(file), | |
216 | - file, i, -1); | |
217 | + file, i, -1, -1); | |
218 | } | |
219 | ||
220 | if (verbose > 2) | |
2aa9af10 WD |
221 | --- orig/main.c 2004-10-08 20:16:26 |
222 | +++ main.c 2004-10-09 03:25:43 | |
d5753a22 | 223 | @@ -59,6 +59,7 @@ extern int filesfrom_fd; |
0bd6d59f WD |
224 | extern pid_t cleanup_child_pid; |
225 | extern char *files_from; | |
226 | extern char *remote_filesfrom_file; | |
227 | +extern char *compare_dest; | |
228 | extern char *rsync_path; | |
229 | extern char *shell_cmd; | |
230 | extern char *batch_name; | |
f635ed27 | 231 | @@ -461,7 +462,8 @@ static int do_recv(int f_in,int f_out,st |
77945073 WD |
232 | { |
233 | int pid; | |
8cec1ead | 234 | int status = 0; |
77945073 | 235 | - int error_pipe[2]; |
77945073 | 236 | + int error_pipe[2], name_pipe[2]; |
d6e18487 | 237 | + BOOL need_name_pipe = compare_dest && !dry_run; |
77945073 | 238 | |
d5753a22 WD |
239 | /* The receiving side mustn't obey this, or an existing symlink that |
240 | * points to an identical file won't be replaced by the referent. */ | |
2aa9af10 | 241 | @@ -476,7 +478,8 @@ static int do_recv(int f_in,int f_out,st |
d24c084d | 242 | delete_files(flist); |
77945073 WD |
243 | } |
244 | ||
245 | - if (fd_pair(error_pipe) < 0) { | |
0bd6d59f WD |
246 | + if (fd_pair(error_pipe) < 0 |
247 | + || (need_name_pipe && fd_pair(name_pipe) < 0)) { | |
2aa9af10 | 248 | rsyserr(FERROR, errno, "pipe failed in do_recv"); |
77945073 WD |
249 | exit_cleanup(RERR_SOCKETIO); |
250 | } | |
f635ed27 | 251 | @@ -485,6 +488,11 @@ static int do_recv(int f_in,int f_out,st |
77945073 | 252 | |
8cec1ead | 253 | if ((pid = do_fork()) == 0) { |
77945073 | 254 | close(error_pipe[0]); |
0bd6d59f WD |
255 | + if (need_name_pipe) { |
256 | + close(name_pipe[1]); | |
257 | + set_blocking(name_pipe[0]); | |
258 | + } else | |
259 | + name_pipe[0] = -1; | |
77945073 WD |
260 | if (f_in != f_out) |
261 | close(f_out); | |
77945073 | 262 | |
f635ed27 | 263 | @@ -494,7 +502,7 @@ static int do_recv(int f_in,int f_out,st |
77945073 WD |
264 | /* set place to send errors */ |
265 | set_msg_fd_out(error_pipe[1]); | |
266 | ||
267 | - recv_files(f_in,flist,local_name); | |
268 | + recv_files(f_in, flist, local_name, name_pipe[0]); | |
269 | io_flush(FULL_FLUSH); | |
270 | report(f_in); | |
271 | ||
f635ed27 | 272 | @@ -513,6 +521,11 @@ static int do_recv(int f_in,int f_out,st |
9be39c35 | 273 | stop_write_batch(); |
77945073 WD |
274 | |
275 | close(error_pipe[1]); | |
0bd6d59f WD |
276 | + if (need_name_pipe) { |
277 | + close(name_pipe[0]); | |
278 | + set_nonblocking(name_pipe[1]); | |
279 | + } else | |
280 | + name_pipe[1] = -1; | |
77945073 WD |
281 | if (f_in != f_out) |
282 | close(f_in); | |
77945073 | 283 | |
f635ed27 | 284 | @@ -520,7 +533,7 @@ static int do_recv(int f_in,int f_out,st |
77945073 WD |
285 | |
286 | set_msg_fd_in(error_pipe[0]); | |
287 | ||
288 | - generate_files(f_out, flist, local_name); | |
289 | + generate_files(f_out, flist, local_name, name_pipe[1]); | |
290 | ||
291 | get_redo_num(); /* Read final MSG_DONE and any prior messages. */ | |
292 | report(-1); | |
a6587818 | 293 | --- orig/receiver.c 2004-09-21 09:40:27 |
ccfe7463 | 294 | +++ receiver.c 2004-09-07 21:57:20 |
a6587818 | 295 | @@ -329,7 +329,8 @@ static void discard_receive_data(int f_i |
77945073 WD |
296 | * main routine for receiver process. |
297 | * | |
298 | * Receiver process runs on the same host as the generator process. */ | |
9be39c35 | 299 | -int recv_files(int f_in, struct file_list *flist, char *local_name) |
77945073 | 300 | +int recv_files(int f_in, struct file_list *flist, char *local_name, |
d6e18487 | 301 | + int f_in_name) |
77945073 | 302 | { |
2f5fa77e | 303 | int next_gen_i = -1; |
77945073 | 304 | int fd1,fd2; |
a6587818 | 305 | @@ -358,8 +359,13 @@ int recv_files(int f_in, struct file_lis |
0bd6d59f WD |
306 | i = read_int(f_in); |
307 | if (i == -1) { | |
2f5fa77e WD |
308 | if (read_batch) { |
309 | - if (next_gen_i != flist->count) | |
310 | - while (read_int(batch_gen_fd) != -1) {} | |
65021ef6 WD |
311 | + if (next_gen_i != flist->count) { |
312 | + do { | |
313 | + if (f_in_name >= 0 | |
314 | + && next_gen_i >= 0) | |
315 | + read_byte(f_in_name); | |
316 | + } while (read_int(batch_gen_fd) != -1); | |
0bd6d59f | 317 | + } |
2f5fa77e WD |
318 | next_gen_i = -1; |
319 | } | |
5823d322 | 320 | |
a6587818 | 321 | @@ -407,6 +413,8 @@ int recv_files(int f_in, struct file_lis |
77945073 | 322 | |
2f5fa77e WD |
323 | if (read_batch) { |
324 | while (i > next_gen_i) { | |
65021ef6 WD |
325 | + if (f_in_name >= 0 && next_gen_i >= 0) |
326 | + read_byte(f_in_name); | |
2f5fa77e WD |
327 | next_gen_i = read_int(batch_gen_fd); |
328 | if (next_gen_i == -1) | |
329 | next_gen_i = flist->count; | |
a6587818 | 330 | @@ -417,6 +425,7 @@ int recv_files(int f_in, struct file_lis |
2f5fa77e WD |
331 | discard_receive_data(f_in, file->length); |
332 | continue; | |
333 | } | |
0bd6d59f | 334 | + next_gen_i = -1; |
2f5fa77e WD |
335 | } |
336 | ||
5823d322 | 337 | if (server_exclude_list.head |
a6587818 | 338 | @@ -426,35 +435,31 @@ int recv_files(int f_in, struct file_lis |
65021ef6 | 339 | exit_cleanup(RERR_PROTOCOL); |
b952a177 WD |
340 | } |
341 | ||
342 | - if (partial_dir) { | |
343 | - if ((partialptr = partial_dir_fname(fname)) != NULL) | |
344 | - fnamecmp = partialptr; | |
345 | - else | |
b952a177 | 346 | + partialptr = partial_dir ? partial_dir_fname(fname) : fname; |
65021ef6 WD |
347 | + |
348 | + if (f_in_name >= 0) { | |
349 | + switch (read_byte(f_in_name)) { | |
350 | + case G2R_FNAME: | |
351 | fnamecmp = fname; | |
352 | + break; | |
353 | + case G2R_PARTIAL_DIR: | |
354 | + fnamecmp = partialptr ? partialptr : fname; | |
355 | + break; | |
ccfe7463 WD |
356 | + case G2R_BACKUP: |
357 | + fnamecmp = get_backup_name(fname); | |
358 | + break; | |
65021ef6 WD |
359 | + default: |
360 | + pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, | |
361 | + compare_dest, fname); | |
362 | + fnamecmp = fnamecmpbuf; | |
363 | + break; | |
364 | + } | |
365 | } else | |
366 | - fnamecmp = partialptr = fname; | |
ccfe7463 WD |
367 | - |
368 | - if (inplace && make_backups) { | |
369 | - if (!(fnamecmp = get_backup_name(fname))) | |
370 | - fnamecmp = partialptr; | |
371 | - } | |
65021ef6 | 372 | + fnamecmp = fname; |
b952a177 | 373 | |
77945073 WD |
374 | /* open the file */ |
375 | fd1 = do_open(fnamecmp, O_RDONLY, 0); | |
376 | ||
65021ef6 WD |
377 | - if (fd1 == -1 && fnamecmp != fname) { |
378 | - fnamecmp = fname; | |
379 | - fd1 = do_open(fnamecmp, O_RDONLY, 0); | |
380 | - } | |
381 | - | |
77945073 WD |
382 | - if (fd1 == -1 && compare_dest != NULL) { |
383 | - /* try the file at compare_dest instead */ | |
384 | - pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, | |
385 | - compare_dest, fname); | |
386 | - fnamecmp = fnamecmpbuf; | |
387 | - fd1 = do_open(fnamecmp, O_RDONLY, 0); | |
388 | - } | |
389 | - | |
390 | if (fd1 != -1 && do_fstat(fd1,&st) != 0) { | |
391 | rsyserr(FERROR, errno, "fstat %s failed", | |
392 | full_fname(fnamecmp)); | |
2aa9af10 | 393 | --- orig/rsync.h 2004-10-09 03:21:56 |
ccfe7463 | 394 | +++ rsync.h 2004-09-07 21:52:22 |
b857cf41 | 395 | @@ -119,6 +119,10 @@ |
65021ef6 WD |
396 | #define PDIR_CREATE 1 |
397 | #define PDIR_DELETE 0 | |
398 | ||
399 | +#define G2R_FNAME 0x80 | |
400 | +#define G2R_PARTIAL_DIR 0x81 | |
ccfe7463 | 401 | +#define G2R_BACKUP 0x82 |
65021ef6 WD |
402 | + |
403 | ||
404 | /* Log-message categories. FLOG is only used on the daemon side to | |
405 | * output messages to the log file. */ |