* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: planner.c,v 1.206.2.6 2006/11/24 18:05:06 martinea Exp $
+ * $Id: planner.c 10421 2008-03-06 18:48:30Z martineau $
*
* backup schedule planner for the Amanda backup system.
*/
#include "amanda.h"
#include "arglist.h"
+#include "find.h"
#include "conffile.h"
#include "diskfile.h"
#include "tapefile.h"
#include "amfeatures.h"
#include "server_util.h"
#include "holding.h"
+#include "timestamp.h"
+#include "amxml.h"
+
+#define planner_debug(i,x) do { \
+ if ((i) <= debug_planner) { \
+ dbprintf(x); \
+ } \
+} while (0)
#define MAX_LEVELS 3 /* max# of estimates per filesys */
/* configuration file stuff */
char * conf_tapetype;
-off_t conf_maxdumpsize;
+gint64 conf_maxdumpsize;
int conf_runtapes;
int conf_dumpcycle;
int conf_runspercycle;
#define DISK_PARTIALY_DONE 2
#define DISK_DONE 3
+typedef struct one_est_s {
+ int level;
+ gint64 nsize; /* native size */
+ gint64 csize; /* compressed size */
+ char *dumpdate;
+ int guessed; /* If server guessed the estimate size */
+} one_est_t;
+static one_est_t default_one_est = {-1, -1, -1, "INVALID_DATE", 0};
+
typedef struct est_s {
int state;
int got_estimate;
int dump_priority;
- int dump_level;
- off_t dump_nsize; /* native size */
- off_t dump_csize; /* compressed size */
- int degr_level; /* if dump_level == 0, what would be the inc level */
- off_t degr_nsize; /* native degraded size */
- off_t degr_csize; /* compressed degraded size */
+ one_est_t *dump_est;
+ one_est_t *degr_est;
+ one_est_t estimate[MAX_LEVELS];
int last_level;
- off_t last_lev0size;
+ gint64 last_lev0size;
int next_level0;
int level_days;
int promote;
+ int post_dle;
double fullrate, incrrate;
double fullcomp, incrcomp;
char *errstr;
- int level[MAX_LEVELS];
- char *dumpdate[MAX_LEVELS];
- off_t est_size[MAX_LEVELS];
+ char *degr_mesg;
} est_t;
#define est(dp) ((est_t *)(dp)->up)
/* pestq = partial estimate */
disklist_t startq, waitq, pestq, estq, failq, schedq;
-off_t total_size;
+gint64 total_size;
double total_lev0, balanced_size, balance_threshold;
-off_t tape_length;
+gint64 tape_length;
size_t tape_mark;
tapetype_t *tape;
int deleted; /* 0=modified, 1=deleted */
disk_t *dp; /* The disk that was changed */
int level; /* The original level */
- off_t nsize; /* The original native size */
- off_t csize; /* The original compressed size */
+ gint64 nsize; /* The original native size */
+ gint64 csize; /* The original compressed size */
char *errstr; /* A message describing why this disk is here */
} bi_t;
static int promote_highest_priority_incremental(void);
static int promote_hills(void);
static void output_scheduleline(disk_t *dp);
+static void server_estimate(disk_t *dp, int i, info_t *info, int level);
int main(int, char **);
-int main(int argc, char **argv)
+int
+main(
+ int argc,
+ char ** argv)
{
disklist_t origq;
disk_t *dp;
int moved_one;
- unsigned long malloc_hist_1, malloc_size_1;
- unsigned long malloc_hist_2, malloc_size_2;
- off_t initial_size;
+ int diskarg_offset;
+ gint64 initial_size;
int i;
- char *conffile;
char *conf_diskfile;
char *conf_tapelist;
char *conf_infofile;
times_t section_start;
- uid_t ruid;
char *qname;
- int new_argc, my_argc;
- char **new_argv, **my_argv;
int nb_disk;
char *errstr = NULL;
+ config_overrides_t *cfg_ovr = NULL;
+ char *cfg_opt = NULL;
+ int planner_setuid;
+ int exit_status = EXIT_SUCCESS;
+ gboolean no_taper = FALSE;
+ gboolean from_client = FALSE;
- safe_fd(-1, 0);
-
- setvbuf(stderr, (char *)NULL, (int)_IOLBF, 0);
-
- parse_server_conf(argc, argv, &new_argc, &new_argv);
- my_argc = new_argc;
- my_argv = new_argv;
+ if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) {
+ printf("planner-%s\n", VERSION);
+ return (0);
+ }
- if (my_argc > 1) {
- config_name = stralloc(my_argv[1]);
- config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
- } else {
- char my_cwd[STR_SIZE];
+ /*
+ * Configure program for internationalization:
+ * 1) Only set the message locale for now.
+ * 2) Set textdomain for all amanda related programs to "amanda"
+ * We don't want to be forced to support dozens of message catalogs.
+ */
+ setlocale(LC_MESSAGES, "C");
+ textdomain("amanda");
- if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
- error("cannot determine current working directory");
- /*NOTREACHED*/
- }
- config_dir = stralloc2(my_cwd, "/");
- if ((config_name = strrchr(my_cwd, '/')) != NULL) {
- config_name = stralloc(config_name + 1);
- }
- }
+ /* drop root privileges */
+ planner_setuid = set_root_privs(0);
- safe_cd();
+ safe_fd(-1, 0);
set_pname("planner");
dbopen(DBG_SUBDIR_SERVER);
+ cfg_ovr = extract_commandline_config_overrides(&argc, &argv);
+ if (argc > 1)
+ cfg_opt = argv[1];
+
+ set_config_overrides(cfg_ovr);
+ config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD, cfg_opt);
+
+ /* conf_diskfile is freed later, as it may be used in an error message */
+ conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
+ read_diskfile(conf_diskfile, &origq);
+ disable_skip_disk(&origq);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- malloc_size_1 = malloc_inuse(&malloc_hist_1);
+ setvbuf(stderr, (char *)NULL, (int)_IOLBF, 0);
+
+ add_amanda_log_handler(amanda_log_stderr);
+ add_amanda_log_handler(amanda_log_trace_log);
+
+ if (!planner_setuid) {
+ error(_("planner must be run setuid root"));
+ }
+
+ if (config_errors(NULL) >= CFGERR_ERRORS) {
+ g_critical(_("errors processing config file"));
+ }
+
+ safe_cd();
+
+ check_running_as(RUNNING_AS_ROOT | RUNNING_AS_UID_ONLY);
+
+ dbrename(get_config_name(), DBG_SUBDIR_SERVER);
- erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
- set_logerror(logerror);
startclock();
section_start = curclock();
our_features = am_init_feature_set();
our_feature_string = am_feature_to_string(our_features);
- fprintf(stderr, "%s: pid %ld executable %s version %s\n",
- get_pname(), (long) getpid(), my_argv[0], version());
+ log_add(L_INFO, "%s pid %ld", get_pname(), (long)getpid());
+ g_fprintf(stderr, _("%s: pid %ld executable %s version %s\n"),
+ get_pname(), (long) getpid(), argv[0], VERSION);
for (i = 0; version_info[i] != NULL; i++)
- fprintf(stderr, "%s: %s", get_pname(), version_info[i]);
+ g_fprintf(stderr, _("%s: %s"), get_pname(), version_info[i]);
- /*
- * 1. Networking Setup
- *
- * Planner runs setuid to get a priviledged socket for BSD security.
- * We get the socket right away as root, then set euid to normal
- * user. Keeping saved uid as root.
- */
+ diskarg_offset = 2;
+ 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;
+ }
- protocol_init();
- ruid = getuid();
- if(geteuid() == 0) {
- seteuid(ruid);
- setgid(getgid());
- }
+ run_server_global_scripts(EXECUTE_ON_PRE_ESTIMATE, get_config_name());
/*
- * From this point on we are running under our real uid, so we don't
- * have to worry about opening security holes below. Make sure we
- * are a valid user.
+ * 1. Networking Setup
+ *
*/
- if(getpwuid(getuid()) == NULL) {
- error("can't get login name for my uid %ld", (long)getuid());
- /*NOTREACHED*/
- }
+ protocol_init();
/*
* 2. Read in Configuration Information
* All the Amanda configuration files are loaded before we begin.
*/
- fprintf(stderr,"READING CONF FILES...\n");
-
- conffile = stralloc2(config_dir, CONFFILE_NAME);
- if(read_conffile(conffile)) {
- error("errors processing config file \"%s\"", conffile);
- /*NOTREACHED*/
- }
- amfree(conffile);
-
- dbrename(config_name, DBG_SUBDIR_SERVER);
-
- report_bad_conf_arg();
+ g_fprintf(stderr,_("READING CONF INFO...\n"));
- conf_diskfile = getconf_str(CNF_DISKFILE);
- if (*conf_diskfile == '/') {
- conf_diskfile = stralloc(conf_diskfile);
- } else {
- conf_diskfile = stralloc2(config_dir, conf_diskfile);
- }
- if (read_diskfile(conf_diskfile, &origq) < 0) {
- error("could not load disklist \"%s\"", conf_diskfile);
- /*NOTREACHED*/
- }
if(origq.head == NULL) {
- error("empty disklist \"%s\"", conf_diskfile);
+ error(_("empty disklist \"%s\""), conf_diskfile);
/*NOTREACHED*/
}
- errstr = match_disklist(&origq, my_argc-2, my_argv+2);
- if (errstr) {
- fprintf(stderr,"%s",errstr);
- amfree(errstr);
- }
- nb_disk = 0;
- for(dp = origq.head; dp != NULL; dp = dp->next) {
- if(dp->todo) {
- qname = quote_string(dp->name);
- log_add(L_DISK, "%s %s", dp->host->hostname, qname);
- amfree(qname);
- nb_disk++;
- }
- }
-
- if(nb_disk == 0) {
- error("no DLE to backup");
- /*NOTREACHED*/
- }
amfree(conf_diskfile);
- conf_tapelist = getconf_str(CNF_TAPELIST);
- if (*conf_tapelist == '/') {
- conf_tapelist = stralloc(conf_tapelist);
- } else {
- conf_tapelist = stralloc2(config_dir, conf_tapelist);
- }
+ conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST));
if(read_tapelist(conf_tapelist)) {
- error("could not load tapelist \"%s\"", conf_tapelist);
+ error(_("could not load tapelist \"%s\""), conf_tapelist);
/*NOTREACHED*/
}
amfree(conf_tapelist);
- conf_infofile = getconf_str(CNF_INFOFILE);
- if (*conf_infofile == '/') {
- conf_infofile = stralloc(conf_infofile);
- } else {
- conf_infofile = stralloc2(config_dir, conf_infofile);
- }
+ conf_infofile = config_dir_relative(getconf_str(CNF_INFOFILE));
if(open_infofile(conf_infofile)) {
- error("could not open info db \"%s\"", conf_infofile);
+ error(_("could not open info db \"%s\""), conf_infofile);
/*NOTREACHED*/
}
if (check_infofile(conf_infofile, &origq, &errstr) == -1) {
amfree(conf_infofile);
conf_tapetype = getconf_str(CNF_TAPETYPE);
- conf_maxdumpsize = getconf_am64(CNF_MAXDUMPSIZE);
+ conf_maxdumpsize = getconf_int64(CNF_MAXDUMPSIZE);
conf_runtapes = getconf_int(CNF_RUNTAPES);
conf_dumpcycle = getconf_int(CNF_DUMPCYCLE);
conf_runspercycle = getconf_int(CNF_RUNSPERCYCLE);
conf_tapecycle = getconf_int(CNF_TAPECYCLE);
- conf_etimeout = getconf_int(CNF_ETIMEOUT);
+ 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);
- amfree(planner_timestamp);
today = time(0);
- if(conf_usetimestamps == 0) {
- planner_timestamp = construct_datestamp(NULL);
+ if (planner_timestamp) {
+ if (conf_usetimestamps == 0) {
+ planner_timestamp[8] = '\0';
+ }
+ } else if(conf_usetimestamps == 0) {
+ planner_timestamp = get_datestamp_from_time(0);
}
else {
- planner_timestamp = construct_timestamp(NULL);
+ planner_timestamp = get_timestamp_from_time(0);
}
- log_add(L_START, "date %s", planner_timestamp);
- printf("DATE %s\n", planner_timestamp);
+ log_add(L_START, _("date %s"), planner_timestamp);
+ g_printf("DATE %s\n", planner_timestamp);
fflush(stdout);
- fprintf(stderr, "%s: timestamp %s\n",
+ g_fprintf(stderr, _("%s: timestamp %s\n"),
get_pname(), planner_timestamp);
+ errstr = match_disklist(&origq, 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) {
+ qname = quote_string(dp->name);
+ log_add(L_DISK, "%s %s", dp->host->hostname, qname);
+ amfree(qname);
+ nb_disk++;
+ }
+ }
+
+ if (nb_disk == 0) {
+ if (errstr) {
+ error(_("no DLE to backup; %s"), errstr);
+ } else {
+ error(_("no DLE to backup"));
+ }
+ /*NOTREACHED*/
+ } else if (errstr) {
+ log_add(L_WARNING, "WARNING: %s", errstr);
+ }
+ amfree(errstr);
+
/* some initializations */
if(conf_runspercycle == 0) {
* do some basic sanity checking
*/
if(conf_tapecycle <= runs_per_cycle) {
- log_add(L_WARNING, "tapecycle (%d) <= runspercycle (%d)",
+ log_add(L_WARNING, _("tapecycle (%d) <= runspercycle (%d)"),
conf_tapecycle, runs_per_cycle);
}
tape = lookup_tapetype(conf_tapetype);
- if(conf_maxdumpsize > (off_t)0) {
- tape_length = (off_t)conf_maxdumpsize;
+ if(conf_maxdumpsize > (gint64)0) {
+ tape_length = conf_maxdumpsize;
+ g_fprintf(stderr, "planner: tape_length is set from maxdumpsize (%jd KB)\n",
+ (intmax_t)conf_maxdumpsize);
}
else {
- tape_length = tapetype_get_length(tape) * (off_t)conf_runtapes;
+ tape_length = tapetype_get_length(tape) * (gint64)conf_runtapes;
+ g_fprintf(stderr, "planner: tape_length is set from tape length (%jd KB) * runtapes (%d) == %jd KB\n",
+ (intmax_t)tapetype_get_length(tape),
+ conf_runtapes,
+ (intmax_t)tape_length);
}
tape_mark = (size_t)tapetype_get_filemark(tape);
tt_blocksize_kb = (size_t)tapetype_get_blocksize(tape);
tt_blocksize = tt_blocksize_kb * 1024;
- fprintf(stderr, "%s: time %s: startup took %s secs\n",
+ g_fprintf(stderr, _("%s: time %s: startup took %s secs\n"),
get_pname(),
walltime_str(curclock()),
walltime_str(timessub(curclock(), section_start)));
* dump schedule.
*/
- fprintf(stderr,"\nSENDING FLUSHES...\n");
+ g_fprintf(stderr,_("\nSENDING FLUSHES...\n"));
+
+ if(conf_autoflush && !no_taper) {
+ dumpfile_t file;
+ GSList *holding_list, *holding_file;
+ char *qdisk, *qhname;
- if(conf_autoflush) {
- dumpfile_t file;
- sl_t *holding_list;
- sle_t *holding_file;
- holding_list = get_flush(NULL, NULL, 0, 0);
- for(holding_file=holding_list->first; holding_file != NULL;
+ /* 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) {
- get_dumpfile(holding_file->name, &file);
-
- log_add(L_DISK, "%s %s", file.name, file.disk);
- fprintf(stderr,
+ holding_file_get_dumpfile((char *)holding_file->data, &file);
+
+ if (holding_file_size((char *)holding_file->data, 1) <= 0) {
+ log_add(L_INFO, "%s: removing file with no data.",
+ (char *)holding_file->data);
+ holding_file_unlink((char *)holding_file->data);
+ dumpfile_free_data(&file);
+ 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);
+ g_fprintf(stderr,
"FLUSH %s %s %s %d %s\n",
file.name,
- file.disk,
+ qdisk,
file.datestamp,
file.dumplevel,
- holding_file->name);
- fprintf(stdout,
+ qhname);
+ g_fprintf(stdout,
"FLUSH %s %s %s %d %s\n",
file.name,
- file.disk,
+ qdisk,
file.datestamp,
file.dumplevel,
- holding_file->name);
+ qhname);
+ amfree(qdisk);
+ amfree(qhname);
+ dumpfile_free_data(&file);
}
- free_sl(holding_list);
+ slist_free_full(holding_list, g_free);
holding_list = NULL;
}
- fprintf(stderr, "ENDFLUSH\n");
- fprintf(stdout, "ENDFLUSH\n");
+ g_fprintf(stderr, _("ENDFLUSH\n"));
+ g_fprintf(stdout, _("ENDFLUSH\n"));
fflush(stdout);
/*
* based on the curinfo database.
*/
- fprintf(stderr,"\nSETTING UP FOR ESTIMATES...\n");
+ g_fprintf(stderr,_("\nSETTING UP FOR ESTIMATES...\n"));
section_start = curclock();
startq.head = startq.tail = NULL;
}
}
- fprintf(stderr, "%s: time %s: setting up estimates took %s secs\n",
+ g_fprintf(stderr, _("%s: time %s: setting up estimates took %s secs\n"),
get_pname(),
walltime_str(curclock()),
walltime_str(timessub(curclock(), section_start)));
/* go out and get the dump estimates */
- fprintf(stderr,"\nGETTING ESTIMATES...\n");
+ g_fprintf(stderr,_("\nGETTING ESTIMATES...\n"));
section_start = curclock();
estq.head = estq.tail = NULL;
get_estimates();
- fprintf(stderr, "%s: time %s: getting estimates took %s secs\n",
+ g_fprintf(stderr, _("%s: time %s: getting estimates took %s secs\n"),
get_pname(),
walltime_str(curclock()),
walltime_str(timessub(curclock(), section_start)));
dump_queue("FAILED", failq, 15, stderr);
dump_queue("DONE", estq, 15, stderr);
+ if (!empty(failq)) {
+ exit_status = EXIT_FAILURE;
+ }
/*
* 6. Analyze Dump Estimates
* total expected size is accumulated as well.
*/
- fprintf(stderr,"\nANALYZING ESTIMATES...\n");
+ g_fprintf(stderr,_("\nANALYZING ESTIMATES...\n"));
section_start = curclock();
/* an empty tape still has a label and an endmark */
- total_size = ((off_t)tt_blocksize_kb + (off_t)tape_mark) * (off_t)2;
+ total_size = ((gint64)tt_blocksize_kb + (gint64)tape_mark) * (gint64)2;
total_lev0 = 0.0;
balanced_size = 0.0;
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;
- fprintf(stderr, "INITIAL SCHEDULE (size " OFF_T_FMT "):\n",
- (OFF_T_FMT_TYPE)total_size);
+ g_fprintf(stderr, _("INITIAL SCHEDULE (size %lld):\n"),
+ (long long)total_size);
for(dp = schedq.head; dp != NULL; dp = dp->next) {
qname = quote_string(dp->name);
- fprintf(stderr, " %s %s pri %d lev %d nsize " OFF_T_FMT " csize " OFF_T_FMT "\n",
+ g_fprintf(stderr, _(" %s %s pri %d lev %d nsize %lld csize %lld\n"),
dp->host->hostname, qname, est(dp)->dump_priority,
- est(dp)->dump_level,
- (OFF_T_FMT_TYPE)est(dp)->dump_nsize,
- (OFF_T_FMT_TYPE)est(dp)->dump_csize);
+ est(dp)->dump_est->level,
+ (long long)est(dp)->dump_est->nsize,
+ (long long)est(dp)->dump_est->csize);
amfree(qname);
}
}
* until the dumps fit on the tape.
*/
- fprintf(stderr, "\nDELAYING DUMPS IF NEEDED, total_size " OFF_T_FMT
- ", tape length " OFF_T_FMT " mark " SIZE_T_FMT "\n",
- (OFF_T_FMT_TYPE)total_size,
- (OFF_T_FMT_TYPE)tape_length,
- (SIZE_T_FMT_TYPE)tape_mark);
+ g_fprintf(stderr, _("\nDELAYING DUMPS IF NEEDED, total_size %lld, tape length %lld mark %zu\n"),
+ (long long)total_size,
+ (long long)tape_length,
+ tape_mark);
initial_size = total_size;
/* XXX - why bother checking this? */
if(empty(schedq) && total_size < initial_size) {
- error("cannot fit anything on tape, bailing out");
+ error(_("cannot fit anything on tape, bailing out"));
/*NOTREACHED*/
}
* a big bump.
*/
- fprintf(stderr,
- "\nPROMOTING DUMPS IF NEEDED, total_lev0 %1.0lf, balanced_size %1.0lf...\n",
+ g_fprintf(stderr,
+ _("\nPROMOTING DUMPS IF NEEDED, total_lev0 %1.0lf, balanced_size %1.0lf...\n"),
total_lev0, balanced_size);
balance_threshold = balanced_size * PROMOTE_THRESHOLD;
moved_one = promote_hills();
- fprintf(stderr, "%s: time %s: analysis took %s secs\n",
+ g_fprintf(stderr, _("%s: time %s: analysis took %s secs\n"),
get_pname(),
walltime_str(curclock()),
walltime_str(timessub(curclock(), section_start)));
- /* done with prvileged ops, make sure root privilege is dropped */
- if ( geteuid() == 0 ) {
- setuid(ruid);
- seteuid(ruid);
- }
-
/*
* 9. Output Schedule
*
* on stderr for the debug file.
*/
- fprintf(stderr,"\nGENERATING SCHEDULE:\n--------\n");
-
- while(!empty(schedq)) output_scheduleline(dequeue_disk(&schedq));
- fprintf(stderr, "--------\n");
+ g_fprintf(stderr,_("\nGENERATING SCHEDULE:\n--------\n"));
+ if (empty(schedq)) {
+ exit_status = EXIT_FAILURE;
+ g_fprintf(stderr, _("--> Generated empty schedule! <--\n"));
+ } else {
+ while(!empty(schedq)) output_scheduleline(dequeue_disk(&schedq));
+ }
+ g_fprintf(stderr, _("--------\n"));
close_infofile();
- log_add(L_FINISH, "date %s time %s", planner_timestamp, walltime_str(curclock()));
+ log_add(L_FINISH, _("date %s time %s"), planner_timestamp, walltime_str(curclock()));
+ log_add(L_INFO, "pid-done %ld", (long)getpid());
clear_tapelist();
- free_new_argv(new_argc, new_argv);
- free_server_config();
amfree(planner_timestamp);
- amfree(config_dir);
- amfree(config_name);
amfree(our_feature_string);
am_release_feature_set(our_features);
our_features = NULL;
- malloc_size_2 = malloc_inuse(&malloc_hist_2);
-
- if(malloc_size_1 != malloc_size_2) {
- malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
- }
-
dbclose();
- return 0;
+ return exit_status;
}
static void askfor(est_t *, int, int, info_t *);
static int last_level(info_t *info); /* subroutines */
-static off_t est_size(disk_t *dp, int level);
-static off_t est_tape_size(disk_t *dp, int level);
+static one_est_t *est_for_level(disk_t *dp, int level);
+static void est_csize(disk_t *dp, one_est_t *one_est);
+static gint64 est_tape_size(disk_t *dp, int level);
static int next_level0(disk_t *dp, info_t *info);
static int runs_at(info_t *info, int lev);
-static off_t bump_thresh(int level, off_t size_level_0, int bumppercent, off_t bumpsize, double bumpmult);
+static gint64 bump_thresh(int level, gint64 size_level_0, int bumppercent, gint64 bumpsize, double bumpmult);
static int when_overwrite(char *label);
static void askfor(
info_t *info) /* info block for disk */
{
if(seq < 0 || seq >= MAX_LEVELS) {
- error("error [planner askfor: seq out of range 0..%d: %d]",
+ error(_("error [planner askfor: seq out of range 0..%d: %d]"),
MAX_LEVELS, seq);
/*NOTREACHED*/
}
if(lev < -1 || lev >= DUMP_LEVELS) {
- error("error [planner askfor: lev out of range -1..%d: %d]",
+ error(_("error [planner askfor: lev out of range -1..%d: %d]"),
DUMP_LEVELS, lev);
/*NOTREACHED*/
}
if (lev == -1) {
- ep->level[seq] = -1;
- ep->dumpdate[seq] = (char *)0;
- ep->est_size[seq] = (off_t)-2;
+ ep->estimate[seq].level = -1;
+ ep->estimate[seq].dumpdate = (char *)0;
+ ep->estimate[seq].nsize = (gint64)-3;
+ ep->estimate[seq].csize = (gint64)-3;
+ ep->estimate[seq].guessed = 0;
return;
}
- ep->level[seq] = lev;
+ ep->estimate[seq].level = lev;
- ep->dumpdate[seq] = stralloc(get_dumpdate(info,lev));
- malloc_mark(ep->dumpdate[seq]);
+ ep->estimate[seq].dumpdate = stralloc(get_dumpdate(info,lev));
- ep->est_size[seq] = (off_t)-2;
+ ep->estimate[seq].nsize = (gint64)-3;
+ ep->estimate[seq].csize = (gint64)-3;
+ ep->estimate[seq].guessed = 0;
return;
}
assert(dp && dp->host);
qname = quote_string(dp->name);
- fprintf(stderr, "%s: time %s: setting up estimates for %s:%s\n",
+ g_fprintf(stderr, _("%s: time %s: setting up estimates for %s:%s\n"),
get_pname(), walltime_str(curclock()),
dp->host->hostname, qname);
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, dp->name);
+ log_add(L_INFO, _("Adding new disk %s:%s."), dp->host->hostname, qname);
+ }
+
+ if (dp->data_path == DATA_PATH_DIRECTTCP) {
+ if (dp->compress != COMP_NONE) {
+ log_add(L_FAIL, _("%s %s %s 0 [Can't compress directtcp data-path]"),
+ dp->host->hostname, qname, planner_timestamp);
+ g_fprintf(stderr,_("%s:%s lev 0 skipped can't compress directtcp data-path\n"),
+ dp->host->hostname, qname);
+ amfree(qname);
+ return;
+ }
+ if (dp->encrypt != ENCRYPT_NONE) {
+ log_add(L_FAIL, _("%s %s %s 0 [Can't encrypt directtcp data-path]"),
+ dp->host->hostname, qname, planner_timestamp);
+ g_fprintf(stderr,_("%s:%s lev 0 skipped can't encrypt directtcp data-path\n"),
+ dp->host->hostname, qname);
+ amfree(qname);
+ return;
+ }
+ if (dp->to_holdingdisk == HOLD_REQUIRED) {
+ log_add(L_FAIL, _("%s %s %s 0 [Holding disk can't be use for directtcp data-path]"),
+ dp->host->hostname, qname, planner_timestamp);
+ g_fprintf(stderr,_("%s:%s lev 0 skipped Holding disk can't be use for directtcp data-path\n"),
+ dp->host->hostname, qname);
+ amfree(qname);
+ return;
+ } else if (dp->to_holdingdisk == HOLD_AUTO) {
+ g_fprintf(stderr,_("%s:%s Disabling holding disk\n"),
+ dp->host->hostname, qname);
+ dp->to_holdingdisk = HOLD_NEVER;
+ }
}
/* setup working data struct for disk */
ep = alloc(SIZEOF(est_t));
- malloc_mark(ep);
dp->up = (void *) ep;
ep->state = DISK_READY;
- ep->dump_nsize = (off_t)-1;
- ep->dump_csize = (off_t)-1;
ep->dump_priority = dp->priority;
ep->errstr = 0;
ep->promote = 0;
+ ep->post_dle = 0;
+ ep->degr_mesg = NULL;
+ ep->dump_est = &default_one_est;
+ ep->degr_est = &default_one_est;
/* calculated fields */
* hosed when that tape gets re-used next. Disallow this for
* now.
*/
- log_add(L_ERROR,
- "Cannot force full dump of %s:%s with no-full option.",
+ 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;
- log_add(L_INFO, "Forcing full dump of %s:%s as directed.",
+ log_add(L_INFO, _("Forcing full dump of %s:%s as directed."),
dp->host->hostname, qname);
}
}
/* adjust priority levels */
/* warn if dump will be overwritten */
- if(ep->last_level > -1) {
+ 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.",
+ 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);
- }
- else if(overwrite_runs <= RUNS_REDZONE) {
- log_add(L_WARNING, "Last full dump of %s:%s on "
- "tape %s overwritten in %d run%s.",
+ } 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,
- overwrite_runs, overwrite_runs == 1? "" : "s");
+ 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(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);
+ 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,
+ overwrite_runs);
}
}
if(ep->next_level0 < 0) {
- fprintf(stderr,"%s:%s overdue %d day%s for level 0\n",
- dp->host->hostname, qname,
- - ep->next_level0, ((- ep->next_level0) == 1) ? "" : "s");
+ g_fprintf(stderr,plural(_("%s:%s overdue %d day for level 0\n"),
+ _("%s:%s overdue %d days for level 0\n"),
+ (-ep->next_level0)),
+ dp->host->hostname, qname, (-ep->next_level0));
ep->dump_priority -= ep->next_level0;
}
else if (ISSET(info.command, FORCE_FULL))
ep->next_level0 += conf_dumpcycle;
ep->last_level = 0;
if(put_info(dp->host->hostname, dp->name, &info)) {
- error("could not put info record for %s:%s: %s",
+ error(_("could not put info record for %s:%s: %s"),
dp->host->hostname, qname, strerror(errno));
/*NOTREACHED*/
}
- log_add(L_INFO, "Skipping full dump of %s:%s today.",
+ log_add(L_INFO, _("Skipping full dump of %s:%s today."),
dp->host->hostname, qname);
- fprintf(stderr,"%s:%s lev 0 skipped due to skip-full flag\n",
+ 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);
- fprintf(stderr, "%s: SKIPPED %s %s 0 [skip-full]\n",
+ 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]",
+ log_add(L_SUCCESS, _("%s %s %s 0 [skipped: skip-full]"),
dp->host->hostname, qname, planner_timestamp);
amfree(qname);
return;
}
if(ep->next_level0 == 1) {
- log_add(L_WARNING, "Skipping full dump of %s:%s tomorrow.",
+ log_add(L_WARNING, _("Skipping full dump of %s:%s tomorrow."),
dp->host->hostname, qname);
}
}
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]",
+ log_add(L_FAIL, _("%s %s 19000101 1 [Skipping incronly because no full dump were done]"),
dp->host->hostname, qname);
- 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 strategy incronly and no full dump were done\n"),
dp->host->hostname, qname);
amfree(qname);
return;
/* handle "skip-incr" type archives */
if(dp->skip_incr && ep->next_level0 > 0) {
- fprintf(stderr,"%s:%s lev 1 skipped due to skip-incr flag\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);
- fprintf(stderr, "%s: SKIPPED %s %s 1 [skip-incr]\n",
+ g_fprintf(stderr, _("%s: SKIPPED %s %s 1 [skip-incr]\n"),
get_pname(), dp->host->hostname, qname);
- log_add(L_SUCCESS, "%s %s %s 1 [skipped: skip-incr]",
+ log_add(L_SUCCESS, _("%s %s %s 1 [skipped: skip-incr]"),
dp->host->hostname, qname, planner_timestamp);
amfree(qname);
return;
if( ep->last_level == -1 && ep->next_level0 > 0 &&
dp->strategy != DS_NOFULL && dp->strategy != DS_INCRONLY &&
conf_reserve == 100) {
- log_add(L_WARNING, "%s:%s mismatch: no tapelist record, "
- "but curinfo next_level0: %d.",
+ log_add(L_WARNING, _("%s:%s mismatch: no tapelist record, "
+ "but curinfo next_level0: %d."),
dp->host->hostname, qname, ep->next_level0);
ep->next_level0 = 0;
}
(!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.",
+ _("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);
+ 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 "
- "because the strategy is NOINC.",
+ 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.",
+ _("Ignoring FORCE_BUMP for %s:%s because the strategy is NOINC."),
dp->host->hostname, qname);
}
case DS_INCRONLY:
if (ISSET(info.command, FORCE_FULL))
- askfor(ep, i++, 0, &info);
+ ep->last_level = 0;
break;
}
}
if(!dp->skip_incr && !(dp->strategy == DS_NOINC)) {
if(ep->last_level == -1) { /* a new disk */
+ 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);
} else {
if(curr_level > 0) { /* level 0 already asked for */
askfor(ep, i++, curr_level, &info);
}
- log_add(L_INFO,"Preventing bump of %s:%s as directed.",
+ 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)
&& curr_level + 1 < DUMP_LEVELS) {
askfor(ep, i++, curr_level+1, &info);
- log_add(L_INFO,"Bumping of %s:%s at level %d as directed.",
+ 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);
} else {
* 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 == (off_t)0 || /* no data, try it anyway */
+ 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) {
/* debug output */
- fprintf(stderr, "setup_estimate: %s:%s: command %u, options: %s "
+ g_fprintf(stderr, _("setup_estimate: %s:%s: command %u, options: %s "
"last_level %d next_level0 %d level_days %d getting estimates "
- "%d (" OFF_T_FMT ") %d (" OFF_T_FMT ") %d (" OFF_T_FMT ")\n",
+ "%d (%lld) %d (%lld) %d (%lld)\n"),
dp->host->hostname, qname, info.command,
dp->strategy == DS_NOFULL ? "no-full" :
dp->strategy == DS_INCRONLY ? "incr-only" :
dp->skip_full ? "skip-full" :
dp->skip_incr ? "skip-incr" : "none",
ep->last_level, ep->next_level0, ep->level_days,
- ep->level[0], (OFF_T_FMT_TYPE)ep->est_size[0],
- ep->level[1], (OFF_T_FMT_TYPE)ep->est_size[1],
- ep->level[2], (OFF_T_FMT_TYPE)ep->est_size[2]);
+ ep->estimate[0].level, (long long)ep->estimate[0].nsize,
+ ep->estimate[1].level, (long long)ep->estimate[1].nsize,
+ ep->estimate[2].level, (long long)ep->estimate[2].nsize);
- assert(ep->level[0] != -1);
+ assert(ep->estimate[0].level != -1);
enqueue_disk(&startq, dp);
amfree(qname);
}
}
/* Return the estimated size for a particular dump */
-static off_t est_size(
+static one_est_t *
+est_for_level(
disk_t *dp,
int level)
{
int i;
- for(i = 0; i < MAX_LEVELS; i++) {
- if(level == est(dp)->level[i])
- return est(dp)->est_size[i];
+ if (level < 0 || level >= DUMP_LEVELS)
+ return &default_one_est;
+
+ for (i = 0; i < MAX_LEVELS; i++) {
+ if (level == est(dp)->estimate[i].level) {
+ if (est(dp)->estimate[i].csize <= -1) {
+ est_csize(dp, &est(dp)->estimate[i]);
+ }
+ return &est(dp)->estimate[i];
+ }
}
- return (off_t)-1;
+ return &default_one_est;
}
/* Return the estimated on-tape size of a particular dump */
-static off_t est_tape_size(
- disk_t *dp,
- int level)
+static void
+est_csize(
+ disk_t *dp,
+ one_est_t *one_est)
{
- off_t size;
+ gint64 size = one_est->nsize;
double ratio;
- size = est_size(dp, level);
-
- if(size == (off_t)-1) return size;
-
- if(dp->compress == COMP_NONE)
- return size;
+ if (dp->compress == COMP_NONE) {
+ one_est->csize = one_est->nsize;
+ return;
+ }
- if(level == 0) ratio = est(dp)->fullcomp;
+ if (one_est->level == 0) ratio = est(dp)->fullcomp;
else ratio = est(dp)->incrcomp;
/*
* (RUG@USM.Uni-Muenchen.DE)
*/
- if(ratio > 1.1) ratio = 1.1;
+ if (ratio > 1.1) ratio = 1.1;
- size = (off_t)((double)size * ratio);
+ size = (gint64)((double)size * ratio);
/*
* Ratio can be very small in some error situations, so make sure
* size goes back greater than zero. It may not be right, but
* indicates we did get an estimate.
*/
- if(size <= (off_t)0) {
- size = (off_t)1;
+ if (size <= (gint64)0) {
+ size = (gint64)1;
}
- return size;
+ one_est->csize = size;
+}
+
+static gint64 est_tape_size(
+ disk_t *dp,
+ int level)
+{
+ one_est_t *dump_est;
+
+ dump_est = est_for_level(dp, level);
+ if (dump_est->level >= 0 && dump_est->csize <= -1)
+ est_csize(dp, dump_est);
+ return dump_est->csize;
}
}
-static off_t bump_thresh(
+static gint64 bump_thresh(
int level,
- off_t size_level_0,
+ gint64 size_level_0,
int bumppercent,
- off_t bumpsize,
+ gint64 bumpsize,
double bumpmult)
{
double bump;
- if ((bumppercent != 0) && (size_level_0 > (off_t)1024)) {
+ if ((bumppercent != 0) && (size_level_0 > (gint64)1024)) {
bump = ((double)size_level_0 * (double)bumppercent) / 100.0;
}
else {
}
while(--level) bump = bump * bumpmult;
- return (off_t)bump;
+ return (gint64)bump;
}
static void get_estimates(void)
{
am_host_t *hostp;
- disk_t *dp;
+ disk_t *dp, *dp1;
int something_started;
something_started = 1;
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_dle_scripts(EXECUTE_ON_PRE_DLE_ESTIMATE,
+ get_config_name(), dp1,
+ est(dp1)->estimate[0].level);
+ }
getsize(hostp);
protocol_check();
/*
while(!empty(waitq)) {
disk_t *dp = dequeue_disk(&waitq);
- est(dp)->errstr = "hmm, disk was stranded on waitq";
+ est(dp)->errstr = _("hmm, disk was stranded on waitq");
enqueue_disk(&failq, dp);
}
while(!empty(pestq)) {
disk_t *dp = dequeue_disk(&pestq);
char * qname = quote_string(dp->name);
-
- if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < (off_t)0) {
- if(est(dp)->est_size[0] == (off_t)-1) {
- log_add(L_WARNING, "disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, qname, est(dp)->level[0]);
- }
- else {
- log_add(L_WARNING,
- "disk %s:%s, estimate of level %d timed out.",
- dp->host->hostname, qname, est(dp)->level[0]);
- }
- est(dp)->level[0] = -1;
- }
-
- if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < (off_t)0) {
- if(est(dp)->est_size[1] == (off_t)-1) {
- log_add(L_WARNING,
- "disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, qname, est(dp)->level[1]);
- }
- else {
- log_add(L_WARNING,
- "disk %s:%s, estimate of level %d timed out.",
- dp->host->hostname, qname, est(dp)->level[1]);
- }
- est(dp)->level[1] = -1;
- }
-
- if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < (off_t)0) {
- if(est(dp)->est_size[2] == (off_t)-1) {
- log_add(L_WARNING,
- "disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, qname, est(dp)->level[2]);
- }
- else {
- log_add(L_WARNING,
- "disk %s:%s, estimate of level %d timed out.",
- dp->host->hostname, qname, est(dp)->level[2]);
- }
- est(dp)->level[2] = -1;
- }
-
- if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > (off_t)0) ||
- (est(dp)->level[1] != -1 && est(dp)->est_size[1] > (off_t)0) ||
- (est(dp)->level[2] != -1 && est(dp)->est_size[2] > (off_t)0)) {
+ int i;
+
+ for (i=0; i < MAX_LEVELS; i++) {
+ if (est(dp)->estimate[i].level != -1 &&
+ est(dp)->estimate[i].nsize < (gint64)0) {
+ if (est(dp)->estimate[i].nsize == (gint64)-3) {
+ log_add(L_WARNING,
+ _("disk %s:%s, estimate of level %d timed out."),
+ dp->host->hostname, qname, est(dp)->estimate[i].level);
+ }
+ est(dp)->estimate[i].level = -1;
+ }
+ }
+
+ if ((est(dp)->estimate[0].level != -1 &&
+ est(dp)->estimate[0].nsize > (gint64)0) ||
+ (est(dp)->estimate[1].level != -1 &&
+ est(dp)->estimate[1].nsize > (gint64)0) ||
+ (est(dp)->estimate[2].level != -1 &&
+ est(dp)->estimate[2].nsize > (gint64)0)) {
enqueue_disk(&estq, dp);
}
else {
est(dp)->errstr = vstralloc("disk ", qname,
- ", all estimate timed out", NULL);
+ _(", all estimate timed out"), NULL);
enqueue_disk(&failq, dp);
}
amfree(qname);
time_t estimates, timeout;
size_t req_len;
const security_driver_t *secdrv;
- char * dumper;
char * calcsize;
- char * qname;
+ char * qname, *b64disk = NULL;
+ char * qdevice, *b64device = NULL;
+ estimate_t estimate;
+ estimatelist_t el;
assert(hostp->disks != NULL);
int has_config = am_has_feature(hostp->features,
fe_req_options_config);
- snprintf(number, SIZEOF(number), "%d", hostp->maxdumps);
+ g_snprintf(number, SIZEOF(number), "%d", hostp->maxdumps);
req = vstralloc("SERVICE ", "sendsize", "\n",
"OPTIONS ",
has_features ? "features=" : "",
has_hostname ? hostp->hostname : "",
has_hostname ? ";" : "",
has_config ? "config=" : "",
- has_config ? config_name : "",
+ has_config ? get_config_name() : "",
has_config ? ";" : "",
"\n",
NULL);
estimates = 0;
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
char *s = NULL;
+ char *es;
size_t s_len = 0;
+ GPtrArray *errarray;
if(dp->todo == 0) continue;
if(est(dp)->state != DISK_READY) continue;
est(dp)->got_estimate = 0;
- if(est(dp)->level[0] == -1) {
+ if (est(dp)->estimate[0].level == -1) {
est(dp)->state = DISK_DONE;
continue;
}
qname = quote_string(dp->name);
- if(dp->estimate == ES_CLIENT ||
- dp->estimate == ES_CALCSIZE) {
- nb_client++;
+ errarray = validate_optionstr(dp);
+ if (errarray->len > 0) {
+ guint i;
+ for (i=0; i < errarray->len; i++) {
+ log_add(L_FAIL, _("%s %s %s 0 [%s]"),
+ dp->host->hostname, qname,
+ planner_timestamp,
+ (char *)g_ptr_array_index(errarray, i));
+ }
+ amfree(qname);
+ est(dp)->state = DISK_DONE;
+ continue;
+ }
+
+ b64disk = amxml_format_tag("disk", dp->name);
+ qdevice = quote_string(dp->device);
+ estimate = (estimate_t)GPOINTER_TO_INT(dp->estimatelist->data);
+ if (dp->device)
+ b64device = amxml_format_tag("diskdevice", dp->device);
+
+ estimate = ES_CLIENT;
+ for (el = dp->estimatelist; el != NULL; el = el->next) {
+ estimate = (estimate_t)GPOINTER_TO_INT(el->data);
+ if (estimate == ES_SERVER)
+ break;
+ }
+ if (estimate == ES_SERVER) {
+ info_t info;
+ nb_server++;
+ get_info(dp->host->hostname, dp->name, &info);
for(i = 0; i < MAX_LEVELS; i++) {
- char *l;
- char *exclude1 = "";
- char *exclude2 = "";
- char *excludefree = NULL;
- char *include1 = "";
- char *include2 = "";
- char *includefree = NULL;
- char spindle[NUM_STR_SIZE];
- char level[NUM_STR_SIZE];
- int lev = est(dp)->level[i];
+ int lev = est(dp)->estimate[i].level;
if(lev == -1) break;
+ server_estimate(dp, i, &info, lev);
+ }
+ g_fprintf(stderr,_("%s time %s: got result for host %s disk %s:"),
+ get_pname(), walltime_str(curclock()),
+ dp->host->hostname, qname);
+ g_fprintf(stderr,_(" %d -> %lldK, %d -> %lldK, %d -> %lldK\n"),
+ est(dp)->estimate[0].level,
+ (long long)est(dp)->estimate[0].nsize,
+ est(dp)->estimate[1].level,
+ (long long)est(dp)->estimate[1].nsize,
+ est(dp)->estimate[2].level,
+ (long long)est(dp)->estimate[2].nsize);
+ if (!am_has_feature(hostp->features, fe_xml_estimate)) {
+ est(dp)->state = DISK_DONE;
+ remove_disk(&startq, dp);
+ enqueue_disk(&estq, dp);
+ }
+ }
+
+ estimate = ES_SERVER;
+ for (el = dp->estimatelist; el != NULL; el = el->next) {
+ estimate = (estimate_t)GPOINTER_TO_INT(el->data);
+ if (estimate == ES_CLIENT || estimate == ES_CALCSIZE)
+ break;
+ }
+ if (estimate == ES_CLIENT ||
+ estimate == ES_CALCSIZE ||
+ (am_has_feature(hostp->features, fe_req_xml) &&
+ am_has_feature(hostp->features, fe_xml_estimate))) {
+ nb_client++;
+ i = 0;
- snprintf(level, SIZEOF(level), "%d", lev);
- snprintf(spindle, SIZEOF(spindle), "%d", dp->spindle);
- if(am_has_feature(hostp->features,fe_sendsize_req_options)){
- exclude1 = " OPTIONS |";
- exclude2 = optionstr(dp, hostp->features, NULL);
- if ( exclude2 == NULL ) {
- error("problem with option string, check the dumptype definition.\n");
+ if (am_has_feature(hostp->features, fe_req_xml)) {
+ char *levelstr = NULL;
+ char *spindlestr = NULL;
+ char level[NUM_STR_SIZE];
+ char spindle[NUM_STR_SIZE];
+ char *o;
+ char *l;
+ info_t info;
+
+ get_info(dp->host->hostname, dp->name, &info);
+ for(i = 0; i < MAX_LEVELS; i++) {
+ char *server;
+ int lev = est(dp)->estimate[i].level;
+ if (lev == -1) break;
+ g_snprintf(level, SIZEOF(level), "%d", lev);
+ if (am_has_feature(hostp->features, fe_xml_level_server) &&
+ server_can_do_estimate(dp, &info, lev)) {
+ server = "<server>YES</server>";
+ } else {
+ server = "";
}
- excludefree = exclude2;
- includefree = NULL;
+ vstrextend(&levelstr, " <level>",
+ level, server,
+ "</level>\n", NULL);
}
- else {
- if(dp->exclude_file &&
- dp->exclude_file->nb_element == 1) {
- exclude1 = " exclude-file=";
- exclude2 =
- quote_string(dp->exclude_file->first->name);
- excludefree = exclude2;
- }
- else if(dp->exclude_list &&
- dp->exclude_list->nb_element == 1) {
- exclude1 = " exclude-list=";
- exclude2 =
- quote_string(dp->exclude_list->first->name);
- excludefree = exclude2;
- }
- if(dp->include_file &&
- dp->include_file->nb_element == 1) {
- include1 = " include-file=";
- include2 =
- quote_string(dp->include_file->first->name);
- includefree = include2;
- }
- else if(dp->include_list &&
- dp->include_list->nb_element == 1) {
- include1 = " include-list=";
- include2 =
- quote_string(dp->include_list->first->name);
- includefree = include2;
+ g_snprintf(spindle, SIZEOF(spindle), "%d", dp->spindle);
+ spindlestr = vstralloc(" <spindle>",
+ spindle,
+ "</spindle>\n", NULL);
+ o = xml_optionstr(dp, 0);
+
+ if (strcmp(dp->program,"DUMP") == 0 ||
+ strcmp(dp->program,"GNUTAR") == 0) {
+ l = vstralloc("<dle>\n",
+ " <program>",
+ dp->program,
+ "</program>\n", NULL);
+ } else {
+ l = vstralloc("<dle>\n",
+ " <program>APPLICATION</program>\n",
+ NULL);
+ if (dp->application) {
+ application_t *application;
+ char *xml_app;
+
+ application = lookup_application(dp->application);
+ g_assert(application != NULL);
+ xml_app = xml_application(dp, application,
+ hostp->features);
+ vstrextend(&l, xml_app, NULL);
+ amfree(xml_app);
}
}
- if(dp->estimate == ES_CALCSIZE &&
- !am_has_feature(hostp->features, fe_calcsize_estimate)) {
- log_add(L_WARNING,"%s:%s does not support CALCSIZE for estimate, using CLIENT.\n",
- hostp->hostname, qname);
- dp->estimate = ES_CLIENT;
- }
- if(dp->estimate == ES_CLIENT)
- calcsize = "";
- else
- calcsize = "CALCSIZE ";
-
- if(strncmp(dp->program,"DUMP",4) == 0 ||
- strncmp(dp->program,"GNUTAR",6) == 0) {
- dumper = "";
- } else {
- dumper = "DUMPER ";
- }
- l = vstralloc(calcsize,
- dumper,
- dp->program,
- " ", qname,
- " ", dp->device ? dp->device : "",
- " ", level,
- " ", est(dp)->dumpdate[i],
- " ", spindle,
- " ", exclude1, exclude2,
- ((includefree != NULL) ? " " : ""),
- include1, include2,
- "\n",
- NULL);
+ es = xml_estimate(dp->estimatelist, hostp->features);
+ vstrextend(&l, es, "\n", NULL);
+ amfree(es);
+ vstrextend(&l, " ", b64disk, "\n", NULL);
+ if (dp->device)
+ vstrextend(&l, " ", b64device, "\n", NULL);
+ vstrextend(&l, levelstr, spindlestr, o, "</dle>\n", NULL);
strappend(s, l);
s_len += strlen(l);
amfree(l);
- amfree(includefree);
- amfree(excludefree);
- }
- if (s != NULL) {
- estimates += i;
- strappend(req, s);
- req_len += s_len;
- amfree(s);
- }
- est(dp)->state = DISK_ACTIVE;
- remove_disk(&startq, dp);
- }
- else if (dp->estimate == ES_SERVER) {
- info_t info;
- nb_server++;
- get_info(dp->host->hostname, dp->name, &info);
- for(i = 0; i < MAX_LEVELS; i++) {
- int j;
- int lev = est(dp)->level[i];
-
- if(lev == -1) break;
- if(lev == 0) { /* use latest level 0, should do extrapolation */
- off_t est_size = (off_t)0;
- int nb_est = 0;
-
- for(j=NB_HISTORY-2;j>=0;j--) {
- if(info.history[j].level == 0) {
- if(info.history[j].size < (off_t)0) continue;
- est_size = info.history[j].size;
- nb_est++;
+ 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,
+ _("does not support application-api"));
+ } else {
+ for(i = 0; i < MAX_LEVELS; i++) {
+ char *l;
+ char *exclude1 = "";
+ char *exclude2 = "";
+ char *excludefree = NULL;
+ char *include1 = "";
+ char *include2 = "";
+ char *includefree = NULL;
+ char spindle[NUM_STR_SIZE];
+ char level[NUM_STR_SIZE];
+ int lev = est(dp)->estimate[i].level;
+
+ if(lev == -1) break;
+
+ g_snprintf(level, SIZEOF(level), "%d", lev);
+ g_snprintf(spindle, SIZEOF(spindle), "%d", dp->spindle);
+ if (am_has_feature(hostp->features,
+ fe_sendsize_req_options)){
+ exclude1 = " OPTIONS |";
+ exclude2 = optionstr(dp);
+ if ( exclude2 == NULL ) {
+ error(_("problem with option string, check the dumptype definition.\n"));
}
- }
- if(nb_est > 0) {
- est(dp)->est_size[i] = est_size;
- }
- else if(info.inf[lev].size > (off_t)1000) { /* stats */
- est(dp)->est_size[i] = info.inf[lev].size;
- }
- else {
- est(dp)->est_size[i] = (off_t)1000000;
- }
- }
- else if(lev == est(dp)->last_level) {
- /* means of all X day at the same level */
- #define NB_DAY 30
- int nb_day = 0;
- off_t est_size_day[NB_DAY];
- int nb_est_day[NB_DAY];
- for(j=0;j<NB_DAY;j++) {
- est_size_day[j]=(off_t)0;
- nb_est_day[j]=0;
- }
-
- for(j=NB_HISTORY-2;j>=0;j--) {
- if(info.history[j].level <= 0) continue;
- if(info.history[j].size < (off_t)0) continue;
- if(info.history[j].level==info.history[j+1].level) {
- if(nb_day <NB_DAY-1) nb_day++;
- est_size_day[nb_day] += info.history[j].size;
- nb_est_day[nb_day]++;
+ excludefree = exclude2;
+ includefree = NULL;
+ } else {
+ if (dp->exclude_file &&
+ dp->exclude_file->nb_element == 1) {
+ exclude1 = " exclude-file=";
+ exclude2 = quote_string(
+ dp->exclude_file->first->name);
+ excludefree = exclude2;
+ }
+ else if (dp->exclude_list &&
+ dp->exclude_list->nb_element == 1) {
+ exclude1 = " exclude-list=";
+ exclude2 = quote_string(
+ dp->exclude_list->first->name);
+ excludefree = exclude2;
}
- else {
- nb_day=0;
+ if (dp->include_file &&
+ dp->include_file->nb_element == 1) {
+ include1 = " include-file=";
+ include2 = quote_string(
+ dp->include_file->first->name);
+ includefree = include2;
+ }
+ else if (dp->include_list &&
+ dp->include_list->nb_element == 1) {
+ include1 = " include-list=";
+ include2 = quote_string(
+ dp->include_list->first->name);
+ includefree = include2;
}
}
- nb_day = info.consecutive_runs + 1;
- if(nb_day > NB_DAY-1) nb_day = NB_DAY-1;
-
- while(nb_day > 0 && nb_est_day[nb_day] == 0) nb_day--;
- if(nb_est_day[nb_day] > 0) {
- est(dp)->est_size[i] = est_size_day[nb_day] /
- (off_t)nb_est_day[nb_day];
- }
- else if(info.inf[lev].size > (off_t)1000) { /* stats */
- est(dp)->est_size[i] = info.inf[lev].size;
- }
- else {
- est(dp)->est_size[i] = (off_t)10000;
+ if (estimate == ES_CALCSIZE &&
+ !am_has_feature(hostp->features,
+ fe_calcsize_estimate)) {
+ log_add(L_WARNING,
+ _("%s:%s does not support CALCSIZE for estimate, using CLIENT.\n"),
+ hostp->hostname, qname);
+ estimate = ES_CLIENT;
}
+ if(estimate == ES_CLIENT)
+ calcsize = "";
+ else
+ calcsize = "CALCSIZE ";
+
+ l = vstralloc(calcsize,
+ dp->program,
+ " ", qname,
+ " ", dp->device ? qdevice : "",
+ " ", level,
+ " ", est(dp)->estimate[i].dumpdate,
+ " ", spindle,
+ " ", exclude1, exclude2,
+ ((includefree != NULL) ? " " : ""),
+ include1, include2,
+ "\n",
+ NULL);
+ strappend(s, l);
+ s_len += strlen(l);
+ amfree(l);
+ amfree(includefree);
+ amfree(excludefree);
}
- else if(lev == est(dp)->last_level + 1) {
- /* means of all first day at a new level */
- off_t est_size = (off_t)0;
- int nb_est = 0;
-
- for(j=NB_HISTORY-2;j>=0;j--) {
- if(info.history[j].level <= 0) continue;
- if(info.history[j].size < (off_t)0) continue;
- if(info.history[j].level == info.history[j+1].level + 1 ) {
- est_size += info.history[j].size;
- nb_est++;
- }
- }
- if(nb_est > 0) {
- est(dp)->est_size[i] = est_size / (off_t)nb_est;
- }
- else if(info.inf[lev].size > (off_t)1000) { /* stats */
- est(dp)->est_size[i] = info.inf[lev].size;
- }
- else {
- est(dp)->est_size[i] = (off_t)100000;
- }
+ }
+ if (s != NULL) {
+ estimates += i;
+ strappend(req, s);
+ req_len += s_len;
+ amfree(s);
+ if (est(dp)->state == DISK_DONE) {
+ remove_disk(&estq, dp);
+ est(dp)->state = DISK_PARTIALY_DONE;
+ enqueue_disk(&pestq, dp);
+ } else {
+ remove_disk(&startq, dp);
+ est(dp)->state = DISK_ACTIVE;
+ }
+ } else if (est(dp)->state != DISK_DONE) {
+ remove_disk(&startq, dp);
+ est(dp)->state = DISK_DONE;
+ if (est(dp)->errstr == NULL) {
+ est(dp)->errstr = vstrallocf(
+ _("Can't request estimate"));
}
+ enqueue_disk(&failq, dp);
}
- fprintf(stderr,"%s time %s: got result for host %s disk %s:",
- get_pname(), walltime_str(curclock()),
- dp->host->hostname, qname);
- fprintf(stderr," %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K\n",
- est(dp)->level[0], (OFF_T_FMT_TYPE)est(dp)->est_size[0],
- est(dp)->level[1], (OFF_T_FMT_TYPE)est(dp)->est_size[1],
- est(dp)->level[2], (OFF_T_FMT_TYPE)est(dp)->est_size[2]);
- est(dp)->state = DISK_DONE;
- remove_disk(&startq, dp);
- enqueue_disk(&estq, dp);
}
+ amfree(b64disk);
+ amfree(b64device);
amfree(qname);
+ amfree(qdevice);
}
if(estimates == 0) {
* We use ctimeout for the "noop" request because it should be
* very fast and etimeout has other side effects.
*/
- timeout = getconf_int(CNF_CTIMEOUT);
+ timeout = (time_t)getconf_int(CNF_CTIMEOUT);
}
- secdrv = security_getdriver(hostp->disks->security_driver);
+ dbprintf(_("send request:\n----\n%s\n----\n\n"), req);
+ secdrv = security_getdriver(hostp->disks->auth);
if (secdrv == NULL) {
- error("could not find security driver '%s' for host '%s'",
- hostp->disks->security_driver, hostp->hostname);
- /*NOTREACHED*/
+ hostp->up = HOST_DONE;
+ log_add(L_ERROR,
+ _("Could not find security driver '%s' for host '%s'"),
+ hostp->disks->auth, hostp->hostname);
+ amfree(req);
+ return;
}
hostp->up = HOST_ACTIVE;
protocol_sendreq(hostp->hostname, secdrv, amhost_get_security_conf,
req, timeout, handle_result, hostp);
+
amfree(req);
}
security_handle_t *sech)
{
int level, i;
- off_t size;
+ gint64 size;
disk_t *dp;
am_host_t *hostp;
- char *msgdisk=NULL, *msgdisk_undo=NULL, msgdisk_undo_ch = '\0';
+ char *msg, msg_undo;
char *remoterr, *errbuf = NULL;
char *s;
char *t;
int tch;
char *qname;
char *disk;
- OFF_T_FMT_TYPE size_;
+ long long size_;
hostp = (am_host_t *)datap;
hostp->up = HOST_READY;
if (pkt == NULL) {
- errbuf = vstralloc("Request to ", hostp->hostname, " failed: ",
- security_geterror(sech), NULL);
+ 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) {
-#define sc "ERROR "
- if(strncmp(pkt->body, sc, SIZEOF(sc)-1) == 0) {
- s = pkt->body + SIZEOF(sc)-1;
+ s = pkt->body;
+ if(strncmp_const_skip(s, "ERROR ", s, ch) == 0) {
ch = *s++;
-#undef sc
} else {
goto NAK_parse_failed;
}
}
}
- msgdisk_undo = NULL;
+ dbprintf(_("got reply:\n----\n%s\n----\n\n"), pkt->body);
s = pkt->body;
ch = *s++;
while(ch) {
line = s - 1;
-#define sc "OPTIONS "
- if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
-#undef sc
-
-#define sc "features="
- t = strstr(line, sc);
- if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) {
- t += SIZEOF(sc)-1;
-#undef sc
+ if(strncmp_const(line, "OPTIONS ") == 0) {
+ t = strstr(line, "features=");
+ if(t != NULL && (g_ascii_isspace((int)t[-1]) || t[-1] == ';')) {
+ char *u = strchr(t, ';');
+ if (u)
+ *u = '\0';
+ t += SIZEOF("features=")-1;
am_release_feature_set(hostp->features);
if((hostp->features = am_string_to_feature(t)) == NULL) {
- errbuf = vstralloc(hostp->hostname,
- ": bad features value: ",
- line,
- "\n",
- NULL);
+ errbuf = vstrallocf(hostp->hostname,
+ _(": bad features value: %s\n"), line);
goto error_return;
}
+ if (u)
+ *u = ';';
}
skip_quoted_line(s, ch);
continue;
}
-#define sc "ERROR "
- if(strncmp(line, sc, SIZEOF(sc) - 1) == 0) {
- t = line + SIZEOF(sc) - 1;
- tch = t[-1];
-#undef sc
-
+ t = line;
+ if ((strncmp_const_skip(t, "ERROR ", t, tch) == 0) ||
+ (strncmp_const_skip(t, "WARNING ", t, tch) == 0)) {
fp = t - 1;
skip_whitespace(t, tch);
if (tch == '\n') {
skip_quoted_line(s, ch);
continue;
}
+ t = strchr(t,'\n');
+ if (t) /* truncate after the first line */
+ *t = '\0';
errbuf = vstralloc(hostp->hostname,
(pkt->type == P_NAK) ? "NAK " : "",
": ",
goto error_return;
}
- msgdisk = t = line;
+ msg = t = line;
tch = *(t++);
skip_quoted_string(t, tch);
- msgdisk_undo = t - 1;
- msgdisk_undo_ch = *msgdisk_undo;
- *msgdisk_undo = '\0';
- disk = unquote_string(msgdisk);
+ t[-1] = '\0';
+ disk = unquote_string(msg);
+
skip_whitespace(t, tch);
- s = t;
- ch = tch;
- size_ = (OFF_T_FMT_TYPE)0;
- if (sscanf(t - 1, "%d SIZE " OFF_T_FMT , &level, &size_) != 2) {
+ if (sscanf(t - 1, "%d", &level) != 1) {
goto bad_msg;
}
- size = size_;
- dp = lookup_hostdisk(hostp, disk);
- amfree(disk);
- *msgdisk_undo = msgdisk_undo_ch; /* for error message */
- msgdisk_undo = NULL;
+ skip_integer(t, tch);
+ skip_whitespace(t, tch);
+ dp = lookup_hostdisk(hostp, disk);
if(dp == NULL) {
- log_add(L_ERROR, "%s: invalid reply from sendsize: `%s'\n",
+ log_add(L_ERROR, _("%s: invalid reply from sendsize: `%s'\n"),
hostp->hostname, line);
+ goto bad_msg;
+ }
+
+ size = (gint64)-1;
+ if (strncmp_const(t-1,"SIZE ") == 0) {
+ if (sscanf(t - 1, "SIZE %lld", &size_) != 1) {
+ goto bad_msg;
+ }
+ size = (gint64)size_;
+ } else if ((strncmp_const(t-1,"ERROR ") == 0) ||
+ (strncmp_const(t-1,"WARNING ") == 0)) {
+ skip_non_whitespace(t, tch);
+ skip_whitespace(t, tch);
+ msg = t-1;
+ skip_quoted_string(t,tch);
+ msg_undo = t[-1];
+ t[-1] = '\0';
+ if (pkt->type == P_REP && !est(dp)->errstr) {
+ est(dp)->errstr = unquote_string(msg);
+ }
+ t[-1] = msg_undo;
} else {
- for(i = 0; i < MAX_LEVELS; i++) {
- if(est(dp)->level[i] == level) {
- est(dp)->est_size[i] = size;
- break;
+ goto bad_msg;
+ }
+
+ amfree(disk);
+
+ for (i = 0; i < MAX_LEVELS; i++) {
+ if (est(dp)->estimate[i].level == level) {
+ if (size == (gint64)-2) {
+ est(dp)->estimate[i].nsize = -1; /* remove estimate */
+ est(dp)->estimate[i].guessed = 0;
+ } else if (size > (gint64)-1) {
+ /* take the size returned by the client */
+ est(dp)->estimate[i].nsize = size;
+ est(dp)->estimate[i].guessed = 0;
}
+ break;
}
- if(i == MAX_LEVELS) {
- goto bad_msg; /* this est wasn't requested */
- }
- est(dp)->got_estimate++;
}
+ 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++;
+
+ s = t;
+ ch = tch;
skip_quoted_line(s, ch);
}
* The client does not support the features list, so give it an
* empty one.
*/
- dbprintf(("%s: no feature set from host %s\n",
- debug_prefix_time(NULL), hostp->hostname));
+ dbprintf(_("no feature set from host %s\n"), hostp->hostname);
hostp->features = am_set_default_feature_set();
}
est(dp)->state = DISK_PARTIALY_DONE;
}
- if(est(dp)->level[0] == -1) continue; /* ignore this disk */
+ if (est(dp)->estimate[0].level == -1) continue; /* ignore this disk */
qname = quote_string(dp->name);
if(pkt->type == P_PREP) {
- fprintf(stderr,"%s: time %s: got partial result for host %s disk %s:",
+ g_fprintf(stderr,_("%s: time %s: got partial result for host %s disk %s:"),
get_pname(), walltime_str(curclock()),
dp->host->hostname, qname);
- fprintf(stderr," %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K\n",
- est(dp)->level[0], (OFF_T_FMT_TYPE)est(dp)->est_size[0],
- est(dp)->level[1], (OFF_T_FMT_TYPE)est(dp)->est_size[1],
- est(dp)->level[2], (OFF_T_FMT_TYPE)est(dp)->est_size[2]);
+ g_fprintf(stderr,_(" %d -> %lldK, %d -> %lldK, %d -> %lldK\n"),
+ est(dp)->estimate[0].level,
+ (long long)est(dp)->estimate[0].nsize,
+ est(dp)->estimate[1].level,
+ (long long)est(dp)->estimate[1].nsize,
+ est(dp)->estimate[2].level,
+ (long long)est(dp)->estimate[2].nsize);
enqueue_disk(&pestq, dp);
}
else if(pkt->type == P_REP) {
- fprintf(stderr,"%s: time %s: got result for host %s disk %s:",
+ g_fprintf(stderr,_("%s: time %s: got result for host %s disk %s:"),
get_pname(), walltime_str(curclock()),
dp->host->hostname, qname);
- fprintf(stderr," %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K\n",
- est(dp)->level[0], (OFF_T_FMT_TYPE)est(dp)->est_size[0],
- est(dp)->level[1], (OFF_T_FMT_TYPE)est(dp)->est_size[1],
- est(dp)->level[2], (OFF_T_FMT_TYPE)est(dp)->est_size[2]);
- if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > (off_t)0) ||
- (est(dp)->level[1] != -1 && est(dp)->est_size[1] > (off_t)0) ||
- (est(dp)->level[2] != -1 && est(dp)->est_size[2] > (off_t)0)) {
-
- if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < (off_t)0) {
- log_add(L_WARNING,
- "disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, qname, est(dp)->level[2]);
- est(dp)->level[2] = -1;
- }
- if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < (off_t)0) {
- log_add(L_WARNING,
- "disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, qname,
- est(dp)->level[1]);
- est(dp)->level[1] = -1;
- }
- if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < (off_t)0) {
- log_add(L_WARNING,
- "disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, qname, est(dp)->level[0]);
- est(dp)->level[0] = -1;
+ g_fprintf(stderr,_(" %d -> %lldK, %d -> %lldK, %d -> %lldK\n"),
+ est(dp)->estimate[0].level,
+ (long long)est(dp)->estimate[0].nsize,
+ est(dp)->estimate[1].level,
+ (long long)est(dp)->estimate[1].nsize,
+ est(dp)->estimate[2].level,
+ (long long)est(dp)->estimate[2].nsize);
+ if ((est(dp)->estimate[0].level != -1 &&
+ est(dp)->estimate[0].nsize > (gint64)0) ||
+ (est(dp)->estimate[1].level != -1 &&
+ est(dp)->estimate[1].nsize > (gint64)0) ||
+ (est(dp)->estimate[2].level != -1 &&
+ est(dp)->estimate[2].nsize > (gint64)0)) {
+
+ for (i=MAX_LEVELS-1; i >=0; i--) {
+ if (est(dp)->estimate[i].level != -1 &&
+ est(dp)->estimate[i].nsize < (gint64)0) {
+ est(dp)->estimate[i].level = -1;
+ }
}
enqueue_disk(&estq, dp);
}
else {
enqueue_disk(&failq, dp);
- if(est(dp)->got_estimate) {
- est(dp)->errstr = vstralloc("disk ", qname,
- ", all estimate failed", NULL);
+ if(est(dp)->got_estimate && !est(dp)->errstr) {
+ est(dp)->errstr = vstrallocf("disk %s, all estimate failed",
+ qname);
}
else {
- fprintf(stderr, "error result for host %s disk %s: missing estimate\n",
- dp->host->hostname, qname);
- est(dp)->errstr = vstralloc("missing result for ", qname,
- " in ", dp->host->hostname,
- " response",
- NULL);
+ g_fprintf(stderr,
+ _("error result for host %s disk %s: missing estimate\n"),
+ dp->host->hostname, qname);
+ if (est(dp)->errstr == NULL) {
+ est(dp)->errstr = vstrallocf(_("missing result for %s in %s response"),
+ qname, dp->host->hostname);
+ }
}
}
+ hostp->up = HOST_DONE;
+ }
+ if (est(dp)->post_dle == 0 &&
+ (pkt->type == P_REP ||
+ ((est(dp)->estimate[0].level == -1 ||
+ est(dp)->estimate[0].nsize > (gint64)0) &&
+ (est(dp)->estimate[1].level == -1 ||
+ est(dp)->estimate[1].nsize > (gint64)0) &&
+ (est(dp)->estimate[2].level == -1 ||
+ est(dp)->estimate[2].nsize > (gint64)0)))) {
+ run_server_dle_scripts(EXECUTE_ON_POST_DLE_ESTIMATE,
+ get_config_name(), dp,
+ est(dp)->estimate[0].level);
+ est(dp)->post_dle = 1;
}
amfree(qname);
}
+
+ if(hostp->up == HOST_DONE) {
+ if (pkt->type == P_REP) {
+ run_server_host_scripts(EXECUTE_ON_POST_HOST_ESTIMATE,
+ get_config_name(), hostp);
+ }
+ }
+
getsize(hostp);
+ /* try to clean up any defunct processes, since Amanda doesn't wait() for
+ them explicitly */
+ while(waitpid(-1, NULL, WNOHANG)> 0);
return;
NAK_parse_failed:
- /* msgdisk_undo is always NULL */
- /* if(msgdisk_undo) { */
- /* *msgdisk_undo = msgdisk_undo_ch; */
- /* msgdisk_undo = NULL; */
- /* } */
- errbuf = stralloc2(hostp->hostname, " NAK: [NAK parse failed]");
- fprintf(stderr, "got strange nak from %s:\n----\n%s----\n\n",
+ errbuf = vstrallocf(_("%s NAK: [NAK parse failed]"), hostp->hostname);
+ g_fprintf(stderr, _("got strange nak from %s:\n----\n%s----\n\n"),
hostp->hostname, pkt->body);
goto error_return;
bad_msg:
- if(msgdisk_undo) {
- *msgdisk_undo = msgdisk_undo_ch;
- msgdisk_undo = NULL;
- }
- fprintf(stderr,"got a bad message, stopped at:\n");
+ g_fprintf(stderr,_("got a bad message, stopped at:\n"));
/*@ignore@*/
- fprintf(stderr,"----\n%s----\n\n", line);
- errbuf = stralloc2("badly formatted response from ", hostp->hostname);
+ g_fprintf(stderr,_("----\n%s----\n\n"), line);
+ errbuf = stralloc2(_("badly formatted response from "), hostp->hostname);
/*@end@*/
error_return:
i = 0;
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
- if(est(dp)->state != DISK_ACTIVE) continue;
- qname = quote_string(dp->name);
- est(dp)->state = DISK_DONE;
- if(est(dp)->state == DISK_ACTIVE) {
- est(dp)->state = DISK_DONE;
- remove_disk(&waitq, dp);
- enqueue_disk(&failq, dp);
- i++;
+ if (dp->todo) {
+ if(est(dp)->state == DISK_ACTIVE) {
+ qname = quote_string(dp->name);
+ est(dp)->state = DISK_DONE;
+ remove_disk(&waitq, dp);
+ enqueue_disk(&failq, dp);
+ i++;
- est(dp)->errstr = stralloc(errbuf);
- fprintf(stderr, "error result for host %s disk %s: %s\n",
- dp->host->hostname, qname, errbuf);
+ est(dp)->errstr = stralloc(errbuf);
+ g_fprintf(stderr, _("error result for host %s disk %s: %s\n"),
+ dp->host->hostname, qname, errbuf);
+ amfree(qname);
+ }
}
- amfree(qname);
}
if(i == 0) {
/*
}
hostp->up = HOST_DONE;
amfree(errbuf);
+ /* try to clean up any defunct processes, since Amanda doesn't wait() for
+ them explicitly */
+ while(waitpid(-1, NULL, WNOHANG)> 0);
}
*/
static int schedule_order(disk_t *a, disk_t *b); /* subroutines */
-static int pick_inclevel(disk_t *dp);
+static one_est_t *pick_inclevel(disk_t *dp);
static void analyze_estimate(
disk_t *dp)
ep = est(dp);
- fprintf(stderr, "pondering %s:%s... ",
+ g_fprintf(stderr, _("pondering %s:%s... "),
dp->host->hostname, qname);
- fprintf(stderr, "next_level0 %d last_level %d ",
+ g_fprintf(stderr, _("next_level0 %d last_level %d "),
ep->next_level0, ep->last_level);
if(get_info(dp->host->hostname, dp->name, &info) == 0) {
have_info = 1;
}
- ep->degr_level = -1;
- ep->degr_nsize = (off_t)-1;
- ep->degr_csize = (off_t)-1;
+ ep->degr_est = &default_one_est;
- if(ep->next_level0 <= 0 || (have_info && ep->last_level == 0
- && (info.command & FORCE_NO_BUMP))) {
- if(ep->next_level0 <= 0) {
- fprintf(stderr,"(due for level 0) ");
- }
- ep->dump_level = 0;
- ep->dump_nsize = est_size(dp, 0);
- ep->dump_csize = est_tape_size(dp, 0);
- if(ep->dump_csize <= (off_t)0) {
- fprintf(stderr,
- "(no estimate for level 0, picking an incr level)\n");
- ep->dump_level = pick_inclevel(dp);
- ep->dump_nsize = est_size(dp, ep->dump_level);
- ep->dump_csize = est_tape_size(dp, ep->dump_level);
-
- if(ep->dump_nsize == (off_t)-1) {
- ep->dump_level = ep->dump_level + 1;
- ep->dump_nsize = est_size(dp, ep->dump_level);
- ep->dump_csize = est_tape_size(dp, ep->dump_level);
+ if (ep->next_level0 <= 0 || (have_info && ep->last_level == 0
+ && (ISSET(info.command, FORCE_NO_BUMP)))) {
+ if (ep->next_level0 <= 0) {
+ g_fprintf(stderr,_("(due for level 0) "));
+ }
+ ep->dump_est = est_for_level(dp, 0);
+ if (ep->dump_est->csize <= (gint64)0) {
+ g_fprintf(stderr,
+ _("(no estimate for level 0, picking an incr level)\n"));
+ ep->dump_est = pick_inclevel(dp);
+
+ if (ep->dump_est->nsize == (gint64)-1) {
+ ep->dump_est = est_for_level(dp, ep->dump_est->level + 1);
}
}
else {
- total_lev0 += (double) ep->dump_csize;
+ total_lev0 += (double) ep->dump_est->csize;
if(ep->last_level == -1 || dp->skip_incr) {
- fprintf(stderr,"(%s disk, can't switch to degraded mode)\n",
- dp->skip_incr? "skip-incr":"new");
- ep->degr_level = -1;
- ep->degr_nsize = (off_t)-1;
- ep->degr_csize = (off_t)-1;
+ g_fprintf(stderr,_("(%s disk, can't switch to degraded mode)\n"),
+ dp->skip_incr? "skip-incr":_("new"));
+ if (dp->skip_incr && ep->degr_mesg == NULL) {
+ ep->degr_mesg = _("Skpping: skip-incr disk can't be dumped in degraded mode");
+ }
+ ep->degr_est = &default_one_est;
}
else {
/* fill in degraded mode info */
- fprintf(stderr,"(picking inclevel for degraded mode)");
- ep->degr_level = pick_inclevel(dp);
- ep->degr_nsize = est_size(dp, ep->degr_level);
- ep->degr_csize = est_tape_size(dp, ep->degr_level);
- if(ep->degr_csize == (off_t)-1) {
- ep->degr_level = ep->degr_level + 1;
- ep->degr_nsize = est_size(dp, ep->degr_level);
- ep->degr_csize = est_tape_size(dp, ep->degr_level);
+ g_fprintf(stderr,_("(picking inclevel for degraded mode)"));
+ ep->degr_est = pick_inclevel(dp);
+ if (ep->degr_est->csize == (gint64)-1) {
+ ep->degr_est = est_for_level(dp, ep->degr_est->level + 1);
}
- if(ep->degr_csize == (off_t)-1) {
- fprintf(stderr,"(no inc estimate)");
- ep->degr_level = -1;
+ if (ep->degr_est->csize == (gint64)-1) {
+ g_fprintf(stderr,_("(no inc estimate)"));
+ if (ep->degr_mesg == NULL)
+ ep->degr_mesg = _("Skipping: an incremental estimate could not be performed, so disk cannot be dumped in degraded mode");
+ ep->degr_est = &default_one_est;
}
- fprintf(stderr,"\n");
+ g_fprintf(stderr,"\n");
}
}
}
else {
- fprintf(stderr,"(not due for a full dump, picking an incr level)\n");
+ g_fprintf(stderr,_("(not due for a full dump, picking an incr level)\n"));
/* XXX - if this returns -1 may be we should force a total? */
- ep->dump_level = pick_inclevel(dp);
- ep->dump_nsize = est_size(dp, ep->dump_level);
- ep->dump_csize = est_tape_size(dp, ep->dump_level);
+ ep->dump_est = pick_inclevel(dp);
- if(ep->dump_csize == (off_t)-1) {
- ep->dump_level = ep->last_level;
- ep->dump_nsize = est_size(dp, ep->dump_level);
- ep->dump_csize = est_tape_size(dp, ep->dump_level);
+ if (ep->dump_est->csize == (gint64)-1) {
+ ep->dump_est = est_for_level(dp, ep->last_level);
}
- if(ep->dump_csize == (off_t)-1) {
- ep->dump_level = ep->last_level + 1;
- ep->dump_nsize = est_size(dp, ep->dump_level);
- ep->dump_csize = est_tape_size(dp, ep->dump_level);
+ if (ep->dump_est->csize == (gint64)-1) {
+ ep->dump_est = est_for_level(dp, ep->last_level + 1);
}
- if(ep->dump_csize == (off_t)-1) {
- ep->dump_level = 0;
- ep->dump_nsize = est_size(dp, ep->dump_level);
- ep->dump_csize = est_tape_size(dp, ep->dump_level);
+ if (ep->dump_est->csize == (gint64)-1) {
+ ep->dump_est = est_for_level(dp, 0);
}
+ if (ep->degr_mesg == NULL) {
+ ep->degr_mesg = _("Skipping: a full is not planned, so can't dump in degraded mode");
+ }
+ }
+
+ 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);
}
- fprintf(stderr," curr level %d nsize " OFF_T_FMT " csize " OFF_T_FMT " ",
- ep->dump_level, (OFF_T_FMT_TYPE)ep->dump_nsize,
- (OFF_T_FMT_TYPE)ep->dump_csize);
+ 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);
insert_disk(&schedq, dp, schedule_order);
- total_size += (off_t)tt_blocksize_kb + ep->dump_csize + tape_mark;
+ total_size += (gint64)tt_blocksize_kb + ep->dump_est->csize + tape_mark;
/* update the balanced size */
if(!(dp->skip_full || dp->strategy == DS_NOFULL ||
dp->strategy == DS_INCRONLY)) {
- off_t lev0size;
+ gint64 lev0size;
lev0size = est_tape_size(dp, 0);
- if(lev0size == (off_t)-1) lev0size = ep->last_lev0size;
+ if(lev0size == (gint64)-1) lev0size = ep->last_lev0size;
+
+ 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);
+ }
+ }
- balanced_size += (double)(lev0size / (off_t)runs_per_cycle);
+ g_fprintf(stderr,_("total size %lld total_lev0 %1.0lf balanced-lev0size %1.0lf\n"),
+ (long long)total_size, total_lev0, balanced_size);
+
+ /* Log errstr even if the estimate succeeded */
+ /* It can be an error from a script */
+ if (est(dp)->errstr) {
+ char *qerrstr = quote_string(est(dp)->errstr);
+ /* Log only a warning if a server estimate is available */
+ if (est(dp)->estimate[0].nsize > 0 ||
+ est(dp)->estimate[1].nsize > 0 ||
+ est(dp)->estimate[2].nsize > 0) {
+ log_add(L_WARNING, _("%s %s %s 0 %s"), dp->host->hostname, qname,
+ planner_timestamp, qerrstr);
+ } else {
+ log_add(L_FAIL, _("%s %s %s 0 %s"), dp->host->hostname, qname,
+ planner_timestamp, qerrstr);
+ }
+ amfree(qerrstr);
}
- fprintf(stderr,"total size " OFF_T_FMT " total_lev0 %1.0lf balanced-lev0size %1.0lf\n",
- (OFF_T_FMT_TYPE)total_size, total_lev0, balanced_size);
amfree(qname);
}
static void handle_failed(
disk_t *dp)
{
- char *errstr;
+ char *errstr, *errstr1, *qerrstr;
char *qname = quote_string(dp->name);
-/*
- * From George Scott <George.Scott@cc.monash.edu.au>:
- * --------
- * If a machine is down when the planner is run it guesses from historical
- * data what the size of tonights dump is likely to be and schedules a
- * dump anyway. The dumper then usually discovers that that machine is
- * still down and ends up with a half full tape. Unfortunately the
- * planner had to delay another dump because it thought that the tape was
- * full. The fix here is for the planner to ignore unavailable machines
- * rather than ignore the fact that they are unavailable.
- * --------
- */
+ errstr = est(dp)->errstr? est(dp)->errstr : _("hmm, no error indicator!");
+ errstr1 = vstralloc("[",errstr,"]", NULL);
+ qerrstr = quote_string(errstr1);
+ amfree(errstr1);
-#ifdef old_behavior
- if(est(dp)->last_level != -1) {
- log_add(L_WARNING,
- "Could not get estimate for %s:%s, using historical data.",
- dp->host->hostname, qname);
- analyze_estimate(dp);
- amfree(qname);
- return;
- }
-#endif
-
- errstr = est(dp)->errstr? est(dp)->errstr : "hmm, no error indicator!";
+ g_fprintf(stderr, _("%s: FAILED %s %s %s 0 %s\n"),
+ get_pname(), dp->host->hostname, qname, planner_timestamp, qerrstr);
- fprintf(stderr, "%s: FAILED %s %s %s 0 [%s]\n",
- get_pname(), dp->host->hostname, qname, planner_timestamp, errstr);
-
- log_add(L_FAIL, "%s %s %s 0 [%s]", dp->host->hostname, qname,
- planner_timestamp, errstr);
+ log_add(L_FAIL, _("%s %s %s 0 %s"), dp->host->hostname, qname,
+ planner_timestamp, qerrstr);
+ amfree(qerrstr);
amfree(qname);
/* XXX - memory leak with *dp */
}
disk_t *b)
{
int diff;
- off_t ldiff;
+ gint64 ldiff;
diff = est(b)->dump_priority - est(a)->dump_priority;
if(diff != 0) return diff;
- ldiff = est(b)->dump_csize - est(a)->dump_csize;
- if(ldiff < (off_t)0) return -1; /* XXX - there has to be a better way to dothis */
- if(ldiff > (off_t)0) return 1;
+ ldiff = est(b)->dump_est->csize - est(a)->dump_est->csize;
+ if(ldiff < (gint64)0) return -1; /* XXX - there has to be a better way to dothis */
+ if(ldiff > (gint64)0) return 1;
return 0;
}
-static int pick_inclevel(
+static one_est_t *pick_inclevel(
disk_t *dp)
{
- int base_level, bump_level;
- off_t base_size, bump_size;
- off_t thresh;
+ one_est_t *level0_est, *base_est, *bump_est;
+ gint64 thresh;
char *qname;
- base_level = est(dp)->last_level;
+ level0_est = est_for_level(dp, 0);
+ base_est = est_for_level(dp, est(dp)->last_level);
/* if last night was level 0, do level 1 tonight, no ifs or buts */
- if(base_level == 0) {
- fprintf(stderr," picklev: last night 0, so tonight level 1\n");
- return 1;
+ if (base_est->level == 0) {
+ g_fprintf(stderr,_(" picklev: last night 0, so tonight level 1\n"));
+ return est_for_level(dp, 1);
}
/* if no-full option set, always do level 1 */
if(dp->strategy == DS_NOFULL) {
- fprintf(stderr," picklev: no-full set, so always level 1\n");
- return 1;
+ g_fprintf(stderr,_(" picklev: no-full set, so always level 1\n"));
+ return est_for_level(dp, 1);
}
- base_size = est_size(dp, base_level);
-
/* if we didn't get an estimate, we can't do an inc */
- if(base_size == (off_t)-1) {
- base_size = est_size(dp, base_level+1);
- if(base_size > (off_t)0) /* FORCE_BUMP */
- return base_level+1;
- fprintf(stderr," picklev: no estimate for level %d, so no incs\n", base_level);
- return base_level;
+ if (base_est->nsize == (gint64)-1) {
+ 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;
}
- thresh = bump_thresh(base_level, est_size(dp, 0), dp->bumppercent, dp->bumpsize, dp->bumpmult);
+ thresh = bump_thresh(base_est->level, level0_est->nsize, dp->bumppercent,
+ dp->bumpsize, dp->bumpmult);
- fprintf(stderr,
- " pick: size " OFF_T_FMT " level %d days %d (thresh " OFF_T_FMT "K, %d days)\n",
- (OFF_T_FMT_TYPE)base_size, base_level, est(dp)->level_days,
- (OFF_T_FMT_TYPE)thresh, dp->bumpdays);
+ g_fprintf(stderr,
+ _(" pick: size %lld level %d days %d (thresh %lldK, %d days)\n"),
+ (long long)base_est->nsize, base_est->level, est(dp)->level_days,
+ (long long)thresh, dp->bumpdays);
- if(base_level == 9
+ if(base_est->level == (DUMP_LEVELS - 1)
|| est(dp)->level_days < dp->bumpdays
- || base_size <= thresh)
- return base_level;
+ || base_est->nsize <= thresh)
+ return base_est;
- bump_level = base_level + 1;
- bump_size = est_size(dp, bump_level);
+ bump_est = est_for_level(dp, base_est->level + 1);
- if(bump_size == (off_t)-1) return base_level;
+ if (bump_est->nsize == (gint64)-1)
+ return base_est;
- fprintf(stderr, " pick: next size " OFF_T_FMT "... ",
- (OFF_T_FMT_TYPE)bump_size);
+ g_fprintf(stderr, _(" pick: next size %lld... "),
+ (long long)bump_est->nsize);
- if(base_size - bump_size < thresh) {
- fprintf(stderr, "not bumped\n");
- return base_level;
+ if (base_est->nsize - bump_est->nsize < thresh) {
+ g_fprintf(stderr, _("not bumped\n"));
+ return base_est;
}
qname = quote_string(dp->name);
- fprintf(stderr, "BUMPED\n");
- log_add(L_INFO, "Incremental of %s:%s bumped to level %d.",
- dp->host->hostname, qname, bump_level);
+ g_fprintf(stderr, _("BUMPED\n"));
+ log_add(L_INFO, _("Incremental of %s:%s bumped to level %d."),
+ dp->host->hostname, qname, bump_est->level);
amfree(qname);
- return bump_level;
+ return bump_est;
}
disk_t * preserve;
bi_t * bi;
bi_t * nbi;
- off_t new_total; /* New total_size */
+ gint64 new_total; /* New total_size */
char est_kb[20]; /* Text formatted dump size */
int nb_forced_level_0;
info_t info;
int delete;
char * message;
- off_t full_size;
+ gint64 full_size;
biq.head = biq.tail = NULL;
for(dp = schedq.head; dp != NULL; dp = ndp) {
int avail_tapes = 1;
- if (dp->tape_splitsize > (off_t)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) * (off_t)avail_tapes) {
+ if (full_size > tapetype_get_length(tape) * (gint64)avail_tapes) {
char *qname = quote_string(dp->name);
- if (conf_runtapes > 1 && dp->tape_splitsize == (off_t)0) {
- log_add(L_WARNING, "disk %s:%s, full dump (" OFF_T_FMT
- "KB) will be larger than available tape space"
- ", you could define a splitsize",
+ 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,
- (OFF_T_FMT_TYPE)full_size);
+ (long long)full_size);
} else {
- log_add(L_WARNING, "disk %s:%s, full dump (" OFF_T_FMT
- "KB) will be larger than available tape space",
+ log_add(L_WARNING, _("disk %s:%s, full dump (%lldKB) will be larger than available tape space"),
dp->host->hostname, qname,
- (OFF_T_FMT_TYPE)full_size);
+ (long long)full_size);
}
amfree(qname);
}
- if (est(dp)->dump_csize == (off_t)-1 ||
- est(dp)->dump_csize <= tapetype_get_length(tape) * (off_t)avail_tapes) {
+ if (est(dp)->dump_est->csize == (gint64)-1 ||
+ est(dp)->dump_est->csize <= tapetype_get_length(tape) * (gint64)avail_tapes) {
continue;
}
/* Format dumpsize for messages */
- snprintf(est_kb, 20, OFF_T_FMT " KB,",
- (OFF_T_FMT_TYPE)est(dp)->dump_csize);
+ g_snprintf(est_kb, 20, "%lld KB,",
+ (long long)est(dp)->dump_est->csize);
- if(est(dp)->dump_level == 0) {
+ if(est(dp)->dump_est->level == 0) {
if(dp->skip_incr) {
delete = 1;
- message = "but cannot incremental dump skip-incr disk";
+ message = _("but cannot incremental dump skip-incr disk");
}
else if(est(dp)->last_level < 0) {
delete = 1;
- message = "but cannot incremental dump new disk";
+ message = _("but cannot incremental dump new disk");
}
- else if(est(dp)->degr_level < 0) {
+ else if(est(dp)->degr_est->level < 0) {
delete = 1;
- message = "but no incremental estimate";
+ message = _("but no incremental estimate");
}
- else if (est(dp)->degr_csize > tapetype_get_length(tape)) {
+ else if (est(dp)->degr_est->csize > tapetype_get_length(tape)) {
delete = 1;
- message = "incremental dump also larger than tape";
+ message = _("incremental dump also larger than tape");
}
else {
delete = 0;
- message = "full dump delayed";
+ message = _("full dump delayed");
}
}
else {
delete = 1;
- message = "skipping incremental";
+ message = _("skipping incremental");
}
- delay_one_dump(dp, delete, "dump larger than available tape space,",
+ delay_one_dump(dp, delete, _("dump larger than available tape space,"),
est_kb, message, NULL);
}
nb_forced_level_0 = 0;
preserve = NULL;
for(dp = schedq.head; dp != NULL && preserve == NULL; dp = dp->next)
- if(est(dp)->dump_level == 0)
+ if(est(dp)->dump_est->level == 0)
preserve = dp;
/* 2.a. Do not delay forced full */
dp = ndp) {
ndp = dp->prev;
- if(est(dp)->dump_level != 0) continue;
+ 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;
if(dp != preserve) {
/* Format dumpsize for messages */
- snprintf(est_kb, 20, OFF_T_FMT " KB,",
- (OFF_T_FMT_TYPE)est(dp)->dump_csize);
+ g_snprintf(est_kb, 20, "%lld KB,",
+ (long long)est(dp)->dump_est->csize);
if(dp->skip_incr) {
delete = 1;
- message = "but cannot incremental dump skip-incr disk";
+ message = _("but cannot incremental dump skip-incr disk");
}
else if(est(dp)->last_level < 0) {
delete = 1;
- message = "but cannot incremental dump new disk";
+ message = _("but cannot incremental dump new disk");
}
- else if(est(dp)->degr_level < 0) {
+ else if(est(dp)->degr_est->level < 0) {
delete = 1;
- message = "but no incremental estimate";
+ message = _("but no incremental estimate");
}
else {
delete = 0;
- message = "full dump delayed";
+ message = _("full dump delayed");
}
- delay_one_dump(dp, delete, "dumps too big,", est_kb,
+ delay_one_dump(dp, delete, _("dumps too big,"), est_kb,
message, NULL);
}
}
dp = ndp) {
ndp = dp->prev;
- if(est(dp)->dump_level == 0 && dp != preserve) {
+ if(est(dp)->dump_est->level == 0 && dp != preserve) {
/* Format dumpsize for messages */
- snprintf(est_kb, 20, OFF_T_FMT " KB,",
- (OFF_T_FMT_TYPE)est(dp)->dump_csize);
+ g_snprintf(est_kb, 20, "%lld KB,",
+ (long long)est(dp)->dump_est->csize);
if(dp->skip_incr) {
delete = 1;
- message = "but cannot incremental dump skip-incr disk";
+ message = _("but cannot incremental dump skip-incr disk");
}
else if(est(dp)->last_level < 0) {
delete = 1;
- message = "but cannot incremental dump new disk";
+ message = _("but cannot incremental dump new disk");
}
- else if(est(dp)->degr_level < 0) {
+ else if(est(dp)->degr_est->level < 0) {
delete = 1;
- message = "but no incremental estimate";
+ message = _("but no incremental estimate");
}
else {
delete = 0;
- message = "full dump delayed";
+ message = _("full dump delayed");
}
- delay_one_dump(dp, delete, "dumps too big,", est_kb,
+ delay_one_dump(dp, delete, _("dumps too big,"), est_kb,
message, NULL);
}
}
dp = ndp) {
ndp = dp->prev;
- if(est(dp)->dump_level != 0) {
+ if(est(dp)->dump_est->level != 0) {
/* Format dumpsize for messages */
- snprintf(est_kb, 20, OFF_T_FMT " KB,",
- (OFF_T_FMT_TYPE)est(dp)->dump_csize);
+ g_snprintf(est_kb, 20, "%lld KB,",
+ (long long)est(dp)->dump_est->csize);
delay_one_dump(dp, 1,
- "dumps way too big,",
+ _("dumps way too big,"),
est_kb,
- "must skip incremental dumps",
+ _("must skip incremental dumps"),
NULL);
}
}
int avail_tapes = 1;
nbi = bi->prev;
dp = bi->dp;
- if(dp->tape_splitsize > (off_t)0)
+ if(dp->splitsize > (gint64)0)
avail_tapes = conf_runtapes;
if(bi->deleted) {
- new_total = total_size + (off_t)tt_blocksize_kb +
- bi->csize + (off_t)tape_mark;
+ new_total = total_size + (gint64)tt_blocksize_kb +
+ bi->csize + (gint64)tape_mark;
} else {
- new_total = total_size - est(dp)->dump_csize + bi->csize;
+ new_total = total_size - est(dp)->dump_est->csize + bi->csize;
}
if((new_total <= tape_length) &&
- (bi->csize < (tapetype_get_length(tape) * (off_t)avail_tapes))) {
+ (bi->csize < (tapetype_get_length(tape) * (gint64)avail_tapes))) {
/* reinstate it */
total_size = new_total;
if(bi->deleted) {
insert_disk(&schedq, dp, schedule_order);
}
else {
- est(dp)->dump_level = bi->level;
- est(dp)->dump_nsize = bi->nsize;
- est(dp)->dump_csize = bi->csize;
+ est(dp)->dump_est = est_for_level(dp, bi->level);
}
/* Keep it clean */
/*@i@*/ for(bi = biq.head; bi != NULL; bi = nbi) {
nbi = bi->next;
if(bi->deleted) {
- fprintf(stderr, "%s: FAILED %s\n", get_pname(), bi->errstr);
+ g_fprintf(stderr, "%s: FAILED %s\n", get_pname(), bi->errstr);
log_add(L_FAIL, "%s", bi->errstr);
}
else {
dp = bi->dp;
- fprintf(stderr, " delay: %s now at level %d\n",
- bi->errstr, est(dp)->dump_level);
+ g_fprintf(stderr, _(" delay: %s now at level %d\n"),
+ bi->errstr, est(dp)->dump_est->level);
log_add(L_INFO, "%s", bi->errstr);
}
/*@ignore@*/
/*@end@*/
}
- fprintf(stderr, " delay: Total size now " OFF_T_FMT ".\n",
- (OFF_T_FMT_TYPE)total_size);
+ g_fprintf(stderr, _(" delay: Total size now %lld.\n"),
+ (long long)total_size);
return;
}
char *sep;
char *next;
char *qname = quote_string(dp->name);
+ char *errstr, *qerrstr;
arglist_start(argp, delete);
- total_size -= (off_t)tt_blocksize_kb + est(dp)->dump_csize + (off_t)tape_mark;
- if(est(dp)->dump_level == 0) {
- total_lev0 -= (double) est(dp)->dump_csize;
+ total_size -= (gint64)tt_blocksize_kb + est(dp)->dump_est->csize + (gint64)tape_mark;
+ if(est(dp)->dump_est->level == 0) {
+ total_lev0 -= (double) est(dp)->dump_est->csize;
}
bi = alloc(SIZEOF(bi_t));
bi->deleted = delete;
bi->dp = dp;
- bi->level = est(dp)->dump_level;
- bi->nsize = est(dp)->dump_nsize;
- bi->csize = est(dp)->dump_csize;
+ bi->level = est(dp)->dump_est->level;
+ bi->nsize = est(dp)->dump_est->nsize;
+ bi->csize = est(dp)->dump_est->csize;
- snprintf(level_str, SIZEOF(level_str), "%d", est(dp)->dump_level);
+ g_snprintf(level_str, SIZEOF(level_str), "%d", est(dp)->dump_est->level);
bi->errstr = vstralloc(dp->host->hostname,
" ", qname,
" ", planner_timestamp ? planner_timestamp : "?",
" ", level_str,
NULL);
- sep = " [";
+ errstr = NULL;
+ sep = "[";
while ((next = arglist_val(argp, char *)) != NULL) {
- bi->errstr = newvstralloc(bi->errstr, bi->errstr, sep, next, NULL);
+ vstrextend(&errstr, sep, next, NULL);
sep = " ";
}
- strappend(bi->errstr, "]");
+ strappend(errstr, "]");
+ qerrstr = quote_string(errstr);
+ vstrextend(&bi->errstr, " ", qerrstr, NULL);
+ amfree(errstr);
+ amfree(qerrstr);
arglist_end(argp);
if (delete) {
remove_disk(&schedq, dp);
} else {
- est(dp)->dump_level = est(dp)->degr_level;
- est(dp)->dump_nsize = est(dp)->degr_nsize;
- est(dp)->dump_csize = est(dp)->degr_csize;
- total_size += (off_t)tt_blocksize_kb + est(dp)->dump_csize + (off_t)tape_mark;
+ est(dp)->dump_est = est(dp)->degr_est;
+ total_size += (gint64)tt_blocksize_kb + est(dp)->dump_est->csize + (gint64)tape_mark;
}
amfree(qname);
return;
static int promote_highest_priority_incremental(void)
{
disk_t *dp, *dp1, *dp_promote;
- off_t new_size, new_total, new_lev0;
+ gint64 new_total, new_lev0;
int check_days;
int nb_today, nb_same_day, nb_today2;
int nb_disk_today, nb_disk_same_day;
dp_promote = NULL;
for(dp = schedq.head; dp != NULL; dp = dp->next) {
-
+ one_est_t *level0_est = est_for_level(dp, 0);
est(dp)->promote = -1000;
- if(est_size(dp,0) <= (off_t)0)
+ if (level0_est->nsize <= (gint64)0)
continue;
if(est(dp)->next_level0 <= 0)
if(est(dp)->next_level0 > dp->maxpromoteday)
continue;
- new_size = est_tape_size(dp, 0);
- new_total = total_size - est(dp)->dump_csize + new_size;
- new_lev0 = (off_t)total_lev0 + new_size;
+ new_total = total_size - est(dp)->dump_est->csize + level0_est->csize;
+ new_lev0 = (gint64)total_lev0 + level0_est->csize;
nb_today = 0;
nb_same_day = 0;
nb_disk_today = 0;
nb_disk_same_day = 0;
for(dp1 = schedq.head; dp1 != NULL; dp1 = dp1->next) {
- if(est(dp1)->dump_level == 0)
+ if(est(dp1)->dump_est->level == 0)
nb_disk_today++;
else if(est(dp1)->next_level0 == est(dp)->next_level0)
nb_disk_same_day++;
if(strcmp(dp->host->hostname, dp1->host->hostname) == 0) {
- if(est(dp1)->dump_level == 0)
+ if(est(dp1)->dump_est->level == 0)
nb_today++;
else if(est(dp1)->next_level0 == est(dp)->next_level0)
nb_same_day++;
/* do not promote if overflow balanced size and something today */
/* promote if nothing today */
- if((new_lev0 > (off_t)(balanced_size + balance_threshold)) &&
+ if((new_lev0 > (gint64)(balanced_size + balance_threshold)) &&
(nb_disk_today > 0))
continue;
qname = quote_string(dp->name);
if(!dp_promote || est(dp_promote)->promote < est(dp)->promote) {
dp_promote = dp;
- fprintf(stderr," try %s:%s %d %d %d = %d\n",
+ g_fprintf(stderr," try %s:%s %d %d %d = %d\n",
dp->host->hostname, qname, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
}
else {
- fprintf(stderr,"no try %s:%s %d %d %d = %d\n",
+ g_fprintf(stderr,"no try %s:%s %d %d %d = %d\n",
dp->host->hostname, qname, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
}
amfree(qname);
}
if(dp_promote) {
+ one_est_t *level0_est;
dp = dp_promote;
+ level0_est = est_for_level(dp, 0);
qname = quote_string(dp->name);
- new_size = est_tape_size(dp, 0);
- new_total = total_size - est(dp)->dump_csize + new_size;
- new_lev0 = (off_t)total_lev0 + new_size;
+ new_total = total_size - est(dp)->dump_est->csize + level0_est->csize;
+ new_lev0 = (gint64)total_lev0 + level0_est->csize;
total_size = new_total;
total_lev0 = (double)new_lev0;
check_days = est(dp)->next_level0;
- est(dp)->degr_level = est(dp)->dump_level;
- est(dp)->degr_nsize = est(dp)->dump_nsize;
- est(dp)->degr_csize = est(dp)->dump_csize;
- est(dp)->dump_level = 0;
- est(dp)->dump_nsize = est_size(dp, 0);
- est(dp)->dump_csize = new_size;
+ est(dp)->degr_est = est(dp)->dump_est;
+ est(dp)->dump_est = level0_est;
est(dp)->next_level0 = 0;
- fprintf(stderr,
- " promote: moving %s:%s up, total_lev0 %1.0lf, total_size " OFF_T_FMT "\n",
+ g_fprintf(stderr,
+ _(" promote: moving %s:%s up, total_lev0 %1.0lf, total_size %lld\n"),
dp->host->hostname, qname,
- total_lev0, (OFF_T_FMT_TYPE)total_size);
+ total_lev0, (long long)total_size);
log_add(L_INFO,
- "Full dump of %s:%s promoted from %d day%s ahead.",
- dp->host->hostname, qname,
- check_days, (check_days == 1) ? "" : "s");
+ plural(_("Full dump of %s:%s promoted from %d day ahead."),
+ _("Full dump of %s:%s promoted from %d days ahead."),
+ check_days),
+ dp->host->hostname, qname, check_days);
amfree(qname);
return 1;
}
disk_t *dp;
struct balance_stats {
int disks;
- off_t size;
+ gint64 size;
} *sp = NULL;
int days;
int hill_days = 0;
- off_t hill_size;
- off_t new_size;
- off_t new_total;
+ gint64 hill_size;
+ gint64 new_total;
int my_dumpcycle;
char *qname;
for(days = 0; days < my_dumpcycle; days++) {
sp[days].disks = 0;
- sp[days].size = (off_t)0;
+ sp[days].size = (gint64)0;
}
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++;
/* Search for a suitable big hill and cut it down */
while(1) {
/* Find the tallest hill */
- hill_size = (off_t)0;
+ hill_size = (gint64)0;
for(days = 0; days < my_dumpcycle; days++) {
if(sp[days].disks > 1 && sp[days].size > hill_size) {
hill_size = sp[days].size;
}
}
- if(hill_size <= (off_t)0) break; /* no suitable hills */
+ if(hill_size <= (gint64)0) break; /* no suitable hills */
/* Find all the dumps in that hill and try and remove one */
for(dp = schedq.head; dp != NULL; dp = dp->next) {
+ one_est_t *level0_est;
if(est(dp)->next_level0 != hill_days ||
est(dp)->next_level0 > dp->maxpromoteday ||
dp->skip_full ||
dp->strategy == DS_NOFULL ||
dp->strategy == DS_INCRONLY)
continue;
- new_size = est_tape_size(dp, 0);
- new_total = total_size - est(dp)->dump_csize + new_size;
+ level0_est = est_for_level(dp, 0);
+ if (level0_est->nsize <= (gint64)0)
+ continue;
+ new_total = total_size - est(dp)->dump_est->csize + level0_est->csize;
if(new_total > tape_length)
continue;
/* We found a disk we can promote */
qname = quote_string(dp->name);
total_size = new_total;
- total_lev0 += (double)new_size;
- est(dp)->degr_level = est(dp)->dump_level;
- est(dp)->degr_nsize = est(dp)->dump_nsize;
- est(dp)->degr_csize = est(dp)->dump_csize;
- est(dp)->dump_level = 0;
+ total_lev0 += (double)level0_est->csize;
+ est(dp)->degr_est = est(dp)->dump_est;
+ est(dp)->dump_est = level0_est;
est(dp)->next_level0 = 0;
- est(dp)->dump_nsize = est_size(dp, 0);
- est(dp)->dump_csize = new_size;
- fprintf(stderr,
- " promote: moving %s:%s up, total_lev0 %1.0lf, total_size " OFF_T_FMT "\n",
+ g_fprintf(stderr,
+ _(" promote: moving %s:%s up, total_lev0 %1.0lf, total_size %lld\n"),
dp->host->hostname, qname,
- total_lev0, (OFF_T_FMT_TYPE)total_size);
+ total_lev0, (long long)total_size);
log_add(L_INFO,
- "Full dump of %s:%s specially promoted from %d day%s ahead.",
- dp->host->hostname, qname,
- hill_days, (hill_days == 1) ? "" : "s");
+ plural(_("Full dump of %s:%s specially promoted from %d day ahead."),
+ _("Full dump of %s:%s specially promoted from %d days ahead."),
+ hill_days),
+ dp->host->hostname, qname, hill_days);
amfree(qname);
amfree(sp);
char degr_kps_str[NUM_STR_SIZE];
char *dump_date, *degr_date;
char *features;
- int i;
char *qname = quote_string(dp->name);
ep = est(dp);
- if(ep->dump_csize == (off_t)-1) {
+ if(ep->dump_est->csize == (gint64)-1) {
/* no estimate, fail the disk */
- fprintf(stderr,
- "%s: FAILED %s %s %s %d [no estimate]\n",
+ g_fprintf(stderr,
+ _("%s: FAILED %s %s %s %d \"[no estimate]\"\n"),
get_pname(),
- dp->host->hostname, qname, planner_timestamp, ep->dump_level);
- log_add(L_FAIL, "%s %s %s %d [no estimate]",
- dp->host->hostname, qname, planner_timestamp, ep->dump_level);
+ dp->host->hostname, qname, planner_timestamp, ep->dump_est->level);
+ log_add(L_FAIL, _("%s %s %s %d [no estimate]"),
+ dp->host->hostname, qname, planner_timestamp, ep->dump_est->level);
amfree(qname);
return;
}
- dump_date = degr_date = (char *)0;
- for(i = 0; i < MAX_LEVELS; i++) {
- if(ep->dump_level == ep->level[i])
- dump_date = ep->dumpdate[i];
- if(ep->degr_level == ep->level[i])
- degr_date = ep->dumpdate[i];
- }
+ dump_date = ep->dump_est->dumpdate;
+ degr_date = ep->degr_est->dumpdate;
#define fix_rate(rate) (rate < 1.0 ? DEFAULT_DUMPRATE : rate)
- if(ep->dump_level == 0) {
+ if(ep->dump_est->level == 0) {
dump_kps = fix_rate(ep->fullrate);
- dump_time = (time_t)((double)ep->dump_csize / dump_kps);
+ dump_time = (time_t)((double)ep->dump_est->csize / dump_kps);
- if(ep->degr_csize != (off_t)-1) {
+ if(ep->degr_est->csize != (gint64)-1) {
degr_kps = fix_rate(ep->incrrate);
- degr_time = (time_t)((double)ep->degr_csize / degr_kps);
+ degr_time = (time_t)((double)ep->degr_est->csize / degr_kps);
}
}
else {
dump_kps = fix_rate(ep->incrrate);
- dump_time = (time_t)((double)ep->dump_csize / dump_kps);
- }
-
- if(ep->dump_level == 0 && ep->degr_csize != (off_t)-1) {
- snprintf(degr_level_str, sizeof(degr_level_str),
- "%d", ep->degr_level);
- snprintf(degr_nsize_str, sizeof(degr_nsize_str),
- OFF_T_FMT, (OFF_T_FMT_TYPE)ep->degr_nsize);
- snprintf(degr_csize_str, sizeof(degr_csize_str),
- OFF_T_FMT, (OFF_T_FMT_TYPE)ep->degr_csize);
- snprintf(degr_time_str, sizeof(degr_time_str),
- OFF_T_FMT, (OFF_T_FMT_TYPE)degr_time);
- snprintf(degr_kps_str, sizeof(degr_kps_str),
+ dump_time = (time_t)((double)ep->dump_est->csize / dump_kps);
+ }
+
+ if(ep->dump_est->level == 0 && ep->degr_est->csize != (gint64)-1) {
+ g_snprintf(degr_level_str, sizeof(degr_level_str),
+ "%d", ep->degr_est->level);
+ g_snprintf(degr_nsize_str, sizeof(degr_nsize_str),
+ "%lld", (long long)ep->degr_est->nsize);
+ g_snprintf(degr_csize_str, sizeof(degr_csize_str),
+ "%lld", (long long)ep->degr_est->csize);
+ g_snprintf(degr_time_str, sizeof(degr_time_str),
+ "%lld", (long long)degr_time);
+ g_snprintf(degr_kps_str, sizeof(degr_kps_str),
"%.0lf", degr_kps);
degr_str = vstralloc(" ", degr_level_str,
" ", degr_date,
" ", degr_time_str,
" ", degr_kps_str,
NULL);
+ } else {
+ char *degr_mesg;
+ if (ep->degr_mesg) {
+ degr_mesg = quote_string(ep->degr_mesg);
+ } else {
+ degr_mesg = quote_string(_("Skipping: cannot dump in degraded mode for unknown reason"));
+ }
+ degr_str = vstralloc(" ", degr_mesg, NULL);
+ amfree(degr_mesg);
}
- snprintf(dump_priority_str, SIZEOF(dump_priority_str),
+ g_snprintf(dump_priority_str, SIZEOF(dump_priority_str),
"%d", ep->dump_priority);
- snprintf(dump_level_str, SIZEOF(dump_level_str),
- "%d", ep->dump_level);
- snprintf(dump_nsize_str, sizeof(dump_nsize_str),
- OFF_T_FMT, (OFF_T_FMT_TYPE)ep->dump_nsize);
- snprintf(dump_csize_str, sizeof(dump_csize_str),
- OFF_T_FMT, (OFF_T_FMT_TYPE)ep->dump_csize);
- snprintf(dump_time_str, sizeof(dump_time_str),
- OFF_T_FMT, (OFF_T_FMT_TYPE)dump_time);
- snprintf(dump_kps_str, sizeof(dump_kps_str),
+ g_snprintf(dump_level_str, SIZEOF(dump_level_str),
+ "%d", ep->dump_est->level);
+ g_snprintf(dump_nsize_str, sizeof(dump_nsize_str),
+ "%lld", (long long)ep->dump_est->nsize);
+ g_snprintf(dump_csize_str, sizeof(dump_csize_str),
+ "%lld", (long long)ep->dump_est->csize);
+ g_snprintf(dump_time_str, sizeof(dump_time_str),
+ "%lld", (long long)dump_time);
+ g_snprintf(dump_kps_str, sizeof(dump_kps_str),
"%.0lf", dump_kps);
features = am_feature_to_string(dp->host->features);
schedline = vstralloc("DUMP ",dp->host->hostname,
degr_str ? degr_str : "",
"\n", NULL);
+ if (est(dp)->dump_est->guessed == 1) {
+ log_add(L_WARNING, _("WARNING: no history available for %s:%s; guessing that size will be %lld KB\n"), dp->host->hostname, qname, (long long)est(dp)->dump_est->csize);
+ }
fputs(schedline, stdout);
fputs(schedline, stderr);
amfree(features);
amfree(degr_str);
amfree(qname);
}
+
+static void
+server_estimate(
+ disk_t *dp,
+ int i,
+ info_t *info,
+ int level)
+{
+ int stats;
+ gint64 size;
+
+ size = internal_server_estimate(dp, info, level, &stats);
+
+ est(dp)->dump_est = &est(dp)->estimate[i];
+ est(dp)->estimate[i].nsize = size;
+ if (stats == 0) {
+ est(dp)->estimate[i].guessed = 1;
+ }
+}