Line data Source code
1 : #include "../../burp.h"
2 : #include "../../alloc.h"
3 : #include "../../asfd.h"
4 : #include "../../async.h"
5 : #include "../../cmd.h"
6 : #include "../../cntr.h"
7 : #include "../../conf.h"
8 : #include "../../fsops.h"
9 : #include "../../fzp.h"
10 : #include "../../handy.h"
11 : #include "../../log.h"
12 : #include "../../prepend.h"
13 : #include "../../sbuf.h"
14 : #include "../../strlist.h"
15 : #include "../child.h"
16 : #include "../compress.h"
17 : #include "../timestamp.h"
18 : #include "blocklen.h"
19 : #include "deleteme.h"
20 : #include "fdirs.h"
21 : #include "link.h"
22 : #include "zlibio.h"
23 :
24 : #include <librsync.h>
25 :
26 : // Also used by restore.c.
27 : // FIX THIS: This stuff is very similar to make_rev_delta, can maybe share
28 : // some code.
29 0 : int do_patch(struct asfd *asfd, const char *dst, const char *del,
30 : const char *upd, bool gzupd, int compression)
31 : {
32 0 : struct fzp *dstp=NULL;
33 0 : struct fzp *delfzp=NULL;
34 0 : struct fzp *upfzp=NULL;
35 0 : rs_result result=RS_IO_ERROR;
36 :
37 0 : if(!(dstp=fzp_open(dst, "rb"))) goto end;
38 :
39 0 : if(!(delfzp=fzp_gzopen(del, "rb")))
40 : goto end;
41 :
42 0 : if(gzupd)
43 0 : upfzp=fzp_gzopen(upd, comp_level(compression));
44 : else
45 0 : upfzp=fzp_open(upd, "wb");
46 :
47 0 : if(!upfzp) goto end;
48 :
49 0 : result=rs_patch_gzfile(dstp, delfzp, upfzp);
50 : end:
51 0 : fzp_close(&dstp);
52 0 : fzp_close(&delfzp);
53 0 : if(fzp_close(&upfzp))
54 : {
55 0 : logp("error closing %s in %s\n", upd, __func__);
56 0 : result=RS_IO_ERROR;
57 : }
58 0 : return result;
59 : }
60 :
61 : // Help librsync-1.0.0
62 : #ifndef RS_DEFAULT_STRONG_LEN
63 : #define RS_DEFAULT_STRONG_LEN 8
64 : #endif
65 :
66 0 : static int make_rev_sig(const char *dst, const char *sig, const char *endfile,
67 : int compression, struct conf **confs)
68 : {
69 0 : int ret=-1;
70 0 : struct fzp *dstfzp=NULL;
71 0 : struct fzp *sigp=NULL;
72 : //logp("make rev sig: %s %s\n", dst, sig);
73 :
74 0 : if(dpth_protocol1_is_compressed(compression, dst))
75 0 : dstfzp=fzp_gzopen(dst, "rb");
76 : else
77 0 : dstfzp=fzp_open(dst, "rb");
78 :
79 0 : if(!dstfzp
80 0 : || !(sigp=fzp_open(sig, "wb"))
81 0 : || rs_sig_gzfile(dstfzp, sigp,
82 : get_librsync_block_len(endfile),
83 0 : RS_DEFAULT_STRONG_LEN, confs)!=RS_DONE)
84 : goto end;
85 0 : ret=0;
86 : end:
87 : //logp("end of make rev sig\n");
88 0 : fzp_close(&dstfzp);
89 0 : if(fzp_close(&sigp))
90 : {
91 0 : logp("error closing %s in %s\n", sig, __func__);
92 0 : return -1;
93 : }
94 : return ret;
95 : }
96 :
97 0 : static int make_rev_delta(const char *src, const char *sig, const char *del,
98 : int compression, struct conf **cconfs)
99 : {
100 0 : int ret=-1;
101 0 : struct fzp *srcfzp=NULL;
102 0 : struct fzp *delfzp=NULL;
103 0 : struct fzp *sigp=NULL;
104 0 : rs_signature_t *sumset=NULL;
105 :
106 : //logp("make rev delta: %s %s %s\n", src, sig, del);
107 0 : if(!(sigp=fzp_open(sig, "rb"))) goto end;
108 :
109 0 : if(rs_loadsig_fzp(sigp, &sumset, NULL)!=RS_DONE
110 0 : || rs_build_hash_table(sumset)!=RS_DONE)
111 : goto end;
112 :
113 : //logp("make rev deltb: %s %s %s\n", src, sig, del);
114 :
115 0 : if(dpth_protocol1_is_compressed(compression, src))
116 0 : srcfzp=fzp_gzopen(src, "rb");
117 : else
118 0 : srcfzp=fzp_open(src, "rb");
119 :
120 0 : if(!srcfzp) goto end;
121 :
122 0 : if(get_int(cconfs[OPT_COMPRESSION]))
123 : delfzp=fzp_gzopen(del,
124 0 : comp_level(get_int(cconfs[OPT_COMPRESSION])));
125 : else
126 0 : delfzp=fzp_open(del, "wb");
127 0 : if(!delfzp) goto end;
128 :
129 0 : if(rs_delta_gzfile(sumset, srcfzp, delfzp)!=RS_DONE)
130 : goto end;
131 0 : ret=0;
132 : end:
133 0 : if(sumset) rs_free_sumset(sumset);
134 0 : fzp_close(&srcfzp);
135 0 : fzp_close(&sigp);
136 0 : if(fzp_close(&delfzp))
137 : {
138 0 : logp("error closing delfzp %s in %s\n", del, __func__);
139 0 : ret=-1;
140 : }
141 0 : return ret;
142 : }
143 :
144 0 : static int gen_rev_delta(const char *sigpath, const char *deltadir,
145 : const char *oldpath, const char *finpath, const char *path,
146 : struct sbuf *sb, struct conf **cconfs)
147 : {
148 0 : int ret=-1;
149 0 : char *delpath=NULL;
150 0 : if(!(delpath=prepend_s(deltadir, path)))
151 : {
152 0 : log_out_of_memory(__func__);
153 : goto end;
154 : }
155 : //logp("Generating reverse delta...\n");
156 : /*
157 : logp("delpath: %s\n", delpath);
158 : logp("finpath: %s\n", finpath);
159 : logp("sigpath: %s\n", sigpath);
160 : logp("oldpath: %s\n", oldpath);
161 : */
162 0 : if(mkpath(&delpath, deltadir))
163 : {
164 0 : logp("could not mkpaths for: %s\n", delpath);
165 : goto end;
166 : }
167 0 : else if(make_rev_sig(finpath, sigpath,
168 0 : sb->endfile.buf, sb->compression, cconfs))
169 : {
170 0 : logp("could not make signature from: %s\n", finpath);
171 : goto end;
172 : }
173 0 : else if(make_rev_delta(oldpath, sigpath,
174 0 : delpath, sb->compression, cconfs))
175 : {
176 0 : logp("could not make delta from: %s\n", oldpath);
177 : goto end;
178 : }
179 0 : else unlink(sigpath);
180 :
181 0 : ret=0;
182 : end:
183 0 : free_w(&delpath);
184 0 : return ret;
185 : }
186 :
187 0 : static int inflate_oldfile(const char *opath, const char *infpath,
188 : struct stat *statp, struct cntr *cntr)
189 : {
190 0 : int ret=0;
191 :
192 0 : if(!statp->st_size)
193 : {
194 0 : struct fzp *dest=NULL;
195 : // Empty file - cannot inflate.
196 : // just close the destination and we have duplicated a
197 : // zero length file.
198 0 : if(!(dest=fzp_open(infpath, "wb"))) goto end;
199 0 : logp("asked to inflate zero length file: %s\n", opath);
200 0 : if(fzp_close(&dest))
201 0 : logp("error closing %s in %s\n", infpath, __func__);
202 : }
203 0 : else if(zlib_inflate(NULL, opath, infpath, cntr))
204 : {
205 0 : logp("zlib_inflate returned error\n");
206 0 : ret=-1;
207 : }
208 : end:
209 0 : return ret;
210 : }
211 :
212 0 : static int inflate_or_link_oldfile(const char *oldpath, const char *infpath,
213 : int compression, struct conf **cconfs)
214 : {
215 : struct stat statp;
216 :
217 0 : if(lstat(oldpath, &statp))
218 : {
219 0 : logp("could not lstat %s\n", oldpath);
220 0 : return -1;
221 : }
222 :
223 0 : if(dpth_protocol1_is_compressed(compression, oldpath))
224 : return inflate_oldfile(oldpath, infpath, &statp,
225 0 : get_cntr(cconfs));
226 :
227 : // If it was not a compressed file, just hard link it.
228 : // It is possible that infpath already exists, if the server
229 : // was interrupted on a previous run just after this point.
230 : return do_link(oldpath, infpath, &statp, cconfs,
231 0 : 1 /* allow overwrite of infpath */);
232 : }
233 :
234 0 : static int forward_patch_and_reverse_diff(
235 : struct fdirs *fdirs,
236 : struct fzp **delfp,
237 : const char *deltabdir,
238 : const char *deltafdir,
239 : const char *deltafpath,
240 : const char *sigpath,
241 : const char *oldpath,
242 : const char *newpath,
243 : const char *datapth,
244 : const char *finpath,
245 : int hardlinked_current,
246 : struct sbuf *sb,
247 : struct conf **cconfs
248 : )
249 : {
250 : int lrs;
251 0 : int ret=-1;
252 0 : char *infpath=NULL;
253 :
254 : // Got a forward patch to do.
255 : // First, need to gunzip the old file, otherwise the librsync patch
256 : // will take forever, because it will be doing seeks all over the
257 : // place, and gzseeks are slow.
258 0 : if(!(infpath=prepend_s(deltafdir, "inflate")))
259 : {
260 0 : log_out_of_memory(__func__);
261 : goto end;
262 : }
263 :
264 : //logp("Fixing up: %s\n", datapth);
265 0 : if(inflate_or_link_oldfile(oldpath, infpath, sb->compression, cconfs))
266 : {
267 0 : logp("error when inflating old file: %s\n", oldpath);
268 : goto end;
269 : }
270 :
271 0 : if((lrs=do_patch(NULL, infpath, deltafpath, newpath,
272 0 : sb->compression, sb->compression /* from manifest */)))
273 : {
274 : logp("WARNING: librsync error when patching %s: %d\n",
275 0 : oldpath, lrs);
276 0 : cntr_add(get_cntr(cconfs), CMD_WARNING, 1);
277 : // Try to carry on with the rest of the backup regardless.
278 : // Remove anything that got written.
279 0 : unlink(newpath);
280 :
281 : // First, note that we want to remove this entry from
282 : // the manifest.
283 0 : if(!*delfp
284 0 : && !(*delfp=fzp_open(fdirs->deletionsfile, "ab")))
285 : {
286 : // Could not mark this file as deleted. Fatal.
287 : goto end;
288 : }
289 0 : if(sbuf_to_manifest(sb, *delfp))
290 : goto end;
291 0 : if(fzp_flush(*delfp))
292 : {
293 : logp("error fflushing deletions file in %s: %s\n",
294 0 : __func__, strerror(errno));
295 : goto end;
296 : }
297 : ret=0;
298 : goto end;
299 : }
300 :
301 : // Need to generate a reverse diff, unless we are keeping a hardlinked
302 : // archive.
303 0 : if(!hardlinked_current)
304 : {
305 0 : if(gen_rev_delta(sigpath, deltabdir,
306 0 : oldpath, newpath, datapth, sb, cconfs))
307 : goto end;
308 : }
309 :
310 : // Power interruptions should be recoverable. If it happens before this
311 : // point, the data jiggle for this file has to be done again.
312 : // Once finpath is in place, no more jiggle is required.
313 :
314 : // Use the fresh new file.
315 : // Rename race condition is of no consequence, because finpath will
316 : // just get recreated automatically.
317 0 : if(do_rename(newpath, finpath))
318 : goto end;
319 :
320 : // Remove the forward delta, as it is no longer needed. There is a
321 : // reverse diff and the finished finished file is in place.
322 : //logp("Deleting delta.forward...\n");
323 0 : unlink(deltafpath);
324 :
325 : // Remove the old file. If a power cut happens just before this, the
326 : // old file will hang around forever.
327 : // FIX THIS: maybe put in something to detect this.
328 : // ie, both a reverse delta and the old file exist.
329 0 : if(!hardlinked_current)
330 : {
331 : //logp("Deleting oldpath...\n");
332 0 : unlink(oldpath);
333 : }
334 :
335 : ret=0;
336 : end:
337 0 : if(infpath)
338 : {
339 0 : unlink(infpath);
340 0 : free_w(&infpath);
341 : }
342 0 : return ret;
343 : }
344 :
345 91 : static int jiggle(struct sdirs *sdirs, struct fdirs *fdirs, struct sbuf *sb,
346 : int hardlinked_current, const char *deltabdir, const char *deltafdir,
347 : const char *sigpath, struct fzp **delfp, struct conf **cconfs)
348 : {
349 91 : int ret=-1;
350 : struct stat statp;
351 91 : char *oldpath=NULL;
352 91 : char *newpath=NULL;
353 91 : char *finpath=NULL;
354 91 : char *deltafpath=NULL;
355 91 : const char *datapth=sb->protocol1->datapth.buf;
356 :
357 : // If the previous backup was a hardlinked_archive, there will not be
358 : // a currentdup directory - just directly use the file in the previous
359 : // backup.
360 91 : if(!(oldpath=prepend_s(hardlinked_current?
361 91 : sdirs->currentdata:fdirs->currentdupdata, datapth))
362 91 : || !(newpath=prepend_s(fdirs->datadirtmp, datapth))
363 91 : || !(finpath=prepend_s(fdirs->datadir, datapth))
364 182 : || !(deltafpath=prepend_s(deltafdir, datapth)))
365 : goto end;
366 :
367 182 : if(!lstat(finpath, &statp) && S_ISREG(statp.st_mode))
368 : {
369 : // Looks like an interrupted jiggle did this file already.
370 : static int donemsg=0;
371 6 : if(!unlink(deltafpath))
372 : logp("deleted unneeded forward delta: %s\n",
373 0 : deltafpath);
374 6 : if(!donemsg)
375 : {
376 1 : logp("skipping already present file: %s\n", finpath);
377 1 : logp("to save log space, skips of other already present files will not be logged\n");
378 1 : donemsg++;
379 : }
380 : ret=0;
381 : goto end;
382 : }
383 :
384 85 : if(mkpath(&finpath, fdirs->datadir))
385 : {
386 0 : logp("could not create path for: %s\n", finpath);
387 : goto end;
388 : }
389 :
390 170 : if(!lstat(deltafpath, &statp) && S_ISREG(statp.st_mode))
391 : {
392 0 : if(mkpath(&newpath, fdirs->datadirtmp))
393 : {
394 0 : logp("could not create path for: %s\n", newpath);
395 : goto end;
396 : }
397 : ret=forward_patch_and_reverse_diff(
398 : fdirs,
399 : delfp,
400 : deltabdir,
401 : deltafdir,
402 : deltafpath,
403 : sigpath,
404 : oldpath,
405 : newpath,
406 : datapth,
407 : finpath,
408 : hardlinked_current,
409 : sb,
410 : cconfs
411 0 : );
412 : goto end;
413 : }
414 :
415 170 : if(!lstat(newpath, &statp) && S_ISREG(statp.st_mode))
416 : {
417 : // Use the fresh new file.
418 : // This needs to happen after checking
419 : // for the forward delta, because the
420 : // patching stuff writes to newpath.
421 :
422 : // Rename race condition is of no consequence, because finpath
423 : // will just get recreated automatically.
424 :
425 : //logp("Using newly received file\n");
426 85 : ret=do_rename(newpath, finpath);
427 : goto end;
428 : }
429 :
430 0 : if(!lstat(oldpath, &statp) && S_ISREG(statp.st_mode))
431 : {
432 : // Use the old unchanged file.
433 : // Hard link it first.
434 : //logp("Hard linking to old file: %s\n", datapth);
435 0 : if(do_link(oldpath, finpath, &statp, cconfs,
436 0 : 0 /* do not overwrite finpath (should never need to) */))
437 : goto end;
438 : else
439 : {
440 : // If we are not keeping a hardlinked
441 : // archive, delete the old link.
442 0 : if(!hardlinked_current)
443 : {
444 : //logp("Unlinking old file: %s\n", oldpath);
445 0 : unlink(oldpath);
446 : }
447 : }
448 : ret=0;
449 : goto end;
450 : }
451 :
452 0 : logp("could not find: %s\n", oldpath);
453 : end:
454 91 : free_w(&oldpath);
455 91 : free_w(&newpath);
456 91 : free_w(&finpath);
457 91 : free_w(&deltafpath);
458 91 : return ret;
459 : }
460 :
461 : /* If OPT_HARDLINKED_ARCHIVE set, hardlink everything.
462 : If unset and there is more than one 'keep' value, periodically hardlink,
463 : based on the first 'keep' value. This is so that we have more choice
464 : of backups to delete than just the oldest.
465 : */
466 2 : static int need_hardlinked_archive(struct conf **cconfs, uint64_t bno)
467 : {
468 2 : int kp=0;
469 2 : int ret=0;
470 2 : struct strlist *keep=get_strlist(cconfs[OPT_KEEP]);
471 2 : if(get_int(cconfs[OPT_HARDLINKED_ARCHIVE]))
472 : {
473 0 : logp("New backup is a hardlinked_archive\n");
474 0 : return 1;
475 : }
476 2 : if(!keep || !keep->next)
477 : {
478 2 : logp("New backup is not a hardlinked_archive\n");
479 2 : return 0;
480 : }
481 :
482 : // If they have specified more than one 'keep' value, need to
483 : // periodically hardlink, based on the first 'keep' value.
484 0 : kp=keep->flag;
485 :
486 : logp("First keep value: %d, backup: %" PRIu64 " (%" PRIu64 "-1=%" PRIu64 ")\n",
487 0 : kp, bno, bno, bno-1);
488 :
489 0 : ret=(bno-1)%kp;
490 : logp("New backup is %sa hardlinked_archive (%" PRIu64 "%%%d=%d)\n",
491 0 : ret?"not ":"", bno-1, kp, ret);
492 :
493 0 : return !ret;
494 : }
495 :
496 2 : static int maybe_delete_files_from_manifest(const char *manifesttmp,
497 : struct fdirs *fdirs, struct conf **cconfs)
498 : {
499 2 : int ars=0;
500 2 : int ret=-1;
501 2 : int pcmp=0;
502 2 : struct fzp *dfp=NULL;
503 2 : struct fzp *nmzp=NULL;
504 2 : struct fzp *omzp=NULL;
505 2 : struct sbuf *db=NULL;
506 2 : struct sbuf *mb=NULL;
507 : struct stat statp;
508 :
509 4 : if(lstat(fdirs->deletionsfile, &statp)) // No deletions, no problem.
510 : return 0;
511 0 : logp("Performing deletions on manifest\n");
512 :
513 0 : if(!(manifesttmp=get_tmp_filename(fdirs->manifest)))
514 : goto end;
515 :
516 0 : if(!(dfp=fzp_open(fdirs->deletionsfile, "rb"))
517 0 : || !(omzp=fzp_gzopen(fdirs->manifest, "rb"))
518 0 : || !(nmzp=fzp_gzopen(manifesttmp,
519 0 : comp_level(get_int(cconfs[OPT_COMPRESSION]))))
520 0 : || !(db=sbuf_alloc(PROTO_1))
521 0 : || !(mb=sbuf_alloc(PROTO_1)))
522 : goto end;
523 :
524 0 : while(omzp || dfp)
525 : {
526 0 : if(dfp && !db->path.buf
527 0 : && (ars=sbuf_fill_from_file(db, dfp, NULL, NULL)))
528 : {
529 0 : if(ars<0) goto end;
530 : // ars==1 means it ended ok.
531 0 : fzp_close(&dfp);
532 : }
533 0 : if(omzp && !mb->path.buf
534 0 : && (ars=sbuf_fill_from_file(mb, omzp, NULL, NULL)))
535 : {
536 0 : if(ars<0) goto end;
537 : // ars==1 means it ended ok.
538 0 : fzp_close(&omzp);
539 : }
540 :
541 0 : if(mb->path.buf && !db->path.buf)
542 : {
543 0 : if(sbuf_to_manifest(mb, nmzp)) goto end;
544 0 : sbuf_free_content(mb);
545 : }
546 0 : else if(!mb->path.buf && db->path.buf)
547 : {
548 0 : sbuf_free_content(db);
549 : }
550 0 : else if(!mb->path.buf && !db->path.buf)
551 : {
552 : continue;
553 : }
554 0 : else if(!(pcmp=sbuf_pathcmp(mb, db)))
555 : {
556 : // They were the same - do not write.
557 0 : sbuf_free_content(mb);
558 0 : sbuf_free_content(db);
559 : }
560 0 : else if(pcmp<0)
561 : {
562 : // Behind in manifest. Write.
563 0 : if(sbuf_to_manifest(mb, nmzp)) goto end;
564 0 : sbuf_free_content(mb);
565 : }
566 : else
567 : {
568 : // Behind in deletions file. Do not write.
569 0 : sbuf_free_content(db);
570 : }
571 : }
572 :
573 : ret=0;
574 : end:
575 0 : if(fzp_close(&nmzp))
576 : {
577 0 : logp("error closing %s in %s\n", manifesttmp, __func__);
578 0 : ret=-1;
579 : }
580 :
581 0 : fzp_close(&dfp);
582 0 : fzp_close(&omzp);
583 0 : sbuf_free(&db);
584 0 : sbuf_free(&mb);
585 0 : if(!ret)
586 : {
587 0 : unlink(fdirs->deletionsfile);
588 : // The rename race condition is not a problem here, as long
589 : // as manifesttmp is the same path as that generated in the
590 : // atomic data jiggle.
591 0 : if(do_rename(manifesttmp, fdirs->manifest))
592 : return -1;
593 : }
594 0 : if(manifesttmp) unlink(manifesttmp);
595 : return ret;
596 : }
597 :
598 : /* Need to make all the stuff that this does atomic so that existing backups
599 : never get broken, even if somebody turns the power off on the server. */
600 2 : static int atomic_data_jiggle(struct sdirs *sdirs, struct fdirs *fdirs,
601 : int hardlinked_current, struct conf **cconfs)
602 : {
603 2 : int ret=-1;
604 2 : char *datapth=NULL;
605 2 : char *tmpman=NULL;
606 : struct stat statp;
607 :
608 2 : char *deltabdir=NULL;
609 2 : char *deltafdir=NULL;
610 2 : char *sigpath=NULL;
611 2 : struct fzp *zp=NULL;
612 2 : struct sbuf *sb=NULL;
613 :
614 2 : struct fzp *delfp=NULL;
615 :
616 2 : logp("Doing the atomic data jiggle...\n");
617 :
618 2 : if(!(tmpman=get_tmp_filename(fdirs->manifest)))
619 : goto error;
620 4 : if(lstat(fdirs->manifest, &statp))
621 : {
622 : // Manifest does not exist - maybe the server was killed before
623 : // it could be renamed.
624 0 : logp("%s did not exist - trying %s\n", fdirs->manifest, tmpman);
625 : // Rename race condition is of no consequence, because manifest
626 : // already does not exist.
627 0 : do_rename(tmpman, fdirs->manifest);
628 : }
629 2 : if(!(zp=fzp_gzopen(fdirs->manifest, "rb")))
630 : goto error;
631 :
632 4 : if(!(deltabdir=prepend_s(fdirs->currentdup, "deltas.reverse"))
633 2 : || !(deltafdir=prepend_s(sdirs->finishing, "deltas.forward"))
634 2 : || !(sigpath=prepend_s(fdirs->currentdup, "sig.tmp"))
635 4 : || !(sb=sbuf_alloc(PROTO_1)))
636 : {
637 0 : log_out_of_memory(__func__);
638 0 : goto error;
639 : }
640 :
641 2 : mkdir(fdirs->datadir, 0777);
642 :
643 : while(1)
644 : {
645 202 : switch(sbuf_fill_from_file(sb, zp, NULL, NULL))
646 : {
647 : case 0: break;
648 : case 1: goto end;
649 : default: goto error;
650 : }
651 200 : if(sb->protocol1->datapth.buf)
652 : {
653 91 : if(write_status(CNTR_STATUS_SHUFFLING,
654 91 : sb->protocol1->datapth.buf, get_cntr(cconfs))
655 182 : || jiggle(sdirs, fdirs, sb, hardlinked_current,
656 : deltabdir, deltafdir,
657 91 : sigpath, &delfp, cconfs))
658 : goto error;
659 : }
660 200 : sbuf_free_content(sb);
661 : }
662 :
663 : end:
664 2 : if(fzp_close(&delfp))
665 : {
666 : logp("error closing %s in atomic_data_jiggle\n",
667 0 : fdirs->deletionsfile);
668 0 : goto error;
669 : }
670 :
671 2 : if(maybe_delete_files_from_manifest(tmpman, fdirs, cconfs))
672 : goto error;
673 :
674 : // Remove the temporary data directory, we have probably removed
675 : // useful files from it.
676 2 : recursive_delete_dirs_only(deltafdir);
677 :
678 2 : ret=0;
679 : error:
680 2 : fzp_close(&zp);
681 2 : fzp_close(&delfp);
682 2 : sbuf_free(&sb);
683 2 : free_w(&deltabdir);
684 2 : free_w(&deltafdir);
685 2 : free_w(&sigpath);
686 2 : free_w(&datapth);
687 2 : free_w(&tmpman);
688 202 : return ret;
689 : }
690 :
691 2 : int backup_phase4_server_protocol1(struct sdirs *sdirs, struct conf **cconfs)
692 : {
693 2 : int ret=-1;
694 : struct stat statp;
695 2 : char realcurrent[256]="";
696 2 : uint64_t bno=0;
697 2 : int hardlinked_current=0;
698 2 : char tstmp[64]="";
699 2 : int previous_backup=0;
700 2 : struct fdirs *fdirs=NULL;
701 :
702 2 : readlink_w(sdirs->current, realcurrent, sizeof(realcurrent));
703 :
704 4 : if(!(fdirs=fdirs_alloc())
705 2 : || fdirs_init(fdirs, sdirs, realcurrent))
706 : goto end;
707 :
708 2 : if(log_fzp_set(fdirs->logpath, cconfs))
709 : goto end;
710 :
711 2 : logp("Begin phase4 (shuffle files)\n");
712 :
713 2 : if(write_status(CNTR_STATUS_SHUFFLING, NULL, get_cntr(cconfs)))
714 : goto end;
715 :
716 4 : if(!lstat(sdirs->current, &statp)) // Had a previous backup.
717 : {
718 0 : previous_backup++;
719 :
720 0 : if(lstat(fdirs->hlinkedcurrent, &statp))
721 : {
722 0 : hardlinked_current=0;
723 0 : logp("Previous backup is not a hardlinked_archive\n");
724 0 : logp(" will generate reverse deltas\n");
725 : }
726 : else
727 : {
728 0 : hardlinked_current=1;
729 0 : logp("Previous backup is a hardlinked_archive\n");
730 0 : logp(" will not generate reverse deltas\n");
731 : }
732 :
733 : // If current was not a hardlinked_archive, need to duplicate
734 : // it.
735 0 : if(!hardlinked_current && lstat(fdirs->currentdup, &statp))
736 : {
737 : // Have not duplicated the current backup yet.
738 0 : if(!lstat(fdirs->currentduptmp, &statp))
739 : {
740 : logp("Removing previous directory: %s\n",
741 0 : fdirs->currentduptmp);
742 0 : if(recursive_delete(fdirs->currentduptmp))
743 : {
744 : logp("Could not delete %s\n",
745 0 : fdirs->currentduptmp);
746 0 : goto end;
747 : }
748 : }
749 0 : logp("Duplicating current backup.\n");
750 0 : if(recursive_hardlink(sdirs->current,
751 0 : fdirs->currentduptmp, cconfs)
752 : // The rename race condition is of no consequence here
753 : // because currentdup does not exist.
754 0 : || do_rename(fdirs->currentduptmp, fdirs->currentdup))
755 : goto end;
756 : }
757 : }
758 :
759 2 : if(timestamp_read(fdirs->timestamp, tstmp, sizeof(tstmp)))
760 : {
761 : logp("could not read timestamp file: %s\n",
762 0 : fdirs->timestamp);
763 0 : goto end;
764 : }
765 : // Get the backup number.
766 2 : bno=strtoull(tstmp, NULL, 10);
767 :
768 : // Determine whether the new backup should be a hardlinked
769 : // archive or not, from the confs and the backup number...
770 2 : if(need_hardlinked_archive(cconfs, bno))
771 : {
772 : // Create a file to indicate that the previous backup
773 : // does not have others depending on it.
774 0 : struct fzp *hfp=NULL;
775 0 : if(!(hfp=fzp_open(fdirs->hlinked, "wb"))) goto end;
776 :
777 : // Stick the next backup timestamp in it. It might
778 : // be useful one day when wondering when the next
779 : // backup, now deleted, was made.
780 0 : fzp_printf(hfp, "%s\n", tstmp);
781 0 : if(fzp_close(&hfp))
782 : {
783 0 : logp("error closing hardlinked indication\n");
784 0 : goto end;
785 : }
786 : }
787 : else
788 2 : unlink(fdirs->hlinked);
789 :
790 2 : if(atomic_data_jiggle(sdirs, fdirs, hardlinked_current, cconfs))
791 : {
792 0 : logp("could not finish up backup.\n");
793 0 : goto end;
794 : }
795 :
796 2 : if(write_status(CNTR_STATUS_SHUFFLING,
797 2 : "deleting temporary files", get_cntr(cconfs)))
798 : goto end;
799 :
800 : // Remove the temporary data directory, we have now removed
801 : // everything useful from it.
802 2 : recursive_delete(fdirs->datadirtmp);
803 :
804 : // Clean up the currentdata directory - this is now the 'old'
805 : // currentdata directory. Any files that were deleted from
806 : // the client will be left in there, so call recursive_delete
807 : // with the option that makes it not delete files.
808 : // This will have the effect of getting rid of unnecessary
809 : // directories.
810 2 : recursive_delete_dirs_only(fdirs->currentdupdata);
811 :
812 : // Rename the old current to something that we know to delete.
813 2 : if(previous_backup && !hardlinked_current)
814 : {
815 0 : if(deleteme_move(sdirs,
816 0 : fdirs->fullrealcurrent, realcurrent, cconfs)
817 : // I have tested that potential race conditions on the
818 : // rename() are automatically recoverable here.
819 0 : || do_rename(fdirs->currentdup, fdirs->fullrealcurrent))
820 : goto end;
821 : }
822 :
823 2 : if(deleteme_maybe_delete(cconfs, sdirs))
824 : goto end;
825 :
826 2 : logp("End phase4 (shuffle files)\n");
827 :
828 2 : ret=0;
829 : end:
830 2 : fdirs_free(&fdirs);
831 2 : log_fzp_set(NULL, cconfs);
832 2 : return ret;
833 : }
|