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; }
static void run_test( int expected_result, int entries, void setup_datadir_tmp_callback( struct slist *slist, struct fdirs *fdirs, struct conf **confs)) { struct conf **confs; struct sdirs *sdirs; struct fdirs *fdirs; struct slist *slist; setup(&sdirs, &fdirs, &confs); build_storage_dirs(sdirs, sd1, ARR_LEN(sd1)); slist=build_manifest( fdirs->manifest, PROTO_1, entries, /*phase*/ 3); setup_datadir_tmp_callback(slist, fdirs, confs); clock_t start; clock_t diff; start = clock(); fail_unless(backup_phase4_server_protocol1(sdirs, confs) ==expected_result); diff = clock() - start; int msec = diff * 1000 / CLOCKS_PER_SEC; printf("%d.%d\n", msec/1000, msec%1000); log_fzp_set(NULL, confs); assert_datadir(slist, fdirs); slist_free(&slist); tear_down(&sdirs, &fdirs, &confs); }