X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Fdriver.c;h=38ebb331538a02842760ae6ae9a7016d3d695767;hb=691567b16c13087b31ee4c2b6d038e57872fae82;hp=bb3eace0acc085797d4a794d6fec1258fa9cf3b0;hpb=cd0b924f27312d57bd42f6c4fae2b795139e2d0b;p=debian%2Famanda diff --git a/server-src/driver.c b/server-src/driver.c index bb3eace..38ebb33 100644 --- a/server-src/driver.c +++ b/server-src/driver.c @@ -1,6 +1,7 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998 University of Maryland at College Park + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -76,6 +77,7 @@ static int inparallel; static int nodump = 0; static off_t tape_length = (off_t)0; static int current_tape = 0; +static int conf_max_dle_by_volume; static int conf_taperalgo; static int conf_taper_parallel_write; static int conf_runtapes; @@ -141,6 +143,7 @@ static void start_some_dumps(disklist_t *rq); static void continue_port_dumps(void); static void update_failed_dump(disk_t *); static int no_taper_flushing(void); +static int active_dumper(void); typedef enum { TAPE_ACTION_NO_ACTION = 0, @@ -186,7 +189,6 @@ main( identlist_t il; unsigned long reserve = 100; char *conf_diskfile; - char **result_argv = NULL; char *taper_program; char *conf_tapetype; tapetype_t *tape; @@ -201,6 +203,11 @@ main( int no_taper = FALSE; int from_client = FALSE; + if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) { + printf("driver-%s\n", VERSION); + return (0); + } + /* * Configure program for internationalization: * 1) Only set the message locale for now. @@ -271,6 +278,7 @@ main( if (argc > 2) { if (strcmp(argv[2], "--from-client") == 0) { from_client = TRUE; + from_client = from_client; argv++; argc--; } @@ -335,6 +343,7 @@ main( conf_taper_parallel_write = getconf_int(CNF_TAPER_PARALLEL_WRITE); conf_tapetype = getconf_str(CNF_TAPETYPE); conf_runtapes = getconf_int(CNF_RUNTAPES); + conf_max_dle_by_volume = getconf_int(CNF_MAX_DLE_BY_VOLUME); if (conf_taper_parallel_write > conf_runtapes) { conf_taper_parallel_write = conf_runtapes; } @@ -344,7 +353,6 @@ main( 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); - flush_threshold_dumped = (conf_flush_threshold_dumped * tape_length) / 100; flush_threshold_scheduled = (conf_flush_threshold_scheduled * tape_length) / 100; taperflush = (conf_taperflush *tape_length) / 100; @@ -578,8 +586,6 @@ main( amfree(dumper_program); amfree(taper_program); - if (result_argv) - g_strfreev(result_argv); dbclose(); @@ -720,46 +726,51 @@ wait_for_children(void) } -static void startaflush_tape(taper_t *taper); +static void startaflush_tape(taper_t *taper, gboolean *state_changed); static void startaflush(void) { taper_t *taper; + gboolean state_changed = FALSE; for(taper = tapetable; taper <= tapetable+conf_taper_parallel_write; taper++) { if (!(taper->state & TAPER_STATE_DONE) && taper->state & TAPER_STATE_WAIT_FOR_TAPE) { - startaflush_tape(taper); + startaflush_tape(taper, &state_changed); } } for(taper = tapetable; taper <= tapetable+conf_taper_parallel_write; taper++) { if (!(taper->state & TAPER_STATE_DONE) && taper->state & TAPER_STATE_TAPE_REQUESTED) { - startaflush_tape(taper); + startaflush_tape(taper, &state_changed); } } for(taper = tapetable; taper <= tapetable+conf_taper_parallel_write; taper++) { if (!(taper->state & TAPER_STATE_DONE) && taper->state & TAPER_STATE_INIT) { - startaflush_tape(taper); + startaflush_tape(taper, &state_changed); } } for(taper = tapetable; taper <= tapetable+conf_taper_parallel_write; taper++) { if (!(taper->state & TAPER_STATE_DONE) && taper->state & TAPER_STATE_IDLE) { - startaflush_tape(taper); + startaflush_tape(taper, &state_changed); } } + if (state_changed) { + short_dump_state(); + } } static void startaflush_tape( - taper_t *taper) + taper_t *taper, + gboolean *state_changed) { disk_t *dp = NULL; disk_t *fit = NULL; @@ -788,6 +799,7 @@ startaflush_tape( taper_cmd(NO_NEW_TAPE, taper->disk, why_no_new_tape, 0, NULL); taper->state |= TAPER_STATE_DONE; start_degraded_mode(&runq); + *state_changed = TRUE; } else if (result_tape_action & TAPE_ACTION_MOVE) { taper_t *taper1 = idle_taper(); if (taper1) { @@ -797,9 +809,11 @@ startaflush_tape( taper1->state = TAPER_STATE_DEFAULT; taper->state |= TAPER_STATE_TAPE_STARTED; taper->left = taper1->left; + taper->nb_dle++; if (last_started_taper == taper1) { last_started_taper = taper; } + *state_changed = TRUE; } } @@ -961,6 +975,7 @@ startaflush_tape( handle_taper_result, NULL); } taper_nb_wait_reply++; + taper->nb_dle++; sched(dp)->taper = taper; taper_cmd(FILE_WRITE, dp, sched(dp)->destname, sched(dp)->level, sched(dp)->datestamp); @@ -969,8 +984,8 @@ startaflush_tape( (long long)sched(taper->disk)->act_size, (long long)taper->left); amfree(qname); + *state_changed = TRUE; } - short_dump_state(); } } @@ -1047,7 +1062,7 @@ allow_dump_dle( enqueue_disk(&directq, diskp); diskp->to_holdingdisk = HOLD_NEVER; } - if (empty(*rq)) force_flush = 1; + if (empty(*rq) && active_dumper() == 0) { force_flush = 1;} } } else if (client_constrained(diskp)) { free_assignedhd(holdp); @@ -1110,6 +1125,7 @@ start_some_dumps( char dumptype; char *dumporder; int dumper_to_holding = 0; + gboolean state_changed = FALSE; /* don't start any actual dumps until the taper is started */ if (!taper_started) return; @@ -1329,8 +1345,8 @@ start_some_dumps( sched(diskp)->level); dumper_cmd(dumper, PORT_DUMP, diskp, NULL); } - diskp->host->start_t = now + 15; - if (empty(*rq)) force_flush = 1; + diskp->host->start_t = now + 5; + if (empty(*rq) && active_dumper() == 0) { force_flush = 1;} if (result_argv) g_strfreev(result_argv); @@ -1364,6 +1380,7 @@ start_some_dumps( taper->dumper = dumper; taper->state |= TAPER_STATE_DUMP_TO_TAPE; taper->state &= ~TAPER_STATE_IDLE; + taper->nb_dle++; if (taper_nb_wait_reply == 0) { taper_ev_read = event_register(taper_fd, EV_READFD, handle_taper_result, NULL); @@ -1372,11 +1389,14 @@ start_some_dumps( taper_nb_wait_reply++; taper_cmd(PORT_WRITE, diskp, NULL, sched(diskp)->level, sched(diskp)->datestamp); - diskp->host->start_t = now + 15; + diskp->host->start_t = now + 5; - short_dump_state(); + state_changed = TRUE; } } + if (state_changed) { + short_dump_state(); + } } /* @@ -1424,6 +1444,31 @@ start_degraded_mode( disklist_t newq; off_t est_full_size; char *qname; + taper_t *taper; + + if (need_degraded == 0) { + for(taper = tapetable; + taper < tapetable+conf_taper_parallel_write; + taper++) { + if (!(taper->state & TAPER_STATE_DONE)) + return; + } + need_degraded = 1; + } + + if (!schedule_done || degraded_mode) { + return; + } + + if (need_degraded == 0) { + for(taper = tapetable; + taper < tapetable+conf_taper_parallel_write; + taper++) { + if (!(taper->state & TAPER_STATE_DONE)) + return; + } + need_degraded = 1; + } newq.head = newq.tail = 0; @@ -1580,6 +1625,7 @@ handle_taper_result( } assert(taper != NULL); taper->left = 0; + taper->nb_dle = 0; taper->state &= ~TAPER_STATE_INIT; taper->state |= TAPER_STATE_RESERVATION; taper->state |= TAPER_STATE_IDLE; @@ -1627,7 +1673,8 @@ handle_taper_result( amfree(qname); break; } - if (strcmp(result_argv[3], "TAPE-ERROR") == 0) { + if (strcmp(result_argv[3], "TAPE-ERROR") == 0 || + strcmp(result_argv[3], "TAPE-CONFIG") == 0) { taper->state &= ~TAPER_STATE_TAPE_STARTED; taper->tape_error = newstralloc(taper->tape_error, result_argv[5]); taper->result = FAILED; @@ -1683,7 +1730,8 @@ handle_taper_result( amfree(qname); break; } - if (strcmp(result_argv[3], "TAPE-ERROR") == 0) { + if (strcmp(result_argv[3], "TAPE-ERROR") == 0 || + strcmp(result_argv[3], "TAPE-CONFIG") == 0) { taper->state &= ~TAPER_STATE_TAPE_STARTED; taper->tape_error = newstralloc(taper->tape_error, result_argv[6]); taper->result = FAILED; @@ -1704,12 +1752,12 @@ handle_taper_result( s = strstr(result_argv[4], " kb "); if (s) { s += 4; - sched(dp)->dumpsize = atol(s); + sched(dp)->dumpsize = OFF_T_ATOI(s); } else { s = strstr(result_argv[4], " bytes "); if (s) { s += 7; - sched(dp)->dumpsize = atol(s)/1024; + sched(dp)->dumpsize = OFF_T_ATOI(s)/1024; } } @@ -1740,12 +1788,12 @@ handle_taper_result( s = strstr(result_argv[5], " kb "); if (s) { s += 4; - partsize = atol(s); + partsize = OFF_T_ATOI(s); } else { s = strstr(result_argv[5], " bytes "); if (s) { s += 7; - partsize = atol(s)/1024; + partsize = OFF_T_ATOI(s)/1024; } } taper->left -= partsize; @@ -1785,6 +1833,7 @@ handle_taper_result( taper = sched(dp)->taper; /* Update our tape counter and reset taper->left */ current_tape++; + taper->nb_dle = 1; taper->left = tape_length; taper->state &= ~TAPER_STATE_WAIT_NEW_TAPE; taper->state |= TAPER_STATE_TAPE_STARTED; @@ -1848,6 +1897,7 @@ handle_taper_result( if (strcmp(result_argv[1], "SETUP") == 0) { taper_nb_wait_reply = 0; taper_nb_scan_volume = 0; + need_degraded = 1; } else { taper = taper_from_name(result_argv[1]); taper->state = TAPER_STATE_DONE; @@ -1864,13 +1914,11 @@ handle_taper_result( taper_nb_scan_volume--; } if (taper_nb_wait_reply == 0) { + need_degraded = 1; event_release(taper_ev_read); taper_ev_read = NULL; } - need_degraded = 1; - if (schedule_done && !degraded_mode) { - start_degraded_mode(&runq); - } + start_degraded_mode(&runq); start_some_dumps(&runq); break; @@ -1898,7 +1946,7 @@ handle_taper_result( sched(dp)->level); /* tell the dumper to dump to a port */ dumper_cmd(dumper, PORT_DUMP, dp, NULL); - dp->host->start_t = time(NULL) + 15; + dp->host->start_t = time(NULL) + 5; amfree(dp->dataport_list); taper->state |= TAPER_STATE_DUMP_TO_TAPE; @@ -1926,7 +1974,7 @@ handle_taper_result( for (taper = tapetable; taper < tapetable + conf_taper_parallel_write; taper++) { - if (taper && taper->disk && taper->result != LAST_TOK) { + if (taper && taper->disk) { taper->tape_error = newstralloc(taper->tape_error,"BOGUS"); taper->result = cmd; if (taper->dumper) { @@ -1938,7 +1986,6 @@ handle_taper_result( file_taper_result(taper->disk); } } - } taper = NULL; @@ -1947,6 +1994,7 @@ handle_taper_result( taper_ev_read = NULL; taper_nb_wait_reply = 0; } + need_degraded = 1; start_degraded_mode(&runq); tapeq.head = tapeq.tail = NULL; aclose(taper_fd); @@ -1962,6 +2010,9 @@ handle_taper_result( g_strfreev(result_argv); if (taper && taper->disk && taper->result != LAST_TOK) { + if (taper->nb_dle >= conf_max_dle_by_volume) { + taper_cmd(CLOSE_VOLUME, dp, NULL, 0, NULL); + } if(taper->dumper) { if (taper->dumper->result != LAST_TOK) { // Dumper already returned it's result @@ -2095,7 +2146,6 @@ dumper_taper_result( { dumper_t *dumper; taper_t *taper; - int is_partial; char *qname; dumper = sched(dp)->dumper; @@ -2120,8 +2170,6 @@ dumper_taper_result( update_failed_dump(dp); } - is_partial = dumper->result != DONE || taper->result != DONE; - sched(dp)->dump_attempted += 1; sched(dp)->taper_attempted += 1; @@ -2454,14 +2502,12 @@ handle_dumper_result( dumper->chunker->result != LAST_TOK) dumper_chunker_result(dp); } else { /* send the dumper result to the taper */ - if (taper->sendresult) { - if (cmd == DONE) { - taper_cmd(DONE, dp, NULL, 0, NULL); - } else { - taper_cmd(FAILED, dp, NULL, 0, NULL); - } - taper->sendresult = 0; + if (cmd == DONE) { + taper_cmd(DONE, dp, NULL, 0, NULL); + } else { + taper_cmd(FAILED, dp, NULL, 0, NULL); } + taper->sendresult = 0; if (taper->dumper && taper->result != LAST_TOK) { dumper_taper_result(dp); } @@ -3171,8 +3217,8 @@ read_schedule( amfree(inpline); if(line == 0) log_add(L_WARNING, _("WARNING: got empty schedule from planner")); - if(need_degraded==1) start_degraded_mode(&runq); schedule_done = 1; + start_degraded_mode(&runq); run_server_global_scripts(EXECUTE_ON_PRE_BACKUP, get_config_name()); if (empty(runq)) force_flush = 1; start_some_dumps(&runq); @@ -3572,10 +3618,18 @@ build_diskspace( break; } } - + if (!ha || j >= num_holdalloc) { + fprintf(stderr,_("build_diskspace: holding disk file '%s' is not in a holding disk directory.\n"), filename); + amfree(used); + amfree(result); + return NULL; + } if(stat(filename, &finfo) == -1) { - g_fprintf(stderr, _("stat %s: %s\n"), filename, strerror(errno)); - finfo.st_size = (off_t)0; + g_fprintf(stderr, _("build_diskspace: can't stat %s: %s\n"), + filename, strerror(errno)); + amfree(used); + amfree(result); + return NULL; } used[j] += ((off_t)finfo.st_size+(off_t)1023)/(off_t)1024; if((fd = open(filename,O_RDONLY)) == -1) { @@ -3713,29 +3767,35 @@ tape_action( int dump_to_disk_terminated; int nb_taper_active = nb_sent_new_tape; int nb_taper_flushing = 0; + int dle_free = 0; /* number of dle that fit on started tape */ + int new_dle = 0; /* number of dle that doesn't fit on started tape */ + off_t new_data = 0; /* size of dle that doesn't fit on started tape */ off_t data_next_tape = 0; off_t data_free = 0; off_t data_lost = 0; off_t data_lost_next_tape = 0; + gboolean taperflush_criteria; + gboolean flush_criteria; + driver_debug(2, "tape_action: ENTER %p\n", taper); dumpers_size = 0; for(dumper = dmptable; dumper < (dmptable+inparallel); dumper++) { if (dumper->busy && !sched(dumper->dp)->taper) dumpers_size += sched(dumper->dp)->est_size; } - driver_debug(1, _("dumpers_size: %lld\n"), (long long)dumpers_size); + driver_debug(2, _("dumpers_size: %lld\n"), (long long)dumpers_size); runq_size = 0; for(dp = runq.head; dp != NULL; dp = dp->next) { runq_size += sched(dp)->est_size; } - driver_debug(1, _("runq_size: %lld\n"), (long long)runq_size); + driver_debug(2, _("runq_size: %lld\n"), (long long)runq_size); directq_size = 0; for(dp = directq.head; dp != NULL; dp = dp->next) { directq_size += sched(dp)->est_size; } - driver_debug(1, _("directq_size: %lld\n"), (long long)directq_size); + driver_debug(2, _("directq_size: %lld\n"), (long long)directq_size); tapeq_size = directq_size; for(dp = tapeq.head; dp != NULL; dp = dp->next) { @@ -3751,40 +3811,80 @@ tape_action( } /* Add what is currently written to tape and in the go. */ + new_data = 0; for (taper1 = tapetable; taper1 < tapetable+conf_taper_parallel_write; taper1++) { if (taper1->state & TAPER_STATE_TAPE_STARTED) { - tapeq_size -= taper1->left; + if (taper1->nb_dle < conf_max_dle_by_volume) { + tapeq_size -= taper1->left; + } + dle_free += (conf_max_dle_by_volume - taper1->nb_dle); } if (taper1->disk) { off_t data_to_go; + off_t t_size; if (taper1->dumper) { - data_to_go = sched(taper1->disk)->est_size - taper1->written; + t_size = sched(taper1->disk)->est_size; } else { - data_to_go = sched(taper1->disk)->act_size - taper1->written; + t_size = sched(taper1->disk)->act_size; } + data_to_go = t_size - taper1->written; if (data_to_go > taper1->left) { data_next_tape += data_to_go - taper1->left; data_lost += taper1->written + taper1->left; + if (taper1->state & TAPER_STATE_TAPE_STARTED) { + dle_free -= (conf_max_dle_by_volume - taper1->nb_dle) + 1; + } else { + dle_free -= 2; + new_data += t_size; + } } else { + if (!(taper1->state & TAPER_STATE_TAPE_STARTED)) { + dle_free--; + new_data += t_size; + } data_free += taper1->left - data_to_go; } tapeq_size += data_to_go; } } + + new_dle = queue_length(tapeq) - dle_free; + driver_debug(2, _("dle_free: %d\n"), dle_free); + driver_debug(2, _("new_dle: %d\n"), new_dle); + if (new_dle > 0) { + if (taperflush == 0 && + flush_threshold_dumped == 0 && + flush_threshold_scheduled == 0) { + /* shortcut, will trigger taperflush_criteria and/or flush_criteria */ + new_data += 1; + } else { + /* sum the size of the first new-dle in tapeq */ + /* they should be the reverse taperalgo */ + for (dp = tapeq.head; + dp != NULL && new_dle > 0; + dp = dp->next, new_dle--) { + new_data += sched(dp)->act_size; + } + } + if (tapeq_size < new_data) { + tapeq_size = new_data; + } + } + driver_debug(2, _("new_data: %lld\n"), (long long)new_data); data_lost_next_tape = tape_length + data_free - data_next_tape - runq_size - directq_size - tapeq_size; - driver_debug(1, _("data_lost: %lld\n"), (long long)data_lost); - driver_debug(1, _("data_free: %lld\n"), (long long)data_free); - driver_debug(1, _("data_next_tape: %lld\n"), (long long)data_next_tape); - driver_debug(1, _("data_lost_next_tape: %lld\n"), (long long)data_lost_next_tape); + driver_debug(2, _("data_lost: %lld\n"), (long long)data_lost); + driver_debug(2, _("data_free: %lld\n"), (long long)data_free); + driver_debug(2, _("data_next_tape: %lld\n"), (long long)data_next_tape); + driver_debug(2, _("data_lost_next_tape: %lld\n"), (long long)data_lost_next_tape); ; - driver_debug(1, _("tapeq_size: %lld\n"), (long long)tapeq_size); + driver_debug(2, _("tapeq_size: %lld\n"), (long long)tapeq_size); sched_size = runq_size + directq_size + tapeq_size + dumpers_size; - driver_debug(1, _("sched_size: %lld\n"), (long long)sched_size); + driver_debug(2, _("sched_size: %lld\n"), (long long)sched_size); dump_to_disk_size = dumpers_size + runq_size + directq_size; - driver_debug(1, _("dump_to_disk_size: %lld\n"), (long long)dump_to_disk_size); + driver_debug(2, _("dump_to_disk_size: %lld\n"), (long long)dump_to_disk_size); dump_to_disk_terminated = schedule_done && dump_to_disk_size == 0; @@ -3795,25 +3895,45 @@ tape_action( } } + taperflush_criteria = (taperflush < tapeq_size && + (force_flush == 1 || dump_to_disk_terminated)); + flush_criteria = (flush_threshold_dumped < tapeq_size && + flush_threshold_scheduled < sched_size) || + taperflush_criteria; + + driver_debug(2, "taperflush %lld\n", (long long)taperflush); + driver_debug(2, "flush_threshold_dumped %lld\n", (long long)flush_threshold_dumped); + driver_debug(2, "flush_threshold_scheduled %lld\n", (long long)flush_threshold_scheduled); + driver_debug(2, "force_flush %d\n", force_flush); + driver_debug(2, "dump_to_disk_terminated %d\n", dump_to_disk_terminated); + driver_debug(2, "queue_length(runq) %d\n", queue_length(runq)); + driver_debug(2, "queue_length(directq) %d\n", queue_length(directq)); + driver_debug(2, "queue_length(tapeq) %d\n", queue_length(tapeq)); + driver_debug(2, "taperflush_criteria %d\n", taperflush_criteria); + driver_debug(2, "flush_criteria %d\n", flush_criteria); + // Changing conditionals can produce a driver hang, take care. - // + // // when to start writting to a new tape if (taper->state & TAPER_STATE_TAPE_REQUESTED) { + driver_debug(2, "tape_action: TAPER_STATE_TAPE_REQUESTED\n"); if (current_tape >= conf_runtapes && taper_nb_scan_volume == 0 && nb_taper_active == 0) { *why_no_new_tape = g_strdup_printf(_("%d tapes filled; runtapes=%d " "does not allow additional tapes"), current_tape, conf_runtapes); + driver_debug(2, "tape_action: TAPER_STATE_TAPE_REQUESTED return TAPE_ACTION_NO_NEW_TAPE\n"); result |= TAPE_ACTION_NO_NEW_TAPE; } else if (current_tape < conf_runtapes && taper_nb_scan_volume == 0 && - ((flush_threshold_dumped < tapeq_size && - flush_threshold_scheduled < sched_size) || + (flush_criteria || (data_lost > data_lost_next_tape) || nb_taper_active == 0) && (last_started_taper == NULL || last_started_taper == taper)) { + driver_debug(2, "tape_action: TAPER_STATE_TAPE_REQUESTED return TAPE_ACTION_SCAN\n"); result |= TAPE_ACTION_SCAN; } else { + driver_debug(2, "tape_action: TAPER_STATE_TAPE_REQUESTED return TAPE_ACTION_MOVE\n"); result |= TAPE_ACTION_MOVE; } } else if ((taper->state & TAPER_STATE_WAIT_FOR_TAPE) && @@ -3821,13 +3941,10 @@ tape_action( !empty(directq) || // if a dle is waiting for a dump to tape !empty(roomq) || // holding disk constraint idle_reason == IDLE_NO_DISKSPACE || // holding disk constraint - (flush_threshold_dumped < tapeq_size && // flush-threshold-dumped && - flush_threshold_scheduled < sched_size) || // flush-threshold-scheduled - (data_lost > data_lost_next_tape) || - (taperflush < tapeq_size && // taperflush - (force_flush == 1 || // if force_flush - dump_to_disk_terminated)) // or all dump to disk terminated + flush_criteria || // flush criteria + data_lost > data_lost_next_tape )) { + driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE return TAPE_ACTION_NEW_TAPE\n"); result |= TAPE_ACTION_NEW_TAPE; // when to stop using new tape } else if ((taper->state & TAPER_STATE_WAIT_FOR_TAPE) && @@ -3835,32 +3952,39 @@ tape_action( (force_flush == 1 || // if force_flush dump_to_disk_terminated)) // or all dump to disk ) { + driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE B\n"); if (nb_taper_active <= 0) { if (current_tape >= conf_runtapes) { *why_no_new_tape = g_strdup_printf(_("%d tapes filled; runtapes=%d " "does not allow additional tapes"), current_tape, conf_runtapes); - } else { + driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE return TAPE_ACTION_NO_NEW_TAPE\n"); + result |= TAPE_ACTION_NO_NEW_TAPE; + } else if (dumpers_size <= 0) { *why_no_new_tape = _("taperflush criteria not met"); + driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE return TAPE_ACTION_NO_NEW_TAPE\n"); + result |= TAPE_ACTION_NO_NEW_TAPE; } - result |= TAPE_ACTION_NO_NEW_TAPE; } } // when to start a flush if (taper->state & TAPER_STATE_IDLE) { + driver_debug(2, "tape_action: TAPER_STATE_IDLE\n"); if (!degraded_mode && (!empty(tapeq) || !empty(directq)) && (taper->state & TAPER_STATE_TAPE_STARTED || // tape already started !empty(roomq) || // holding disk constraint idle_reason == IDLE_NO_DISKSPACE || // holding disk constraint - (flush_threshold_dumped < tapeq_size && // flush-threshold-dumped && - flush_threshold_scheduled < sched_size) || // flush-threshold-scheduled - (force_flush == 1 && taperflush < tapeq_size))) { // taperflush if force_flush + flush_criteria)) { // flush if (nb_taper_flushing == 0) { + driver_debug(2, "tape_action: TAPER_STATE_IDLE return TAPE_ACTION_START_A_FLUSH\n"); result |= TAPE_ACTION_START_A_FLUSH; } else { + driver_debug(2, "tape_action: TAPER_STATE_IDLE return TAPE_ACTION_START_A_FLUSH_FIT\n"); result |= TAPE_ACTION_START_A_FLUSH_FIT; } + } else { + driver_debug(2, "tape_action: TAPER_STATE_IDLE return TAPE_ACTION_NO_ACTION\n"); } } return result; @@ -3879,6 +4003,14 @@ no_taper_flushing(void) return 1; } +static int +active_dumper(void) +{ + int i, nidle=0; + + for(i = 0; i < inparallel; i++) if(!dmptable[i].busy) nidle++; + return inparallel - nidle; +} #if 0 static void dump_state(