int backup_phase2_client_protocol2(struct asfd *asfd, struct conf **confs, int resume) { int ret=-1; uint8_t end_flags=0; struct slist *slist=NULL; struct iobuf *rbuf=NULL; struct iobuf *wbuf=NULL; struct cntr *cntr=NULL; if(confs) cntr=get_cntr(confs); if(!asfd || !asfd->as) { logp("%s() called without async structs!\n", __func__); goto end; } logp("Phase 2 begin (send backup data)\n"); logfmt("\n"); if(!(slist=slist_alloc()) || !(wbuf=iobuf_alloc()) || blks_generate_init()) goto end; rbuf=asfd->rbuf; if(!resume) { // Only do this bit if the server did not tell us to resume. if(asfd->write_str(asfd, CMD_GEN, "backupphase2") || asfd_read_expect(asfd, CMD_GEN, "ok")) goto end; } else { // On resume, the server might update the client with cntr. if(cntr_recv(asfd, confs)) goto end; } while(!(end_flags&END_BACKUP)) { if(!wbuf->len) { get_wbuf_from_data(confs, wbuf, slist, end_flags); if(!wbuf->len) { if(get_wbuf_from_blks(wbuf, slist, &end_flags)) goto end; } } if(wbuf->len) { if(asfd->append_all_to_write_buffer(asfd, wbuf) ==APPEND_ERROR) goto end; } if(asfd->as->read_write(asfd->as)) { logp("error in %s\n", __func__); goto end; } if(rbuf->buf && deal_with_read(rbuf, slist, cntr, &end_flags)) goto end; if(slist->head // Need to limit how many blocks are allocated at once. && (!slist->blist->head || slist->blist->tail->index - slist->blist->head->index<BLKS_MAX_IN_MEM) ) { if(add_to_blks_list(asfd, confs, slist)) goto end; } if(end_flags&END_BLK_REQUESTS) { // If got to the end of the file request list // and the last block of the last file, and // the write buffer is empty, we got to the end. if(slist->head==slist->tail) { if(!slist->tail || slist->blist->last_sent== slist->tail->protocol2->bend) { if(!wbuf->len) break; } } } } if(asfd->write_str(asfd, CMD_GEN, "backup_end")) goto end; ret=0; end: slist_free(&slist); blks_generate_free(); if(wbuf) { // Write buffer did not allocate 'buf'. wbuf->buf=NULL; iobuf_free(&wbuf); } cntr_print_end(cntr); cntr_print(cntr, ACTION_BACKUP, asfd); if(ret) logp("Error in backup\n"); logp("End backup\n"); return ret; }
int backup_phase2_client_burp2(struct asfd *asfd, struct conf *conf, int resume) { int ret=-1; int sigs_end=0; int backup_end=0; int requests_end=0; int blk_requests_end=0; struct win *win=NULL; // Rabin sliding window. struct slist *slist=NULL; struct blist *blist=NULL; struct iobuf *rbuf=NULL; struct iobuf *wbuf=NULL; logp("Phase 2 begin (send backup data)\n"); if(!(slist=slist_alloc()) || !(blist=blist_alloc()) || !(wbuf=iobuf_alloc()) || blks_generate_init(conf) || !(win=win_alloc(&conf->rconf))) goto end; rbuf=asfd->rbuf; if(!resume) { // Only do this bit if the server did not tell us to resume. if(asfd->write_str(asfd, CMD_GEN, "backupphase2") || asfd->read_expect(asfd, CMD_GEN, "ok")) goto end; } else if(conf->send_client_cntr) { // On resume, the server might update the client with the // counters. if(cntr_recv(asfd, conf)) goto end; } while(!backup_end) { if(!wbuf->len) { get_wbuf_from_data(conf, wbuf, slist, blist, blk_requests_end); if(!wbuf->len) { get_wbuf_from_blks(wbuf, slist, requests_end, &sigs_end); } } if(wbuf->len) asfd->append_all_to_write_buffer(asfd, wbuf); if(asfd->as->read_write(asfd->as)) { logp("error in %s\n", __func__); goto end; } if(rbuf->buf && deal_with_read(rbuf, slist, blist, conf, &backup_end, &requests_end, &blk_requests_end)) goto end; if(slist->head // Need to limit how many blocks are allocated at once. && (!blist->head || blist->tail->index - blist->head->index<BLKS_MAX_IN_MEM) ) { if(add_to_blks_list(asfd, conf, slist, blist, win)) goto end; } if(blk_requests_end) { // If got to the end of the file request list // and the last block of the last file, and // the write buffer is empty, we got to the end. if(slist->head==slist->tail) { if(!slist->tail || blist->last_sent==slist->tail->burp2->bend) { if(!wbuf->len) break; } } } } if(asfd->write_str(asfd, CMD_GEN, "backup_end")) goto end; ret=0; end: blk_print_alloc_stats(); //sbuf_print_alloc_stats(); win_free(win); slist_free(&slist); blist_free(&blist); // Write buffer did not allocate 'buf'. wbuf->buf=NULL; iobuf_free(&wbuf); cntr_print_end(conf->cntr); cntr_print(conf->cntr, ACTION_BACKUP); if(ret) logp("Error in backup\n"); logp("End backup\n"); return ret; }