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 jiggle(struct sdirs *sdirs, struct fdirs *fdirs, struct sbuf *sb,
235 : int hardlinked_current, const char *deltabdir, const char *deltafdir,
236 : const char *sigpath, struct fzp **delfp, struct conf **cconfs)
237 : {
238 0 : int ret=-1;
239 : struct stat statp;
240 0 : char *oldpath=NULL;
241 0 : char *newpath=NULL;
242 0 : char *finpath=NULL;
243 0 : char *deltafpath=NULL;
244 0 : const char *datapth=sb->protocol1->datapth.buf;
245 :
246 : // If the previous backup was a hardlinked_archive, there will not be
247 : // a currentdup directory - just directly use the file in the previous
248 : // backup.
249 0 : if(!(oldpath=prepend_s(hardlinked_current?
250 0 : sdirs->currentdata:fdirs->currentdupdata, datapth))
251 0 : || !(newpath=prepend_s(fdirs->datadirtmp, datapth))
252 0 : || !(finpath=prepend_s(fdirs->datadir, datapth))
253 0 : || !(deltafpath=prepend_s(deltafdir, datapth)))
254 : goto end;
255 :
256 0 : if(!lstat(finpath, &statp) && S_ISREG(statp.st_mode))
257 : {
258 : // Looks like an interrupted jiggle
259 : // did this file already.
260 : static int donemsg=0;
261 0 : if(!lstat(deltafpath, &statp) && S_ISREG(statp.st_mode))
262 : {
263 : logp("deleting unneeded forward delta: %s\n",
264 0 : deltafpath);
265 0 : unlink(deltafpath);
266 : }
267 0 : if(!donemsg)
268 : {
269 0 : logp("skipping already present file: %s\n", finpath);
270 0 : logp("to save log space, skips of other already present files will not be logged\n");
271 0 : donemsg++;
272 : }
273 : }
274 0 : else if(mkpath(&finpath, fdirs->datadir))
275 : {
276 0 : logp("could not create path for: %s\n", finpath);
277 : goto end;
278 : }
279 0 : else if(mkpath(&newpath, fdirs->datadirtmp))
280 : {
281 0 : logp("could not create path for: %s\n", newpath);
282 : goto end;
283 : }
284 0 : else if(!lstat(deltafpath, &statp) && S_ISREG(statp.st_mode))
285 : {
286 : int lrs;
287 0 : char *infpath=NULL;
288 :
289 : // Got a forward patch to do.
290 : // First, need to gunzip the old file,
291 : // otherwise the librsync patch will take
292 : // forever, because it will be doing seeks
293 : // all over the place, and gzseeks are slow.
294 0 : if(!(infpath=prepend_s(deltafdir, "inflate")))
295 : {
296 0 : log_out_of_memory(__func__);
297 0 : goto end;
298 : }
299 :
300 : //logp("Fixing up: %s\n", datapth);
301 0 : if(inflate_or_link_oldfile(oldpath, infpath,
302 0 : sb->compression, cconfs))
303 : {
304 0 : logp("error when inflating old file: %s\n", oldpath);
305 0 : free_w(&infpath);
306 : goto end;
307 : }
308 :
309 0 : if((lrs=do_patch(NULL, infpath, deltafpath, newpath,
310 0 : sb->compression, sb->compression /* from manifest */)))
311 : {
312 : logp("WARNING: librsync error when patching %s: %d\n",
313 0 : oldpath, lrs);
314 0 : cntr_add(get_cntr(cconfs), CMD_WARNING, 1);
315 : // Try to carry on with the rest of the backup
316 : // regardless.
317 : //ret=-1;
318 : // Remove anything that got written.
319 0 : unlink(newpath);
320 0 : unlink(infpath);
321 0 : free_w(&infpath);
322 :
323 : // First, note that we want to remove this entry from
324 : // the manifest.
325 0 : if(!*delfp
326 0 : && !(*delfp=fzp_open(fdirs->deletionsfile, "ab")))
327 : {
328 : // Could not mark this file as deleted. Fatal.
329 : goto end;
330 : }
331 0 : if(sbuf_to_manifest(sb, *delfp))
332 : goto end;
333 0 : if(fzp_flush(*delfp))
334 : {
335 0 : logp("error fflushing deletions file in %s: %s\n", __func__, strerror(errno));
336 : goto end;
337 : }
338 :
339 : ret=0;
340 : goto end;
341 : }
342 :
343 : // Get rid of the inflated old file.
344 0 : unlink(infpath);
345 0 : free_w(&infpath);
346 :
347 : // Need to generate a reverse diff, unless we are keeping a
348 : // hardlinked archive.
349 0 : if(!hardlinked_current)
350 : {
351 0 : if(gen_rev_delta(sigpath, deltabdir,
352 0 : oldpath, newpath, datapth, sb, cconfs))
353 : goto end;
354 : }
355 :
356 : // Power interruptions should be recoverable. If it happens
357 : // before this point, the data jiggle for this file has to be
358 : // done again.
359 : // Once finpath is in place, no more jiggle is required.
360 :
361 : // Use the fresh new file.
362 : // Rename race condition is of no consequence, because finpath
363 : // will just get recreated automatically.
364 0 : if(do_rename(newpath, finpath))
365 : goto end;
366 :
367 : // Remove the forward delta, as it is no longer needed. There
368 : // is a reverse diff and the finished finished file is in place.
369 : //logp("Deleting delta.forward...\n");
370 0 : unlink(deltafpath);
371 :
372 : // Remove the old file. If a power cut happens just before
373 : // this, the old file will hang around forever.
374 : // FIX THIS: maybe put in something to detect this.
375 : // ie, both a reverse delta and the old file exist.
376 0 : if(!hardlinked_current)
377 : {
378 : //logp("Deleting oldpath...\n");
379 0 : unlink(oldpath);
380 : }
381 : }
382 0 : else if(!lstat(newpath, &statp) && S_ISREG(statp.st_mode))
383 : {
384 : // Use the fresh new file.
385 : // This needs to happen after checking
386 : // for the forward delta, because the
387 : // patching stuff writes to newpath.
388 :
389 : // Rename race condition is of no consequence, because finpath
390 : // will just get recreated automatically.
391 :
392 : //logp("Using newly received file\n");
393 0 : if(do_rename(newpath, finpath))
394 : goto end;
395 : }
396 0 : else if(!lstat(oldpath, &statp) && S_ISREG(statp.st_mode))
397 : {
398 : // Use the old unchanged file.
399 : // Hard link it first.
400 : //logp("Hard linking to old file: %s\n", datapth);
401 0 : if(do_link(oldpath, finpath, &statp, cconfs,
402 0 : 0 /* do not overwrite finpath (should never need to) */))
403 : goto end;
404 : else
405 : {
406 : // If we are not keeping a hardlinked
407 : // archive, delete the old link.
408 0 : if(!hardlinked_current)
409 : {
410 : //logp("Unlinking old file: %s\n", oldpath);
411 0 : unlink(oldpath);
412 : }
413 : }
414 : }
415 : else
416 : {
417 0 : logp("could not find: %s\n", oldpath);
418 : goto end;
419 : }
420 :
421 : ret=0;
422 : end:
423 0 : free_w(&oldpath);
424 0 : free_w(&newpath);
425 0 : free_w(&finpath);
426 0 : free_w(&deltafpath);
427 0 : return ret;
428 : }
429 :
430 : /* If OPT_HARDLINKED_ARCHIVE set, hardlink everything.
431 : If unset and there is more than one 'keep' value, periodically hardlink,
432 : based on the first 'keep' value. This is so that we have more choice
433 : of backups to delete than just the oldest.
434 : */
435 0 : static int need_hardlinked_archive(struct conf **cconfs, uint64_t bno)
436 : {
437 0 : int kp=0;
438 0 : int ret=0;
439 0 : struct strlist *keep=get_strlist(cconfs[OPT_KEEP]);
440 0 : if(get_int(cconfs[OPT_HARDLINKED_ARCHIVE]))
441 : {
442 0 : logp("New backup is a hardlinked_archive\n");
443 0 : return 1;
444 : }
445 0 : if(!keep || !keep->next)
446 : {
447 0 : logp("New backup is not a hardlinked_archive\n");
448 0 : return 0;
449 : }
450 :
451 : // If they have specified more than one 'keep' value, need to
452 : // periodically hardlink, based on the first 'keep' value.
453 0 : kp=keep->flag;
454 :
455 : logp("First keep value: %d, backup: %"PRIu64" (%"PRIu64"-1=%"PRIu64")\n",
456 0 : kp, bno, bno, bno-1);
457 :
458 0 : ret=(bno-1)%kp;
459 : logp("New backup is %sa hardlinked_archive (%"PRIu64"%%%d=%d)\n",
460 0 : ret?"not ":"", bno-1, kp, ret);
461 :
462 0 : return !ret;
463 : }
464 :
465 0 : static int maybe_delete_files_from_manifest(const char *manifesttmp,
466 : struct fdirs *fdirs, struct conf **cconfs)
467 : {
468 0 : int ars=0;
469 0 : int ret=-1;
470 0 : int pcmp=0;
471 0 : struct fzp *dfp=NULL;
472 0 : struct fzp *nmzp=NULL;
473 0 : struct fzp *omzp=NULL;
474 0 : struct sbuf *db=NULL;
475 0 : struct sbuf *mb=NULL;
476 : struct stat statp;
477 :
478 0 : if(lstat(fdirs->deletionsfile, &statp)) // No deletions, no problem.
479 : return 0;
480 0 : logp("Performing deletions on manifest\n");
481 :
482 0 : if(!(manifesttmp=get_tmp_filename(fdirs->manifest)))
483 : goto end;
484 :
485 0 : if(!(dfp=fzp_open(fdirs->deletionsfile, "rb"))
486 0 : || !(omzp=fzp_gzopen(fdirs->manifest, "rb"))
487 0 : || !(nmzp=fzp_gzopen(manifesttmp,
488 0 : comp_level(get_int(cconfs[OPT_COMPRESSION]))))
489 0 : || !(db=sbuf_alloc(PROTO_1))
490 0 : || !(mb=sbuf_alloc(PROTO_1)))
491 : goto end;
492 :
493 0 : while(omzp || dfp)
494 : {
495 0 : if(dfp && !db->path.buf
496 0 : && (ars=sbuf_fill_from_file(db, dfp, NULL, NULL)))
497 : {
498 0 : if(ars<0) goto end;
499 : // ars==1 means it ended ok.
500 0 : fzp_close(&dfp);
501 : }
502 0 : if(omzp && !mb->path.buf
503 0 : && (ars=sbuf_fill_from_file(mb, omzp, NULL, NULL)))
504 : {
505 0 : if(ars<0) goto end;
506 : // ars==1 means it ended ok.
507 0 : fzp_close(&omzp);
508 : }
509 :
510 0 : if(mb->path.buf && !db->path.buf)
511 : {
512 0 : if(sbuf_to_manifest(mb, nmzp)) goto end;
513 0 : sbuf_free_content(mb);
514 : }
515 0 : else if(!mb->path.buf && db->path.buf)
516 : {
517 0 : sbuf_free_content(db);
518 : }
519 0 : else if(!mb->path.buf && !db->path.buf)
520 : {
521 : continue;
522 : }
523 0 : else if(!(pcmp=sbuf_pathcmp(mb, db)))
524 : {
525 : // They were the same - do not write.
526 0 : sbuf_free_content(mb);
527 0 : sbuf_free_content(db);
528 : }
529 0 : else if(pcmp<0)
530 : {
531 : // Behind in manifest. Write.
532 0 : if(sbuf_to_manifest(mb, nmzp)) goto end;
533 0 : sbuf_free_content(mb);
534 : }
535 : else
536 : {
537 : // Behind in deletions file. Do not write.
538 0 : sbuf_free_content(db);
539 : }
540 : }
541 :
542 : ret=0;
543 : end:
544 0 : if(fzp_close(&nmzp))
545 : {
546 0 : logp("error closing %s in %s\n", manifesttmp, __func__);
547 0 : ret=-1;
548 : }
549 :
550 0 : fzp_close(&dfp);
551 0 : fzp_close(&omzp);
552 0 : sbuf_free(&db);
553 0 : sbuf_free(&mb);
554 0 : if(!ret)
555 : {
556 0 : unlink(fdirs->deletionsfile);
557 : // The rename race condition is not a problem here, as long
558 : // as manifesttmp is the same path as that generated in the
559 : // atomic data jiggle.
560 0 : if(do_rename(manifesttmp, fdirs->manifest))
561 : return -1;
562 : }
563 0 : if(manifesttmp) unlink(manifesttmp);
564 : return ret;
565 : }
566 :
567 : /* Need to make all the stuff that this does atomic so that existing backups
568 : never get broken, even if somebody turns the power off on the server. */
569 0 : static int atomic_data_jiggle(struct sdirs *sdirs, struct fdirs *fdirs,
570 : int hardlinked_current, struct conf **cconfs, uint64_t bno)
571 : {
572 0 : int ret=-1;
573 0 : char *datapth=NULL;
574 0 : char *tmpman=NULL;
575 : struct stat statp;
576 :
577 0 : char *deltabdir=NULL;
578 0 : char *deltafdir=NULL;
579 0 : char *sigpath=NULL;
580 0 : struct fzp *zp=NULL;
581 0 : struct sbuf *sb=NULL;
582 :
583 0 : struct fzp *delfp=NULL;
584 :
585 0 : logp("Doing the atomic data jiggle...\n");
586 :
587 0 : if(!(tmpman=get_tmp_filename(fdirs->manifest)))
588 : goto error;
589 0 : if(lstat(fdirs->manifest, &statp))
590 : {
591 : // Manifest does not exist - maybe the server was killed before
592 : // it could be renamed.
593 0 : logp("%s did not exist - trying %s\n", fdirs->manifest, tmpman);
594 : // Rename race condition is of no consequence, because manifest
595 : // already does not exist.
596 0 : do_rename(tmpman, fdirs->manifest);
597 : }
598 0 : if(!(zp=fzp_gzopen(fdirs->manifest, "rb")))
599 : goto error;
600 :
601 0 : if(!(deltabdir=prepend_s(fdirs->currentdup, "deltas.reverse"))
602 0 : || !(deltafdir=prepend_s(sdirs->finishing, "deltas.forward"))
603 0 : || !(sigpath=prepend_s(fdirs->currentdup, "sig.tmp"))
604 0 : || !(sb=sbuf_alloc(PROTO_1)))
605 : {
606 0 : log_out_of_memory(__func__);
607 : goto error;
608 : }
609 :
610 0 : mkdir(fdirs->datadir, 0777);
611 :
612 : while(1)
613 : {
614 0 : switch(sbuf_fill_from_file(sb, zp, NULL, NULL))
615 : {
616 : case 0: break;
617 : case 1: goto end;
618 : default: goto error;
619 : }
620 0 : if(sb->protocol1->datapth.buf)
621 : {
622 0 : if(write_status(CNTR_STATUS_SHUFFLING,
623 0 : sb->protocol1->datapth.buf, get_cntr(cconfs))
624 0 : || jiggle(sdirs, fdirs, sb, hardlinked_current,
625 : deltabdir, deltafdir,
626 0 : sigpath, &delfp, cconfs))
627 : goto error;
628 : }
629 0 : sbuf_free_content(sb);
630 : }
631 :
632 : end:
633 0 : if(fzp_close(&delfp))
634 : {
635 : logp("error closing %s in atomic_data_jiggle\n",
636 0 : fdirs->deletionsfile);
637 : goto error;
638 : }
639 :
640 0 : if(maybe_delete_files_from_manifest(tmpman, fdirs, cconfs))
641 : goto error;
642 :
643 : // Remove the temporary data directory, we have probably removed
644 : // useful files from it.
645 0 : sync(); // try to help CIFS
646 0 : recursive_delete_dirs_only(deltafdir);
647 :
648 0 : ret=0;
649 : error:
650 0 : fzp_close(&zp);
651 0 : fzp_close(&delfp);
652 0 : sbuf_free(&sb);
653 0 : free_w(&deltabdir);
654 0 : free_w(&deltafdir);
655 0 : free_w(&sigpath);
656 0 : free_w(&datapth);
657 0 : free_w(&tmpman);
658 0 : return ret;
659 : }
660 :
661 0 : int backup_phase4_server_protocol1(struct sdirs *sdirs, struct conf **cconfs)
662 : {
663 0 : int ret=-1;
664 : struct stat statp;
665 0 : ssize_t len=0;
666 0 : char realcurrent[256]="";
667 0 : uint64_t bno=0;
668 0 : int hardlinked_current=0;
669 0 : char tstmp[64]="";
670 0 : int previous_backup=0;
671 0 : struct fdirs *fdirs=NULL;
672 :
673 0 : if((len=readlink(sdirs->current, realcurrent, sizeof(realcurrent)-1))<0)
674 0 : len=0;
675 0 : realcurrent[len]='\0';
676 :
677 0 : if(!(fdirs=fdirs_alloc())
678 0 : || fdirs_init(fdirs, sdirs, realcurrent))
679 : goto end;
680 :
681 0 : if(log_fzp_set(fdirs->logpath, cconfs))
682 : goto end;
683 :
684 0 : logp("Begin phase4 (shuffle files)\n");
685 :
686 0 : if(write_status(CNTR_STATUS_SHUFFLING, NULL, get_cntr(cconfs)))
687 : goto end;
688 :
689 0 : if(!lstat(sdirs->current, &statp)) // Had a previous backup.
690 : {
691 0 : previous_backup++;
692 :
693 0 : if(lstat(fdirs->hlinkedcurrent, &statp))
694 : {
695 0 : hardlinked_current=0;
696 0 : logp("Previous backup is not a hardlinked_archive\n");
697 0 : logp(" will generate reverse deltas\n");
698 : }
699 : else
700 : {
701 0 : hardlinked_current=1;
702 0 : logp("Previous backup is a hardlinked_archive\n");
703 0 : logp(" will not generate reverse deltas\n");
704 : }
705 :
706 : // If current was not a hardlinked_archive, need to duplicate
707 : // it.
708 0 : if(!hardlinked_current && lstat(fdirs->currentdup, &statp))
709 : {
710 : // Have not duplicated the current backup yet.
711 0 : if(!lstat(fdirs->currentduptmp, &statp))
712 : {
713 : logp("Removing previous directory: %s\n",
714 0 : fdirs->currentduptmp);
715 0 : if(recursive_delete(fdirs->currentduptmp))
716 : {
717 : logp("Could not delete %s\n",
718 0 : fdirs->currentduptmp);
719 0 : goto end;
720 : }
721 : }
722 0 : logp("Duplicating current backup.\n");
723 0 : if(recursive_hardlink(sdirs->current,
724 0 : fdirs->currentduptmp, cconfs)
725 : // The rename race condition is of no consequence here
726 : // because currentdup does not exist.
727 0 : || do_rename(fdirs->currentduptmp, fdirs->currentdup))
728 : goto end;
729 : }
730 : }
731 :
732 0 : if(timestamp_read(fdirs->timestamp, tstmp, sizeof(tstmp)))
733 : {
734 : logp("could not read timestamp file: %s\n",
735 0 : fdirs->timestamp);
736 0 : goto end;
737 : }
738 : // Get the backup number.
739 0 : bno=strtoull(tstmp, NULL, 10);
740 :
741 : // Determine whether the new backup should be a hardlinked
742 : // archive or not, from the confs and the backup number...
743 0 : if(need_hardlinked_archive(cconfs, bno))
744 : {
745 : // Create a file to indicate that the previous backup
746 : // does not have others depending on it.
747 0 : struct fzp *hfp=NULL;
748 0 : if(!(hfp=fzp_open(fdirs->hlinked, "wb"))) goto end;
749 :
750 : // Stick the next backup timestamp in it. It might
751 : // be useful one day when wondering when the next
752 : // backup, now deleted, was made.
753 0 : fzp_printf(hfp, "%s\n", tstmp);
754 0 : if(fzp_close(&hfp))
755 : {
756 0 : logp("error closing hardlinked indication\n");
757 0 : goto end;
758 : }
759 : }
760 : else
761 0 : unlink(fdirs->hlinked);
762 :
763 0 : if(atomic_data_jiggle(sdirs, fdirs, hardlinked_current, cconfs, bno))
764 : {
765 0 : logp("could not finish up backup.\n");
766 0 : goto end;
767 : }
768 :
769 0 : if(write_status(CNTR_STATUS_SHUFFLING,
770 0 : "deleting temporary files", get_cntr(cconfs)))
771 : goto end;
772 :
773 : // Remove the temporary data directory, we have now removed
774 : // everything useful from it.
775 0 : recursive_delete(fdirs->datadirtmp);
776 :
777 : // Clean up the currentdata directory - this is now the 'old'
778 : // currentdata directory. Any files that were deleted from
779 : // the client will be left in there, so call recursive_delete
780 : // with the option that makes it not delete files.
781 : // This will have the effect of getting rid of unnecessary
782 : // directories.
783 0 : sync(); // try to help CIFS
784 0 : recursive_delete_dirs_only(fdirs->currentdupdata);
785 :
786 : // Rename the old current to something that we know to delete.
787 0 : if(previous_backup && !hardlinked_current)
788 : {
789 0 : if(deleteme_move(sdirs,
790 0 : fdirs->fullrealcurrent, realcurrent, cconfs)
791 : // I have tested that potential race conditions on the
792 : // rename() are automatically recoverable here.
793 0 : || do_rename(fdirs->currentdup, fdirs->fullrealcurrent))
794 : goto end;
795 : }
796 :
797 0 : if(deleteme_maybe_delete(cconfs, sdirs))
798 : goto end;
799 :
800 0 : logp("End phase4 (shuffle files)\n");
801 :
802 0 : ret=0;
803 : end:
804 0 : fdirs_free(&fdirs);
805 0 : return ret;
806 : }
|