X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Fplanner.c;h=af97336cc83bf2755e9b5590b33960a56b031fc8;hb=34197d9f46a5f4e944378cbb65fca32ee0eec7b9;hp=9aec032e7d20902f6dc2d15bcdfe3790f2612fdf;hpb=0de2ad0a86685398621fb8ffa6990c029681bb3a;p=debian%2Famanda diff --git a/server-src/planner.c b/server-src/planner.c index 9aec032..af97336 100644 --- a/server-src/planner.c +++ b/server-src/planner.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 1991-1998 University of Maryland at College Park + * Copyright (c) 1991-1999 University of Maryland at College Park * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: planner.c,v 1.76.2.15.2.13.2.32.2.16 2005/03/16 18:09:50 martinea Exp $ + * $Id: planner.c,v 1.206.2.6 2006/11/24 18:05:06 martinea Exp $ * * backup schedule planner for the Amanda backup system. */ @@ -36,7 +36,8 @@ #include "infofile.h" #include "logfile.h" #include "clock.h" -#include "dgram.h" +#include "packet.h" +#include "security.h" #include "protocol.h" #include "version.h" #include "amfeatures.h" @@ -48,19 +49,20 @@ #define RUNS_REDZONE 5 /* should be in conf file? */ #define PROMOTE_THRESHOLD 0.05 /* if <5% unbalanced, don't promote */ -#define DEFAULT_DUMPRATE 30.0 /* K/s */ +#define DEFAULT_DUMPRATE 1024.0 /* K/s */ /* configuration file stuff */ -char *conf_tapetype; -int conf_maxdumpsize; -int conf_runtapes; -int conf_dumpcycle; -int conf_runspercycle; -int conf_tapecycle; -int conf_etimeout; -int conf_reserve; -int conf_autoflush; +char * conf_tapetype; +off_t conf_maxdumpsize; +int conf_runtapes; +int conf_dumpcycle; +int conf_runspercycle; +int conf_tapecycle; +time_t conf_etimeout; +int conf_reserve; +int conf_autoflush; +int conf_usetimestamps; #define HOST_READY ((void *)0) /* must be 0 */ #define HOST_ACTIVE ((void *)1) @@ -76,11 +78,13 @@ typedef struct est_s { int got_estimate; int dump_priority; int dump_level; - long dump_size; + 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 */ - long degr_size; + off_t degr_nsize; /* native degraded size */ + off_t degr_csize; /* compressed degraded size */ int last_level; - long last_lev0size; + off_t last_lev0size; int next_level0; int level_days; int promote; @@ -89,32 +93,27 @@ typedef struct est_s { char *errstr; int level[MAX_LEVELS]; char *dumpdate[MAX_LEVELS]; - long est_size[MAX_LEVELS]; + off_t est_size[MAX_LEVELS]; } est_t; #define est(dp) ((est_t *)(dp)->up) /* pestq = partial estimate */ disklist_t startq, waitq, pestq, estq, failq, schedq; -long total_size; +off_t total_size; double total_lev0, balanced_size, balance_threshold; -unsigned long tape_length, tape_mark; -int result_port, amanda_port; - -static am_feature_t *our_features = NULL; -static char *our_feature_string = NULL; - -#ifdef KRB4_SECURITY -int kamanda_port; -#endif +off_t tape_length; +size_t tape_mark; tapetype_t *tape; -long tt_blocksize; -long tt_blocksize_kb; +size_t tt_blocksize; +size_t tt_blocksize_kb; int runs_per_cycle = 0; time_t today; +char *planner_timestamp = NULL; -dgram_t *msg; +static am_feature_t *our_features = NULL; +static char *our_feature_string = NULL; /* We keep a LIFO queue of before images for all modifications made * to schedq in our attempt to make the schedule fit on the tape. @@ -127,7 +126,8 @@ typedef struct bi_s { int deleted; /* 0=modified, 1=deleted */ disk_t *dp; /* The disk that was changed */ int level; /* The original level */ - long size; /* The original size */ + off_t nsize; /* The original native size */ + off_t csize; /* The original compressed size */ char *errstr; /* A message describing why this disk is here */ } bi_t; @@ -137,61 +137,60 @@ typedef struct bilist_s { bilist_t biq; /* The BI queue itself */ -char *datestamp = NULL; - /* * ======================================================================== * MAIN PROGRAM * */ -static void setup_estimate P((disk_t *dp)); -static void get_estimates P((void)); -static void analyze_estimate P((disk_t *dp)); -static void handle_failed P((disk_t *dp)); -static void delay_dumps P((void)); -static int promote_highest_priority_incremental P((void)); -static int promote_hills P((void)); -static void output_scheduleline P((disk_t *dp)); - -int main(argc, argv) -int argc; -char **argv; +static void setup_estimate(disk_t *dp); +static void get_estimates(void); +static void analyze_estimate(disk_t *dp); +static void handle_failed(disk_t *dp); +static void delay_dumps(void); +static int promote_highest_priority_incremental(void); +static int promote_hills(void); +static void output_scheduleline(disk_t *dp); +int main(int, char **); + +int main(int argc, char **argv) { - disklist_t *origqp; + disklist_t origq; disk_t *dp; int moved_one; - char **vp; unsigned long malloc_hist_1, malloc_size_1; unsigned long malloc_hist_2, malloc_size_2; - long initial_size; - int fd; + off_t 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; - for(fd = 3; fd < FD_SETSIZE; fd++) { - /* - * Make sure nobody spoofs us with a lot of extra open files - * that would cause an open we do to get a very high file - * descriptor, which in turn might be used as an index into - * an array (e.g. an fd_set). - */ - close(fd); - } + safe_fd(-1, 0); - setvbuf(stderr, (char *)NULL, _IOLBF, 0); + setvbuf(stderr, (char *)NULL, (int)_IOLBF, 0); - if (argc > 1) { - config_name = stralloc(argv[1]); + parse_server_conf(argc, argv, &new_argc, &new_argv); + my_argc = new_argc; + my_argv = new_argv; + + if (my_argc > 1) { + config_name = stralloc(my_argv[1]); config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL); } else { char my_cwd[STR_SIZE]; - if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) { + 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) { @@ -203,6 +202,11 @@ char **argv; set_pname("planner"); + dbopen(DBG_SUBDIR_SERVER); + + /* Don't die when child closes pipe */ + signal(SIGPIPE, SIG_IGN); + malloc_size_1 = malloc_inuse(&malloc_hist_1); erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE); @@ -214,31 +218,24 @@ char **argv; our_feature_string = am_feature_to_string(our_features); fprintf(stderr, "%s: pid %ld executable %s version %s\n", - get_pname(), (long) getpid(), argv[0], version()); - for(vp = version_info; *vp != NULL; vp++) - fprintf(stderr, "%s: %s", get_pname(), *vp); + get_pname(), (long) getpid(), my_argv[0], version()); + for (i = 0; version_info[i] != NULL; i++) + 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 setuid back to a normal - * user. If we are not using BSD security, planner is not installed - * setuid root. + * We get the socket right away as root, then set euid to normal + * user. Keeping saved uid as root. */ - /* set up dgram port first thing */ - - msg = dgram_alloc(); - - if(dgram_bind(msg, &result_port) == -1) { - error("could not bind result datagram port: %s", strerror(errno)); - } + protocol_init(); + ruid = getuid(); if(geteuid() == 0) { - /* set both real and effective uid's to real uid, likewise for gid */ + seteuid(ruid); setgid(getgid()); - setuid(getuid()); } /* @@ -249,6 +246,7 @@ char **argv; if(getpwuid(getuid()) == NULL) { error("can't get login name for my uid %ld", (long)getuid()); + /*NOTREACHED*/ } /* @@ -262,23 +260,50 @@ char **argv; 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(); + conf_diskfile = getconf_str(CNF_DISKFILE); if (*conf_diskfile == '/') { conf_diskfile = stralloc(conf_diskfile); } else { conf_diskfile = stralloc2(config_dir, conf_diskfile); } - if((origqp = read_diskfile(conf_diskfile)) == NULL) { + if (read_diskfile(conf_diskfile, &origq) < 0) { error("could not load disklist \"%s\"", conf_diskfile); + /*NOTREACHED*/ } - match_disklist(origqp, argc-2, argv+2); - for(dp = origqp->head; dp != NULL; dp = dp->next) { - if(dp->todo) - log_add(L_DISK, "%s %s", dp->host->hostname, dp->name); + if(origq.head == NULL) { + 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); @@ -287,8 +312,10 @@ char **argv; } if(read_tapelist(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); @@ -297,23 +324,38 @@ char **argv; } if(open_infofile(conf_infofile)) { error("could not open info db \"%s\"", conf_infofile); + /*NOTREACHED*/ + } + if (check_infofile(conf_infofile, &origq, &errstr) == -1) { + log_add(L_WARNING, "problem copying infofile: %s", errstr); + amfree(errstr); } amfree(conf_infofile); conf_tapetype = getconf_str(CNF_TAPETYPE); - conf_maxdumpsize = getconf_int(CNF_MAXDUMPSIZE); + conf_maxdumpsize = getconf_am64(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_reserve = getconf_int(CNF_RESERVE); - conf_autoflush = getconf_int(CNF_AUTOFLUSH); + conf_autoflush = getconf_boolean(CNF_AUTOFLUSH); + conf_usetimestamps = getconf_boolean(CNF_USETIMESTAMPS); - amfree(datestamp); + amfree(planner_timestamp); today = time(0); - datestamp = construct_datestamp(NULL); - log_add(L_START, "date %s", datestamp); + if(conf_usetimestamps == 0) { + planner_timestamp = construct_datestamp(NULL); + } + else { + planner_timestamp = construct_timestamp(NULL); + } + log_add(L_START, "date %s", planner_timestamp); + printf("DATE %s\n", planner_timestamp); + fflush(stdout); + fprintf(stderr, "%s: timestamp %s\n", + get_pname(), planner_timestamp); /* some initializations */ @@ -337,22 +379,16 @@ char **argv; } tape = lookup_tapetype(conf_tapetype); - if(conf_maxdumpsize > 0) { - tape_length = conf_maxdumpsize; + if(conf_maxdumpsize > (off_t)0) { + tape_length = (off_t)conf_maxdumpsize; } else { - tape_length = tape->length * conf_runtapes; + tape_length = tapetype_get_length(tape) * (off_t)conf_runtapes; } - tape_mark = tape->filemark; - tt_blocksize_kb = tape->blocksize; + tape_mark = (size_t)tapetype_get_filemark(tape); + tt_blocksize_kb = (size_t)tapetype_get_blocksize(tape); tt_blocksize = tt_blocksize_kb * 1024; - proto_init(msg->socket, today, 1000); /* XXX handles should eq nhosts */ - -#ifdef KRB4_SECURITY - kerberos_service_init(); -#endif - fprintf(stderr, "%s: time %s: startup took %s secs\n", get_pname(), walltime_str(curclock()), @@ -366,6 +402,7 @@ char **argv; */ fprintf(stderr,"\nSENDING FLUSHES...\n"); + if(conf_autoflush) { dumpfile_t file; sl_t *holding_list; @@ -410,8 +447,8 @@ char **argv; section_start = curclock(); startq.head = startq.tail = NULL; - while(!empty(*origqp)) { - disk_t *dp = dequeue_disk(origqp); + while(!empty(origq)) { + disk_t *dp = dequeue_disk(&origq); if(dp->todo == 1) { setup_estimate(dp); } @@ -470,7 +507,7 @@ char **argv; section_start = curclock(); /* an empty tape still has a label and an endmark */ - total_size = (tt_blocksize_kb + tape_mark) * 2; + total_size = ((off_t)tt_blocksize_kb + (off_t)tape_mark) * (off_t)2; total_lev0 = 0.0; balanced_size = 0.0; @@ -486,11 +523,16 @@ char **argv; { disk_t *dp; - fprintf(stderr, "INITIAL SCHEDULE (size %ld):\n", total_size); + fprintf(stderr, "INITIAL SCHEDULE (size " OFF_T_FMT "):\n", + (OFF_T_FMT_TYPE)total_size); for(dp = schedq.head; dp != NULL; dp = dp->next) { - fprintf(stderr, " %s %s pri %d lev %d size %ld\n", - dp->host->hostname, dp->name, est(dp)->dump_priority, - est(dp)->dump_level, est(dp)->dump_size); + qname = quote_string(dp->name); + fprintf(stderr, " %s %s pri %d lev %d nsize " OFF_T_FMT " csize " OFF_T_FMT "\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); + amfree(qname); } } @@ -507,17 +549,21 @@ char **argv; * until the dumps fit on the tape. */ - fprintf(stderr, - "\nDELAYING DUMPS IF NEEDED, total_size %ld, tape length %lu mark %lu\n", - total_size, tape_length, tape_mark); + 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); initial_size = total_size; delay_dumps(); /* XXX - why bother checking this? */ - if(empty(schedq) && total_size < initial_size) + if(empty(schedq) && total_size < initial_size) { error("cannot fit anything on tape, bailing out"); + /*NOTREACHED*/ + } /* @@ -539,7 +585,7 @@ char **argv; */ fprintf(stderr, - "\nPROMOTING DUMPS IF NEEDED, total_lev0 %1.0f, balanced_size %1.0f...\n", + "\nPROMOTING DUMPS IF NEEDED, total_lev0 %1.0lf, balanced_size %1.0lf...\n", total_lev0, balanced_size); balance_threshold = balanced_size * PROMOTE_THRESHOLD; @@ -555,6 +601,12 @@ char **argv; 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 * @@ -568,10 +620,12 @@ char **argv; fprintf(stderr, "--------\n"); close_infofile(); - log_add(L_FINISH, "date %s time %s", datestamp, walltime_str(curclock())); + log_add(L_FINISH, "date %s time %s", planner_timestamp, walltime_str(curclock())); - amfree(msg); - amfree(datestamp); + 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); @@ -584,6 +638,8 @@ char **argv; malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2); } + dbclose(); + return 0; } @@ -595,33 +651,36 @@ char **argv; * */ -static int last_level P((info_t *info)); /* subroutines */ -static long est_size P((disk_t *dp, int level)); -static long est_tape_size P((disk_t *dp, int level)); -static int next_level0 P((disk_t *dp, info_t *info)); -static int runs_at P((info_t *info, int lev)); -static long bump_thresh P((int level, long size_level_0, int bumppercent, int bumpsize, double bumpmult)); -static int when_overwrite P((char *label)); - -static void askfor(ep, seq, lev, info) -est_t *ep; /* esimate data block */ -int seq; /* sequence number of request */ -int lev; /* dump level being requested */ -info_t *info; /* info block for disk */ +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 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 int when_overwrite(char *label); + +static void askfor( + est_t *ep, /* esimate data block */ + int seq, /* sequence number of request */ + int lev, /* dump level being requested */ + info_t *info) /* info block for disk */ { if(seq < 0 || seq >= MAX_LEVELS) { 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]", DUMP_LEVELS, lev); + /*NOTREACHED*/ } if (lev == -1) { ep->level[seq] = -1; ep->dumpdate[seq] = (char *)0; - ep->est_size[seq] = -2; + ep->est_size[seq] = (off_t)-2; return; } @@ -630,23 +689,27 @@ info_t *info; /* info block for disk */ ep->dumpdate[seq] = stralloc(get_dumpdate(info,lev)); malloc_mark(ep->dumpdate[seq]); - ep->est_size[seq] = -2; + ep->est_size[seq] = (off_t)-2; return; } static void -setup_estimate(dp) - disk_t *dp; +setup_estimate( + disk_t *dp) { est_t *ep; info_t info; int i; + char *qname; + int overwrite_runs; assert(dp && dp->host); + + qname = quote_string(dp->name); fprintf(stderr, "%s: time %s: setting up estimates for %s:%s\n", get_pname(), walltime_str(curclock()), - dp->host->hostname, dp->name); + dp->host->hostname, qname); /* get current information about disk */ @@ -657,18 +720,19 @@ setup_estimate(dp) /* setup working data struct for disk */ - ep = alloc(sizeof(est_t)); + ep = alloc(SIZEOF(est_t)); malloc_mark(ep); dp->up = (void *) ep; ep->state = DISK_READY; - ep->dump_size = -1; + ep->dump_nsize = (off_t)-1; + ep->dump_csize = (off_t)-1; ep->dump_priority = dp->priority; ep->errstr = 0; ep->promote = 0; /* calculated fields */ - if(info.command & FORCE_FULL) { + if (ISSET(info.command, FORCE_FULL)) { /* force a level 0, kind of like a new disk */ if(dp->strategy == DS_NOFULL) { /* @@ -684,14 +748,15 @@ setup_estimate(dp) */ log_add(L_ERROR, "Cannot force full dump of %s:%s with no-full option.", - dp->host->hostname, dp->name); + dp->host->hostname, qname); /* clear force command */ - if(info.command & FORCE_FULL) - info.command ^= FORCE_FULL; - if(put_info(dp->host->hostname, dp->name, &info)) + 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, dp->name, strerror(errno)); + dp->host->hostname, qname, strerror(errno)); + /*NOTREACHED*/ + } ep->last_level = last_level(&info); ep->next_level0 = next_level0(dp, &info); } @@ -699,7 +764,7 @@ setup_estimate(dp) ep->last_level = -1; ep->next_level0 = -conf_dumpcycle; log_add(L_INFO, "Forcing full dump of %s:%s as directed.", - dp->host->hostname, dp->name); + dp->host->hostname, qname); } } else if(dp->strategy == DS_NOFULL) { @@ -714,28 +779,29 @@ setup_estimate(dp) /* adjust priority levels */ + /* warn if dump will be overwritten */ + if(ep->last_level > -1) { + overwrite_runs = when_overwrite(info.inf[0].label); + if(overwrite_runs == 0) { + log_add(L_WARNING, "Last full dump of %s:%s " + "on tape %s overwritten on this run.", + dp->host->hostname, qname, info.inf[0].label); + } + else if(overwrite_runs <= RUNS_REDZONE) { + log_add(L_WARNING, "Last full dump of %s:%s on " + "tape %s overwritten in %d run%s.", + dp->host->hostname, qname, info.inf[0].label, + overwrite_runs, overwrite_runs == 1? "" : "s"); + } + } + if(ep->next_level0 < 0) { fprintf(stderr,"%s:%s overdue %d day%s for level 0\n", - dp->host->hostname, dp->name, + dp->host->hostname, qname, - ep->next_level0, ((- ep->next_level0) == 1) ? "" : "s"); ep->dump_priority -= ep->next_level0; - /* warn if dump will be overwritten */ - if(ep->last_level > -1) { - int overwrite_runs = when_overwrite(info.inf[0].label); - if(overwrite_runs == 0) { - log_add(L_WARNING, - "Last full dump of %s:%s on tape %s overwritten on this run.", - dp->host->hostname, dp->name, 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.", - dp->host->hostname, dp->name, info.inf[0].label, - overwrite_runs, overwrite_runs == 1? "" : "s"); - } - } } - else if(info.command & FORCE_FULL) + else if (ISSET(info.command, FORCE_FULL)) ep->dump_priority += 1; /* else XXX bump up the priority of incrementals that failed last night */ @@ -745,25 +811,27 @@ setup_estimate(dp) if(ep->next_level0 <= 0) { /* update the date field */ info.inf[0].date = today; - if(info.command & FORCE_FULL) - info.command ^= FORCE_FULL; + CLR(info.command, FORCE_FULL); ep->next_level0 += conf_dumpcycle; ep->last_level = 0; - if(put_info(dp->host->hostname, dp->name, &info)) + if(put_info(dp->host->hostname, dp->name, &info)) { error("could not put info record for %s:%s: %s", - dp->host->hostname, dp->name, strerror(errno)); + dp->host->hostname, qname, strerror(errno)); + /*NOTREACHED*/ + } log_add(L_INFO, "Skipping full dump of %s:%s today.", - dp->host->hostname, dp->name); + dp->host->hostname, qname); fprintf(stderr,"%s:%s lev 0 skipped due to skip-full flag\n", - dp->host->hostname, dp->name); + 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", - get_pname(), dp->host->hostname, dp->name); + get_pname(), dp->host->hostname, qname); log_add(L_SUCCESS, "%s %s %s 0 [skipped: skip-full]", - dp->host->hostname, dp->name, datestamp); + dp->host->hostname, qname, planner_timestamp); + amfree(qname); return; } @@ -774,34 +842,48 @@ setup_estimate(dp) if(ep->next_level0 == 1) { log_add(L_WARNING, "Skipping full dump of %s:%s tomorrow.", - dp->host->hostname, dp->name); + dp->host->hostname, qname); } } + if(dp->strategy == DS_INCRONLY && ep->last_level == -1 && !ISSET(info.command, FORCE_FULL)) { + /* don't enqueue the disk */ + askfor(ep, 0, -1, &info); + askfor(ep, 1, -1, &info); + askfor(ep, 2, -1, &info); + 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", + 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", - dp->host->hostname, dp->name); + 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", - get_pname(), dp->host->hostname, dp->name); + get_pname(), dp->host->hostname, qname); log_add(L_SUCCESS, "%s %s %s 1 [skipped: skip-incr]", - dp->host->hostname, dp->name, datestamp); + 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.", - dp->host->hostname, dp->name, ep->next_level0); + 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; } @@ -819,30 +901,29 @@ setup_estimate(dp) i = 0; - if(dp->strategy == DS_NOINC || - (!dp->skip_full && - (!(info.command & FORCE_BUMP) || - dp->skip_incr || - ep->last_level == -1))){ - + if (dp->strategy == DS_NOINC || + (!dp->skip_full && + (!ISSET(info.command, FORCE_BUMP) || + dp->skip_incr || + ep->last_level == -1))) { if(info.command & FORCE_BUMP && ep->last_level == -1) { log_add(L_INFO, "Remove force-bump command of %s:%s because it's a new disk.", - dp->host->hostname, dp->name); + dp->host->hostname, qname); } switch (dp->strategy) { case DS_STANDARD: case DS_NOINC: askfor(ep, i++, 0, &info); if(dp->skip_full) { - log_add(L_INFO, - "Ignoring skip_full for %s:%s because the strategy is NOINC.", - dp->host->hostname, dp->name); + log_add(L_INFO, "Ignoring skip_full for %s:%s " + "because the strategy is NOINC.", + dp->host->hostname, qname); } if(info.command & FORCE_BUMP) { log_add(L_INFO, "Ignoring FORCE_BUMP for %s:%s because the strategy is NOINC.", - dp->host->hostname, dp->name); + dp->host->hostname, qname); } break; @@ -851,7 +932,7 @@ setup_estimate(dp) break; case DS_INCRONLY: - if (info.command & FORCE_FULL) + if (ISSET(info.command, FORCE_FULL)) askfor(ep, i++, 0, &info); break; } @@ -869,23 +950,20 @@ setup_estimate(dp) curr_level = ep->last_level; - if(info.command & FORCE_NO_BUMP) { + if (ISSET(info.command, FORCE_NO_BUMP)) { if(curr_level > 0) { /* level 0 already asked for */ askfor(ep, i++, curr_level, &info); } log_add(L_INFO,"Preventing bump of %s:%s as directed.", - dp->host->hostname, dp->name); - } - else if((info.command & FORCE_BUMP) - && curr_level + 1 < DUMP_LEVELS) { + dp->host->hostname, qname); + } 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.", - dp->host->hostname, dp->name, curr_level+1); - } - else if(curr_level == 0) { + dp->host->hostname, qname, curr_level+1); + } else if (curr_level == 0) { askfor(ep, i++, 1, &info); - } - else { + } else { askfor(ep, i++, curr_level, &info); /* * If last time we dumped less than the threshold, then this @@ -894,7 +972,7 @@ setup_estimate(dp) * 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 == 0 || /* no data, try it anyway */ + if((info.inf[curr_level].size == (off_t)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) { @@ -909,40 +987,47 @@ setup_estimate(dp) /* debug output */ - fprintf(stderr, "setup_estimate: %s:%s: command %d, options: %s last_level %d next_level0 %d level_days %d getting estimates %d (%ld) %d (%ld) %d (%ld)\n", - dp->host->hostname, dp->name, info.command, + 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", + 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], ep->est_size[0], - ep->level[1], ep->est_size[1], - ep->level[2], ep->est_size[2]); + 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]); assert(ep->level[0] != -1); enqueue_disk(&startq, dp); + amfree(qname); } -static int when_overwrite(label) -char *label; +static int when_overwrite( + char *label) { tape_t *tp; + int runtapes; + + runtapes = conf_runtapes; + if(runtapes == 0) runtapes = 1; if((tp = lookup_tapelabel(label)) == NULL) return 1; /* "shouldn't happen", but trigger warning message */ - else if(!reusable_tape(tp)) + else if(tp->reuse == 0) return 1024; else if(lookup_nb_tape() > conf_tapecycle) - return (lookup_nb_tape() - tp->position) / conf_runtapes; + return (lookup_nb_tape() - tp->position) / runtapes; else - return (conf_tapecycle - tp->position) / conf_runtapes; + return (conf_tapecycle - tp->position) / runtapes; } /* Return the estimated size for a particular dump */ -static long est_size(dp, level) -disk_t *dp; -int level; +static off_t est_size( + disk_t *dp, + int level) { int i; @@ -950,20 +1035,20 @@ int level; if(level == est(dp)->level[i]) return est(dp)->est_size[i]; } - return -1; + return (off_t)-1; } /* Return the estimated on-tape size of a particular dump */ -static long est_tape_size(dp, level) -disk_t *dp; -int level; +static off_t est_tape_size( + disk_t *dp, + int level) { - long size; + off_t size; double ratio; size = est_size(dp, level); - if(size == -1) return size; + if(size == (off_t)-1) return size; if(dp->compress == COMP_NONE) return size; @@ -982,15 +1067,15 @@ int level; if(ratio > 1.1) ratio = 1.1; - size *= ratio; + size = (off_t)((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 <= 0) { - size = 1; + if(size <= (off_t)0) { + size = (off_t)1; } return size; @@ -998,8 +1083,8 @@ int level; /* what was the level of the last successful dump to tape? */ -static int last_level(info) -info_t *info; +static int last_level( + info_t *info) { int min_pos, min_level, i; time_t lev0_date, last_date; @@ -1040,9 +1125,9 @@ info_t *info; /* when is next level 0 due? 0 = today, 1 = tomorrow, etc*/ static int -next_level0(dp, info) - disk_t *dp; - info_t *info; +next_level0( + disk_t *dp, + info_t *info) { if(dp->strategy == DS_NOFULL || dp->strategy == DS_INCRONLY) return 1; /* fake it */ @@ -1055,9 +1140,9 @@ next_level0(dp, info) } /* how many runs at current level? */ -static int runs_at(info, lev) -info_t *info; -int lev; +static int runs_at( + info_t *info, + int lev) { tape_t *cur_tape, *old_tape; int last, nb_runs; @@ -1074,31 +1159,34 @@ int lev; old_tape = lookup_tapelabel(info->inf[lev-1].label); if(cur_tape == NULL || old_tape == NULL) return 0; - nb_runs = (old_tape->position - cur_tape->position) / conf_runtapes; + if(conf_runtapes == 0) + nb_runs = (old_tape->position - cur_tape->position) / 1; + else + nb_runs = (old_tape->position - cur_tape->position) / conf_runtapes; info->consecutive_runs = nb_runs; return nb_runs; } -static long bump_thresh(level, size_level_0, bumppercent, bumpsize, bumpmult) -int level; -long size_level_0; -int bumppercent; -int bumpsize; -double bumpmult; +static off_t bump_thresh( + int level, + off_t size_level_0, + int bumppercent, + off_t bumpsize, + double bumpmult) { double bump; - if(bumppercent != 0 && size_level_0 > 1024) { - bump = (size_level_0 * bumppercent)/100.0; + if ((bumppercent != 0) && (size_level_0 > (off_t)1024)) { + bump = ((double)size_level_0 * (double)bumppercent) / 100.0; } else { - bump = bumpsize; + bump = (double)bumpsize; } while(--level) bump = bump * bumpmult; - return (long)bump; + return (off_t)bump; } @@ -1109,30 +1197,17 @@ double bumpmult; * */ -static void getsize P((am_host_t *hostp)); -static disk_t *lookup_hostdisk P((am_host_t *hp, char *str)); -static void handle_result P((proto_t *p, pkt_t *pkt)); +static void getsize(am_host_t *hostp); +static disk_t *lookup_hostdisk(am_host_t *hp, char *str); +static void handle_result(void *datap, pkt_t *pkt, security_handle_t *sech); -static void get_estimates P((void)) +static void get_estimates(void) { am_host_t *hostp; disk_t *dp; - struct servent *amandad; int something_started; - if((amandad = getservbyname(AMANDA_SERVICE_NAME, "udp")) == NULL) - amanda_port = AMANDA_SERVICE_DEFAULT; - else - amanda_port = ntohs(amandad->s_port); - -#ifdef KRB4_SECURITY - if((amandad = getservbyname(KAMANDA_SERVICE_NAME, "udp")) == NULL) - kamanda_port = KAMANDA_SERVICE_DEFAULT; - else - kamanda_port = ntohs(amandad->s_port); -#endif - something_started = 1; while(something_started) { something_started = 0; @@ -1141,7 +1216,7 @@ static void get_estimates P((void)) if(hostp->up == HOST_READY) { something_started = 1; getsize(hostp); - check_protocol(); + protocol_check(); /* * dp is no longer on startq, so dp->next is not valid * and we have to start all over. @@ -1150,7 +1225,7 @@ static void get_estimates P((void)) } } } - run_protocol(); + protocol_run(); while(!empty(waitq)) { disk_t *dp = dequeue_disk(&waitq); @@ -1160,77 +1235,75 @@ static void get_estimates P((void)) while(!empty(pestq)) { disk_t *dp = dequeue_disk(&pestq); - - if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < 0) { - if(est(dp)->est_size[0] == -1) { - log_add(L_WARNING, - "disk %s:%s, estimate of level %d failed: %d.", - dp->host->hostname, dp->name, - est(dp)->level[0], est(dp)->est_size[0]); + 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: %d.", - dp->host->hostname, dp->name, - est(dp)->level[0], est(dp)->est_size[0]); + "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] < 0) { - if(est(dp)->est_size[1] == -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: %d.", - dp->host->hostname, dp->name, - est(dp)->level[1], est(dp)->est_size[1]); + "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: %d.", - dp->host->hostname, dp->name, - est(dp)->level[1], est(dp)->est_size[1]); + "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] < 0) { - if(est(dp)->est_size[2] == -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: %d.", - dp->host->hostname, dp->name, - est(dp)->level[2], est(dp)->est_size[2]); + "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: %d.", - dp->host->hostname, dp->name, - est(dp)->level[2], est(dp)->est_size[2]); + "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] > 0) || - (est(dp)->level[1] != -1 && est(dp)->est_size[1] > 0) || - (est(dp)->level[2] != -1 && est(dp)->est_size[2] > 0)) { + 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)) { enqueue_disk(&estq, dp); } else { - est(dp)->errstr = vstralloc("disk ", dp->name, + est(dp)->errstr = vstralloc("disk ", qname, ", all estimate timed out", NULL); enqueue_disk(&failq, dp); } + amfree(qname); } } -static void getsize(hostp) -am_host_t *hostp; +static void getsize( + am_host_t *hostp) { - disklist_t *destqp; - disk_t *dp; - char *req = NULL, *errstr = NULL; - int i, estimates, rc, timeout, disk_state, req_len; - char number[NUM_STR_SIZE]; - char *calcsize; + char number[NUM_STR_SIZE], *req; + disk_t * dp; + int i; + time_t estimates, timeout; + size_t req_len; + const security_driver_t *secdrv; + char * dumper; + char * calcsize; + char * qname; assert(hostp->disks != NULL); @@ -1245,7 +1318,6 @@ am_host_t *hostp; * empty structure. In either case, we do the disks on the second * (and subsequent) pass(es). */ - if(hostp->features != NULL) { /* sendsize service */ int nb_client = 0; int nb_server = 0; @@ -1256,8 +1328,10 @@ am_host_t *hostp; fe_req_options_hostname); int has_maxdumps = am_has_feature(hostp->features, fe_req_options_maxdumps); + int has_config = am_has_feature(hostp->features, + fe_req_options_config); - ap_snprintf(number, sizeof(number), "%d", hostp->maxdumps); + snprintf(number, SIZEOF(number), "%d", hostp->maxdumps); req = vstralloc("SERVICE ", "sendsize", "\n", "OPTIONS ", has_features ? "features=" : "", @@ -1269,65 +1343,93 @@ am_host_t *hostp; has_hostname ? "hostname=" : "", has_hostname ? hostp->hostname : "", has_hostname ? ";" : "", + has_config ? "config=" : "", + has_config ? config_name : "", + has_config ? ";" : "", "\n", NULL); req_len = strlen(req); - req_len += 128; /* room for SECURITY ... */ + req_len += 128; /* room for SECURITY ... */ estimates = 0; for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) { char *s = NULL; - int s_len = 0; - + size_t s_len = 0; + if(dp->todo == 0) continue; - if(est(dp)->state != DISK_READY) { - continue; - } + if(est(dp)->state != DISK_READY) continue; est(dp)->got_estimate = 0; if(est(dp)->level[0] == -1) { est(dp)->state = DISK_DONE; - continue; /* ignore this disk */ + continue; } - + + qname = quote_string(dp->name); if(dp->estimate == ES_CLIENT || dp->estimate == ES_CALCSIZE) { nb_client++; - + 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]; - + if(lev == -1) break; - - ap_snprintf(level, sizeof(level), "%d", lev); - ap_snprintf(spindle, sizeof(spindle), "%d", dp->spindle); + + 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"); + } excludefree = exclude2; + includefree = NULL; } else { if(dp->exclude_file && dp->exclude_file->nb_element == 1) { exclude1 = " exclude-file="; - exclude2 = dp->exclude_file->first->name; + 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 = dp->exclude_list->first->name; + 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; } } + 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, dp->name); + hostp->hostname, qname); dp->estimate = ES_CLIENT; } if(dp->estimate == ES_CLIENT) @@ -1335,51 +1437,42 @@ am_host_t *hostp; else calcsize = "CALCSIZE "; - if(dp->device) { - l = vstralloc(calcsize, - dp->program, " ", - dp->name, " ", - dp->device, " ", - level, " ", - est(dp)->dumpdate[i], " ", spindle, - exclude1, - exclude2, - "\n", - NULL); - } - else { - l = vstralloc(calcsize, - dp->program, " ", - dp->name, " ", - level, " ", - est(dp)->dumpdate[i], " ", spindle, - exclude1, - exclude2, - "\n", - NULL); + if(strncmp(dp->program,"DUMP",4) == 0 || + strncmp(dp->program,"GNUTAR",6) == 0) { + dumper = ""; + } else { + dumper = "DUMPER "; } - amfree(excludefree); + 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); strappend(s, l); s_len += strlen(l); amfree(l); + amfree(includefree); + amfree(excludefree); } - /* - * Allow 2X for err response. - */ - if(req_len + s_len > MAX_DGRAM / 2) { + if (s != NULL) { + estimates += i; + strappend(req, s); + req_len += s_len; amfree(s); - break; } - 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++) { @@ -1388,11 +1481,12 @@ am_host_t *hostp; if(lev == -1) break; if(lev == 0) { /* use latest level 0, should do extrapolation */ - long est_size = 0; + 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++; } @@ -1400,28 +1494,28 @@ am_host_t *hostp; if(nb_est > 0) { est(dp)->est_size[i] = est_size; } - else if(info.inf[lev].size > 1000) { /* stats */ + 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] = 1000000; + 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; - long est_size_day[NB_DAY]; + off_t est_size_day[NB_DAY]; int nb_est_day[NB_DAY]; - for(j=0;j=0;j--) { if(info.history[j].level <= 0) continue; - if(info.history[j].level == info.history[j+1].level) { + if(info.history[j].size < (off_t)0) continue; + if(info.history[j].level==info.history[j+1].level) { if(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] / nb_est_day[nb_day]; + est(dp)->est_size[i] = est_size_day[nb_day] / + (off_t)nb_est_day[nb_day]; } - else if(info.inf[lev].size > 1000) { /* stats */ + 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] = 10000; + est(dp)->est_size[i] = (off_t)10000; } } else if(lev == est(dp)->last_level + 1) { /* means of all first day at a new level */ - long est_size = 0; + 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 / nb_est; + est(dp)->est_size[i] = est_size / (off_t)nb_est; } - else if(info.inf[lev].size > 1000) { /* stats */ + 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] = 100000; + est(dp)->est_size[i] = (off_t)100000; } } } fprintf(stderr,"%s time %s: got result for host %s disk %s:", get_pname(), walltime_str(curclock()), - dp->host->hostname, dp->name); - fprintf(stderr," %d -> %ldK, %d -> %ldK, %d -> %ldK\n", - est(dp)->level[0], est(dp)->est_size[0], - est(dp)->level[1], est(dp)->est_size[1], - est(dp)->level[2], est(dp)->est_size[2]); + 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(qname); } + if(estimates == 0) { amfree(req); hostp->up = HOST_DONE; @@ -1505,47 +1602,32 @@ am_host_t *hostp; timeout = getconf_int(CNF_CTIMEOUT); } -#ifdef KRB4_SECURITY - if(hostp->disks->auth == AUTH_KRB4) - rc = make_krb_request(hostp->hostname, kamanda_port, req, - hostp, timeout, handle_result); - else -#endif - rc = make_request(hostp->hostname, amanda_port, req, - hostp, timeout, handle_result); - - req = NULL; /* do not own this any more */ - - if(rc) { - errstr = vstralloc("could not resolve hostname \"", - hostp->hostname, - "\"", - NULL); - destqp = &failq; - hostp->up = HOST_DONE; - disk_state = DISK_DONE; - } - else { - errstr = NULL; - destqp = &waitq; - hostp->up = HOST_ACTIVE; - disk_state = DISK_ACTIVE; + secdrv = security_getdriver(hostp->disks->security_driver); + if (secdrv == NULL) { + error("could not find security driver '%s' for host '%s'", + hostp->disks->security_driver, hostp->hostname); + /*NOTREACHED*/ } + hostp->up = HOST_ACTIVE; for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) { - if(dp->todo && est(dp)->state == DISK_ACTIVE) { - est(dp)->state = disk_state; - est(dp)->errstr = errstr; - errstr = NULL; - enqueue_disk(destqp, dp); + if(dp->todo == 0) { + continue; + } + if(est(dp)->state == DISK_ACTIVE) { + est(dp)->errstr = NULL; + enqueue_disk(&waitq, dp); } } - amfree(errstr); + + protocol_sendreq(hostp->hostname, secdrv, amhost_get_security_conf, + req, timeout, handle_result, hostp); + amfree(req); } -static disk_t *lookup_hostdisk(hp, str) -am_host_t *hp; -char *str; +static disk_t *lookup_hostdisk( + /*@keep@*/ am_host_t *hp, + char *str) { disk_t *dp; @@ -1556,71 +1638,73 @@ char *str; } -static void handle_result(p, pkt) -proto_t *p; -pkt_t *pkt; +static void handle_result( + void *datap, + pkt_t *pkt, + security_handle_t *sech) { int level, i; - long size; + off_t size; disk_t *dp; am_host_t *hostp; char *msgdisk=NULL, *msgdisk_undo=NULL, msgdisk_undo_ch = '\0'; - char *errbuf = NULL; - char *line; - char *fp; + char *remoterr, *errbuf = NULL; char *s; char *t; + char *fp; + char *line; int ch; int tch; + char *qname; + char *disk; + OFF_T_FMT_TYPE size_; - hostp = (am_host_t *) p->datap; + hostp = (am_host_t *)datap; hostp->up = HOST_READY; - if(p->state == S_FAILED && pkt == NULL) { - if(p->prevstate == S_REPWAIT) { - errbuf = vstralloc("Estimate timeout from ", hostp->hostname, - NULL); - } - else { - errbuf = vstralloc("Request to ", hostp->hostname, " timed out.", - NULL); - } + if (pkt == NULL) { + errbuf = vstralloc("Request to ", hostp->hostname, " failed: ", + security_geterror(sech), NULL); goto error_return; } - -#if 0 - fprintf(stderr, "got %sresponse from %s:\n----\n%s----\n\n", - (p->state == S_FAILED) ? "NAK " : "", hostp->hostname, pkt->body); -#endif - -#ifdef KRB4_SECURITY - if(hostp->disks->auth == AUTH_KRB4 && - !check_mutual_authenticator(host2key(hostp->hostname), pkt, p)) { - errbuf = vstralloc(hostp->hostname, - "[mutual-authentication failed]", - NULL); - 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; + ch = *s++; +#undef sc + } else { + goto NAK_parse_failed; + } + skip_whitespace(s, ch); + if(ch == '\0') goto NAK_parse_failed; + remoterr = s - 1; + if((s = strchr(remoterr, '\n')) != NULL) { + if(s == remoterr) goto NAK_parse_failed; + *s = '\0'; + } + if (strcmp(remoterr, "unknown service: noop") != 0 + && strcmp(remoterr, "noop: invalid service") != 0) { + errbuf = vstralloc(hostp->hostname, " NAK: ", remoterr, NULL); + if(s) *s = '\n'; + goto error_return; + } } -#endif msgdisk_undo = NULL; s = pkt->body; ch = *s++; while(ch) { line = s - 1; - skip_line(s, ch); - if (s[-2] == '\n') { - s[-2] = '\0'; - } #define sc "OPTIONS " - if(strncmp(line, sc, sizeof(sc)-1) == 0) { + 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; + t += SIZEOF(sc)-1; #undef sc am_release_feature_set(hostp->features); if((hostp->features = am_string_to_feature(t)) == NULL) { @@ -1632,13 +1716,13 @@ pkt_t *pkt; goto error_return; } } - + skip_quoted_line(s, ch); continue; } #define sc "ERROR " - if(strncmp(line, sc, sizeof(sc)-1) == 0) { - t = line + sizeof(sc)-1; + if(strncmp(line, sc, SIZEOF(sc) - 1) == 0) { + t = line + SIZEOF(sc) - 1; tch = t[-1]; #undef sc @@ -1647,39 +1731,45 @@ pkt_t *pkt; if (tch == '\n') { t[-1] = '\0'; } + /* * If the "error" is that the "noop" service is unknown, it * just means the client is "old" (does not support the servie). * We can ignore this. */ if(hostp->features == NULL - && p->state == S_FAILED + && pkt->type == P_NAK && (strcmp(t - 1, "unknown service: noop") == 0 - || strcmp(t - 1, "noop: invalid service") == 0)) { + || strcmp(t - 1, "noop: invalid service") == 0)) { + skip_quoted_line(s, ch); continue; - } else { - errbuf = vstralloc(hostp->hostname, - (p->state == S_FAILED) ? "NAK " : "", - ": ", - fp, - NULL); - goto error_return; } + errbuf = vstralloc(hostp->hostname, + (pkt->type == P_NAK) ? "NAK " : "", + ": ", + fp, + NULL); + goto error_return; } msgdisk = t = line; - tch = *t++; - skip_non_whitespace(t, tch); + tch = *(t++); + skip_quoted_string(t, tch); msgdisk_undo = t - 1; msgdisk_undo_ch = *msgdisk_undo; *msgdisk_undo = '\0'; - + disk = unquote_string(msgdisk); skip_whitespace(t, tch); - if (sscanf(t - 1, "%d SIZE %ld", &level, &size) != 2) { + s = t; + ch = tch; + + size_ = (OFF_T_FMT_TYPE)0; + if (sscanf(t - 1, "%d SIZE " OFF_T_FMT , &level, &size_) != 2) { goto bad_msg; } - - dp = lookup_hostdisk(hostp, msgdisk); + size = size_; + dp = lookup_hostdisk(hostp, disk); + amfree(disk); *msgdisk_undo = msgdisk_undo_ch; /* for error message */ msgdisk_undo = NULL; @@ -1699,6 +1789,7 @@ pkt_t *pkt; } est(dp)->got_estimate++; } + skip_quoted_line(s, ch); } if(hostp->up == HOST_READY && hostp->features == NULL) { @@ -1711,6 +1802,8 @@ pkt_t *pkt; hostp->features = am_set_default_feature_set(); } + security_close_connection(sech, hostp->hostname); + /* XXX what about disks that only got some estimates... do we care? */ /* XXX amanda 2.1 treated that case as a bad msg */ @@ -1736,47 +1829,46 @@ pkt_t *pkt; if(est(dp)->level[0] == -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:", get_pname(), walltime_str(curclock()), - dp->host->hostname, dp->name); - fprintf(stderr," %d -> %ldK, %d -> %ldK, %d -> %ldK\n", - est(dp)->level[0], est(dp)->est_size[0], - est(dp)->level[1], est(dp)->est_size[1], - est(dp)->level[2], est(dp)->est_size[2]); + 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]); enqueue_disk(&pestq, dp); } else if(pkt->type == P_REP) { fprintf(stderr,"%s: time %s: got result for host %s disk %s:", get_pname(), walltime_str(curclock()), - dp->host->hostname, dp->name); - fprintf(stderr," %d -> %ldK, %d -> %ldK, %d -> %ldK\n", - est(dp)->level[0], est(dp)->est_size[0], - est(dp)->level[1], est(dp)->est_size[1], - est(dp)->level[2], est(dp)->est_size[2]); - if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > 0) || - (est(dp)->level[1] != -1 && est(dp)->est_size[1] > 0) || - (est(dp)->level[2] != -1 && est(dp)->est_size[2] > 0)) { - - if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < 0) { + 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: %d.", - dp->host->hostname, dp->name, - est(dp)->level[2], est(dp)->est_size[2]); + "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] < 0) { + 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: %d.", - dp->host->hostname, dp->name, - est(dp)->level[1], est(dp)->est_size[1]); + "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] < 0) { + 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: %d.", - dp->host->hostname, dp->name, - est(dp)->level[0], est(dp)->est_size[0]); + "disk %s:%s, estimate of level %d failed.", + dp->host->hostname, qname, est(dp)->level[0]); est(dp)->level[0] = -1; } enqueue_disk(&estq, dp); @@ -1784,42 +1876,53 @@ pkt_t *pkt; else { enqueue_disk(&failq, dp); if(est(dp)->got_estimate) { - est(dp)->errstr = vstralloc("disk ", dp->name, + est(dp)->errstr = vstralloc("disk ", qname, ", all estimate failed", NULL); } else { fprintf(stderr, "error result for host %s disk %s: missing estimate\n", - dp->host->hostname, dp->name); - est(dp)->errstr = vstralloc("missing result for ", dp->name, + dp->host->hostname, qname); + est(dp)->errstr = vstralloc("missing result for ", qname, " in ", dp->host->hostname, " response", NULL); } } } + amfree(qname); } getsize(hostp); return; - bad_msg: + 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", + 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"); - fprintf(stderr,"----\n%s\n----\n\n", line); + /*@ignore@*/ + fprintf(stderr,"----\n%s----\n\n", line); errbuf = stralloc2("badly formatted response from ", hostp->hostname); - /* fall through to ... */ + /*@end@*/ error_return: - - if(msgdisk_undo) { - *msgdisk_undo = msgdisk_undo_ch; - msgdisk_undo = NULL; - } 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); @@ -1827,10 +1930,10 @@ pkt_t *pkt; i++; est(dp)->errstr = stralloc(errbuf); - fprintf(stderr, "%s: time %s: error result for host %s disk %s: %s\n", - get_pname(), walltime_str(curclock()), - dp->host->hostname, dp->name, errbuf); + fprintf(stderr, "error result for host %s disk %s: %s\n", + dp->host->hostname, qname, errbuf); } + amfree(qname); } if(i == 0) { /* @@ -1852,20 +1955,21 @@ pkt_t *pkt; * */ -static int schedule_order P((disk_t *a, disk_t *b)); /* subroutines */ -static int pick_inclevel P((disk_t *dp)); +static int schedule_order(disk_t *a, disk_t *b); /* subroutines */ +static int pick_inclevel(disk_t *dp); -static void analyze_estimate(dp) -disk_t *dp; +static void analyze_estimate( + disk_t *dp) { est_t *ep; info_t info; int have_info = 0; + char *qname = quote_string(dp->name); ep = est(dp); fprintf(stderr, "pondering %s:%s... ", - dp->host->hostname, dp->name); + dp->host->hostname, qname); fprintf(stderr, "next_level0 %d last_level %d ", ep->next_level0, ep->last_level); @@ -1874,44 +1978,51 @@ disk_t *dp; } ep->degr_level = -1; - ep->degr_size = -1; + ep->degr_nsize = (off_t)-1; + ep->degr_csize = (off_t)-1; - if(ep->next_level0 <= 0 - || (have_info && ep->last_level == 0 && (info.command & FORCE_NO_BUMP))) { + 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_size = est_tape_size(dp, 0); - if(ep->dump_size <= 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_size = est_tape_size(dp, ep->dump_level); + ep->dump_nsize = est_size(dp, ep->dump_level); + ep->dump_csize = est_tape_size(dp, ep->dump_level); - if(ep->dump_size == -1) { + if(ep->dump_nsize == (off_t)-1) { ep->dump_level = ep->dump_level + 1; - ep->dump_size = est_tape_size(dp, ep->dump_level); + ep->dump_nsize = est_size(dp, ep->dump_level); + ep->dump_csize = est_tape_size(dp, ep->dump_level); } } else { - total_lev0 += (double) ep->dump_size; + total_lev0 += (double) ep->dump_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_size = -1; + ep->degr_nsize = (off_t)-1; + ep->degr_csize = (off_t)-1; } else { /* fill in degraded mode info */ fprintf(stderr,"(picking inclevel for degraded mode)"); ep->degr_level = pick_inclevel(dp); - ep->degr_size = est_tape_size(dp, ep->degr_level); - if(ep->degr_size == -1) { + 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_size = est_tape_size(dp, ep->degr_level); + ep->degr_nsize = est_size(dp, ep->degr_level); + ep->degr_csize = est_tape_size(dp, ep->degr_level); } - if(ep->degr_size == -1) { + if(ep->degr_csize == (off_t)-1) { fprintf(stderr,"(no inc estimate)"); ep->degr_level = -1; } @@ -1923,47 +2034,55 @@ disk_t *dp; 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_size = est_tape_size(dp, ep->dump_level); + ep->dump_nsize = est_size(dp, ep->dump_level); + ep->dump_csize = est_tape_size(dp, ep->dump_level); - if(ep->dump_size == -1) { + if(ep->dump_csize == (off_t)-1) { ep->dump_level = ep->last_level; - ep->dump_size = est_tape_size(dp, ep->dump_level); + ep->dump_nsize = est_size(dp, ep->dump_level); + ep->dump_csize = est_tape_size(dp, ep->dump_level); } - if(ep->dump_size == -1) { + if(ep->dump_csize == (off_t)-1) { ep->dump_level = ep->last_level + 1; - ep->dump_size = est_tape_size(dp, ep->dump_level); + ep->dump_nsize = est_size(dp, ep->dump_level); + ep->dump_csize = est_tape_size(dp, ep->dump_level); } - if(ep->dump_size == -1) { + if(ep->dump_csize == (off_t)-1) { ep->dump_level = 0; - ep->dump_size = est_tape_size(dp, ep->dump_level); + ep->dump_nsize = est_size(dp, ep->dump_level); + ep->dump_csize = est_tape_size(dp, ep->dump_level); } } - fprintf(stderr," curr level %d size %ld ", ep->dump_level, ep->dump_size); + 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); insert_disk(&schedq, dp, schedule_order); - total_size += tt_blocksize_kb + ep->dump_size + tape_mark; + total_size += (off_t)tt_blocksize_kb + ep->dump_csize + tape_mark; /* update the balanced size */ if(!(dp->skip_full || dp->strategy == DS_NOFULL || dp->strategy == DS_INCRONLY)) { - long lev0size; + off_t lev0size; lev0size = est_tape_size(dp, 0); - if(lev0size == -1) lev0size = ep->last_lev0size; + if(lev0size == (off_t)-1) lev0size = ep->last_lev0size; - balanced_size += lev0size / runs_per_cycle; + balanced_size += (double)(lev0size / (off_t)runs_per_cycle); } - fprintf(stderr,"total size %ld total_lev0 %1.0f balanced-lev0size %1.0f\n", - total_size, total_lev0, balanced_size); + 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(dp) -disk_t *dp; +static void handle_failed( + disk_t *dp) { char *errstr; + char *qname = quote_string(dp->name); /* * From George Scott : @@ -1981,9 +2100,10 @@ disk_t *dp; #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, dp->name); + "Could not get estimate for %s:%s, using historical data.", + dp->host->hostname, qname); analyze_estimate(dp); + amfree(qname); return; } #endif @@ -1991,40 +2111,45 @@ disk_t *dp; errstr = est(dp)->errstr? est(dp)->errstr : "hmm, no error indicator!"; fprintf(stderr, "%s: FAILED %s %s %s 0 [%s]\n", - get_pname(), dp->host->hostname, dp->name, datestamp, errstr); + get_pname(), dp->host->hostname, qname, planner_timestamp, errstr); - log_add(L_FAIL, "%s %s %s 0 [%s]", dp->host->hostname, dp->name, datestamp, errstr); + log_add(L_FAIL, "%s %s %s 0 [%s]", dp->host->hostname, qname, + planner_timestamp, errstr); + amfree(qname); /* XXX - memory leak with *dp */ } -static int schedule_order(a, b) -disk_t *a, *b; /* * insert-sort by decreasing priority, then * by decreasing size within priority levels. */ + +static int schedule_order( + disk_t *a, + disk_t *b) { int diff; - long ldiff; + off_t ldiff; diff = est(b)->dump_priority - est(a)->dump_priority; if(diff != 0) return diff; - ldiff = est(b)->dump_size - est(a)->dump_size; - if(ldiff < 0) return -1; /* XXX - there has to be a better way to dothis */ - if(ldiff > 0) return 1; + 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; return 0; } -static int pick_inclevel(dp) -disk_t *dp; +static int pick_inclevel( + disk_t *dp) { int base_level, bump_level; - long base_size, bump_size; - long thresh; + off_t base_size, bump_size; + off_t thresh; + char *qname; base_level = est(dp)->last_level; @@ -2043,9 +2168,9 @@ disk_t *dp; base_size = est_size(dp, base_level); /* if we didn't get an estimate, we can't do an inc */ - if(base_size == -1) { + if(base_size == (off_t)-1) { base_size = est_size(dp, base_level+1); - if(base_size > 0) /* FORCE_BUMP */ + 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; @@ -2054,9 +2179,9 @@ disk_t *dp; thresh = bump_thresh(base_level, est_size(dp, 0), dp->bumppercent, dp->bumpsize, dp->bumpmult); fprintf(stderr, - " pick: size %ld level %d days %d (thresh %ldK, %d days)\n", - base_size, base_level, est(dp)->level_days, - thresh, dp->bumpdays); + " 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); if(base_level == 9 || est(dp)->level_days < dp->bumpdays @@ -2066,18 +2191,21 @@ disk_t *dp; bump_level = base_level + 1; bump_size = est_size(dp, bump_level); - if(bump_size == -1) return base_level; + if(bump_size == (off_t)-1) return base_level; - fprintf(stderr, " pick: next size %ld... ", bump_size); + fprintf(stderr, " pick: next size " OFF_T_FMT "... ", + (OFF_T_FMT_TYPE)bump_size); if(base_size - bump_size < thresh) { fprintf(stderr, "not bumped\n"); return base_level; } + qname = quote_string(dp->name); fprintf(stderr, "BUMPED\n"); log_add(L_INFO, "Incremental of %s:%s bumped to level %d.", - dp->host->hostname, dp->name, bump_level); + dp->host->hostname, qname, bump_level); + amfree(qname); return bump_level; } @@ -2109,19 +2237,25 @@ disk_t *dp; ** more balanced cycle. */ -static void delay_one_dump P((disk_t *dp, int delete, ...)); +static void delay_one_dump(disk_t *dp, int delete, ...); +static int promote_highest_priority_incremental(void); +static int promote_hills(void); -static void delay_dumps P((void)) /* delay any dumps that will not fit */ +static void delay_dumps(void) { - disk_t *dp, *ndp, *preserve; - bi_t *bi, *nbi; - long 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; + disk_t * dp; + disk_t * ndp; + disk_t * preserve; + bi_t * bi; + bi_t * nbi; + off_t 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; biq.head = biq.tail = NULL; @@ -2137,14 +2271,38 @@ static void delay_dumps P((void)) */ for(dp = schedq.head; dp != NULL; dp = ndp) { + int avail_tapes = 1; + if (dp->tape_splitsize > (off_t)0) + avail_tapes = conf_runtapes; + ndp = dp->next; /* remove_disk zaps this */ - if (est(dp)->dump_size <= tape->length) { + full_size = est_tape_size(dp, 0); + if (full_size > tapetype_get_length(tape) * (off_t)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", + dp->host->hostname, qname, + (OFF_T_FMT_TYPE)full_size); + } else { + log_add(L_WARNING, "disk %s:%s, full dump (" OFF_T_FMT + "KB) will be larger than available tape space", + dp->host->hostname, qname, + (OFF_T_FMT_TYPE)full_size); + } + amfree(qname); + } + + if (est(dp)->dump_csize == (off_t)-1 || + est(dp)->dump_csize <= tapetype_get_length(tape) * (off_t)avail_tapes) { continue; } - /* Format dumpsize for messages */ - ap_snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size); + /* Format dumpsize for messages */ + snprintf(est_kb, 20, OFF_T_FMT " KB,", + (OFF_T_FMT_TYPE)est(dp)->dump_csize); if(est(dp)->dump_level == 0) { if(dp->skip_incr) { @@ -2159,6 +2317,10 @@ static void delay_dumps P((void)) delete = 1; message = "but no incremental estimate"; } + else if (est(dp)->degr_csize > tapetype_get_length(tape)) { + delete = 1; + message = "incremental dump also larger than tape"; + } else { delete = 0; message = "full dump delayed"; @@ -2168,8 +2330,8 @@ static void delay_dumps P((void)) delete = 1; message = "skipping incremental"; } - delay_one_dump(dp, delete, "dump larger than tape,", est_kb, - message, NULL); + delay_one_dump(dp, delete, "dump larger than available tape space,", + est_kb, message, NULL); } /* @@ -2208,8 +2370,9 @@ static void delay_dumps P((void)) if(dp != preserve) { - /* Format dumpsize for messages */ - ap_snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size); + /* Format dumpsize for messages */ + snprintf(est_kb, 20, OFF_T_FMT " KB,", + (OFF_T_FMT_TYPE)est(dp)->dump_csize); if(dp->skip_incr) { delete = 1; @@ -2242,7 +2405,8 @@ static void delay_dumps P((void)) if(est(dp)->dump_level == 0 && dp != preserve) { /* Format dumpsize for messages */ - ap_snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size); + snprintf(est_kb, 20, OFF_T_FMT " KB,", + (OFF_T_FMT_TYPE)est(dp)->dump_csize); if(dp->skip_incr) { delete = 1; @@ -2281,8 +2445,9 @@ static void delay_dumps P((void)) if(est(dp)->dump_level != 0) { - /* Format dumpsize for messages */ - ap_snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size); + /* Format dumpsize for messages */ + snprintf(est_kb, 20, OFF_T_FMT " KB,", + (OFF_T_FMT_TYPE)est(dp)->dump_csize); delay_one_dump(dp, 1, "dumps way too big,", @@ -2301,27 +2466,33 @@ static void delay_dumps P((void)) ** in but why complicate the code? */ - for(bi = biq.tail; bi != NULL; bi = nbi) { +/*@i@*/ for(bi = biq.tail; bi != NULL; bi = nbi) { + int avail_tapes = 1; nbi = bi->prev; dp = bi->dp; + if(dp->tape_splitsize > (off_t)0) + avail_tapes = conf_runtapes; - if(bi->deleted) - new_total = total_size + tt_blocksize_kb + bi->size + tape_mark; - else - new_total = total_size - est(dp)->dump_size + bi->size; - - if(new_total <= tape_length && bi->size < tape->length) { + if(bi->deleted) { + new_total = total_size + (off_t)tt_blocksize_kb + + bi->csize + (off_t)tape_mark; + } else { + new_total = total_size - est(dp)->dump_csize + bi->csize; + } + if((new_total <= tape_length) && + (bi->csize < (tapetype_get_length(tape) * (off_t)avail_tapes))) { /* reinstate it */ total_size = new_total; if(bi->deleted) { if(bi->level == 0) { - total_lev0 += (double) bi->size; + total_lev0 += (double) bi->csize; } insert_disk(&schedq, dp, schedule_order); } else { est(dp)->dump_level = bi->level; - est(dp)->dump_size = bi->size; + est(dp)->dump_nsize = bi->nsize; + est(dp)->dump_csize = bi->csize; } /* Keep it clean */ @@ -2333,6 +2504,7 @@ static void delay_dumps P((void)) biq.head = bi->next; else (bi->prev)->next = bi->next; + amfree(bi->errstr); amfree(bi); } @@ -2346,9 +2518,8 @@ static void delay_dumps P((void)) ** now. */ - for(bi = biq.head; bi != NULL; bi = nbi) { +/*@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); log_add(L_FAIL, "%s", bi->errstr); @@ -2359,13 +2530,14 @@ static void delay_dumps P((void)) bi->errstr, est(dp)->dump_level); log_add(L_INFO, "%s", bi->errstr); } - - /* Clean up - dont be too fancy! */ + /*@ignore@*/ amfree(bi->errstr); amfree(bi); + /*@end@*/ } - fprintf(stderr, " delay: Total size now %ld.\n", total_size); + fprintf(stderr, " delay: Total size now " OFF_T_FMT ".\n", + (OFF_T_FMT_TYPE)total_size); return; } @@ -2375,24 +2547,26 @@ static void delay_dumps P((void)) * Remove a dump or modify it from full to incremental. * Keep track of it on the bi q in case we can add it back later. */ -arglist_function1(static void delay_one_dump, - disk_t *, dp, - int, delete) +arglist_function1( + static void delay_one_dump, + disk_t *, dp, + int, delete) { bi_t *bi; va_list argp; char level_str[NUM_STR_SIZE]; char *sep; char *next; + char *qname = quote_string(dp->name); arglist_start(argp, delete); - total_size -= tt_blocksize_kb + est(dp)->dump_size + tape_mark; + 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_size; + total_lev0 -= (double) est(dp)->dump_csize; } - bi = alloc(sizeof(bi_t)); + bi = alloc(SIZEOF(bi_t)); bi->next = NULL; bi->prev = biq.tail; if(biq.tail == NULL) @@ -2404,12 +2578,13 @@ arglist_function1(static void delay_one_dump, bi->deleted = delete; bi->dp = dp; bi->level = est(dp)->dump_level; - bi->size = est(dp)->dump_size; + bi->nsize = est(dp)->dump_nsize; + bi->csize = est(dp)->dump_csize; - ap_snprintf(level_str, sizeof(level_str), "%d", est(dp)->dump_level); + snprintf(level_str, SIZEOF(level_str), "%d", est(dp)->dump_level); bi->errstr = vstralloc(dp->host->hostname, - " ", dp->name, - " ", datestamp ? datestamp : "?", + " ", qname, + " ", planner_timestamp ? planner_timestamp : "?", " ", level_str, NULL); sep = " ["; @@ -2424,21 +2599,23 @@ arglist_function1(static void delay_one_dump, remove_disk(&schedq, dp); } else { est(dp)->dump_level = est(dp)->degr_level; - est(dp)->dump_size = est(dp)->degr_size; - total_size += tt_blocksize_kb + est(dp)->dump_size + tape_mark; + 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; } - + amfree(qname); return; } -static int promote_highest_priority_incremental P((void)) +static int promote_highest_priority_incremental(void) { disk_t *dp, *dp1, *dp_promote; - long new_size, new_total, new_lev0; + off_t new_size, new_total, new_lev0; int check_days; int nb_today, nb_same_day, nb_today2; int nb_disk_today, nb_disk_same_day; + char *qname; /* * return 1 if did so; must update total_size correctly; must not @@ -2450,7 +2627,7 @@ static int promote_highest_priority_incremental P((void)) est(dp)->promote = -1000; - if(est_size(dp,0) <= 0) + if(est_size(dp,0) <= (off_t)0) continue; if(est(dp)->next_level0 <= 0) @@ -2460,14 +2637,14 @@ static int promote_highest_priority_incremental P((void)) continue; new_size = est_tape_size(dp, 0); - new_total = total_size - est(dp)->dump_size + new_size; - new_lev0 = total_lev0 + new_size; + new_total = total_size - est(dp)->dump_csize + new_size; + new_lev0 = (off_t)total_lev0 + new_size; 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) { + for(dp1 = schedq.head; dp1 != NULL; dp1 = dp1->next) { if(est(dp1)->dump_level == 0) nb_disk_today++; else if(est(dp1)->next_level0 == est(dp)->next_level0) @@ -2481,18 +2658,22 @@ static int promote_highest_priority_incremental P((void)) } /* do not promote if overflow tape */ - if(new_total > tape_length) continue; + if(new_total > tape_length) + continue; /* do not promote if overflow balanced size and something today */ /* promote if nothing today */ - if(new_lev0 > balanced_size+balance_threshold && nb_disk_today > 0) + if((new_lev0 > (off_t)(balanced_size + balance_threshold)) && + (nb_disk_today > 0)) continue; /* do not promote if only one disk due that day and nothing today */ - if(nb_disk_same_day == 1 && nb_disk_today == 0) continue; + if(nb_disk_same_day == 1 && nb_disk_today == 0) + continue; nb_today2 = nb_today*nb_today; - if(nb_today == 0 && nb_same_day > 1) nb_same_day++; + if(nb_today == 0 && nb_same_day > 1) + nb_same_day++; if(nb_same_day >= nb_today2) { est(dp)->promote = ((nb_same_day - nb_today2)*(nb_same_day - nb_today2)) + @@ -2503,61 +2684,68 @@ static int promote_highest_priority_incremental P((void)) conf_dumpcycle - est(dp)->next_level0; } - if(!dp_promote || est(dp_promote)->promote < est(dp)->promote) { + 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", - dp->host->hostname, dp->name, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote); + dp->host->hostname, qname, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote); } - else { + else { fprintf(stderr,"no try %s:%s %d %d %d = %d\n", - dp->host->hostname, dp->name, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote); + dp->host->hostname, qname, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote); } + amfree(qname); } if(dp_promote) { dp = dp_promote; + qname = quote_string(dp->name); new_size = est_tape_size(dp, 0); - new_total = total_size - est(dp)->dump_size + new_size; - new_lev0 = total_lev0 + new_size; + new_total = total_size - est(dp)->dump_csize + new_size; + new_lev0 = (off_t)total_lev0 + new_size; total_size = new_total; - total_lev0 = new_lev0; + total_lev0 = (double)new_lev0; check_days = est(dp)->next_level0; est(dp)->degr_level = est(dp)->dump_level; - est(dp)->degr_size = est(dp)->dump_size; + est(dp)->degr_nsize = est(dp)->dump_nsize; + est(dp)->degr_csize = est(dp)->dump_csize; est(dp)->dump_level = 0; - est(dp)->dump_size = new_size; + est(dp)->dump_nsize = est_size(dp, 0); + est(dp)->dump_csize = new_size; est(dp)->next_level0 = 0; fprintf(stderr, - " promote: moving %s:%s up, total_lev0 %1.0f, total_size %ld\n", - dp->host->hostname, dp->name, - total_lev0, total_size); + " promote: moving %s:%s up, total_lev0 %1.0lf, total_size " OFF_T_FMT "\n", + dp->host->hostname, qname, + total_lev0, (OFF_T_FMT_TYPE)total_size); log_add(L_INFO, "Full dump of %s:%s promoted from %d day%s ahead.", - dp->host->hostname, dp->name, + dp->host->hostname, qname, check_days, (check_days == 1) ? "" : "s"); + amfree(qname); return 1; } return 0; } -static int promote_hills P((void)) +static int promote_hills(void) { disk_t *dp; struct balance_stats { int disks; - long size; + off_t size; } *sp = NULL; int days; int hill_days = 0; - long hill_size; - long new_size; - long new_total; + off_t hill_size; + off_t new_size; + off_t new_total; int my_dumpcycle; + char *qname; /* If we are already doing a level 0 don't bother */ if(total_lev0 > 0) @@ -2568,10 +2756,12 @@ static int promote_hills P((void)) if(my_dumpcycle > 10000) my_dumpcycle = 10000; sp = (struct balance_stats *) - alloc(sizeof(struct balance_stats) * my_dumpcycle); + alloc(SIZEOF(struct balance_stats) * my_dumpcycle); - for(days = 0; days < my_dumpcycle; days++) - sp[days].disks = sp[days].size = 0; + for(days = 0; days < my_dumpcycle; days++) { + sp[days].disks = 0; + sp[days].size = (off_t)0; + } for(dp = schedq.head; dp != NULL; dp = dp->next) { days = est(dp)->next_level0; /* This is > 0 by definition */ @@ -2585,7 +2775,7 @@ static int promote_hills P((void)) /* Search for a suitable big hill and cut it down */ while(1) { /* Find the tallest hill */ - hill_size = 0; + hill_size = (off_t)0; for(days = 0; days < my_dumpcycle; days++) { if(sp[days].disks > 1 && sp[days].size > hill_size) { hill_size = sp[days].size; @@ -2593,7 +2783,7 @@ static int promote_hills P((void)) } } - if(hill_size <= 0) break; /* no suitable hills */ + if(hill_size <= (off_t)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) { @@ -2604,28 +2794,32 @@ static int promote_hills P((void)) dp->strategy == DS_INCRONLY) continue; new_size = est_tape_size(dp, 0); - new_total = total_size - est(dp)->dump_size + new_size; + new_total = total_size - est(dp)->dump_csize + new_size; if(new_total > tape_length) continue; /* We found a disk we can promote */ + qname = quote_string(dp->name); total_size = new_total; - total_lev0 += new_size; + total_lev0 += (double)new_size; est(dp)->degr_level = est(dp)->dump_level; - est(dp)->degr_size = est(dp)->dump_size; + est(dp)->degr_nsize = est(dp)->dump_nsize; + est(dp)->degr_csize = est(dp)->dump_csize; est(dp)->dump_level = 0; est(dp)->next_level0 = 0; - est(dp)->dump_size = new_size; + est(dp)->dump_nsize = est_size(dp, 0); + est(dp)->dump_csize = new_size; fprintf(stderr, - " promote: moving %s:%s up, total_lev0 %1.0f, total_size %ld\n", - dp->host->hostname, dp->name, - total_lev0, total_size); + " promote: moving %s:%s up, total_lev0 %1.0lf, total_size " OFF_T_FMT "\n", + dp->host->hostname, qname, + total_lev0, (OFF_T_FMT_TYPE)total_size); log_add(L_INFO, "Full dump of %s:%s specially promoted from %d day%s ahead.", - dp->host->hostname, dp->name, + dp->host->hostname, qname, hill_days, (hill_days == 1) ? "" : "s"); + amfree(qname); amfree(sp); return 1; } @@ -2643,33 +2837,40 @@ static int promote_hills P((void)) * * XXX - memory leak - we shouldn't just throw away *dp */ -static void output_scheduleline(dp) - disk_t *dp; +static void output_scheduleline( + disk_t *dp) { est_t *ep; - long dump_time = 0, degr_time = 0; + time_t dump_time = 0, degr_time = 0; + double dump_kps = 0, degr_kps = 0; char *schedline = NULL, *degr_str = NULL; char dump_priority_str[NUM_STR_SIZE]; char dump_level_str[NUM_STR_SIZE]; - char dump_size_str[NUM_STR_SIZE]; + char dump_nsize_str[NUM_STR_SIZE]; + char dump_csize_str[NUM_STR_SIZE]; char dump_time_str[NUM_STR_SIZE]; + char dump_kps_str[NUM_STR_SIZE]; char degr_level_str[NUM_STR_SIZE]; - char degr_size_str[NUM_STR_SIZE]; + char degr_nsize_str[NUM_STR_SIZE]; + char degr_csize_str[NUM_STR_SIZE]; char degr_time_str[NUM_STR_SIZE]; + 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_size == -1) { + if(ep->dump_csize == (off_t)-1) { /* no estimate, fail the disk */ fprintf(stderr, "%s: FAILED %s %s %s %d [no estimate]\n", get_pname(), - dp->host->hostname, dp->name, datestamp, ep->dump_level); + dp->host->hostname, qname, planner_timestamp, ep->dump_level); log_add(L_FAIL, "%s %s %s %d [no estimate]", - dp->host->hostname, dp->name, datestamp, ep->dump_level); + dp->host->hostname, qname, planner_timestamp, ep->dump_level); + amfree(qname); return; } @@ -2684,47 +2885,62 @@ static void output_scheduleline(dp) #define fix_rate(rate) (rate < 1.0 ? DEFAULT_DUMPRATE : rate) if(ep->dump_level == 0) { - dump_time = ep->dump_size / fix_rate(ep->fullrate); + dump_kps = fix_rate(ep->fullrate); + dump_time = (time_t)((double)ep->dump_csize / dump_kps); - if(ep->degr_size != -1) { - degr_time = ep->degr_size / fix_rate(ep->incrrate); + if(ep->degr_csize != (off_t)-1) { + degr_kps = fix_rate(ep->incrrate); + degr_time = (time_t)((double)ep->degr_csize / degr_kps); } } else { - dump_time = ep->dump_size / fix_rate(ep->incrrate); + dump_kps = fix_rate(ep->incrrate); + dump_time = (time_t)((double)ep->dump_csize / dump_kps); } - if(ep->dump_level == 0 && ep->degr_size != -1) { - ap_snprintf(degr_level_str, sizeof(degr_level_str), + if(ep->dump_level == 0 && ep->degr_csize != (off_t)-1) { + snprintf(degr_level_str, sizeof(degr_level_str), "%d", ep->degr_level); - ap_snprintf(degr_size_str, sizeof(degr_size_str), - "%ld", ep->degr_size); - ap_snprintf(degr_time_str, sizeof(degr_time_str), - "%ld", degr_time); + 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), + "%.0lf", degr_kps); degr_str = vstralloc(" ", degr_level_str, " ", degr_date, - " ", degr_size_str, + " ", degr_nsize_str, + " ", degr_csize_str, " ", degr_time_str, + " ", degr_kps_str, NULL); } - ap_snprintf(dump_priority_str, sizeof(dump_priority_str), + snprintf(dump_priority_str, SIZEOF(dump_priority_str), "%d", ep->dump_priority); - ap_snprintf(dump_level_str, sizeof(dump_level_str), + snprintf(dump_level_str, SIZEOF(dump_level_str), "%d", ep->dump_level); - ap_snprintf(dump_size_str, sizeof(dump_size_str), - "%ld", ep->dump_size); - ap_snprintf(dump_time_str, sizeof(dump_time_str), - "%ld", dump_time); + 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), + "%.0lf", dump_kps); features = am_feature_to_string(dp->host->features); schedline = vstralloc("DUMP ",dp->host->hostname, " ", features, - " ", dp->name, - " ", datestamp, + " ", qname, + " ", planner_timestamp, " ", dump_priority_str, " ", dump_level_str, " ", dump_date, - " ", dump_size_str, + " ", dump_nsize_str, + " ", dump_csize_str, " ", dump_time_str, + " ", dump_kps_str, degr_str ? degr_str : "", "\n", NULL); @@ -2733,4 +2949,5 @@ static void output_scheduleline(dp) amfree(features); amfree(schedline); amfree(degr_str); + amfree(qname); }