X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Fdriver.c;h=d7a6fea7a83d9e10bfca84e25697e55ad18daa22;hb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;hp=e9504edceb4597029173eafb477fcf734914603a;hpb=fb2bd066c2f8b34addafe48d62550e3033a59431;p=debian%2Famanda diff --git a/server-src/driver.c b/server-src/driver.c index e9504ed..d7a6fea 100644 --- a/server-src/driver.c +++ b/server-src/driver.c @@ -144,7 +144,7 @@ typedef enum { TAPE_ACTION_START_A_FLUSH = (1 << 2) } TapeAction; -static TapeAction tape_action(void); +static TapeAction tape_action(char **why_no_new_tape); static const char *idle_strings[] = { #define NOT_IDLE 0 @@ -179,7 +179,7 @@ main( char *conf_diskfile; cmd_t cmd; int result_argc; - char *result_argv[MAX_ARGS+1]; + char **result_argv = NULL; char *taper_program; char *conf_tapetype; tapetype_t *tape; @@ -222,10 +222,21 @@ main( if (argc > 1) cfg_opt = argv[1]; - config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD | CONFIG_INIT_FATAL, - cfg_opt); + config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD, cfg_opt); apply_config_overwrites(cfg_ovr); + conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE)); + read_diskfile(conf_diskfile, &origq); + amfree(conf_diskfile); + + if (config_errors(NULL) >= CFGERR_WARNINGS) { + config_print_errors(); + if (config_errors(NULL) >= CFGERR_ERRORS) { + g_critical(_("errors processing config file")); + } + } + + log_add(L_INFO, "%s pid %ld", get_pname(), (long)getpid()); g_printf(_("%s: pid %ld executable %s version %s\n"), get_pname(), (long) getpid(), argv[0], version()); @@ -239,7 +250,7 @@ main( check_running_as(RUNNING_AS_DUMPUSER); - dbrename(config_name, DBG_SUBDIR_SERVER); + dbrename(get_config_name(), DBG_SUBDIR_SERVER); amfree(driver_timestamp); /* read timestamp from stdin */ @@ -292,6 +303,7 @@ main( conf_runtapes = getconf_int(CNF_RUNTAPES); tape = lookup_tapetype(conf_tapetype); tape_length = tapetype_get_length(tape); + g_printf("driver: tape size %lld\n", (long long)tape_length); conf_flush_threshold_dumped = getconf_int(CNF_FLUSH_THRESHOLD_DUMPED); conf_flush_threshold_scheduled = getconf_int(CNF_FLUSH_THRESHOLD_SCHEDULED); conf_taperflush = getconf_int(CNF_TAPERFLUSH); @@ -304,15 +316,6 @@ main( driver_debug(1, _("flush_threshold_scheduled: %lld\n"), (long long)flush_threshold_scheduled); driver_debug(1, _("taperflush: %lld\n"), (long long)taperflush); - /* start initializing: read in databases */ - - conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE)); - if (read_diskfile(conf_diskfile, &origq) < 0) { - error(_("could not load disklist \"%s\""), conf_diskfile); - /*NOTREACHED*/ - } - amfree(conf_diskfile); - /* set up any configuration-dependent variables */ inparallel = getconf_int(CNF_INPARALLEL); @@ -441,7 +444,7 @@ main( /* ok, planner is done, now lets see if the tape is ready */ if (conf_runtapes > 0) { - cmd = getresult(taper, 1, &result_argc, result_argv, MAX_ARGS+1); + cmd = getresult(taper, 1, &result_argc, &result_argv); if (cmd != TAPER_OK) { /* no tape, go into degraded mode: dump to holding disk */ need_degraded = 1; @@ -452,8 +455,8 @@ main( tape_left = tape_length; taper_busy = 0; - taper_input_error = NULL; - taper_tape_error = NULL; + amfree(taper_input_error); + amfree(taper_tape_error); taper_disk = NULL; taper_ev_read = NULL; @@ -478,10 +481,33 @@ main( /* handle any remaining dumps by dumping directly to tape, if possible */ while(!empty(directq) && taper > 0) { - diskp = dequeue_disk(&directq); + time_t sleep_time = 100000000; + disk_t *sleep_diskp = NULL; + time_t now = time(0); + + /* Find one we can do immediately or the sonner */ + for (diskp = directq.head; diskp != NULL; diskp = diskp->next) { + if (diskp->to_holdingdisk == HOLD_REQUIRED || + degraded_mode) { + sleep_time = 0; + sleep_diskp = diskp; + } else if (diskp->host->start_t - now < sleep_time && + diskp->start_t -now < sleep_time) { + if (diskp->host->start_t > diskp->start_t) + sleep_time = diskp->host->start_t - now; + else + sleep_time = diskp->start_t - now; + sleep_diskp = diskp; + } + } + diskp = sleep_diskp; + if (sleep_time > 0) + sleep(sleep_time); + remove_disk(&directq, diskp); + if (diskp->to_holdingdisk == HOLD_REQUIRED) { char *qname = quote_string(diskp->name); - log_add(L_FAIL, _("%s %s %s %d [%s]"), + log_add(L_FAIL, "%s %s %s %d [%s]", diskp->host->hostname, qname, sched(diskp)->datestamp, sched(diskp)->level, _("can't dump required holdingdisk")); @@ -491,16 +517,18 @@ main( taper_state |= TAPER_STATE_DUMP_TO_TAPE; dump_to_tape(diskp); event_loop(0); - taper_state &= !TAPER_STATE_DUMP_TO_TAPE; + taper_state &= ~TAPER_STATE_DUMP_TO_TAPE; } else { char *qname = quote_string(diskp->name); - log_add(L_FAIL, _("%s %s %s %d [%s]"), + log_add(L_FAIL, "%s %s %s %d [%s]", diskp->host->hostname, qname, sched(diskp)->datestamp, sched(diskp)->level, - diskp->to_holdingdisk == HOLD_AUTO ? - _("no more holding disk space") : - _("can't dump no-hold disk in degraded mode")); + num_holdalloc == 0 ? + _("can't do degraded dump without holding disk") : + diskp->to_holdingdisk != HOLD_NEVER ? + _("out of holding space in degraded mode") : + _("can't dump 'holdingdisk never' dle in degraded mode")); amfree(qname); } } @@ -518,7 +546,7 @@ main( if(!nodump) { for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) { if(dumper->fd >= 0) - dumper_cmd(dumper, QUIT, NULL); + dumper_cmd(dumper, QUIT, NULL, NULL); } } @@ -538,10 +566,13 @@ main( g_printf(_("driver: FINISHED time %s\n"), walltime_str(curclock())); fflush(stdout); log_add(L_FINISH,_("date %s time %s"), driver_timestamp, walltime_str(curclock())); + log_add(L_INFO, "pid-done %ld", (long)getpid()); amfree(driver_timestamp); amfree(dumper_program); amfree(taper_program); + if (result_argv) + g_strfreev(result_argv); dbclose(); @@ -641,11 +672,12 @@ kill_children(int signal) } } - if(taper_pid > 1) + if(taper_pid > 1) { g_printf(_("driver: sending signal %d to %s pid %u\n"), signal, "taper", (unsigned)taper_pid); if (kill(taper_pid, signal) == -1 && errno == ESRCH) taper_pid = 0; + } } static void @@ -656,10 +688,10 @@ wait_for_children(void) if(!nodump) { for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) { if (dumper->pid > 1 && dumper->fd >= 0) { - dumper_cmd(dumper, QUIT, NULL); + dumper_cmd(dumper, QUIT, NULL, NULL); if (dumper->chunker && dumper->chunker->pid > 1 && dumper->chunker->fd >= 0) - chunker_cmd(dumper->chunker, QUIT, NULL); + chunker_cmd(dumper->chunker, QUIT, NULL, NULL); } } } @@ -690,15 +722,17 @@ startaflush(void) int extra_tapes = 0; char *qname; TapeAction result_tape_action; + char *why_no_new_tape; - result_tape_action = tape_action(); + result_tape_action = tape_action(&why_no_new_tape); if (result_tape_action & TAPE_ACTION_NEW_TAPE) { - taper_state &= !TAPER_STATE_WAIT_FOR_TAPE; + taper_state &= ~TAPER_STATE_WAIT_FOR_TAPE; taper_cmd(NEW_TAPE, NULL, NULL, 0, NULL); } else if (result_tape_action & TAPE_ACTION_NO_NEW_TAPE) { - taper_state &= !TAPER_STATE_WAIT_FOR_TAPE; - taper_cmd(NO_NEW_TAPE, NULL, NULL, 0, NULL); + taper_state &= ~TAPER_STATE_WAIT_FOR_TAPE; + taper_cmd(NO_NEW_TAPE, why_no_new_tape, NULL, 0, NULL); + start_degraded_mode(&runq); } if (!degraded_mode && !taper_busy && !empty(tapeq) && @@ -781,13 +815,13 @@ startaflush(void) if (dp) { taper_disk = dp; taper_busy = 1; - taper_input_error = NULL; - taper_tape_error = NULL; + amfree(taper_input_error); + amfree(taper_tape_error); taper_result = LAST_TOK; taper_sendresult = 0; taper_first_label = NULL; taper_written = 0; - taper_state &= !TAPER_STATE_DUMP_TO_TAPE; + taper_state &= ~TAPER_STATE_DUMP_TO_TAPE; taper_dumper = NULL; qname = quote_string(dp->name); taper_cmd(FILE_WRITE, dp, sched(dp)->destname, sched(dp)->level, @@ -805,6 +839,7 @@ startaflush(void) error(_("FATAL: Taper marked busy and no work found.")); /*NOTREACHED*/ } + short_dump_state(); } else if(!taper_busy && taper_ev_read != NULL) { event_release(taper_ev_read); taper_ev_read = NULL; @@ -843,11 +878,12 @@ start_some_dumps( { int cur_idle; disk_t *diskp, *delayed_diskp, *diskp_accept; + disk_t *dp; assignedhd_t **holdp=NULL, **holdp_accept; const time_t now = time(NULL); cmd_t cmd; int result_argc; - char *result_argv[MAX_ARGS+1]; + char **result_argv; chunker_t *chunker; dumper_t *dumper; char dumptype; @@ -1027,10 +1063,10 @@ start_some_dumps( chunker->result = LAST_TOK; dumper->result = LAST_TOK; startup_chunk_process(chunker,chunker_program); - chunker_cmd(chunker, START, (void *)driver_timestamp); + chunker_cmd(chunker, START, NULL, driver_timestamp); chunker->dumper = dumper; - chunker_cmd(chunker, PORT_WRITE, diskp); - cmd = getresult(chunker->fd, 1, &result_argc, result_argv, MAX_ARGS+1); + chunker_cmd(chunker, PORT_WRITE, diskp, NULL); + cmd = getresult(chunker->fd, 1, &result_argc, &result_argv); if(cmd != PORT) { assignedhd_t **h=NULL; int activehd; @@ -1063,11 +1099,25 @@ start_some_dumps( handle_dumper_result, dumper); chunker->ev_read = event_register((event_id_t)chunker->fd, EV_READFD, handle_chunker_result, chunker); - dumper->output_port = atoi(result_argv[2]); + dumper->output_port = atoi(result_argv[1]); - dumper_cmd(dumper, PORT_DUMP, diskp); + if (diskp->host->pre_script == 0) { + for (dp=diskp->host->disks; dp != NULL; dp = dp->hostnext) { + run_server_scripts(EXECUTE_ON_PRE_HOST_BACKUP, + get_config_name(), dp, -1); + } + diskp->host->pre_script = 1; + } + run_server_scripts(EXECUTE_ON_PRE_DLE_BACKUP, + get_config_name(), diskp, + sched(diskp)->level); + dumper_cmd(dumper, PORT_DUMP, diskp, NULL); } diskp->host->start_t = now + 15; + + if (result_argv) + g_strfreev(result_argv); + short_dump_state(); } } } @@ -1146,9 +1196,9 @@ start_degraded_mode( enqueue_disk(&newq, dp); } else { - log_add(L_FAIL,_("%s %s %s %d [can't switch to incremental dump]"), + log_add(L_FAIL, "%s %s %s %d [%s]", dp->host->hostname, qname, sched(dp)->datestamp, - sched(dp)->level); + sched(dp)->level, sched(dp)->degr_mesg); } } amfree(qname); @@ -1186,7 +1236,7 @@ continue_port_dumps(void) } assert( dumper < dmptable + inparallel ); sched(dp)->activehd = assign_holdingdisk( h, dp ); - chunker_cmd( dumper->chunker, CONTINUE, dp ); + chunker_cmd( dumper->chunker, CONTINUE, dp, NULL ); amfree(h); remove_disk( &roomq, dp ); } @@ -1229,8 +1279,8 @@ continue_port_dumps(void) * We abort that dump, hopefully not wasting too much time retrying it. */ remove_disk( &roomq, dp ); - chunker_cmd( sched(dp)->dumper->chunker, ABORT, NULL); - dumper_cmd( sched(dp)->dumper, ABORT, NULL ); + chunker_cmd(sched(dp)->dumper->chunker, ABORT, NULL, _("Not enough holding disk space")); + dumper_cmd( sched(dp)->dumper, ABORT, NULL, _("Not enough holding disk space")); pending_aborts++; } } @@ -1238,23 +1288,24 @@ continue_port_dumps(void) static void handle_taper_result( - void *cookie) + void *cookie G_GNUC_UNUSED) { disk_t *dp; cmd_t cmd; int result_argc; - char *result_argv[MAX_ARGS+1]; - char *qname; - - (void)cookie; /* Quiet unused parameter warning */ + char **result_argv; + char *qname, *q; + char *s; assert(cookie == NULL); + amfree(taper_input_error); + amfree(taper_tape_error); do { short_dump_state(); - cmd = getresult(taper, 1, &result_argc, result_argv, MAX_ARGS+1); + cmd = getresult(taper, 1, &result_argc, &result_argv); switch(cmd) { @@ -1264,24 +1315,42 @@ handle_taper_result( /*NOTREACHED*/ } - dp = serial2disk(result_argv[2]); + dp = serial2disk(result_argv[1]); assert(dp == taper_disk); if (!taper_dumper) - free_serial(result_argv[2]); + free_serial(result_argv[1]); qname = quote_string(dp->name); g_printf(_("driver: finished-cmd time %s taper wrote %s:%s\n"), walltime_str(curclock()), dp->host->hostname, qname); fflush(stdout); - amfree(qname); - if (strcmp(result_argv[3], "INPUT-ERROR") == 0) { - taper_input_error = stralloc(result_argv[5]); + if (strcmp(result_argv[2], "INPUT-ERROR") == 0) { + taper_input_error = newstralloc(taper_input_error, result_argv[4]); + } else if (strcmp(result_argv[2], "INPUT-GOOD") != 0) { + taper_tape_error = newstralloc(taper_tape_error, + _("Taper protocol error")); + taper_result = FAILED; + log_add(L_FAIL, _("%s %s %s %d [%s]"), + dp->host->hostname, qname, sched(dp)->datestamp, + sched(dp)->level, taper_tape_error); + amfree(qname); + break; } - if (strcmp(result_argv[4], "TAPE-ERROR") == 0) { - taper_tape_error = stralloc(result_argv[6]); + if (strcmp(result_argv[3], "TAPE-ERROR") == 0) { + taper_tape_error = newstralloc(taper_tape_error, result_argv[5]); + } else if (strcmp(result_argv[3], "TAPE-GOOD") != 0) { + taper_tape_error = newstralloc(taper_tape_error, + _("Taper protocol error")); + taper_result = FAILED; + log_add(L_FAIL, _("%s %s %s %d [%s]"), + dp->host->hostname, qname, sched(dp)->datestamp, + sched(dp)->level, taper_tape_error); + amfree(qname); + break; } + amfree(qname); taper_result = cmd; break; @@ -1293,70 +1362,96 @@ handle_taper_result( /*NOTREACHED*/ } - dp = serial2disk(result_argv[2]); + dp = serial2disk(result_argv[1]); assert(dp == taper_disk); if (!taper_dumper) - free_serial(result_argv[2]); + free_serial(result_argv[1]); qname = quote_string(dp->name); g_printf(_("driver: finished-cmd time %s taper wrote %s:%s\n"), walltime_str(curclock()), dp->host->hostname, qname); - amfree(qname); fflush(stdout); - if (strcmp(result_argv[3], "INPUT-ERROR") == 0) { - taper_input_error = stralloc(result_argv[5]); + if (strcmp(result_argv[2], "INPUT-ERROR") == 0) { + taper_input_error = newstralloc(taper_input_error, result_argv[5]); + } else if (strcmp(result_argv[2], "INPUT-GOOD") != 0) { + taper_tape_error = newstralloc(taper_tape_error, + _("Taper protocol error")); + taper_result = FAILED; + log_add(L_FAIL, _("%s %s %s %d [%s]"), + dp->host->hostname, qname, sched(dp)->datestamp, + sched(dp)->level, taper_tape_error); + amfree(qname); + break; + } + if (strcmp(result_argv[3], "TAPE-ERROR") == 0) { + taper_tape_error = newstralloc(taper_tape_error, result_argv[6]); + } else if (strcmp(result_argv[3], "TAPE-GOOD") != 0) { + taper_tape_error = newstralloc(taper_tape_error, + _("Taper protocol error")); + taper_result = FAILED; + log_add(L_FAIL, _("%s %s %s %d [%s]"), + dp->host->hostname, qname, sched(dp)->datestamp, + sched(dp)->level, taper_tape_error); + amfree(qname); + break; } - if (strcmp(result_argv[4], "TAPE-ERROR") == 0) { - taper_tape_error = stralloc(result_argv[6]); + + s = strstr(result_argv[4], " kb "); + if (s) { + s += 4; + sched(dp)->dumpsize = atol(s); } taper_result = cmd; + amfree(qname); break; - case PARTDONE: /* PARTDONE