X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Fplanner.c;h=c8501e2f35aced2ab93db61374600e0fd921c0ef;hb=refs%2Ftags%2Fupstream%2F3.3.1;hp=031e36b6fe0a0ae7a6353fd947560a84c7343b3a;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e;p=debian%2Famanda diff --git a/server-src/planner.c b/server-src/planner.c index 031e36b..c8501e2 100644 --- a/server-src/planner.c +++ b/server-src/planner.c @@ -30,6 +30,7 @@ */ #include "amanda.h" #include "arglist.h" +#include "find.h" #include "conffile.h" #include "diskfile.h" #include "tapefile.h" @@ -189,6 +190,13 @@ main( char *cfg_opt = NULL; int planner_setuid; int exit_status = EXIT_SUCCESS; + gboolean no_taper = FALSE; + gboolean from_client = FALSE; + + if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) { + printf("planner-%s\n", VERSION); + return (0); + } /* * Configure program for internationalization: @@ -255,12 +263,22 @@ main( g_fprintf(stderr, _("%s: %s"), get_pname(), version_info[i]); diskarg_offset = 2; - if (argc > 3 && strcmp(argv[2], "--starttime") == 0) { - planner_timestamp = stralloc(argv[3]); + if (argc - diskarg_offset > 1 && strcmp(argv[diskarg_offset], "--starttime") == 0) { + planner_timestamp = stralloc(argv[diskarg_offset+1]); diskarg_offset += 2; } + if (argc - diskarg_offset > 0 && strcmp(argv[diskarg_offset], "--no-taper") == 0) { + no_taper = TRUE; + diskarg_offset += 1; + } + if (argc - diskarg_offset > 0 && strcmp(argv[diskarg_offset], "--from-client") == 0) { + from_client = TRUE; + diskarg_offset += 1; + } + run_server_global_scripts(EXECUTE_ON_PRE_ESTIMATE, get_config_name()); + /* * 1. Networking Setup * @@ -309,7 +327,7 @@ main( conf_tapecycle = getconf_int(CNF_TAPECYCLE); conf_etimeout = (time_t)getconf_int(CNF_ETIMEOUT); conf_reserve = getconf_int(CNF_RESERVE); - conf_autoflush = getconf_boolean(CNF_AUTOFLUSH); + conf_autoflush = getconf_no_yes_all(CNF_AUTOFLUSH); conf_usetimestamps = getconf_boolean(CNF_USETIMESTAMPS); today = time(0); @@ -335,6 +353,19 @@ main( g_fprintf(stderr,"%s",errstr); exit_status = EXIT_FAILURE; } + + for (dp = origq.head; dp != NULL; dp = dp->next) { + if (dp->todo) { + if (from_client) { + if (!dp->dump_limit || !dp->dump_limit->same_host) + dp->todo = 0; + } else { + if (dp->dump_limit && !dp->dump_limit->server) + dp->todo = 0; + } + } + } + nb_disk = 0; for (dp = origq.head; dp != NULL; dp = dp->next) { if (dp->todo) { @@ -409,12 +440,13 @@ main( g_fprintf(stderr,_("\nSENDING FLUSHES...\n")); - if(conf_autoflush) { + if(conf_autoflush && !no_taper) { dumpfile_t file; GSList *holding_list, *holding_file; char *qdisk, *qhname; - /* get *all* flushable files in holding */ + /* get *all* flushable files in holding, without checking against + * the disklist (which may not contain some of the dumps) */ holding_list = holding_get_files_for_flush(NULL); for(holding_file=holding_list; holding_file != NULL; holding_file = holding_file->next) { @@ -428,6 +460,13 @@ main( continue; } + /* see if this matches the command-line arguments */ + if (conf_autoflush == 1 && + !match_dumpfile(&file, argc-diskarg_offset, + argv+diskarg_offset)) { + continue; + } + qdisk = quote_string(file.disk); qhname = quote_string((char *)holding_file->data); log_add(L_DISK, "%s %s", file.name, qdisk); @@ -449,7 +488,7 @@ main( amfree(qhname); dumpfile_free_data(&file); } - g_slist_free_full(holding_list); + slist_free_full(holding_list, g_free); holding_list = NULL; } g_fprintf(stderr, _("ENDFLUSH\n")); @@ -539,6 +578,8 @@ main( while(!empty(estq)) analyze_estimate(dequeue_disk(&estq)); while(!empty(failq)) handle_failed(dequeue_disk(&failq)); + run_server_global_scripts(EXECUTE_ON_POST_ESTIMATE, get_config_name()); + /* * At this point, all the disks are on schedq sorted by priority. * The total estimated size of the backups is in total_size. @@ -759,8 +800,6 @@ setup_estimate( amfree(qname); return; } else if (dp->to_holdingdisk == HOLD_AUTO) { - log_add(L_INFO, _("Disabling holding disk for %s:%s."), - dp->host->hostname, qname); g_fprintf(stderr,_("%s:%s Disabling holding disk\n"), dp->host->hostname, qname); dp->to_holdingdisk = HOLD_NEVER; @@ -796,21 +835,24 @@ setup_estimate( * hosed when that tape gets re-used next. Disallow this for * now. */ - log_add(L_ERROR, + log_add(L_WARNING, _("Cannot force full dump of %s:%s with no-full option."), dp->host->hostname, qname); /* clear force command */ CLR(info.command, FORCE_FULL); - if(put_info(dp->host->hostname, dp->name, &info)) { - error(_("could not put info record for %s:%s: %s"), - dp->host->hostname, qname, strerror(errno)); - /*NOTREACHED*/ - } ep->last_level = last_level(&info); ep->next_level0 = next_level0(dp, &info); - } - else { + } else if (dp->strategy == DS_INCRONLY) { + log_add(L_WARNING, + _("Cannot force full dump of %s:%s with incronly option."), + dp->host->hostname, qname); + + /* clear force command */ + CLR(info.command, FORCE_FULL); + ep->last_level = last_level(&info); + ep->next_level0 = next_level0(dp, &info); + } else { ep->degr_mesg = _("Skipping: force-full disk can't be dumped in degraded mode"); ep->last_level = -1; ep->next_level0 = -conf_dumpcycle; @@ -975,7 +1017,7 @@ setup_estimate( (!ISSET(info.command, FORCE_BUMP) || dp->skip_incr || ep->last_level == -1))) { - if(info.command & FORCE_BUMP && ep->last_level == -1) { + if(ISSET(info.command, FORCE_BUMP) && ep->last_level == -1) { log_add(L_INFO, _("Remove force-bump command of %s:%s because it's a new disk."), dp->host->hostname, qname); @@ -984,12 +1026,16 @@ setup_estimate( case DS_STANDARD: case DS_NOINC: askfor(ep, i++, 0, &info); + if (ep->last_level == -1) + ep->degr_mesg = _("Skipping: new disk can't be dumped in degraded mode"); + else + ep->degr_mesg = _("Skipping: strategy NOINC can't be dumped in degraded mode"); if(dp->skip_full) { - log_add(L_INFO, _("Ignoring skip_full for %s:%s " + log_add(L_INFO, _("Ignoring skip-full for %s:%s " "because the strategy is NOINC."), dp->host->hostname, qname); } - if(info.command & FORCE_BUMP) { + if(ISSET(info.command, FORCE_BUMP)) { log_add(L_INFO, _("Ignoring FORCE_BUMP for %s:%s because the strategy is NOINC."), dp->host->hostname, qname); @@ -1168,7 +1214,7 @@ static gint64 est_tape_size( one_est_t *dump_est; dump_est = est_for_level(dp, level); - if (dump_est->csize <= -1) + if (dump_est->level >= 0 && dump_est->csize <= -1) est_csize(dp, dump_est); return dump_est->csize; } @@ -1307,15 +1353,11 @@ static void get_estimates(void) hostp = dp->host; if(hostp->up == HOST_READY) { something_started = 1; + run_server_host_scripts(EXECUTE_ON_PRE_HOST_ESTIMATE, + get_config_name(), hostp); for(dp1 = hostp->disks; dp1 != NULL; dp1 = dp1->hostnext) { if (dp1->todo) - run_server_scripts(EXECUTE_ON_PRE_HOST_ESTIMATE, - get_config_name(), dp1, - est(dp1)->estimate[0].level); - } - for(dp1 = hostp->disks; dp1 != NULL; dp1 = dp1->hostnext) { - if (dp1->todo) - run_server_scripts(EXECUTE_ON_PRE_DLE_ESTIMATE, + run_server_dle_scripts(EXECUTE_ON_PRE_DLE_ESTIMATE, get_config_name(), dp1, est(dp1)->estimate[0].level); } @@ -1580,6 +1622,9 @@ static void getsize( strappend(s, l); s_len += strlen(l); amfree(l); + amfree(levelstr); + amfree(spindlestr); + amfree(o); } else if (strcmp(dp->program,"DUMP") != 0 && strcmp(dp->program,"GNUTAR") != 0) { est(dp)->errstr = newvstrallocf(est(dp)->errstr, @@ -1696,6 +1741,8 @@ static void getsize( enqueue_disk(&failq, dp); } } + amfree(b64disk); + amfree(b64device); amfree(qname); amfree(qdevice); } @@ -1724,6 +1771,7 @@ static void getsize( timeout = (time_t)getconf_int(CNF_CTIMEOUT); } + dbprintf(_("send request:\n----\n%s\n----\n\n"), req); secdrv = security_getdriver(hostp->disks->auth); if (secdrv == NULL) { hostp->up = HOST_DONE; @@ -1789,8 +1837,12 @@ static void handle_result( hostp->up = HOST_READY; if (pkt == NULL) { - errbuf = vstrallocf(_("Request to %s failed: %s"), + if (strcmp(security_geterror(sech), "timeout waiting for REP") == 0) { + errbuf = vstrallocf("Some estimate timeout on %s, using server estimate if possible", hostp->hostname); + } else { + errbuf = vstrallocf(_("Request to %s failed: %s"), hostp->hostname, security_geterror(sech)); + } goto error_return; } if (pkt->type == P_NAK) { @@ -1815,6 +1867,7 @@ static void handle_result( } } + dbprintf(_("got reply:\n----\n%s\n----\n\n"), pkt->body); s = pkt->body; ch = *s++; while(ch) { @@ -1931,7 +1984,8 @@ static void handle_result( break; } } - if (i == MAX_LEVELS) { + if (i == MAX_LEVELS && level > 0) { + /* client always report level 0 for some error */ goto bad_msg; /* this est wasn't requested */ } est(dp)->got_estimate++; @@ -2043,7 +2097,7 @@ static void handle_result( est(dp)->estimate[1].nsize > (gint64)0) && (est(dp)->estimate[2].level == -1 || est(dp)->estimate[2].nsize > (gint64)0)))) { - run_server_scripts(EXECUTE_ON_POST_DLE_ESTIMATE, + run_server_dle_scripts(EXECUTE_ON_POST_DLE_ESTIMATE, get_config_name(), dp, est(dp)->estimate[0].level); est(dp)->post_dle = 1; @@ -2052,13 +2106,9 @@ static void handle_result( } if(hostp->up == HOST_DONE) { - for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) { - if (dp->todo) - if (pkt->type == P_REP) { - run_server_scripts(EXECUTE_ON_POST_HOST_ESTIMATE, - get_config_name(), dp, - est(dp)->estimate[0].level); - } + if (pkt->type == P_REP) { + run_server_host_scripts(EXECUTE_ON_POST_HOST_ESTIMATE, + get_config_name(), hostp); } } @@ -2148,7 +2198,7 @@ static void analyze_estimate( ep->degr_est = &default_one_est; if (ep->next_level0 <= 0 || (have_info && ep->last_level == 0 - && (info.command & FORCE_NO_BUMP))) { + && (ISSET(info.command, FORCE_NO_BUMP)))) { if (ep->next_level0 <= 0) { g_fprintf(stderr,_("(due for level 0) ")); } @@ -2208,6 +2258,24 @@ static void analyze_estimate( } } + if (ep->dump_est->level < 0) { + int i; + char *q = quote_string("no estimate"); + + g_fprintf(stderr,_(" no valid estimate\n")); + for(i=0; iestimate[i].level >= 0) { + g_fprintf(stderr,(" level: %d nsize: %lld csize: %lld\n"), + est(dp)->estimate[i].level, + (long long)est(dp)->estimate[i].nsize, + (long long)est(dp)->estimate[i].csize); + } + } + log_add(L_WARNING, _("%s %s %s 0 %s"), dp->host->hostname, qname, + planner_timestamp, q); + amfree(q); + } + g_fprintf(stderr,_(" curr level %d nsize %lld csize %lld "), ep->dump_est->level, (long long)ep->dump_est->nsize, (long long)ep->dump_est->csize); @@ -2224,7 +2292,15 @@ static void analyze_estimate( lev0size = est_tape_size(dp, 0); if(lev0size == (gint64)-1) lev0size = ep->last_lev0size; - balanced_size += (double)(lev0size / (gint64)runs_per_cycle); + if (dp->strategy == DS_NOINC) { + balanced_size += (double)lev0size; + } else if (dp->dumpcycle == 0) { + balanced_size += (double)(lev0size * conf_dumpcycle / (gint64)runs_per_cycle); + } else if (dp->dumpcycle != conf_dumpcycle) { + balanced_size += (double)(lev0size * (conf_dumpcycle / dp->dumpcycle) / (gint64)runs_per_cycle); + } else { + balanced_size += (double)(lev0size / (gint64)runs_per_cycle); + } } g_fprintf(stderr,_("total size %lld total_lev0 %1.0lf balanced-lev0size %1.0lf\n"), @@ -2319,9 +2395,11 @@ static one_est_t *pick_inclevel( /* if we didn't get an estimate, we can't do an inc */ if (base_est->nsize == (gint64)-1) { - bump_est = est_for_level(dp, base_est->level + 1); - if (bump_est->nsize > (gint64)0) /* FORCE_BUMP */ + bump_est = est_for_level(dp, est(dp)->last_level + 1); + if (bump_est->nsize > (gint64)0) { /* FORCE_BUMP */ + g_fprintf(stderr,_(" picklev: bumping to level %d\n"), bump_est->level); return bump_est; + } g_fprintf(stderr,_(" picklev: no estimate for level %d, so no incs\n"), base_est->level); return base_est; } @@ -2423,7 +2501,7 @@ static void delay_dumps(void) for(dp = schedq.head; dp != NULL; dp = ndp) { int avail_tapes = 1; - if (dp->tape_splitsize > (gint64)0) + if (dp->splitsize > (gint64)0 || dp->allow_split) avail_tapes = conf_runtapes; ndp = dp->next; /* remove_disk zaps this */ @@ -2431,7 +2509,7 @@ static void delay_dumps(void) full_size = est_tape_size(dp, 0); if (full_size > tapetype_get_length(tape) * (gint64)avail_tapes) { char *qname = quote_string(dp->name); - if (conf_runtapes > 1 && dp->tape_splitsize == (gint64)0) { + if (conf_runtapes > 1 && dp->splitsize == (gint64)0) { log_add(L_WARNING, _("disk %s:%s, full dump (%lldKB) will be larger than available tape space" ", you could define a splitsize"), dp->host->hostname, qname, @@ -2511,7 +2589,7 @@ static void delay_dumps(void) if(est(dp)->dump_est->level != 0) continue; get_info(dp->host->hostname, dp->name, &info); - if(info.command & FORCE_FULL) { + if(ISSET(info.command, FORCE_FULL)) { nb_forced_level_0 += 1; preserve = dp; continue; @@ -2619,7 +2697,7 @@ static void delay_dumps(void) int avail_tapes = 1; nbi = bi->prev; dp = bi->dp; - if(dp->tape_splitsize > (gint64)0) + if(dp->splitsize > (gint64)0) avail_tapes = conf_runtapes; if(bi->deleted) { @@ -2911,7 +2989,8 @@ static int promote_hills(void) } for(dp = schedq.head; dp != NULL; dp = dp->next) { - days = est(dp)->next_level0; /* This is > 0 by definition */ + days = est(dp)->next_level0; + if (days < 0) days = 0; if(daysskip_full && dp->strategy != DS_NOFULL && dp->strategy != DS_INCRONLY) { sp[days].disks++;