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