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