static int backup_phase4_server(struct sdirs *sdirs, struct conf **cconfs) { int breaking=get_int(cconfs[OPT_BREAKPOINT]); if(breaking==4) return breakpoint(breaking, __func__); log_fzp_set(NULL, cconfs); // Phase4 will open logfp again (in case it is resuming). switch(get_protocol(cconfs)) { case PROTO_1: return backup_phase4_server_protocol1(sdirs, cconfs); default: return backup_phase4_server_protocol2(sdirs, cconfs); } }
static int recover_finishing(struct async *as, struct sdirs *sdirs, struct conf **cconfs) { int r; char msg[128]=""; struct asfd *asfd=as->asfd; logp("Found finishing symlink - attempting to complete prior backup!\n"); snprintf(msg, sizeof(msg), "Now finalising previous backup of client. " "Please try again later."); asfd->write_str(asfd, CMD_ERROR, msg); // Do not need the client connected any more. // Disconnect. logp("Disconnect from client.\n"); as->asfd_remove(as, asfd); asfd_close(asfd); switch(get_protocol(cconfs)) { case PROTO_1: r=backup_phase4_server_protocol1(sdirs, cconfs); break; case PROTO_2: default: r=backup_phase4_server_protocol2(sdirs, cconfs); break; } if(r) { logp("Problem with prior backup. Please check the client log on the server."); return -1; } logp("Prior backup completed OK.\n"); // Move the symlink to indicate that we are now in the end // phase. // FIX THIS: Check whether the rename race condition is recoverable // here. if(do_rename(sdirs->finishing, sdirs->current)) return -1; return 0; }