📄 planner.c
字号:
if(dp->exclude_file && dp->exclude_file->nb_element == 1) { exclude1 = " exclude-file="; exclude2 = quote_string(dp->exclude_file->first->name); excludefree = exclude2; } else if(dp->exclude_list && dp->exclude_list->nb_element == 1) { exclude1 = " exclude-list="; exclude2 = quote_string(dp->exclude_list->first->name); excludefree = exclude2; } if(dp->include_file && dp->include_file->nb_element == 1) { include1 = " include-file="; include2 = quote_string(dp->include_file->first->name); includefree = include2; } else if(dp->include_list && dp->include_list->nb_element == 1) { include1 = " include-list="; include2 = quote_string(dp->include_list->first->name); includefree = include2; } } if(dp->estimate == ES_CALCSIZE && !am_has_feature(hostp->features, fe_calcsize_estimate)) { log_add(L_WARNING,_("%s:%s does not support CALCSIZE for estimate, using CLIENT.\n"), hostp->hostname, qname); dp->estimate = ES_CLIENT; } if(dp->estimate == ES_CLIENT) calcsize = ""; else calcsize = "CALCSIZE "; if(strcmp(dp->program,"DUMP") == 0 || strcmp(dp->program,"GNUTAR") == 0) { backup_api = ""; } else { backup_api = "BACKUP "; } l = vstralloc(calcsize, backup_api, dp->program, " ", qname, " ", dp->device ? qdevice : "", " ", 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); } if (s != NULL) { estimates += i; strappend(req, s); req_len += s_len; amfree(s); } est(dp)->state = DISK_ACTIVE; remove_disk(&startq, dp); } else if (dp->estimate == ES_SERVER) { info_t info; nb_server++; get_info(dp->host->hostname, dp->name, &info); for(i = 0; i < MAX_LEVELS; i++) { int j; int lev = est(dp)->level[i]; if(lev == -1) break; if(lev == 0) { /* use latest level 0, should do extrapolation */ off_t est_size = (off_t)0; int nb_est = 0; for(j=NB_HISTORY-2;j>=0;j--) { if(info.history[j].level == 0) { if(info.history[j].size < (off_t)0) continue; est_size = info.history[j].size; nb_est++; } } if(nb_est > 0) { est(dp)->est_size[i] = est_size; } else if(info.inf[lev].size > (off_t)1000) { /* stats */ est(dp)->est_size[i] = info.inf[lev].size; } else { est(dp)->est_size[i] = (off_t)1000000; } } else if(lev == est(dp)->last_level) { /* means of all X day at the same level */ #define NB_DAY 30 int nb_day = 0; off_t est_size_day[NB_DAY]; int nb_est_day[NB_DAY]; for(j=0;j<NB_DAY;j++) { est_size_day[j]=(off_t)0; nb_est_day[j]=0; } for(j=NB_HISTORY-2;j>=0;j--) { if(info.history[j].level <= 0) continue; if(info.history[j].size < (off_t)0) continue; if(info.history[j].level==info.history[j+1].level) { if(nb_day <NB_DAY-1) nb_day++; est_size_day[nb_day] += info.history[j].size; nb_est_day[nb_day]++; } else { nb_day=0; } } nb_day = info.consecutive_runs + 1; if(nb_day > NB_DAY-1) nb_day = NB_DAY-1; while(nb_day > 0 && nb_est_day[nb_day] == 0) nb_day--; if(nb_est_day[nb_day] > 0) { est(dp)->est_size[i] = est_size_day[nb_day] / (off_t)nb_est_day[nb_day]; } else if(info.inf[lev].size > (off_t)1000) { /* stats */ est(dp)->est_size[i] = info.inf[lev].size; } else { est(dp)->est_size[i] = (off_t)10000; } } else if(lev == est(dp)->last_level + 1) { /* means of all first day at a new level */ off_t est_size = (off_t)0; int nb_est = 0; for(j=NB_HISTORY-2;j>=0;j--) { if(info.history[j].level <= 0) continue; if(info.history[j].size < (off_t)0) continue; if(info.history[j].level == info.history[j+1].level + 1 ) { est_size += info.history[j].size; nb_est++; } } if(nb_est > 0) { est(dp)->est_size[i] = est_size / (off_t)nb_est; } else if(info.inf[lev].size > (off_t)1000) { /* stats */ est(dp)->est_size[i] = info.inf[lev].size; } else { est(dp)->est_size[i] = (off_t)100000; } } } g_fprintf(stderr,_("%s time %s: got result for host %s disk %s:"), get_pname(), walltime_str(curclock()), dp->host->hostname, qname); g_fprintf(stderr,_(" %d -> %lldK, %d -> %lldK, %d -> %lldK\n"), est(dp)->level[0], (long long)est(dp)->est_size[0], est(dp)->level[1], (long long)est(dp)->est_size[1], est(dp)->level[2], (long long)est(dp)->est_size[2]); est(dp)->state = DISK_DONE; remove_disk(&startq, dp); enqueue_disk(&estq, dp); } amfree(qname); amfree(qdevice); } if(estimates == 0) { amfree(req); hostp->up = HOST_DONE; return; } if (conf_etimeout < 0) { timeout = - conf_etimeout; } else { timeout = estimates * conf_etimeout; } } else { /* noop service */ req = vstralloc("SERVICE ", "noop", "\n", "OPTIONS ", "features=", our_feature_string, ";", "\n", NULL); /* * We use ctimeout for the "noop" request because it should be * very fast and etimeout has other side effects. */ timeout = (time_t)getconf_int(CNF_CTIMEOUT); } secdrv = security_getdriver(hostp->disks->security_driver); if (secdrv == NULL) { hostp->up = HOST_DONE; log_add(L_ERROR, _("Could not find security driver '%s' for host '%s'"), hostp->disks->security_driver, hostp->hostname); amfree(req); return; } hostp->up = HOST_ACTIVE; for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) { if(dp->todo == 0) { continue; } if(est(dp)->state == DISK_ACTIVE) { est(dp)->errstr = NULL; enqueue_disk(&waitq, dp); } } protocol_sendreq(hostp->hostname, secdrv, amhost_get_security_conf, req, timeout, handle_result, hostp); amfree(req);}static disk_t *lookup_hostdisk( /*@keep@*/ am_host_t *hp, char *str){ disk_t *dp; for(dp = hp->disks; dp != NULL; dp = dp->hostnext) if(strcmp(str, dp->name) == 0) return dp; return NULL;}static void handle_result( void *datap, pkt_t *pkt, security_handle_t *sech){ int level, i; off_t size; disk_t *dp; am_host_t *hostp; char *msg, msg_undo; char *remoterr, *errbuf = NULL; char *s; char *t; char *fp; char *line; int ch; int tch; char *qname; char *disk; long long size_; hostp = (am_host_t *)datap; hostp->up = HOST_READY; if (pkt == NULL) { errbuf = vstrallocf(_("Request to %s failed: %s"), hostp->hostname, security_geterror(sech)); goto error_return; } if (pkt->type == P_NAK) { s = pkt->body; if(strncmp_const_skip(s, "ERROR ", s, ch) == 0) { ch = *s++; } 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; } } s = pkt->body; ch = *s++; while(ch) { line = s - 1; if(strncmp_const(line, "OPTIONS ") == 0) { t = strstr(line, "features="); if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) { t += SIZEOF("features=")-1; am_release_feature_set(hostp->features); if((hostp->features = am_string_to_feature(t)) == NULL) { errbuf = vstrallocf(hostp->hostname, _(": bad features value: %s\n"), line); goto error_return; } } skip_quoted_line(s, ch); continue; } t = line; if(strncmp_const_skip(t, "ERROR ", t, tch) == 0) { fp = t - 1; skip_whitespace(t, tch); 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 && pkt->type == P_NAK && (strcmp(t - 1, "unknown service: noop") == 0 || strcmp(t - 1, "noop: invalid service") == 0)) { skip_quoted_line(s, ch); continue; } errbuf = vstralloc(hostp->hostname, (pkt->type == P_NAK) ? "NAK " : "", ": ", fp, NULL); goto error_return; } msg = t = line; tch = *(t++); skip_quoted_string(t, tch); t[-1] = '\0'; disk = unquote_string(msg); skip_whitespace(t, tch); if (sscanf(t - 1, "%d", &level) != 1) { goto bad_msg; } skip_integer(t, tch); skip_whitespace(t, tch); dp = lookup_hostdisk(hostp, disk); dp = lookup_hostdisk(hostp, disk); if(dp == NULL) { log_add(L_ERROR, _("%s: invalid reply from sendsize: `%s'\n"), hostp->hostname, line); goto bad_msg; } size = (off_t)-1; if (strncmp_const(t-1,"SIZE ") == 0) { if (sscanf(t - 1, "SIZE %lld", &size_) != 1) { goto bad_msg; } size = (off_t)size_; } else if (strncmp_const(t-1,"ERROR ") == 0) { skip_non_whitespace(t, tch); skip_whitespace(t, tch); msg = t-1; skip_quoted_string(t,tch); msg_undo = t[-1]; t[-1] = '\0'; if (pkt->type == P_REP) { est(dp)->errstr = unquote_string(msg); } t[-1] = msg_undo; } else { goto bad_msg; } amfree(disk); if (size > (off_t)-1) { for(i = 0; i < MAX_LEVELS; i++) { if(est(dp)->level[i] == level) { est(dp)->est_size[i] = size; break; } } if(i == MAX_LEVELS) { goto bad_msg; /* this est wasn't requested */ } est(dp)->got_estimate++; } s = t; ch = tch; skip_quoted_line(s, ch); } if(hostp->up == HOST_READY && hostp->features == NULL) { /* * The client does not support the features list, so give it an * empty one. */ dbprintf(_("no feature set from host %s\n"), hostp->hostname); 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 */ for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) { if(dp->todo == 0) continue; if(est(dp)->state != DISK_ACTIVE && est(dp)->state != DISK_PARTIALY_DONE) continue; if(est(dp)->state == DISK_ACTIVE) { remove_disk(&waitq, dp); } else if(est(dp)->state == DISK_PARTIALY_DONE) { remove_disk(&pestq, dp); } if(pkt->type == P_REP) { est(dp)->state = DISK_DONE; } else if(pkt->type == P_PREP) { est(dp)->state = DISK_PARTIALY_DONE; } if(est(dp)->level[0] == -1) continue; /* ignore this disk */ qname = quote_string(dp->name); if(pkt->type == P_PREP) { g_fprintf(stderr,_("%s: time %s: got partial result for host %s disk %s:"), get_pname(), walltime_str(curclock()), dp->host->hostname, qname); g_fprintf(stderr,_(" %d -> %lldK, %d -> %lldK, %d -> %lldK\n"), est(dp)->level[0], (long long)est(dp)->est_size[0], est(dp)->level[1], (long long)est(dp)->est_size[1], est(dp)->level[2], (long long)est(dp)->est_size[2]); enqueue_disk(&pestq, dp); } else if(pkt->type == P_REP) { g_fprintf(stderr,_("%s: time %s: got result for host %s disk %s:"), get_pname(), walltime_str(curclock()), dp->host->hostname, qname); g_fprintf(stderr,_(" %d -> %lldK, %d -> %lldK, %d -> %lldK\n"), est(dp)->level[0], (long long)est(dp)->est_size[0], est(dp)->level[1], (long long)est(dp)->est_size[1],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -