static int champ_chooser_new_client(struct async *as, struct conf **confs) { int fd=-1; socklen_t t; struct asfd *newfd=NULL; struct sockaddr_un remote; struct blist *blist=NULL; t=sizeof(remote); if((fd=accept(as->asfd->fd, (struct sockaddr *)&remote, &t))<0) { logp("accept error in %s: %s\n", __func__, strerror(errno)); goto error; } if(!(blist=blist_alloc()) || !(newfd=setup_asfd(as, "(unknown)", &fd, /*listen*/""))) goto error; newfd->blist=blist; newfd->set_timeout(newfd, get_int(confs[OPT_NETWORK_TIMEOUT])); logp("Connected to fd %d\n", newfd->fd); return 0; error: close_fd(&fd); blist_free(&blist); return -1; }
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; }
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; }