📄 driver.c
字号:
break; case NO_NEW_TAPE: /* NO-NEW-TAPE <handle> */ if (result_argc != 2) { error(_("error [taper NO_NEW_TAPE result_argc != 2: %d]"), result_argc); /*NOTREACHED*/ } break; case DUMPER_STATUS: /* DUMPER-STATUS <handle> */ if (result_argc != 2) { error(_("error [taper NO_NEW_TAPE result_argc != 2: %d]"), result_argc); /*NOTREACHED*/ } if (taper_dumper->result == LAST_TOK) { taper_sendresult = 1; } else { if( taper_dumper->result == DONE) { taper_cmd(DONE, NULL, NULL, 0, NULL); } else { taper_cmd(FAILED, NULL, NULL, 0, NULL); } } break; case TAPE_ERROR: /* TAPE-ERROR <handle> <err mess> */ dp = serial2disk(result_argv[2]); if (!taper_dumper) free_serial(result_argv[2]); g_printf(_("driver: finished-cmd time %s taper wrote %s:%s\n"), walltime_str(curclock()), dp->host->hostname, dp->name); fflush(stdout); log_add(L_WARNING, _("Taper error: %s"), result_argv[3]); taper_tape_error = stralloc(result_argv[3]); /*FALLTHROUGH*/ case BOGUS: if (cmd == BOGUS) { log_add(L_WARNING, _("Taper protocol error")); taper_tape_error = stralloc("BOGUS"); } /* * Since we received a taper error, we can't send anything more * to the taper. Go into degraded mode to try to get everthing * onto disk. Later, these dumps can be flushed to a new tape. * The tape queue is zapped so that it appears empty in future * checks. If there are dumps waiting for diskspace to be freed, * cancel one. */ if(!nodump) { log_add(L_WARNING, _("going into degraded mode because of taper component error.")); start_degraded_mode(&runq); } tapeq.head = tapeq.tail = NULL; taper_busy = 0; if(taper_ev_read != NULL) { event_release(taper_ev_read); taper_ev_read = NULL; } if(cmd != TAPE_ERROR) aclose(taper); taper_result = cmd; break; default: error(_("driver received unexpected token (%s) from taper"), cmdstr[cmd]); /*NOTREACHED*/ } if (taper_result != LAST_TOK) { if(taper_dumper) { if (taper_dumper->result != LAST_TOK) { // Dumper already returned it's result dumper_taper_result(taper_disk); } } else { file_taper_result(taper_disk); } } } while(areads_dataready(taper));}static voidfile_taper_result( disk_t *dp){ if (taper_result == DONE) { update_info_taper(dp, taper_first_label, taper_first_fileno, sched(dp)->level); } sched(dp)->taper_attempted += 1; if (taper_input_error) { g_printf("driver: taper failed %s %s: %s\n", dp->host->hostname, dp->name, taper_input_error); if (strcmp(sched(dp)->datestamp, driver_timestamp) == 0) { if(sched(dp)->taper_attempted >= 2) { log_add(L_FAIL, _("%s %s %s %d [too many taper retries after holding disk error: %s]"), dp->host->hostname, dp->name, sched(dp)->datestamp, sched(dp)->level, taper_input_error); g_printf("driver: taper failed %s %s, too many taper retry after holding disk error\n", dp->host->hostname, dp->name); amfree(sched(dp)->destname); amfree(sched(dp)->dumpdate); amfree(sched(dp)->degr_dumpdate); amfree(sched(dp)->datestamp); amfree(dp->up); } else { log_add(L_INFO, _("%s %s %s %d [Will retry dump because of holding disk error: %s]"), dp->host->hostname, dp->name, sched(dp)->datestamp, sched(dp)->level, taper_input_error); g_printf("driver: taper will retry %s %s because of holding disk error\n", dp->host->hostname, dp->name); if (dp->to_holdingdisk != HOLD_REQUIRED) { dp->to_holdingdisk = HOLD_NEVER; sched(dp)->dump_attempted -= 1; headqueue_disk(&directq, dp); } else { amfree(sched(dp)->destname); amfree(sched(dp)->dumpdate); amfree(sched(dp)->degr_dumpdate); amfree(sched(dp)->datestamp); amfree(dp->up); } } } else { amfree(sched(dp)->destname); amfree(sched(dp)->dumpdate); amfree(sched(dp)->degr_dumpdate); amfree(sched(dp)->datestamp); amfree(dp->up); } } else if (taper_tape_error) { if(sched(dp)->taper_attempted >= 2) { log_add(L_FAIL, _("%s %s %s %d [too many taper retries]"), dp->host->hostname, dp->name, sched(dp)->datestamp, sched(dp)->level); g_printf("driver: taper failed %s %s, too many taper retry\n", dp->host->hostname, dp->name); amfree(sched(dp)->destname); amfree(sched(dp)->dumpdate); amfree(sched(dp)->degr_dumpdate); amfree(sched(dp)->datestamp); amfree(dp->up); } else { g_printf("driver: taper will retry %s %s\n", dp->host->hostname, dp->name); /* Re-insert into taper queue. */ headqueue_disk(&tapeq, dp); } } else { delete_diskspace(dp); amfree(sched(dp)->destname); amfree(sched(dp)->dumpdate); amfree(sched(dp)->degr_dumpdate); amfree(sched(dp)->datestamp); amfree(dp->up); } taper_busy = 0; taper_input_error = NULL; taper_tape_error = NULL; taper_disk = NULL; /* continue with those dumps waiting for diskspace */ continue_port_dumps(); start_some_dumps(&runq); startaflush();}static voiddumper_taper_result( disk_t *dp){ dumper_t *dumper; int is_partial; char *qname; dumper = sched(dp)->dumper; free_serial_dp(dp); if(dumper->result == DONE && taper_result == DONE) { update_info_dumper(dp, sched(dp)->origsize, sched(dp)->dumpsize, sched(dp)->dumptime); update_info_taper(dp, taper_first_label, taper_first_fileno, sched(dp)->level); qname = quote_string(dp->name); /*quote to take care of spaces*/ log_add(L_STATS, _("estimate %s %s %s %d [sec %ld nkb %lld ckb %lld kps %lu]"), dp->host->hostname, qname, sched(dp)->datestamp, sched(dp)->level, sched(dp)->est_time, (long long)sched(dp)->est_nsize, (long long)sched(dp)->est_csize, sched(dp)->est_kps); amfree(qname); } else { update_failed_dump_to_tape(dp); } is_partial = dumper->result != DONE || taper_result != DONE; sched(dp)->dump_attempted += 1; sched(dp)->taper_attempted += 1; if((dumper->result != DONE || taper_result != DONE) && sched(dp)->dump_attempted <= 1 && sched(dp)->taper_attempted <= 1) { enqueue_disk(&directq, dp); } if(dumper->ev_read != NULL) { event_release(dumper->ev_read); dumper->ev_read = NULL; } if(taper_ev_read != NULL) { event_release(taper_ev_read); taper_ev_read = NULL; } taper_busy = 0; taper_input_error = NULL; taper_tape_error = NULL; dumper->busy = 0; dp->host->inprogress -= 1; dp->inprogress = 0; deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);}static dumper_t *idle_dumper(void){ dumper_t *dumper; for(dumper = dmptable; dumper < dmptable+inparallel; dumper++) if(!dumper->busy && !dumper->down) return dumper; return NULL;}static voiddumper_chunker_result( disk_t * dp){ dumper_t *dumper; chunker_t *chunker; assignedhd_t **h=NULL; int activehd, i; off_t dummy; off_t size; int is_partial; char *qname; dumper = sched(dp)->dumper; chunker = dumper->chunker; free_serial_dp(dp); h = sched(dp)->holdp; activehd = sched(dp)->activehd; if(dumper->result == DONE && chunker->result == DONE) { update_info_dumper(dp, sched(dp)->origsize, sched(dp)->dumpsize, sched(dp)->dumptime); qname = quote_string(dp->name);/*quote to take care of spaces*/ log_add(L_STATS, _("estimate %s %s %s %d [sec %ld nkb %lld ckb %lld kps %lu]"), dp->host->hostname, qname, sched(dp)->datestamp, sched(dp)->level, sched(dp)->est_time, (long long)sched(dp)->est_nsize, (long long)sched(dp)->est_csize, sched(dp)->est_kps); amfree(qname); } deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps); is_partial = dumper->result != DONE || chunker->result != DONE; rename_tmp_holding(sched(dp)->destname, !is_partial); dummy = (off_t)0; for( i = 0, h = sched(dp)->holdp; i < activehd; i++ ) { dummy += h[i]->used; } size = holding_file_size(sched(dp)->destname, 0); h[activehd]->used = size - dummy; h[activehd]->disk->allocated_dumpers--; adjust_diskspace(dp, DONE); sched(dp)->dump_attempted += 1; if((dumper->result != DONE || chunker->result != DONE) && sched(dp)->dump_attempted <= 1) { delete_diskspace(dp); if (sched(dp)->no_space) { enqueue_disk(&directq, dp); } else { enqueue_disk(&runq, dp); } } else if(size > (off_t)DISK_BLOCK_KB) { enqueue_disk(&tapeq, dp); } else { delete_diskspace(dp); } dumper->busy = 0; dp->host->inprogress -= 1; dp->inprogress = 0; waitpid(chunker->pid, NULL, 0 ); aclose(chunker->fd); chunker->fd = -1; chunker->down = 1; dp = NULL; if (chunker->result == ABORT_FINISHED) pending_aborts--; continue_port_dumps(); /* * Wakeup any dumpers that are sleeping because of network * or disk constraints. */ start_some_dumps(&runq); startaflush();}static voidhandle_dumper_result( void * cookie){ /*static int pending_aborts = 0;*/ dumper_t *dumper = cookie; disk_t *dp, *sdp; cmd_t cmd; int result_argc; char *qname; char *result_argv[MAX_ARGS+1]; assert(dumper != NULL); dp = dumper->dp; assert(dp != NULL); assert(sched(dp) != NULL); do { short_dump_state(); cmd = getresult(dumper->fd, 1, &result_argc, result_argv, MAX_ARGS+1); if(cmd != BOGUS) { /* result_argv[2] always contains the serial number */ sdp = serial2disk(result_argv[2]); if (sdp != dp) { error(_("Invalid serial number %s"), result_argv[2]); g_assert_not_reached(); } } qname = quote_string(dp->name); switch(cmd) { case DONE: /* DONE <handle> <origsize> <dumpsize> <dumptime> <errstr> */ if(result_argc != 6) { error(_("error [dumper DONE result_argc != 6: %d]"), result_argc); /*NOTREACHED*/ } sched(dp)->origsize = OFF_T_ATOI(result_argv[3]); sched(dp)->dumptime = TIME_T_ATOI(result_argv[5]); g_printf(_("driver: finished-cmd time %s %s dumped %s:%s\n"), walltime_str(curclock()), dumper->name, dp->host->hostname, qname); fflush(stdout); dumper->result = cmd; break; case TRYAGAIN: /* TRY-AGAIN <handle> <errstr> */ /* * Requeue this disk, and fall through to the FAILED * case for cleanup. */ if(sched(dp)->dump_attempted) { log_add(L_FAIL, _("%s %s %s %d [too many dumper retry: %s]"), dp->host->hostname, dp->name, sched(dp)->datestamp, sched(dp)->level, result_argv[3]); g_printf(_("driver: dump failed %s %s %s, too many dumper retry: %s\n"), result_argv[2], dp->host->hostname, dp->name, result_argv[3]); } /* FALLTHROUGH */ case FAILED: /* FAILED <handle> <errstr> */ /*free_serial(result_argv[2]);*/ dumper->result = cmd; break; case ABORT_FINISHED: /* ABORT-FINISHED <handle> */ /* * We sent an ABORT from the NO-ROOM case because this dump * wasn't going to fit onto the holding disk. We now need to * clean up the remains of this image, and try to finish * other dumps that are waiting on disk space. */ assert(pending_aborts); /*free_serial(result_argv[2]);*/ dumper->result = cmd; break; case BOGUS: /* either EOF or garbage from dumper. Turn it off */ log_add(L_WARNING, _("%s pid %ld is messed up, ignoring it.\n"), dumper->name, (long)dumper->pid); if (dumper->ev_read) { event_release(dumper->ev_read); dumper->ev_read = NULL; } aclose(dumper->fd); dumper->busy = 0; dumper->down = 1; /* mark it down so it isn't used again */ if(dp) { /* if it was dumping something, zap it and try again */ if(sched(dp)->dump_attempted) { log_add(L_FAIL, _("%s %s %s %d [%s died]"), dp->host->hostname, qname, sched(dp)->datestamp, sched(dp)->level, dumper->name); } else { log_add(L_WARNING, _("%s died while dumping %s:%s lev %d."), dumper->name, dp->host->hostname, qname, sched(dp)->level); } } dumper->result = cmd; break; default: assert(0); } amfree(qname); /* send the dumper result to the chunker */ if (dumper->chunker) { if (dumper->chunker->down == 0 && dumper->chunker->fd != -1 && dumper->chunker->result == LAST_TOK) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -