X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Freporter.c;h=1b2a8c2e6d35a189f7b2e55a9875ce230e8803e0;hb=422c17cad7cd7473d9a3b0888ba5a02dd931262c;hp=17497f897e5c6eed0dd25ab4d09334d9b5cd6cc9;hpb=94a044f90357edefa6f4ae9f0b1d5885b0e34aee;p=debian%2Famanda diff --git a/server-src/reporter.c b/server-src/reporter.c index 17497f8..1b2a8c2 100644 --- a/server-src/reporter.c +++ b/server-src/reporter.c @@ -63,7 +63,7 @@ #define STATUS_TAPE 16 typedef struct line_s { - struct line_s *next; + struct line_s *next, *last; char *str; } line_t; @@ -84,6 +84,7 @@ typedef struct repdata_s { timedata_t taper; timedata_t dumper; timedata_t chunker; + timedata_t planner; int level; struct repdata_s *next; } repdata_t; @@ -302,6 +303,7 @@ addline( /* allocate new line node */ new = (line_t *) alloc(SIZEOF(line_t)); new->next = NULL; + new->last = NULL; new->str = stralloc(str); /* add to end of list */ @@ -309,9 +311,12 @@ addline( if (p == NULL) { *lp = new; } else { - while (p->next != NULL) - p = p->next; - p->next = new; + if (p->last) { + p->last->next = new; + } else { + p->next = new; + } + p->last = new; } } @@ -344,6 +349,7 @@ main( char *lbl_templ = NULL; config_overwrites_t *cfg_ovr = NULL; char *cfg_opt = NULL; + char *mailer; /* * Configure program for internationalization: @@ -460,26 +466,30 @@ main( amfree(cwd); -#if !defined MAILER - if(!outfname) { - g_printf(_("You must run amreport with '-f ' because configure\n")); - g_printf(_("didn't find a mailer.\n")); - exit (1); - } -#endif - /* read configuration files */ /* ignore any errors reading the config file (amreport can run without a config) */ config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD, cfg_opt); - if (cfg_ovr) apply_config_overwrites(cfg_ovr); + apply_config_overwrites(cfg_ovr); + + if (config_errors(NULL) >= CFGERR_WARNINGS) { + config_print_errors(); + } check_running_as(RUNNING_AS_DUMPUSER); - dbrename(config_name, DBG_SUBDIR_SERVER); + dbrename(get_config_name(), DBG_SUBDIR_SERVER); safe_cd(); /* must be called *after* config_init() */ + mailer = getconf_str(CNF_MAILER); + if (mailer && *mailer == '\0') + mailer = NULL; + if (!mailer && !outfname) { + g_printf(_("You must run amreport with '-f ' because a mailer is not defined\n")); + exit (1); + } + conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE)); /* Ignore error from read_diskfile */ read_diskfile(conf_diskfile, &diskq); @@ -605,41 +615,6 @@ main( /* ignore SIGPIPE so if a child process dies we do not also go away */ signal(SIGPIPE, SIG_IGN); - /* open pipe to mailer */ - - if(outfname) { - /* output to a file */ - if((mailf = fopen(outfname,"w")) == NULL) { - error(_("could not open output file: %s %s"), outfname, strerror(errno)); - /*NOTREACHED*/ - } - if (mailto != NULL) { - g_fprintf(mailf, "To: %s\n", mailto); - g_fprintf(mailf, "Subject: %s\n\n", subj_str); - } - - } else { -#ifdef MAILER - if(mailto) { - mail_cmd = vstralloc(MAILER, - " -s", " \"", subj_str, "\"", - " ", mailto, NULL); - if((mailf = popen(mail_cmd, "w")) == NULL) { - error(_("could not open pipe to \"%s\": %s"), - mail_cmd, strerror(errno)); - /*NOTREACHED*/ - } - } - else { - if(mailout) { - g_printf(_("No mail sent! ")); - g_printf(_("No valid mail address has been specified in amanda.conf or on the commmand line\n")); - } - mailf = NULL; - } -#endif - } - /* open pipe to print spooler if necessary) */ if(psfname) { @@ -694,10 +669,55 @@ main( } } - amfree(subj_str); - sort_disks(); + /* open pipe to mailer */ + + if(outfname) { + /* output to a file */ + if((mailf = fopen(outfname,"w")) == NULL) { + error(_("could not open output file: %s %s"), outfname, strerror(errno)); + /*NOTREACHED*/ + } + if (mailto != NULL) { + g_fprintf(mailf, "To: %s\n", mailto); + g_fprintf(mailf, "Subject: %s\n\n", subj_str); + } + + } else if (mailer) { + if(mailto) { + send_amreport_t send_amreport; + int do_mail; + + send_amreport = getconf_send_amreport(CNF_SEND_AMREPORT_ON); + do_mail = send_amreport == SEND_AMREPORT_ALL || + (send_amreport == SEND_AMREPORT_STRANGE && + (!got_finish || first_failed || errsum || + first_strange || errdet || strangedet)) || + (send_amreport == SEND_AMREPORT_ERROR && + (!got_finish || first_failed || errsum || errdet)); + if (do_mail) { + mail_cmd = vstralloc(mailer, + " -s", " \"", subj_str, "\"", + " ", mailto, NULL); + if((mailf = popen(mail_cmd, "w")) == NULL) { + error(_("could not open pipe to \"%s\": %s"), + mail_cmd, strerror(errno)); + /*NOTREACHED*/ + } + } + } + else { + if (mailout) { + g_printf(_("No mail sent! ")); + g_printf(_("No valid mail address has been specified in amanda.conf or on the commmand line\n")); + } + mailf = NULL; + } + } + + amfree(subj_str); + if(mailf) { if(!got_finish) fputs(_("*** THE DUMPS DID NOT FINISH PROPERLY!\n\n"), mailf); @@ -705,7 +725,7 @@ main( if (ghostname) { g_fprintf(mailf, _("Hostname: %s\n"), ghostname); g_fprintf(mailf, _("Org : %s\n"), getconf_str(CNF_ORG)); - g_fprintf(mailf, _("Config : %s\n"), config_name); + g_fprintf(mailf, _("Config : %s\n"), get_config_name()); g_fprintf(mailf, _("Date : %s\n"), nicedate(run_datestamp ? run_datestamp : "0")); g_fprintf(mailf,"\n"); @@ -776,7 +796,7 @@ main( int exitcode; if((exitcode = pclose(mailf)) != 0) { char *exitstr = str_exit_status("mail command", exitcode); - error(exitstr); + error("%s", exitstr); /*NOTREACHED*/ } mailf = NULL; @@ -807,20 +827,24 @@ main( double q = (b); \ if (!isnormal(q)) \ g_fprintf((fp)," -- "); \ - else if ((q = (a)/q) >= 999.95) \ - g_fprintf((fp), "###.#"); \ + else if ((q = (a)/q) >= 99999.95) \ + g_fprintf((fp), "#####"); \ + else if (q >= 999.95) \ + g_fprintf((fp), "%5.0lf",q); \ else \ - g_fprintf((fp), "%5.1lf",q); \ + g_fprintf((fp), "%5.1lf",q); \ } while(0) #define divzero_wide(fp,a,b) \ do { \ double q = (b); \ if (!isnormal(q)) \ g_fprintf((fp)," -- "); \ - else if ((q = (a)/q) >= 99999.95) \ - g_fprintf((fp), "#####.#"); \ + else if ((q = (a)/q) >= 9999999.95) \ + g_fprintf((fp), "#######"); \ + else if (q >= 99999.95) \ + g_fprintf((fp), "%7.0lf",q); \ else \ - g_fprintf((fp), "%7.1lf",q); \ + g_fprintf((fp), "%7.1lf",q); \ } while(0) static void @@ -1002,9 +1026,10 @@ output_stats(void) static void output_tapeinfo(void) { - tape_t *tp, *lasttp; + tape_t *tp; int run_tapes; int skip = 0; + int i, nb_new_tape; if (last_run_tapes > 0) { if(amflush_run) @@ -1046,7 +1071,7 @@ output_tapeinfo(void) if (h_size > 0) { g_fprintf(mailf, _("There are %lld%s of dumps left in the holding disk.\n"), - (long long)h_size, displayunit); + (long long)du(h_size), displayunit); if (getconf_boolean(CNF_AUTOFLUSH)) { g_fprintf(mailf, _("They will be flushed on the next run.\n")); } else { @@ -1068,53 +1093,36 @@ output_tapeinfo(void) else if(run_tapes > 1) g_fprintf(mailf, _("The next %d tapes Amanda expects to use are: "), run_tapes); - - while(run_tapes > 0) { + + nb_new_tape = 0; + for (i=0 ; i < run_tapes ; i++) { if(tp != NULL) { + if (nb_new_tape > 0) { + if (nb_new_tape == 1) + g_fprintf(mailf, _("1 new tape, ")); + else + g_fprintf(mailf, _("%d new tapes, "), nb_new_tape); + nb_new_tape = 0; + } g_fprintf(mailf, "%s", tp->label); + if (i < run_tapes-1) fputs(", ", mailf); } else { - if (run_tapes == 1) - g_fprintf(mailf, _("a new tape")); - else - g_fprintf(mailf, _("%d new tapes"), run_tapes); - run_tapes = 1; + nb_new_tape++; } - - if(run_tapes > 1) fputs(", ", mailf); - - run_tapes -= 1; skip++; + tp = lookup_last_reusable_tape(skip); } + if (nb_new_tape > 0) { + if (nb_new_tape == 1) + g_fprintf(mailf, _("1 new tape")); + else + g_fprintf(mailf, _("%d new tapes"), nb_new_tape); + } fputs(".\n", mailf); - lasttp = lookup_tapepos(lookup_nb_tape()); run_tapes = getconf_int(CNF_RUNTAPES); - if(lasttp && run_tapes > 0 && strcmp(lasttp->datestamp,"0") == 0) { - int c = 0; - while(lasttp && run_tapes > 0 && strcmp(lasttp->datestamp,"0") == 0) { - c++; - lasttp = lasttp->prev; - run_tapes--; - } - lasttp = lookup_tapepos(lookup_nb_tape()); - if(c == 1) { - g_fprintf(mailf, _("The next new tape already labelled is: %s.\n"), - lasttp->label); - } - else { - g_fprintf(mailf, _("The next %d new tapes already labelled are: %s"), c, - lasttp->label); - lasttp = lasttp->prev; - c--; - while(lasttp && c > 0 && strcmp(lasttp->datestamp,"0") == 0) { - g_fprintf(mailf, ", %s", lasttp->label); - lasttp = lasttp->prev; - c--; - } - g_fprintf(mailf, ".\n"); - } - } + print_new_tapes(mailf, run_tapes); } /* ----- */ @@ -1298,7 +1306,7 @@ CalcMaxWidth(void) "%3d:%02d", mnsc(repdata->dumper.sec)); else g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "N/A "); + " "); CheckStringMax(&ColumnData[DumpTime], TimeRateBuffer); CheckFloatMax(&ColumnData[DumpRate], repdata->dumper.kps); @@ -1314,14 +1322,14 @@ CalcMaxWidth(void) "%3d:%02d", mnsc(repdata->taper.sec)); else g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "N/A "); + " "); CheckStringMax(&ColumnData[TapeTime], TimeRateBuffer); if(repdata->taper.result == L_SUCCESS || repdata->taper.result == L_CHUNKSUCCESS) CheckFloatMax(&ColumnData[TapeRate], repdata->taper.kps); else - CheckStringMax(&ColumnData[TapeRate], "N/A "); + CheckStringMax(&ColumnData[TapeRate], " "); } } } @@ -1339,6 +1347,7 @@ output_summary(void) int i, h, w1, wDump, wTape; double outsize, origsize; double f; + int cdWidth; HostName = StringToColumn("HostName"); Disk = StringToColumn("Disk"); @@ -1427,9 +1436,14 @@ output_summary(void) qdevname = quote_string(devname); devlen = strlen(qdevname); if (devlen > (size_t)cd->Width) { - fputc('-', mailf); - g_fprintf(mailf, cd->Format, cd->Width-1, cd->Precision-1, - qdevname+devlen - (cd->Width-1) ); + int nb = 1; + if (strcmp(devname, qdevname)) { + nb = 2; + fputc('"', mailf); + } + fputc('-', mailf); + g_fprintf(mailf, cd->Format, cd->Width-nb, cd->Precision-nb, + qdevname+devlen - (cd->Width-nb) ); } else g_fprintf(mailf, cd->Format, cd->Width, cd->Width, qdevname); @@ -1492,7 +1506,7 @@ output_summary(void) if(isnormal(origsize)) g_fprintf(mailf, cd->Format, cd->Width, cd->Precision, du(origsize)); else - g_fprintf(mailf, "%*.*s", cd->Width, cd->Width, "N/A"); + g_fprintf(mailf, "%*.*s", cd->Width, cd->Width, ""); cd= &ColumnData[OutKB]; g_fprintf(mailf, "%*s", cd->PrefixSpace, ""); @@ -1512,23 +1526,46 @@ output_summary(void) fputs(sDivZero(pct(outsize), f, Compress), mailf); cd= &ColumnData[DumpTime]; + cdWidth = 0; g_fprintf(mailf, "%*s", cd->PrefixSpace, ""); if(repdata->dumper.result == L_SUCCESS || - repdata->dumper.result == L_CHUNKSUCCESS) + repdata->dumper.result == L_CHUNKSUCCESS) { g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "%3d:%02d", mnsc(repdata->dumper.sec)); - else - g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "N/A "); - g_fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer); + "%3d:%02d", mnsc(repdata->dumper.sec)); + g_fprintf(mailf, cd->Format, cd->Width, cd->Width, + TimeRateBuffer); + } else { + cdWidth = cd->Width; + } cd= &ColumnData[DumpRate]; g_fprintf(mailf, "%*s", cd->PrefixSpace, ""); - if(repdata->dumper.result == L_SUCCESS || - repdata->dumper.result == L_CHUNKSUCCESS) - g_fprintf(mailf, cd->Format, cd->Width, cd->Precision, repdata->dumper.kps); - else - g_fprintf(mailf, "%*s", cd->Width, "N/A "); + if (repdata->dumper.result == L_SUCCESS || + repdata->dumper.result == L_CHUNKSUCCESS) { + g_fprintf(mailf, cd->Format, cd->Width, cd->Precision, + repdata->dumper.kps); + } else if (repdata->dumper.result == L_FAIL) { + if (repdata->chunker.result == L_PARTIAL || + repdata->taper.result == L_PARTIAL) { + int i; + cdWidth += cd->Width; + i = (cdWidth - strlen("PARTIAL")) / 2; + g_fprintf(mailf, "%*s%*s", cdWidth-i, "PARTIAL", i, ""); + } else { + int i; + cdWidth += cd->Width; + i = (cdWidth - strlen("FAILED")) / 2; + g_fprintf(mailf, "%*s%*s", cdWidth-i, "FAILED", i, ""); + } + } else if (repdata->dumper.result == L_BOGUS) { + int i; + cdWidth += cd->Width; + i = (cdWidth - strlen("FLUSH")) / 2; + g_fprintf(mailf, "%*s%*s", cdWidth-i, "FLUSH", i, ""); + } else { + cdWidth += cd->Width; + g_fprintf(mailf, "%*s", cdWidth, ""); + } cd= &ColumnData[TapeTime]; g_fprintf(mailf, "%*s", cd->PrefixSpace, ""); @@ -1546,7 +1583,7 @@ output_summary(void) "%3d:%02d", mnsc(repdata->taper.sec)); else g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "N/A "); + " "); g_fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer); cd= &ColumnData[TapeRate]; @@ -1556,7 +1593,7 @@ output_summary(void) repdata->taper.result == L_CHUNKSUCCESS) g_fprintf(mailf, cd->Format, cd->Width, cd->Precision, repdata->taper.kps); else - g_fprintf(mailf, "%*s", cd->Width, "N/A "); + g_fprintf(mailf, "%*s", cd->Width, " "); if (repdata->chunker.result == L_PARTIAL) g_fprintf(mailf, " PARTIAL"); @@ -1932,10 +1969,23 @@ static void handle_note(void) { char *str = NULL; + char *pidstr; - str = vstrallocf(" %s: %s", program_str[curprog], curstr); - addline(¬es, str); - amfree(str); + if (curprog == P_DRIVER && + BSTRNCMP(curstr, "Taper protocol error") == 0) { + exit_status |= STATUS_TAPE; + } + pidstr = strchr(curstr,' '); + if (pidstr) { + pidstr++; + } + /* Don't report the pid lines */ + if ((!pidstr || BSTRNCMP(pidstr, "pid ") != 0) && + BSTRNCMP(curstr, "pid-done ") != 0) { + str = vstrallocf(" %s: %s", program_str[curprog], curstr); + addline(¬es, str); + amfree(str); + } } @@ -2354,6 +2404,17 @@ handle_success( if(!isnormal(origkb)) origkb = 0.1; } + if (curprog == P_TAPER && logtype == L_PARTIAL) { + char *t = strchr(s-1,']'); + if (t) { + char *errmsg, *u; + errmsg = unquote_string(t+1); + u = vstrallocf(" %s: partial %s: %s", + prefix(hostname, diskname, level), + program_str[curprog], errmsg); + addline(&errsum, u); + } + } } @@ -2386,7 +2447,12 @@ handle_success( i = level > 0; - if(origkb < 0.0) { + if (origkb < 0.0 && (curprog == P_CHUNKER || curprog == P_TAPER) && + isnormal(repdata->dumper.outsize)) { + /* take origkb from DUMPER line */ + origkb = repdata->dumper.outsize; + } else if (origkb < 0.0) { + /* take origkb from infofile, needed for amflush */ info_t inf; struct tm *tm; int Idatestamp; @@ -2441,6 +2507,8 @@ handle_success( if(!isnormal(repdata->chunker.outsize) && isnormal(repdata->dumper.outsize)) { /* dump to tape */ stats[i].outsize += kbytes; if (abs(kbytes - origkb) >= 32) { + /* server compressed */ + stats[i].corigsize += origkb; stats[i].coutsize += kbytes; } } @@ -2450,10 +2518,13 @@ handle_success( if(curprog == P_DUMPER) { stats[i].dumper_time += sec; if (abs(kbytes - origkb) < 32) { + /* not client compressed */ sp->origsize = kbytes; } else { + /* client compressed */ stats[i].corigsize += sp->origsize; + stats[i].coutsize += kbytes; } dumpdisks[level] +=1; stats[i].dumpdisks +=1; @@ -2464,6 +2535,8 @@ handle_success( sp->outsize = kbytes; stats[i].outsize += kbytes; if (abs(kbytes - origkb) >= 32) { + /* server compressed */ + stats[i].corigsize += origkb; stats[i].coutsize += kbytes; } } @@ -2617,6 +2690,8 @@ handle_failed(void) if(curprog == P_TAPER) sp = &(repdata->taper); + else if (curprog == P_PLANNER) + sp = &(repdata->planner); else sp = &(repdata->dumper); if(sp->result != L_SUCCESS) @@ -2624,10 +2699,17 @@ handle_failed(void) } amfree(datestamp); - str = vstrallocf(_("FAILED %s"), errstr); - addtoX_summary(&first_failed, &last_failed, hostname, qdiskname, level, - str); - amfree(str); + if (!((curprog == P_CHUNKER && + strcmp(errstr, "[dumper returned FAILED]") == 0) || + (curprog == P_CHUNKER && + strcmp(errstr, "[Not enough holding disk space]") == 0) || + (curprog == P_CHUNKER && + strcmp(errstr, "[cannot read header: got 0 bytes instead of 32768]") == 0))) { + str = vstrallocf(_("FAILED %s"), errstr); + addtoX_summary(&first_failed, &last_failed, hostname, qdiskname, level, + str); + amfree(str); + } if(curprog == P_DUMPER) { addline(&errdet,""); @@ -2688,7 +2770,7 @@ generate_bad_estimate(void) else outsize = repdata->dumper.outsize; - if(repdata->est_csize * 0.9 > outsize) { + if( (repdata->est_csize * 0.9 > outsize) && ( repdata->est_csize - outsize > 1.0e5 ) ) { g_snprintf(s, 1000, _(" big estimate: %s %s %d"), repdata->disk->host->hostname, @@ -2703,7 +2785,7 @@ generate_bad_estimate(void) s[999] = '\0'; addline(¬es, s); } - else if(repdata->est_csize * 1.1 < outsize) { + else if( (repdata->est_csize * 1.1 < outsize) && (outsize - repdata->est_csize > 1.0e5 ) ) { g_snprintf(s, 1000, _(" small estimate: %s %s %d"), repdata->disk->host->hostname, @@ -2982,7 +3064,7 @@ do_postscript_output(void) else { g_fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8s) (%8.0lf) DrawHost\n", dp->host->hostname, dp->name, repdata->level, - repdata->taper.filenum, "N/A", + repdata->taper.filenum, "", outsize); } }