/*
* Amanda, The Advanced Maryland Automatic Network Disk Archiver
* Copyright (c) 1991-1999 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
*/
#include "amanda.h"
#include "arglist.h"
+#include "find.h"
#include "conffile.h"
#include "diskfile.h"
#include "tapefile.h"
double fullcomp, incrcomp;
char *errstr;
char *degr_mesg;
+ info_t *info;
} est_t;
#define est(dp) ((est_t *)(dp)->up)
char *cfg_opt = NULL;
int planner_setuid;
int exit_status = EXIT_SUCCESS;
+ gboolean no_taper = FALSE;
+ gboolean from_client = FALSE;
+ gboolean exact_match = FALSE;
+
+ if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) {
+ printf("planner-%s\n", VERSION);
+ return (0);
+ }
/*
* Configure program for internationalization:
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;
+ }
+ if (argc - diskarg_offset > 0 && g_str_equal(argv[diskarg_offset],
+ "--exact_match")) {
+ exact_match = TRUE;
+ diskarg_offset += 1;
+ }
+
+ run_server_global_scripts(EXECUTE_ON_PRE_ESTIMATE, get_config_name());
/*
* 1. Networking Setup
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);
g_fprintf(stderr, _("%s: timestamp %s\n"),
get_pname(), planner_timestamp);
- errstr = match_disklist(&origq, argc-diskarg_offset,
+ errstr = match_disklist(&origq, exact_match, argc-diskarg_offset,
argv+diskarg_offset);
if (errstr) {
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) {
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) {
continue;
}
+ /* see if this matches the command-line arguments */
+ if (conf_autoflush == 1 &&
+ !match_dumpfile(&file, exact_match, 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);
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"));
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.
disk_t *dp)
{
est_t *ep;
- info_t info;
+ info_t *info;
int i;
char *qname;
int overwrite_runs;
/* get current information about disk */
- if(get_info(dp->host->hostname, dp->name, &info)) {
+ info = g_new0(info_t, 1);
+ if(get_info(dp->host->hostname, dp->name, info)) {
/* no record for this disk, make a note of it */
log_add(L_INFO, _("Adding new disk %s:%s."), dp->host->hostname, qname);
}
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;
ep = alloc(SIZEOF(est_t));
dp->up = (void *) ep;
+ ep->info = info;
ep->state = DISK_READY;
ep->dump_priority = dp->priority;
ep->errstr = 0;
/* calculated fields */
- if (ISSET(info.command, FORCE_FULL)) {
+ if (ISSET(info->command, FORCE_FULL)) {
/* force a level 0, kind of like a new disk */
if(dp->strategy == DS_NOFULL) {
/*
* 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 {
+ CLR(info->command, FORCE_FULL);
+ ep->last_level = last_level(info);
+ ep->next_level0 = next_level0(dp, info);
+ } 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;
else if(dp->strategy == DS_NOFULL) {
/* force estimate of level 1 */
ep->last_level = 1;
- ep->next_level0 = next_level0(dp, &info);
+ ep->next_level0 = next_level0(dp, info);
}
else {
- ep->last_level = last_level(&info);
- ep->next_level0 = next_level0(dp, &info);
+ ep->last_level = last_level(info);
+ ep->next_level0 = next_level0(dp, info);
}
/* adjust priority levels */
/* warn if dump will be overwritten */
- if (ep->last_level > -1 && strlen(info.inf[0].label) > 0) {
- overwrite_runs = when_overwrite(info.inf[0].label);
+ if (ep->last_level > -1 && strlen(info->inf[0].label) > 0) {
+ overwrite_runs = when_overwrite(info->inf[0].label);
if(overwrite_runs == 0) {
log_add(L_WARNING, _("Last full dump of %s:%s "
"on tape %s overwritten on this run."),
- dp->host->hostname, qname, info.inf[0].label);
+ dp->host->hostname, qname, info->inf[0].label);
} else if(overwrite_runs <= RUNS_REDZONE) {
log_add(L_WARNING,
plural(_("Last full dump of %s:%s on tape %s overwritten in %d run."),
_("Last full dump of %s:%s on tape %s overwritten in %d runs."), overwrite_runs),
- dp->host->hostname, qname, info.inf[0].label,
+ dp->host->hostname, qname, info->inf[0].label,
overwrite_runs);
}
}
/* warn if last level 1 will be overwritten */
- if (ep->last_level > 1 && strlen(info.inf[1].label) > 0) {
- overwrite_runs = when_overwrite(info.inf[1].label);
+ if (ep->last_level > 1 && strlen(info->inf[1].label) > 0) {
+ overwrite_runs = when_overwrite(info->inf[1].label);
if(overwrite_runs == 0) {
log_add(L_WARNING, _("Last level 1 dump of %s:%s "
"on tape %s overwritten on this run, resetting to level 1"),
- dp->host->hostname, qname, info.inf[1].label);
+ dp->host->hostname, qname, info->inf[1].label);
ep->last_level = 0;
} else if(overwrite_runs <= RUNS_REDZONE) {
log_add(L_WARNING,
plural(_("Last level 1 dump of %s:%s on tape %s overwritten in %d run."),
_("Last level 1 dump of %s:%s on tape %s overwritten in %d runs."), overwrite_runs),
- dp->host->hostname, qname, info.inf[1].label,
+ dp->host->hostname, qname, info->inf[1].label,
overwrite_runs);
}
}
dp->host->hostname, qname, (-ep->next_level0));
ep->dump_priority -= ep->next_level0;
}
- else if (ISSET(info.command, FORCE_FULL))
+ else if (ISSET(info->command, FORCE_FULL))
ep->dump_priority += 1;
/* else XXX bump up the priority of incrementals that failed last night */
if(dp->skip_full && dp->strategy != DS_NOINC) {
if(ep->next_level0 <= 0) {
/* update the date field */
- info.inf[0].date = today;
- CLR(info.command, FORCE_FULL);
+ info->inf[0].date = today;
+ CLR(info->command, FORCE_FULL);
ep->next_level0 += conf_dumpcycle;
ep->last_level = 0;
- if(put_info(dp->host->hostname, dp->name, &info)) {
+ 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*/
g_fprintf(stderr,_("%s:%s lev 0 skipped due to skip-full flag\n"),
dp->host->hostname, qname);
/* don't enqueue the disk */
- askfor(ep, 0, -1, &info);
- askfor(ep, 1, -1, &info);
- askfor(ep, 2, -1, &info);
+ askfor(ep, 0, -1, info);
+ askfor(ep, 1, -1, info);
+ askfor(ep, 2, -1, info);
g_fprintf(stderr, _("%s: SKIPPED %s %s 0 [skip-full]\n"),
get_pname(), dp->host->hostname, qname);
log_add(L_SUCCESS, _("%s %s %s 0 [skipped: skip-full]"),
}
}
- if(dp->strategy == DS_INCRONLY && ep->last_level == -1 && !ISSET(info.command, FORCE_FULL)) {
+ if(dp->strategy == DS_INCRONLY && ep->last_level == -1 && !ISSET(info->command, FORCE_FULL)) {
/* don't enqueue the disk */
- askfor(ep, 0, -1, &info);
- askfor(ep, 1, -1, &info);
- askfor(ep, 2, -1, &info);
+ askfor(ep, 0, -1, info);
+ askfor(ep, 1, -1, info);
+ askfor(ep, 2, -1, info);
log_add(L_FAIL, _("%s %s 19000101 1 [Skipping incronly because no full dump were done]"),
dp->host->hostname, qname);
g_fprintf(stderr,_("%s:%s lev 1 skipped due to strategy incronly and no full dump were done\n"),
g_fprintf(stderr,_("%s:%s lev 1 skipped due to skip-incr flag\n"),
dp->host->hostname, qname);
/* don't enqueue the disk */
- askfor(ep, 0, -1, &info);
- askfor(ep, 1, -1, &info);
- askfor(ep, 2, -1, &info);
+ askfor(ep, 0, -1, info);
+ askfor(ep, 1, -1, info);
+ askfor(ep, 2, -1, info);
g_fprintf(stderr, _("%s: SKIPPED %s %s 1 [skip-incr]\n"),
get_pname(), dp->host->hostname, qname);
ep->next_level0 = 0;
}
- if(ep->last_level == 0) ep->level_days = 0;
- else ep->level_days = runs_at(&info, ep->last_level);
- ep->last_lev0size = info.inf[0].csize;
+ //if(ep->last_level == 0) ep->level_days = 0;
+ //else ep->level_days = runs_at(info, ep->last_level);
+ ep->level_days = runs_at(info, ep->last_level);
+ ep->last_lev0size = info->inf[0].csize;
- ep->fullrate = perf_average(info.full.rate, 0.0);
- ep->incrrate = perf_average(info.incr.rate, 0.0);
+ ep->fullrate = perf_average(info->full.rate, 0.0);
+ ep->incrrate = perf_average(info->incr.rate, 0.0);
- ep->fullcomp = perf_average(info.full.comp, dp->comprate[0]);
- ep->incrcomp = perf_average(info.incr.comp, dp->comprate[1]);
+ ep->fullcomp = perf_average(info->full.comp, dp->comprate[0]);
+ ep->incrcomp = perf_average(info->incr.comp, dp->comprate[1]);
/* determine which estimates to get */
if (dp->strategy == DS_NOINC ||
(!dp->skip_full &&
- (!ISSET(info.command, FORCE_BUMP) ||
+ (!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);
switch (dp->strategy) {
case DS_STANDARD:
case DS_NOINC:
- askfor(ep, i++, 0, &info);
+ 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);
break;
case DS_INCRONLY:
- if (ISSET(info.command, FORCE_FULL))
+ if (ISSET(info->command, FORCE_FULL))
ep->last_level = 0;
break;
}
if (ep->degr_mesg == NULL)
ep->degr_mesg = _("Skipping: new disk can't be dumped in degraded mode");
if(dp->strategy == DS_NOFULL || dp->strategy == DS_INCRONLY) {
- askfor(ep, i++, 1, &info);
+ askfor(ep, i++, 1, info);
} else {
assert(!dp->skip_full); /* should be handled above */
}
curr_level = ep->last_level;
- if (ISSET(info.command, FORCE_NO_BUMP)) {
+ if (ISSET(info->command, FORCE_NO_BUMP)) {
if(curr_level > 0) { /* level 0 already asked for */
- askfor(ep, i++, curr_level, &info);
+ askfor(ep, i++, curr_level, info);
}
log_add(L_INFO,_("Preventing bump of %s:%s as directed."),
dp->host->hostname, qname);
ep->degr_mesg = _("Skipping: force-no-bump disk can't be dumped in degraded mode");
- } else if (ISSET(info.command, FORCE_BUMP)
+ } else if (ISSET(info->command, FORCE_BUMP)
&& curr_level + 1 < DUMP_LEVELS) {
- askfor(ep, i++, curr_level+1, &info);
+ askfor(ep, i++, curr_level+1, info);
log_add(L_INFO,_("Bumping of %s:%s at level %d as directed."),
dp->host->hostname, qname, curr_level+1);
ep->degr_mesg = _("Skipping: force-bump disk can't be dumped in degraded mode");
} else if (curr_level == 0) {
- askfor(ep, i++, 1, &info);
+ askfor(ep, i++, 1, info);
} else {
- askfor(ep, i++, curr_level, &info);
+ askfor(ep, i++, curr_level, info);
/*
* If last time we dumped less than the threshold, then this
* time we will too, OR the extra size will be charged to both
* if we haven't been at this level 2 days, or the dump failed
* last night, we can't bump.
*/
- if((info.inf[curr_level].size == (gint64)0 || /* no data, try it anyway */
- (((info.inf[curr_level].size > bump_thresh(curr_level, info.inf[0].size,dp->bumppercent, dp->bumpsize, dp->bumpmult)))
+ if((info->inf[curr_level].size == (gint64)0 || /* no data, try it anyway */
+ (((info->inf[curr_level].size > bump_thresh(curr_level, info->inf[0].size,dp->bumppercent, dp->bumpsize, dp->bumpmult)))
&& ep->level_days >= dp->bumpdays))
&& curr_level + 1 < DUMP_LEVELS) {
- askfor(ep, i++, curr_level+1, &info);
+ askfor(ep, i++, curr_level+1, info);
}
- }
+ }
}
}
- while(i < MAX_LEVELS) /* mark end of estimates */
- askfor(ep, i++, -1, &info);
+ while(i < MAX_LEVELS) /* mark end of estimates */
+ askfor(ep, i++, -1, info);
/* debug output */
g_fprintf(stderr, _("setup_estimate: %s:%s: command %u, options: %s "
- "last_level %d next_level0 %d level_days %d getting estimates "
+ "last_level %d next_level0 %d level_days %d getting estimates "
"%d (%lld) %d (%lld) %d (%lld)\n"),
- dp->host->hostname, qname, info.command,
+ dp->host->hostname, qname, info->command,
dp->strategy == DS_NOFULL ? "no-full" :
dp->strategy == DS_INCRONLY ? "incr-only" :
dp->skip_full ? "skip-full" :
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;
}
last = last_level(info);
if(lev != last) return 0;
- if(lev == 0) return 1;
-
if(info->consecutive_runs != -1)
return info->consecutive_runs;
+ if(lev == 0) return 1;
/* to keep compatibility with old infofile */
cur_tape = lookup_tapelabel(info->inf[lev].label);
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);
}
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,
enqueue_disk(&failq, dp);
}
}
+ amfree(b64disk);
+ amfree(b64device);
amfree(qname);
amfree(qdevice);
}
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;
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) {
}
}
+ dbprintf(_("got reply:\n----\n%s\n----\n\n"), pkt->body);
s = pkt->body;
ch = *s++;
while(ch) {
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++;
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;
}
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);
}
}
* reported.
*/
log_add(L_ERROR, "%s", errbuf);
+ for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+ if (dp->todo) {
+ qname = quote_string(dp->name);
+ est(dp)->state = DISK_DONE;
+ remove_disk(&waitq, dp);
+ enqueue_disk(&failq, dp);
+
+ est(dp)->errstr = g_strdup(errbuf);
+ g_fprintf(stderr, _("error result for host %s disk %s: %s\n"),
+ dp->host->hostname, qname, errbuf);
+ amfree(qname);
+ }
+ }
}
hostp->up = HOST_DONE;
amfree(errbuf);
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) "));
}
/* fill in degraded mode info */
g_fprintf(stderr,_("(picking inclevel for degraded mode)"));
ep->degr_est = pick_inclevel(dp);
- if (ep->degr_est->csize == (gint64)-1) {
+ if (ep->degr_est->level >= 0 &&
+ ep->degr_est->csize == (gint64)-1) {
ep->degr_est = est_for_level(dp, ep->degr_est->level + 1);
}
if (ep->degr_est->csize == (gint64)-1) {
}
}
+ if (ep->dump_est->level < 0) {
+ int i;
+ char *q = quote_string("no estimate");
+
+ g_fprintf(stderr,_(" no valid estimate\n"));
+ for(i=0; i<MAX_LEVELS; i++) {
+ if (est(dp)->estimate[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);
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"),
/* 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;
}
disk_t * dp;
disk_t * ndp;
disk_t * preserve;
+ disk_t * delayed_dp;
bi_t * bi;
bi_t * nbi;
gint64 new_total; /* New total_size */
int delete;
char * message;
gint64 full_size;
+ time_t timestamps;
+ int priority;
biq.head = biq.tail = NULL;
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 */
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,
}
else {
delete = 0;
- message = _("full dump delayed");
+ message = _("full dump delayed, doing incremental");
}
}
else {
nb_forced_level_0 = 0;
preserve = NULL;
- for(dp = schedq.head; dp != NULL && preserve == NULL; dp = dp->next)
- if(est(dp)->dump_est->level == 0)
- preserve = dp;
+ timestamps = 2147483647;
+ priority = 0;
+ for(dp = schedq.head; dp != NULL; dp = dp->next) {
+ if (est(dp)->dump_est->level == 0) {
+ if (!preserve ||
+ est(dp)->dump_priority > priority ||
+ (est(dp)->dump_priority == priority &&
+ est(dp)->info->inf[0].date < timestamps)) {
+ priority = est(dp)->dump_priority;
+ timestamps = est(dp)->info->inf[0].date;
+ preserve = dp;
+ }
+ }
+ }
/* 2.a. Do not delay forced full */
- for(dp = schedq.tail;
+ delayed_dp = NULL;
+ do {
+ delayed_dp = 0;
+ timestamps = 0;
+ for(dp = schedq.tail;
dp != NULL && total_size > tape_length;
dp = ndp) {
- ndp = dp->prev;
+ ndp = dp->prev;
- if(est(dp)->dump_est->level != 0) continue;
+ if(est(dp)->dump_est->level != 0) continue;
- get_info(dp->host->hostname, dp->name, &info);
- if(info.command & FORCE_FULL) {
- nb_forced_level_0 += 1;
- preserve = dp;
- continue;
- }
-
- if(dp != preserve) {
+ get_info(dp->host->hostname, dp->name, &info);
+ if(ISSET(info.command, FORCE_FULL)) {
+ nb_forced_level_0 += 1;
+ preserve = dp;
+ continue;
+ }
+ if (dp != preserve &&
+ est(dp)->info->inf[0].date > timestamps) {
+ delayed_dp = dp;
+ timestamps = est(dp)->info->inf[0].date;
+ }
+ }
+ if (delayed_dp) {
/* Format dumpsize for messages */
g_snprintf(est_kb, 20, "%lld KB,",
- (long long)est(dp)->dump_est->csize);
+ (long long)est(delayed_dp)->dump_est->csize);
- if(dp->skip_incr) {
+ if(delayed_dp->skip_incr) {
delete = 1;
message = _("but cannot incremental dump skip-incr disk");
}
- else if(est(dp)->last_level < 0) {
+ else if(est(delayed_dp)->last_level < 0) {
delete = 1;
message = _("but cannot incremental dump new disk");
}
- else if(est(dp)->degr_est->level < 0) {
+ else if(est(delayed_dp)->degr_est->level < 0) {
delete = 1;
message = _("but no incremental estimate");
}
else {
delete = 0;
- message = _("full dump delayed");
+ message = _("full dump delayed, doing incremental");
}
- delay_one_dump(dp, delete, _("dumps too big,"), est_kb,
+ delay_one_dump(delayed_dp, delete, _("dumps too big,"), est_kb,
message, NULL);
}
- }
+ } while (delayed_dp);
/* 2.b. Delay forced full if needed */
if(nb_forced_level_0 > 0 && total_size > tape_length) {
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) {
}
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(days<my_dumpcycle && !dp->skip_full && dp->strategy != DS_NOFULL &&
dp->strategy != DS_INCRONLY) {
sp[days].disks++;