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