static int merge_into_global_sparse(const char *sparse, const char *global) { int ret=-1; char *tmpfile=NULL; struct stat statp; struct lock *lock=NULL; const char *globalsrc=NULL; if(!(tmpfile=get_global_sparse_tmp(global))) goto end; if(!(lock=try_to_get_sparse_lock(global))) goto end; if(!lstat(global, &statp)) globalsrc=global; if(merge_sparse_indexes(tmpfile, globalsrc, sparse)) goto end; // FIX THIS: nasty race condition needs to be recoverable. if(do_rename(tmpfile, global)) goto end; ret=0; end: lock_release(lock); lock_free(&lock); free_w(&tmpfile); return ret; }
static int merge_into_global_sparse(const char *sparse, const char *global, struct conf **confs) { int ret=-1; char *tmpfile=NULL; struct stat statp; char *lockfile=NULL; struct lock *lock=NULL; const char *globalsrc=NULL; if(!(tmpfile=prepend_n(global, "tmp", strlen("tmp"), "."))) goto end; // Get a lock before messing with the global sparse index. if(!(lockfile=prepend_n(global, "lock", strlen("lock"), ".")) || !(lock=lock_alloc_and_init(lockfile))) goto end; if(try_to_get_lock(lock)) goto end; if(!lstat(global, &statp)) globalsrc=global; if(merge_sparse_indexes(sparse, globalsrc, tmpfile, confs)) goto end; // FIX THIS: nasty race condition needs to be recoverable. if(do_rename(tmpfile, global)) goto end; ret=0; end: lock_release(lock); lock_free(&lock); if(lockfile) free(lockfile); if(tmpfile) free(tmpfile); return ret; }
int backup_phase4_server_protocol2(struct sdirs *sdirs, struct conf **confs) { int ret=-1; uint64_t i=0; uint64_t pass=0; char *sparse=NULL; char *global_sparse=NULL; char *h1dir=NULL; char *h2dir=NULL; char *hooksdir=NULL; char *srca=NULL; char *srcb=NULL; char *dst=NULL; char compa[32]=""; char compb[32]=""; char compd[32]=""; struct manio *newmanio=NULL; char *logpath=NULL; char *fmanifest=NULL; // FIX THIS: should be part of sdirs. if(!(logpath=prepend_s(sdirs->finishing, "log"))) goto end; if(set_logfp(logpath, confs)) goto end; logp("Begin phase4 (sparse generation)\n"); if(!(newmanio=manio_alloc()) || !(fmanifest=prepend_s(sdirs->finishing, "manifest")) || manio_init_read(newmanio, fmanifest) || manio_read_fcount(newmanio) || !(hooksdir=prepend_s(fmanifest, "hooks")) || !(h1dir=prepend_s(fmanifest, "h1")) || !(h2dir=prepend_s(fmanifest, "h2"))) goto end; while(1) { char *srcdir=NULL; char *dstdir=NULL; if(!pass) { srcdir=hooksdir; dstdir=h1dir; } else if(pass%2) { srcdir=h1dir; dstdir=h2dir; } else { srcdir=h2dir; dstdir=h1dir; } pass++; for(i=0; i<newmanio->offset.fcount; i+=2) { free_w(&srca); free_w(&srcb); free_w(&dst); snprintf(compa, sizeof(compa), "%08"PRIX64, i); snprintf(compb, sizeof(compb), "%08"PRIX64, i+1); snprintf(compd, sizeof(compd), "%08"PRIX64, i/2); if(!(srca=prepend_s(srcdir, compa)) || !(dst=prepend_s(dstdir, compd))) goto end; if(i+1<newmanio->offset.fcount && !(srcb=prepend_s(srcdir, compb))) goto end; if(merge_sparse_indexes(srca, srcb, dst, confs)) goto end; } if((newmanio->offset.fcount=i/2)<2) break; } if(!(sparse=prepend_s(fmanifest, "sparse")) || !(global_sparse=prepend_s(sdirs->data, "sparse"))) goto end; // FIX THIS: nasty race condition here needs to be automatically // recoverable. if(do_rename(dst, sparse)) goto end; if(merge_into_global_sparse(sparse, global_sparse, confs)) goto end; logp("End phase4 (sparse generation)\n"); ret=0; end: manio_free(&newmanio); free_w(&sparse); free_w(&global_sparse); free_w(&srca); free_w(&srcb); recursive_delete(h1dir, NULL, 1); recursive_delete(h2dir, NULL, 1); free_w(&h1dir); free_w(&h2dir); free_w(&logpath); free_w(&fmanifest); return ret; }