⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 planner.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 5 页
字号:
			est(dp)->level[2], (long long)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;		    }		    enqueue_disk(&estq, dp);	    }	    else {		enqueue_disk(&failq, dp);		if(est(dp)->got_estimate) {		    est(dp)->errstr = vstrallocf("disk %s, all estimate failed",						 qname);		}		else {		    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);		    }		}	    }	}	amfree(qname);    }    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:    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:    g_fprintf(stderr,_("got a bad message, stopped at:\n"));    /*@ignore@*/    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 (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);		g_fprintf(stderr, _("error result for host %s disk %s: %s\n"),			  dp->host->hostname, qname, errbuf);		amfree(qname);	    }	}    }    if(i == 0) {	/*	 * If there were no disks involved, make sure the error gets	 * reported.	 */	log_add(L_ERROR, "%s", errbuf);    }    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);}/* * ======================================================================== * ANALYSE ESTIMATES * */static int schedule_order(disk_t *a, disk_t *b);	  /* subroutines */static int pick_inclevel(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);    g_fprintf(stderr, _("pondering %s:%s... "),	    dp->host->hostname, qname);    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;    if(ep->next_level0 <= 0 || (have_info && ep->last_level == 0       && (info.command & FORCE_NO_BUMP))) {	if(ep->next_level0 <= 0) {	    g_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) {	    g_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);	    }	}	else {	    total_lev0 += (double) ep->dump_csize;	    if(ep->last_level == -1 || dp->skip_incr) {		g_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;	    }	    else {		/* fill in degraded mode info */		g_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);		}		if(ep->degr_csize == (off_t)-1) {		    g_fprintf(stderr,_("(no inc estimate)"));		    ep->degr_level = -1;		}		g_fprintf(stderr,"\n");	    }	}    }    else {	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);	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_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_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);	}    }    g_fprintf(stderr,_("  curr level %d nsize %lld csize %lld "),    	    ep->dump_level, (long long)ep->dump_nsize,             (long long)ep->dump_csize);    insert_disk(&schedq, dp, schedule_order);    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)) {	off_t lev0size;	lev0size = est_tape_size(dp, 0);	if(lev0size == (off_t)-1) lev0size = ep->last_lev0size;	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);    amfree(qname);}static void handle_failed(    disk_t *dp){    char *errstr, *errstr1, *qerrstr;    char *qname = quote_string(dp->name);    errstr = est(dp)->errstr? est(dp)->errstr : _("hmm, no error indicator!");    errstr1 = vstralloc("[",errstr,"]", NULL);    qerrstr = quote_string(errstr1);    amfree(errstr1);    g_fprintf(stderr, _("%s: FAILED %s %s %s 0 %s\n"),	get_pname(), dp->host->hostname, qname, planner_timestamp, qerrstr);    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 */}/* * insert-sort by decreasing priority, then * by decreasing size within priority levels. */static int schedule_order(    disk_t *a,    disk_t *b){    int diff;    off_t 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;    return 0;}static int pick_inclevel(    disk_t *dp){    int base_level, bump_level;    off_t base_size, bump_size;    off_t thresh;    char *qname;    base_level = est(dp)->last_level;    /* if last night was level 0, do level 1 tonight, no ifs or buts */    if(base_level == 0) {	g_fprintf(stderr,_("   picklev: last night 0, so tonight level 1\n"));	return 1;    }    /* if no-full option set, always do level 1 */    if(dp->strategy == DS_NOFULL) {	g_fprintf(stderr,_("   picklev: no-full set, so always level 1\n"));	return 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;	g_fprintf(stderr,_("   picklev: no estimate for level %d, so no incs\n"), base_level);	return base_level;    }    thresh = bump_thresh(base_level, est_size(dp, 0), dp->bumppercent, dp->bumpsize, dp->bumpmult);    g_fprintf(stderr,	    _("   pick: size %lld level %d days %d (thresh %lldK, %d days)\n"),	    (long long)base_size, base_level, est(dp)->level_days,	    (long long)thresh, dp->bumpdays);    if(base_level == 9       || est(dp)->level_days < dp->bumpdays       || base_size <= thresh)	    return base_level;    bump_level = base_level + 1;    bump_size = est_size(dp, bump_level);    if(bump_size == (off_t)-1) return base_level;    g_fprintf(stderr, _("   pick: next size %lld... "),    	    (long long)bump_size);    if(base_size - bump_size < thresh) {	g_fprintf(stderr, _("not bumped\n"));	return base_level;    }    qname = quote_string(dp->name);    g_fprintf(stderr, _("BUMPED\n"));    log_add(L_INFO, _("Incremental of %s:%s bumped to level %d."),	    dp->host->hostname, qname, bump_level);    amfree(qname);    return bump_level;}/*** ========================================================================** ADJUST SCHEDULE**** We have two strategies here:**** 1. Delay dumps**** If we are trying to fit too much on the tape something has to go.  We** try to delay totals until tomorrow by converting them into incrementals** and, if that is not effective enough, dropping incrementals altogether.** While we are searching for the guilty dump (the one that is really** causing the schedule to be oversize) we have probably trampled on a lot of** innocent dumps, so we maintain a "before image" list and use this to** put back what we can.**** 2. Promote dumps.**** We try to keep the amount of tape used by total dumps the same each night.** If there is some spare tape in this run we have a look to see if any of** tonights incrementals could be promoted to totals and leave us with a** more balanced cycle.*/static void delay_one_dump(disk_t *dp, int delete, ...);static int promote_highest_priority_incremental(void);static int promote_hills(void);/* delay any dumps that will not fit */static void delay_dumps(void){    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;    /*    ** 1. Delay dumps that are way oversize.    **    ** Dumps larger that the size of the tapes we are using are just plain    ** not going to fit no matter how many other dumps we drop.  Delay    ** oversize totals until tomorrow (by which time my owner will have    ** resolved the problem!) and drop incrementals altogether.  Naturally    ** a large total might be delayed into a large incremental so these    ** need to be checked for separately.    */    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 */	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 (%lldKB) will be larger than available tape space"			", you could define a splitsize"),			dp->host->hostname, qname,			(long long)full_size);	    } else {		log_add(L_WARNING, _("disk %s:%s, full dump (%lldKB) will be larger than available tape space"),			dp->host->hostname, qname,			(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) {	    continue;	}	/* Format dumpsize for messages */	g_snprintf(est_kb, 20, "%lld KB,",		 (long long)est(dp)->dump_csize);	if(est(dp)->dump_level == 0) {	    if(dp->skip_incr) {		delete = 1;		message = _("but cannot incremental dump skip-incr disk");	    }	    else if(est(dp)->last_level < 0) {		delete = 1;		message = _("but cannot incremental dump new disk");	    }	    else if(est(dp)->degr_level < 0) {		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");	    }	}	else {	    delete = 1;	    message = _("skipping incremental");	}	delay_one_dump(dp, delete, _("dump larger than available tape space,"),		       est_kb, message, NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -