static #endif int do_backup_phase2_server_protocol2(struct async *as, struct asfd *chfd, struct sdirs *sdirs, int resume, struct conf **confs) { int ret=-1; uint8_t end_flags=0; struct slist *slist=NULL; struct iobuf wbuf; struct dpth *dpth=NULL; man_off_t *p1pos=NULL; struct manios *manios=NULL; // This is used to tell the client that a number of consecutive blocks // have been found and can be freed. uint64_t wrap_up=0; struct asfd *asfd=NULL; struct cntr *cntr=NULL; struct sbuf *csb=NULL; uint64_t file_no=1; if(!as) { logp("async not provided to %s()\n", __func__); goto end; } if(!sdirs) { logp("sdirs not provided to %s()\n", __func__); goto end; } if(!confs) { logp("confs not provided to %s()\n", __func__); goto end; } asfd=as->asfd; if(!asfd) { logp("asfd not provided to %s()\n", __func__); goto end; } if(!chfd) { logp("chfd not provided to %s()\n", __func__); goto end; } cntr=get_cntr(confs); if(get_int(confs[OPT_BREAKPOINT])>=2000 && get_int(confs[OPT_BREAKPOINT])<3000) { breaking=get_int(confs[OPT_BREAKPOINT]); breakcount=breaking-2000; } logp("Phase 2 begin (recv backup data)\n"); if(!(dpth=dpth_alloc()) || dpth_protocol2_init(dpth, sdirs->data, get_string(confs[OPT_CNAME]), sdirs->cfiles, get_int(confs[OPT_MAX_STORAGE_SUBDIRS]))) goto end; if(resume && !(p1pos=do_resume(sdirs, dpth, confs))) goto end; if(!(manios=manios_open_phase2(sdirs, p1pos, PROTO_2)) || !(slist=slist_alloc()) || !(csb=sbuf_alloc(PROTO_2))) goto end; iobuf_free_content(asfd->rbuf); memset(&wbuf, 0, sizeof(struct iobuf)); while(!(end_flags&END_BACKUP)) { if(maybe_add_from_scan(manios, slist, chfd, &csb)) goto end; if(!wbuf.len) { if(get_wbuf_from_sigs(&wbuf, slist, &end_flags)) goto end; if(!wbuf.len) { get_wbuf_from_files(&wbuf, slist, manios, &end_flags, &file_no); } } if(wbuf.len && asfd->append_all_to_write_buffer(asfd, &wbuf)==APPEND_ERROR) goto end; if(append_for_champ_chooser(chfd, slist->blist, end_flags)) goto end; if(as->read_write(as)) { logp("error from as->read_write in %s\n", __func__); goto end; } while(asfd->rbuf->buf) { if(deal_with_read(asfd->rbuf, slist, cntr, &end_flags, dpth)) goto end; // Get as much out of the readbuf as possible. if(asfd->parse_readbuf(asfd)) goto end; } while(chfd->rbuf->buf) { if(deal_with_read_from_chfd(chfd, slist->blist, &wrap_up, dpth, cntr)) goto end; // Get as much out of the readbuf as possible. if(chfd->parse_readbuf(chfd)) goto end; } if(write_to_changed_file(asfd, chfd, manios, slist, end_flags)) goto end; } // Hack: If there are some entries left after the last entry that // contains block data, it will not be written to the changed file // yet because the last entry of block data has not had // sb->protocol2->bend set. if(slist->head && slist->head->next) { struct sbuf *sb=NULL; sb=slist->head; slist->head=sb->next; sbuf_free(&sb); if(write_to_changed_file(asfd, chfd, manios, slist, end_flags)) goto end; } if(manios_close(&manios)) goto end; if(check_for_missing_work_in_slist(slist)) goto end; // Need to release the last left. There should be one at most. if(dpth->head && dpth->head->next) { logp("ERROR: More data locks remaining after: %s\n", dpth->head->save_path); goto end; } if(dpth_release_all(dpth)) goto end; ret=0; end: logp("End backup\n"); sbuf_free(&csb); slist_free(&slist); if(asfd) iobuf_free_content(asfd->rbuf); if(chfd) iobuf_free_content(chfd->rbuf); dpth_free(&dpth); manios_close(&manios); man_off_t_free(&p1pos); return ret; }
int backup_phase2_server(struct async *as, struct sdirs *sdirs, const char *manifest_dir, int resume, struct conf *conf) { int ret=-1; int sigs_end=0; int backup_end=0; int requests_end=0; int blk_requests_end=0; struct slist *slist=NULL; struct blist *blist=NULL; struct iobuf *wbuf=NULL; struct dpth *dpth=NULL; struct manio *cmanio=NULL; // current manifest struct manio *p1manio=NULL; // phase1 scan manifest struct manio *chmanio=NULL; // changed manifest struct manio *unmanio=NULL; // unchanged manifest // This is used to tell the client that a number of consecutive blocks // have been found and can be freed. uint64_t wrap_up=0; // Main fd is first in the list. struct asfd *asfd=as->asfd; // Champ chooser fd is second in the list. struct asfd *chfd=asfd->next; logp("Phase 2 begin (recv backup data)\n"); //if(champ_chooser_init(sdirs->data, conf) if(!(cmanio=manio_alloc()) || !(p1manio=manio_alloc()) || !(chmanio=manio_alloc()) || !(unmanio=manio_alloc()) || manio_init_read(cmanio, sdirs->cmanifest) || manio_init_read(p1manio, sdirs->phase1data) || manio_init_write(chmanio, sdirs->changed) || manio_init_write(unmanio, sdirs->unchanged) || !(slist=slist_alloc()) || !(blist=blist_alloc()) || !(wbuf=iobuf_alloc()) || !(dpth=dpth_alloc(sdirs->data)) || dpth_init(dpth)) goto end; // The phase1 manifest looks the same as a burp1 one. manio_set_protocol(p1manio, PROTO_BURP1); while(!backup_end) { if(maybe_add_from_scan(asfd, p1manio, cmanio, unmanio, slist, conf)) goto end; if(!wbuf->len) { if(get_wbuf_from_sigs(wbuf, slist, blist, sigs_end, &blk_requests_end, dpth, conf)) goto end; if(!wbuf->len) { get_wbuf_from_files(wbuf, slist, p1manio, &requests_end); } } if(wbuf->len) asfd->append_all_to_write_buffer(asfd, wbuf); append_for_champ_chooser(chfd, blist, sigs_end); if(as->read_write(as)) { logp("error in %s\n", __func__); goto end; } while(asfd->rbuf->buf) { if(deal_with_read(asfd->rbuf, slist, blist, conf, &sigs_end, &backup_end, dpth)) goto end; // Get as much out of the // readbuf as possible. if(asfd->parse_readbuf(asfd)) goto end; } while(chfd->rbuf->buf) { if(deal_with_read_from_chfd(asfd, chfd, blist, &wrap_up, dpth)) goto end; // Get as much out of the // readbuf as possible. if(chfd->parse_readbuf(chfd)) goto end; } if(write_to_changed_file(asfd, chfd, chmanio, slist, blist, dpth, backup_end, conf)) goto end; } // Hack: If there are some entries left after the last entry that // contains block data, it will not be written to the changed file // yet because the last entry of block data has not had // sb->burp2->bend set. if(slist->head && slist->head->next) { slist->head=slist->head->next; if(write_to_changed_file(asfd, chfd, chmanio, slist, blist, dpth, backup_end, conf)) goto end; } if(manio_close(unmanio) || manio_close(chmanio)) goto end; if(blist->head) { logp("ERROR: finishing but still want block: %lu\n", blist->head->index); goto end; } // Need to release the last left. There should be one at most. if(dpth->head && dpth->head->next) { logp("ERROR: More data locks remaining after: %s\n", dpth->head->save_path); goto end; } if(dpth_release_all(dpth)) goto end; ret=0; end: logp("End backup\n"); slist_free(slist); blist_free(blist); iobuf_free_content(asfd->rbuf); iobuf_free_content(chfd->rbuf); // Write buffer did not allocate 'buf'. if(wbuf) wbuf->buf=NULL; iobuf_free(wbuf); dpth_release_all(dpth); dpth_free(&dpth); manio_free(&cmanio); manio_free(&p1manio); manio_free(&chmanio); manio_free(&unmanio); return ret; }